CSL  6.0
Ambisonic.h
Go to the documentation of this file.
1 //
2 // Ambisonic.h -- Higher Order Ambisonic abstract base class for all Ambisonic effects and panners.
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 // Higher Order Ambisonic classes written by Jorge Castellanos, Graham Wakefield, Florian Hollerweger, 2005
5 //
6 // Encapsulates parameters regarding the ambisonic order of the class (including hybrid orders)
7 //
8 // CONVENTIONS USED IN THIS CODE:
9 // ------------------------------
10 //
11 // ***coordinate system***
12 // Left oriented
13 // Azimuth = 0 on the x/z plane and increasing towards the positive y direction
14 // Elevation = 0 on x/y plane and increasing towards the positive z direction
15 // Internal angle representation: spherical radians
16 //
17 // ***encoding convention***
18 // following the Furse-Malham set (Ambisonic channel weighting for uniform energy distribution)
19 //
20 // ***abbreviations used in code and comments***
21 // M ... Ambisonic order (in uniform order system)
22 // M_h ... horizontal Ambisonic order (in hybrid order systems)
23 // M_v ... horizontal Ambisonic order (in hybrid order systems)
24 // N ... total number of Ambisonic encoded channels (horizontal and vertical)
25 // N_h ... number of horizontal Ambisonic channels (in hybrid order systems)
26 // N_v ... number of vertical Ambisonic channels (in hybrid order systems)
27 // L ... number of available loudspeakers
28 //
29 // ***ordering and naming of Ambisonic channels = spherical harmonics***
30 // These conventions follow the ones used in the thesis by Jerome Daniel.
31 // The 3rd order naming convention (which Daniel doesn't provide) follows the one used in the thesis of David Malham.
32 // Watch out for different conventions in other papers!
33 // index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
34 // M (order) 0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3
35 // m (=M) 0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3
36 // n 0 1 1 0 2 2 1 1 0 3 3 2 2 1 1 0
37 // sigma '1' 1 -1 '1' 1 -1 1 -1 '1' 1 -1 1 -1 1 -1 '1'
38 // name W X Y Z U V S T R P Q N O L M K
39 // hor/vert/omni om h h v h h v v v h h v v v v v
40 //
41 
42 #ifndef CSL_AMBISONIC_H
43 #define CSL_AMBISONIC_H
44 
45 #include "CSL_Core.h"
46 #include "CPoint.h"
47 #include "SpatialSource.h"
48 #include "SpeakerLayout.h"
49 
50 #define HOA_MAX_ORDER 2 // maximum order that the CSL HOA will handle
51 
52 namespace csl {
53 
54 /// Ambisonic order structure (separate definition for horizontal and vertical order):
55 /// \relates AmbisonicUnitGenerator
56 
58 public:
59  AmbisonicOrder(unsigned hOrder = 0, unsigned vOrder = 0) : horizontalOrder(hOrder), verticalOrder(vOrder) { };
61 
62  unsigned horizontalOrder;
63  unsigned verticalOrder;
64  bool isUniform; ///< Returns true if horizontal and verical orders are identical.
65 };
66 
67 /// Ambisonic Abstract Base Class.
68 
70 public:
71 
72  // Constructors & destructor:
73  AmbisonicUnitGenerator(unsigned order = 0); ///< Initialize with uniform Ambisonic order. Defaults to zeroth order.
74  AmbisonicUnitGenerator(unsigned horder, unsigned vorder); ///< Initialize with hybrid Ambisonic order
76  virtual ~AmbisonicUnitGenerator();
77 
78  AmbisonicOrder order() { return mOrder; }; ///< Returns the Ambisonic order.
79 
80 protected:
81  void setOrder(AmbisonicOrder order);
82 
83  AmbisonicOrder mOrder; ///< the order of the Unit Generator
84 
85  // returns the Ambisonic order from the number of Ambisonic channels: M = floor(sqrt(N) - 1)
86  // NOTE - only works for uniform horizontal and vertical order (whereas ambiguity occurs in hybrid order systems)!
87  unsigned channelsToUniformOrder(const unsigned channels);
88 
89  /// Compares the horizontal and vertical Ambisonic order of a hybrid order and returns the largest
90  unsigned greaterOrder(const AmbisonicOrder order);
91 
92  /// Returns the number of Ambisonic channels from a hybrid Ambisonic order: N = 2*M_h + 1 + (M_v + 1)^2 - (2*M_v + 1)
93  unsigned orderToChannels(const AmbisonicOrder order);
94 
95  /// Returns the number of Ambisonic channels corresponding to a uniform Ambisonic order: N = (M+1)^2
96  unsigned orderToChannels(unsigned order);
97 
98  /// Returns the number of horizontal Ambisonic channels from a hybrid Ambisonic order: N_h = 2*M_h + 1
99  unsigned orderToHorizontalChannels(const AmbisonicOrder order);
100 
101  /// Returns the number of vertical Ambisonic channels from a hybrid Ambisonic order: N_v = (M_v + 1)^2 - (2*M_v + 1)
102  unsigned orderToVerticalChannels(const AmbisonicOrder order);
103 
104  /// Calculates a lookup table to map Ambisonic channel index to actually used UnitGenerator channel
105  void channelIndexer(unsigned *indexArray);
106 
107  /// Calculates a lookup table to map actually used UnitGenerator channel to Ambisonic channel index
108  void invChannelIndexer(unsigned *indexArray);
109 
110 private:
111 
112  void initOrder(); // generic initialisation function
113 
114 };
115 
116 // AmbisonicEncoder -- Higher Order Ambisonic encoding class
117 //
118 // Higher Order Ambisonic class for positioning mono sound sources into an Ambisonic encoded soundfield.
119 // The position information is fed to the encoder as two multichannel framestreams (azimuth and elevation).
120 // It is possible to specify either one uniform Ambisonic order or to define the horizontal and vertical
121 // order separately (hybrid order encoding). If no order(s) is/are specified, first order Ambisonic will be used (B-Format).
122 
124 public:
125 
126  AmbisonicEncoder(); ///< Default constructor
127  AmbisonicEncoder(SpatialSource &input, unsigned order = 1); ///< Initialize with uniform Ambisonic order
128  AmbisonicEncoder(SpatialSource &input, unsigned horder, unsigned vorder); ///< Initialize with hybrid Ambisonic order
129 
130  virtual ~AmbisonicEncoder(); ///< Destructor
131 
132  void setInput(SpatialSource &input); ///< Set my input
134 
135  /// Does the DSP processing for the Ambisonic Encoder.
136  virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
137 
138 protected:
139  SampleBuffer mWeights; ///< Encoding weights for each order (per source)
140  Port *mInputPort; ///< Holds the input to be encoded.
141  void initialize(); ///< Initializing method called by constructors
142 };
143 
144 /// Flag for the decoding method
145 
146 typedef enum {
150 
151 /// Flag for the decoder flavour
152 
153 typedef enum {
154  kBASIC = 0,
158 
159 //
160 // AmbisonicDecoder -- Higher Order Ambisonic Decoding class
161 //
162 // Higher Order Ambisonic class for decoding an Ambisonic encoded soundfield (e.g. the output of the AmbisonicEncoder or
163 // the AmbisonicRotator) to a loudspeaker layout specified by SpeakerLayout. The Ambisonic order at which the decoder
164 // oprates is derived by the following criteria: If no order is specified in the constructor, the order of the Ambisonic
165 // encoded input is used. This order can be downgraded either by specifying a lower order in the constructor
166 // (obviously, it cannot be increased). The decoder might further decrease the given order to match the maximum
167 // order reproducable on the available loudspeaker layout. One out of two different decoding methods can be chosen by
168 // using the flags kPROJECTION, kPSEUDOINVERSE in the constructor. One out of three available decoder flavors can
169 // be applied by using the flags kBASIC, kINPHASE, kMAXRE.
170 //
171 
173 public:
174  // Constructors & destructor:
175  /// Defaults to standard speaker layout as defined in "HOA_SpeakerLayout" class and to Ambisonic order of encoded input
179  AmbisonicDecoderFlavour flavour = kBASIC);
180  /// Initializes with uniform Ambisonic order, defaults to standard speaker layout as defined in "HOA_SpeakerLayout" class
181  AmbisonicDecoder(UnitGenerator &input, unsigned order,
184  AmbisonicDecoderFlavour flavour = kBASIC);
185  /// Initializes with hybrid Ambisonic order
186  AmbisonicDecoder(UnitGenerator &input, unsigned hOrder, unsigned vOrder,
189  AmbisonicDecoderFlavour flavour = kBASIC);
190 
191  ~AmbisonicDecoder(); ///< Destructor
192 
193  /// Does the DSP processing for the Ambisonic Decoder.
194  virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
195 
196 protected:
197 
199  float mNumChannelsInv; // inverse of the numbers of loudspeakers (used for normalization)
200  int *mIOChannelMap; // lookup table from index of actually used Ambisonic channel input Ambisonic channel index
201  SampleBufferVector mDecodingMatrix; // deccoding matrix D
202  SpeakerLayout *mSpeakerLayout; // loudspeaker layout provided by "HOA_SpeakerLayout" class
203  AmbisonicDecoderMethod mDecodingMethod; // decoding method: projection or pseudoinverse
204  AmbisonicDecoderFlavour mDecoderFlavour; // decoder flavour: basic, in-phase or max-rE
205 
206 
207  /// initializing method called by constructors
209 
210  void asProjection(); ///< Create the decoding matrix "D" using the projection method
211  void asPseudoInverse(); ///< create the decoding matrix "D" using the pseudoinverse method
212 
213  void makeInPhase(unsigned greaterOrder); ///< Adjusts the decoding matrix D for in-phase flavour
214  void makeMaxRE(unsigned greaterOrder); ///< Adjusts the decoding matrix D for Max rE flavour
215 
216  void makeTransposedReEncodingMatrix(float **transposeMatrix); ///< Utility method that creates the transposed re-encoding matrix C'
217 
218 };
219 
220 }
221 
222 #endif
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
Definition: CSL_Types.h:194
AmbisonicOrder(unsigned hOrder=0, unsigned vOrder=0)
Definition: Ambisonic.h:59
AmbisonicDecoder(AmbisonicUnitGenerator &input, SpeakerLayout *layout=SpeakerLayout::defaultSpeakerLayout(), AmbisonicDecoderMethod method=kPROJECTION, AmbisonicDecoderFlavour flavour=kBASIC)
Defaults to standard speaker layout as defined in "HOA_SpeakerLayout" class and to Ambisonic order of...
Definition: Ambisonic.cpp:291
void setOrder(AmbisonicOrder order)
Returns the Ambisonic order.
Definition: Ambisonic.cpp:59
void makeMaxRE(unsigned greaterOrder)
Adjusts the decoding matrix D for Max rE flavour.
Definition: Ambisonic.cpp:610
void asProjection()
Create the decoding matrix "D" using the projection method.
Definition: Ambisonic.cpp:457
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
void channelIndexer(unsigned *indexArray)
Calculates a lookup table to map Ambisonic channel index to actually used UnitGenerator channel...
Definition: Ambisonic.cpp:98
unsigned orderToChannels(const AmbisonicOrder order)
Returns the number of Ambisonic channels from a hybrid Ambisonic order: N = 2*M_h + 1 + (M_v + 1)^2 -...
Definition: Ambisonic.cpp:75
SampleBuffer mWeights
Encoding weights for each order (per source)
Definition: Ambisonic.h:139
unsigned greaterOrder(const AmbisonicOrder order)
Compares the horizontal and vertical Ambisonic order of a hybrid order and returns the largest...
Definition: Ambisonic.cpp:71
AmbisonicDecoderFlavour mDecoderFlavour
Definition: Ambisonic.h:204
AmbisonicUnitGenerator(unsigned order=0)
Initialize with uniform Ambisonic order. Defaults to zeroth order.
Definition: Ambisonic.cpp:34
Ambisonic order structure (separate definition for horizontal and vertical order): ...
Definition: Ambisonic.h:57
virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
Does the DSP processing for the Ambisonic Decoder.
Definition: Ambisonic.cpp:667
unsigned orderToHorizontalChannels(const AmbisonicOrder order)
Returns the number of horizontal Ambisonic channels from a hybrid Ambisonic order: N_h = 2*M_h + 1...
Definition: Ambisonic.cpp:85
AmbisonicOrder order()
Definition: Ambisonic.h:78
void asPseudoInverse()
create the decoding matrix "D" using the pseudoinverse method
Definition: Ambisonic.cpp:474
bool isUniform
Returns true if horizontal and verical orders are identical.
Definition: Ambisonic.h:64
void initialize(UnitGenerator &input, AmbisonicDecoderMethod method, AmbisonicDecoderFlavour flavour)
initializing method called by constructors
Definition: Ambisonic.cpp:325
unsigned horizontalOrder
Definition: Ambisonic.h:60
SpatialSource * input()
Definition: Ambisonic.h:133
void makeTransposedReEncodingMatrix(float **transposeMatrix)
Utility method that creates the transposed re-encoding matrix C'.
Definition: Ambisonic.cpp:587
Temp Spatial Sound Source.
Definition: SpatialSource.h:29
~AmbisonicDecoder()
Destructor.
Definition: Ambisonic.cpp:312
void makeInPhase(unsigned greaterOrder)
Adjusts the decoding matrix D for in-phase flavour.
Definition: Ambisonic.cpp:638
virtual ~AmbisonicEncoder()
Destructor.
Definition: Ambisonic.cpp:203
void initialize()
Initializing method called by constructors.
Definition: Ambisonic.cpp:214
AmbisonicDecoderFlavour
Flag for the decoder flavour.
Definition: Ambisonic.h:153
unsigned orderToVerticalChannels(const AmbisonicOrder order)
Returns the number of vertical Ambisonic channels from a hybrid Ambisonic order: N_v = (M_v + 1)^2 - ...
Definition: Ambisonic.cpp:90
void invChannelIndexer(unsigned *indexArray)
Calculates a lookup table to map actually used UnitGenerator channel to Ambisonic channel index...
Definition: Ambisonic.cpp:146
SpeakerLayout * mSpeakerLayout
Definition: Ambisonic.h:202
UnitGenerator * mUGen
my unit generator (pointer or NULL)
Definition: CSL_Core.h:320
void setInput(SpatialSource &input)
Set my input.
Definition: Ambisonic.cpp:226
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
AmbisonicEncoder()
Default constructor.
Definition: Ambisonic.cpp:191
Ambisonic Abstract Base Class.
Definition: Ambisonic.h:69
AmbisonicOrder mOrder
the order of the Unit Generator
Definition: Ambisonic.h:83
AmbisonicDecoderMethod
Flag for the decoding method.
Definition: Ambisonic.h:146
SampleBuffer * SampleBufferVector
Multi-channel buffer data type, vector of (SampleBuffer)
Definition: CSL_Types.h:195
Port – used to represent constant, control-rate or signal inputs and outputs in named maps; holds a ...
Definition: CSL_Core.h:312
AmbisonicDecoderMethod mDecodingMethod
Definition: Ambisonic.h:203
virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
Does the DSP processing for the Ambisonic Encoder.
Definition: Ambisonic.cpp:245
forward declaration
Definition: CSL_Core.h:241
static SpeakerLayout * defaultSpeakerLayout()
Returns a pointer to the default layout. If no default exists, it creates one.
unsigned channelsToUniformOrder(const unsigned channels)
Definition: Ambisonic.cpp:66
Port * mInputPort
Holds the input to be encoded.
Definition: Ambisonic.h:140
SampleBufferVector mDecodingMatrix
Definition: Ambisonic.h:201
unsigned verticalOrder
Definition: Ambisonic.h:63
Base class of CSL exceptions (written upper-case). Has a string message.