CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

VBAP.h
Go to the documentation of this file.
1 ///
2 /// VBAP.h -- Vector Base Amplitude Panning class (v2 - Nov 2006)
3 /// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 /// Doug McCoy, 2004.
5 ///
6
7 #ifndef CSL_VBAP_H
8 #define CSL_VBAP_H
9
10 #include "CSL_Core.h"
11 #include "SpatialPanner.h"
12
13 //#define CSL_DEBUG
14
15 #define MAX_NUM_VBAP_SOURCES 8
16
17 #include <iostream>
18
19 ///////////////// used for matrix.h //////////////////
20 #define _NO_EXCEPTION
21
22 #include "matrix.hpp"
23 //#include <cmatrix>
24
25 #ifndef _NO_NAMESPACE
26 using namespace std;
27 using namespace math;
28 // using namespace techsoft;
29 #define STD std
30 #else
31 #define STD
32 #endif
33
34 #define TRYBEGIN()
35 #define CATCHERROR()
36
37 typedef matrix<double> CSLMatrix;
38
39 ///////////////// end used for matrix.h //////////////////
40
41 namespace csl {
42
43 #define deg2rad(x) (((double)x ) * CSL_TWOPI) / 360.0
44
45 /// VBAP types
46 typedef enum {
47 kAuto = 0,
48 kPantophonic = 2, ///< Only uses the horizontally placed speakers (zero elevation)
49 kPeriphonic = 3 ///< Full 3D VBAP
50 } VBAPMode;
51
52 class SpeakerSetLayout; // Forward declaration. See below.
53
54
55 /// Vector Base Amplitude Panning.
56 /**
57 A panning technique that uses amplitude as the method for sound placement (just as stereo panning does).
58 When multiple speakers are present, sets of all possible adjacent speaker pairs or in triples (depending if doing
59 3D or only 2D panning) are found, reducing the "Active speakers" to two or three. See Pulkki for more info.
60 */
61 class VBAP : public SpatialPanner {
62 public:
63 /// Initializer for a VBAP Panner. Optionally a speaker layout can be specified.
64 /// Defaults to auto, decided according to layout. If not specified uses the default speaker layout.
65 VBAP(VBAPMode mode = kAuto, SpeakerLayout *layout = SpeakerLayout::defaultSpeakerLayout());
66
67 virtual ~VBAP();
68
69 /// Just as any Effect in CSL, this method gets called at runtime by the audio driver. Here is where the actual processing happens.
70 void nextBuffer(Buffer &outputBuffer) throw (CException);
71 void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
72
73 void dump() { }; ///< Prints useful information about this VBAP instance.
74
75 protected:
76 VBAPMode mMode; ///< Represents the dimensionality of the panner, either 2 or 3. 2D meaning horizontal panning only.
77 SpeakerSetLayout *mSpeakerSetLayout; ///< A reference to the layout that contains the speaker pairs or triplets.
78
79 virtual void *cache(); ///< Returns an instance of it's cache data per sound source.
80 virtual void speakerLayoutChanged(); ///< called when the speaker layout changes, so panners update precalculated data
81
82 };
83
84 /// Simple Stereo Panner
85 /// @todo Add method for setting the pan value from 0 to 1.
86 class StereoPanner : public VBAP {
87 public:
88 StereoPanner();
89 virtual ~StereoPanner();
90
91 void addInput(UnitGenerator &input, float panPosition);
92
93 };
94
95 /// Generic Panner for most surround formats.
96 /// It accepts any number of speakers around the horizontal plane, and a subwoofer (.1 or not)
97 class SurroundPanner : public VBAP {
98 public:
99 /// The constructor defaults to a 5.1 setup.
100 SurroundPanner(unsigned numSpeakers = 5, bool useSubwoofer = true);
101 virtual ~SurroundPanner();
102
103 };
104
105 // Used for caching data from previous callbacks. Each SpatialSource has its own set of data to be remembered.
106 // This is just for internal use of the VBAP object.
107 class VBAPSourceCache {
108 public:
109 VBAPSourceCache() : tripletIndex(0) { };
110 ~VBAPSourceCache() { };
111
112 float gains[3];
113 unsigned tripletIndex;
114 };
115
116 /// Groups two or three loudspeakers, and their inverse. Used for VBAP computations.
117 class SpeakerSet {
118 public:
119 SpeakerSet(unsigned size = 3);
120 ~SpeakerSet();
121
122 unsigned *nodes; ///< the index for each of the three speakers that represent the triplet
123 CSLMatrix *invL; ///< pre-computed inverse matrix for this triplet
124 void dump(); ///< just print friendly info about the triplet
125 };
126
127 /*// **** SPEAKER TRIPLET LAYOUT *****
128 TO AVOID BUILDING A TRIPLET LAYOUT PER VBAP INSTANCE, THE VBAP CLASS WILL HAVE A STATIC METHOD THAT
129 RETURS A MAP OF THE SPEAKER LAYOUT (KEY) AND THE TRIPLET SPEAKER LAYOUT (VALUE). THIS WAY, IF ANOTHER
130 INSTANCE HAS ALREADY CREATED A TRIPLET LAYOUT (IN OTHER WORDS IF A NEW INSTANCE IS USING THE SAME LAYOUT
131 THAN THE ALREADY CREATED INSTANCE) THEN A POINTER TO THE TRIPLET LAYOUT WILL BE RETURNED.
132 AS AN ALTERNATIVE, INSTEAD OF A MAP, THE TRIPLET SPEAKER LAYOUT WILL HOLD A POINTER TO THE SPEAKER LAYOUT
133 AND WILL BE ABLE TO COMPARE TO A PASSED POINTER. IN THES CASE, A STATIC VECTOR OF TRIPLET LAYOUTS WOULD HOLD
134 THE ALREADY CREATED TRIPLET LAYOUTS AND WHEN CREATING A NEW VBAP INSTANCE, IT WOULD GO THRU EACH TRIPLET LAYOUT
135 (IF ANY) COMPARING SPEAKER LAYOUT ADDRESSES. IF A MATCH IS FOUND, THE TRIPLET LAYOUT WOULD BE SET TO BE THE OBJECT
136 HELD BY THE VBAP INSTANCE (EACH VBAP INSTANCE WILL KEEP ITS OWN POINTER TO ITS TRIPLET LAYOUT OBJECT. FOR THIS TO WORK
137 SOME SORT OF COUNT WILL BE NEEDED SO WHEN NO OBJECT IS KEEPING A TRIPLET, THEN IT SHOULD GET DESTROYED.
138 WHEN SETTING THE SPEAKER LAYOUT, THE OBJECT WILL HAVE TO SEARCH AGAIN FOR TRIPLET LAYOUTS ALREADY CREATED, AND RE COMPUTE
139 ONE IF NONE EXISTS.
140 ADVANTAGES:
141 A) THE TRIPLET FINDING GOES TO THE LAYOUT AND AWAY FROM THE VBAP, SIMPLIFYING THE VABAP INTERFACE.
142 B) SAVES MEMORY USAGE BY HAVING ONLY ONE INSTANCE OF TRIPLETS FOR EACH LAYOUT USED.
143 IN MOST CASES, ONLY ONE LAYOUT IS USED, WHICH TRANSLATIES INTO ONLY ONE SET OF TRIPLETS IN MEMORY.
144 C) SAVES COMPUTATION BY NOT RECALCULATING TRIPLETS FOR EACH VBAP INSTANCE. IT DOES IT ONLY ON ONE.
145
146 COST:
147 A) COMPUTATIONALLY THE COST IS MINIMAL. AT INSTANTIATION TIME, THE OBJECT HAS TO SEARCH THRU A VECTOR.
148 THIS BECOMES NULL IF NO OBJECTS ARE USED AND INSIGNIFICANT WHEN ONE OR MORE OBJECTS ARE INSTANTIATED.
149 B) REGARDING MEMORY, IT'LL HAVE TO LOAD STATICALLY A VECTOR AT APP LOAD TIME...
150
151 */
152 class SpeakerSetLayout {
153 friend class VBAP; // Grant VBAP the access to your private members.
154 public:
155 /// Constructors & destructor:
156 SpeakerSetLayout(SpeakerLayout *aLayout, VBAPMode mode = kAuto); ///< default constructor. Creates an empty speaker layout.
157 ~SpeakerSetLayout(); ///< destructor
158
159 /// Returns the Speaker Layout used to find the triplets.
160 SpeakerLayout *speakerLayout() { return mSpeakerLayout; }; // Ussed to compare layouts in case it's already calculated.
161
162 void dump();
163
164 private:
165 // THE TRIPLETS SHOULD BE SHARED AMONG ALL VBAP OBJECTS, UNLESS MULTIPLE LAYOUTS ARE USED SIMULTANEOUSLY.
166 SpeakerSet **mTriplets; // list of output triples
167 SpeakerLayout *mSpeakerLayout;
168 unsigned mNumTriplets;
169 unsigned mMode;
170
171 void findSpeakerTriplets() throw(CException);
172 void findSpeakerPairs() throw(CException);
173 void invertTripleMatrix(SpeakerSet *lst);
174 void addTriple(SpeakerSet *lst);
175 void removeTriple(SpeakerSet *lst);
176 bool evaluateCrossing(CPoint &li, CPoint &lj, CPoint &ln, CPoint &lm);
177 };
178
179 } // end namespace
180
181 #endif
182