00001 /* 00002 00003 HOA_AmbisonicDecoder.h -- Higher Order Ambisonic decoding class 00004 See the copyright notice and acknowledgment of authors in the file COPYRIGHT 00005 Higher Order Ambisonic classes written by Jorge Castellanos, Graham Wakefield, Florian Hollerweger, 2005 00006 00007 Higher Order Ambisonic class for decoding an Ambisonic encoded soundfield (e.g. the output of the HOA_Encoder or 00008 the HOA_Rotator) to a loudspeaker layout specified by HOA_SpeakerLayout. The Ambisonic order at which the decoder 00009 oprates is derived by the following criteria: If no order is specified in the constructor, the order of the Ambisonic 00010 encoded input framestream is used. This order can be degraded either by specifying a lower order in the constructor 00011 (obviously, it cannot be increased). The decoder might further decrease the such given order to match the maximum 00012 order reproducable on the available loudspeaker layout. One out of two different decoding methods can be chosen by 00013 using the flags HOA_PROJECTION, HOA_PSEUDOINVERSE in the constructor. One out of three available decoder flavors can 00014 be applied by using the flags HOA_BASIC, HOA_INPHASE, HOA_MAXRE. 00015 00016 */ 00017 00018 #ifndef HOA_DECODER_H 00019 #define HOA_DECODER_H 00020 00021 #include "CSL_Core.h" 00022 #include "Variable.h" 00023 #include "CPoint.h" 00024 00025 #include "HOA_Encoder.h" 00026 #include "HOA_Utilities.h" 00027 #include "HOA_SpeakerLayout.h" 00028 #include "HOA_AmbisonicFramestream.h" 00029 00030 #define HOA_MAX_ORDER 2 // maximum order that the CSL HOA will handle 00031 00032 namespace csl { 00033 00034 /* 00035 00036 CONVENTIONS USED IN THIS CODE: 00037 ------------------------------ 00038 00039 ***coordinate system*** 00040 Left oriented 00041 Azimuth = 0 on the x/z plane and increasing towards the positive y direction 00042 Elevation = 0 on x/y plane and increasing towards the positive z direction 00043 Internal angle representation: spherical radians 00044 00045 ***encoding convention*** 00046 following the Furse-Malham set (Ambisonic channel weighting for uniform energy distribution) 00047 00048 ***abbreviations used in code and comments*** 00049 M ... Ambisonic order (in uniform order system) 00050 M_h ... horizontal Ambisonic order (in hybrid order systems) 00051 M_v ... horizontal Ambisonic order (in hybrid order systems) 00052 N ... total number of Ambisonic encoded channels (horizontal and vertical) 00053 N_h ... number of horizontal Ambisonic channels (in hybrid order systems) 00054 N_v ... number of vertical Ambisonic channels (in hybrid order systems) 00055 L ... number of available loudspeakers 00056 00057 ***ordering and naming of Ambisonic channels = spherical harmonics*** 00058 These conventions follow the ones used in the thesis by Jerome Daniel. 00059 The 3rd order naming convention (which Daniel doesn't provide) follows the one used in the thesis of David Malham. 00060 Watch out for different conventions in other papers! 00061 index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 00062 M (order) 0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 00063 m (=M) 0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 00064 n 0 1 1 0 2 2 1 1 0 3 3 2 2 1 1 0 00065 sigma '1' 1 -1 '1' 1 -1 1 -1 '1' 1 -1 1 -1 1 -1 '1' 00066 name W X Y Z U V S T R P Q N O L M K 00067 hor/vert/omni om h h v h h v v v h h v v v v v 00068 00069 */ 00070 00071 typedef enum { 00072 HOA_PSEUDOINVERSE = 0, HOA_PROJECTION // flag for the decoding method 00073 } HOA_DecoderMethod; 00074 00075 typedef enum { 00076 HOA_BASIC = 0, HOA_INPHASE, HOA_MAXRE // flag for the decoder flavour 00077 } HOA_DecoderFlavour; 00078 00079 class HOA_Decoder : public FrameStream, public Processor, public HOA_AmbisonicFramestream { 00080 00081 private: 00082 00083 sample *mOutPtr; // pointer to decoded output buffers (loudspeaker signals) 00084 sample **mInPtr; // pointer to Ambisonic encoded input buffers 00085 00086 void asProjection(); // create the decoding matrix D using the projection method 00087 void asPseudoInverse(); // create the decoding matrix D using the pseudoinverse method 00088 00089 sample** makeTransposedReEncodingMatrix(); // utility method to create the transposed reencoding matrix C' 00090 00091 void makeInPhase(); // method to adjust the decoding matrix D for in-phase flavour 00092 void makeMaxRE(); // method to adjust the decoding matrix D for Max rE flavour 00093 00094 protected: 00095 00096 unsigned mNumSpeakers; // number of loudspeakers in the provided layout 00097 float mNumChannelsInv; // inverse of the numbers of loudspeakers (used for normalization) 00098 int* mIOChannelMap; // lookup table from index of actually used Ambisonic channel input Ambisonic channel index 00099 sample **mDecodingMatrix; // deccoding matrix D 00100 Buffer mInBuffer; // Ambisonic encoded multi-channel audio input 00101 HOA_SpeakerLayout *mSpkLayout; // loudspeaker layout provided by "HOA_SpeakerLayout" class 00102 HOA_DecoderMethod mDecodingMethod; // decoding method: projection or pseudoinverse 00103 HOA_DecoderFlavour mDecoderFlavour; // decoder flavour: basic, in-phase or max-rE 00104 00105 public: 00106 00107 // Constructors & destructor: 00108 00109 // default constructor 00110 HOA_Decoder(); 00111 00112 // defaults to standard speaker layout as defined in "HOA_SpeakerLayout" class and to Ambisonic order of encoded input 00113 HOA_Decoder(FrameStream &input, HOA_DecoderMethod method = HOA_PSEUDOINVERSE, HOA_DecoderFlavour flavour = HOA_BASIC); 00114 00115 // defaults to Ambisonic order of encoded input 00116 HOA_Decoder(FrameStream &input, HOA_SpeakerLayout &spkLayout, HOA_DecoderMethod method = HOA_PSEUDOINVERSE, HOA_DecoderFlavour flavour = HOA_BASIC); 00117 00118 // initializes with uniform Ambisonic order, defaults to standard speaker layout as defined in "HOA_SpeakerLayout" class 00119 HOA_Decoder(FrameStream &input, unsigned order, HOA_DecoderMethod method = HOA_PSEUDOINVERSE, HOA_DecoderFlavour flavour = HOA_BASIC); 00120 00121 // initializes with uniform Ambisonic order 00122 HOA_Decoder(FrameStream &input, unsigned order, HOA_SpeakerLayout &spkLayout, HOA_DecoderMethod method = HOA_PSEUDOINVERSE, HOA_DecoderFlavour flavour = HOA_BASIC); 00123 00124 // initializes with hybrid Ambisonic order 00125 HOA_Decoder(FrameStream &input, unsigned horder, unsigned vorder, HOA_DecoderMethod method = HOA_PSEUDOINVERSE, HOA_DecoderFlavour flavour = HOA_BASIC); 00126 00127 // initializes with hybrid Ambisonic order 00128 HOA_Decoder(FrameStream &input, unsigned horder, unsigned vorder, HOA_SpeakerLayout &spkLayout, HOA_DecoderMethod method = HOA_PSEUDOINVERSE, HOA_DecoderFlavour flavour = HOA_BASIC); 00129 00130 // destructor 00131 ~HOA_Decoder(); 00132 00133 00134 // initializing method called by constructors 00135 void initialize(FrameStream &input, HOA_DecoderMethod method, HOA_DecoderFlavour flavour); 00136 00137 // Overriding Framestream::next_buffer(). Does the DSP processing for the Ambisonic Decoder. 00138 virtual status next_buffer(Buffer &inputBuffer, Buffer &outputBuffer); 00139 00140 }; 00141 00142 } 00143 00144 #endif
1.4.5-20051010