Ambisonic.h

Go to the documentation of this file.
00001 //
00002 //  Ambisonic.h -- Higher Order Ambisonic abstract base class for all Ambisonic effects and panners.
00003 //  See the copyright notice and acknowledgment of authors in the file COPYRIGHT
00004 //  Higher Order Ambisonic classes written by Jorge Castellanos, Graham Wakefield, Florian Hollerweger, 2005
00005 //
00006 //  Encapsulates parameters regarding the ambisonic order of the class (including hybrid orders)
00007 //
00008 //  CONVENTIONS USED IN THIS CODE:
00009 //  ------------------------------
00010 //
00011 //  ***coordinate system***
00012 //  Left oriented
00013 //  Azimuth = 0 on the x/z plane and increasing towards the positive y direction
00014 //  Elevation = 0 on x/y plane and increasing towards the positive z direction
00015 //  Internal angle representation: spherical radians
00016 //
00017 //  ***encoding convention***
00018 //  following the Furse-Malham set (Ambisonic channel weighting for uniform energy distribution)
00019 //
00020 //  ***abbreviations used in code and comments***
00021 //  M   ... Ambisonic order (in uniform order system)
00022 //  M_h ... horizontal Ambisonic order (in hybrid order systems)
00023 //  M_v ... horizontal Ambisonic order (in hybrid order systems)
00024 //  N   ... total number of Ambisonic encoded channels (horizontal and vertical)
00025 //  N_h ... number of horizontal Ambisonic channels (in hybrid order systems)
00026 //  N_v ... number of vertical Ambisonic channels (in hybrid order systems)
00027 //  L   ... number of available loudspeakers
00028 //
00029 //  ***ordering and naming of Ambisonic channels = spherical harmonics***
00030 //  These conventions follow the ones used in the thesis by Jerome Daniel.
00031 //  The 3rd order naming convention (which Daniel doesn't provide) follows the one used in the thesis of David Malham.
00032 //  Watch out for different conventions in other papers!
00033 //  index           0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
00034 //  M (order)       0   1   1   1   2   2   2   2   2   3   3   3   3   3   3   3
00035 //  m (=M)          0   1   1   1   2   2   2   2   2   3   3   3   3   3   3   3
00036 //  n               0   1   1   0   2   2   1   1   0   3   3   2   2   1   1   0
00037 //  sigma           '1' 1   -1  '1' 1   -1  1   -1  '1' 1   -1  1   -1  1   -1  '1'
00038 //  name            W   X   Y   Z   U   V   S   T   R   P   Q   N   O   L   M   K
00039 //  hor/vert/omni   om  h   h   v   h   h   v   v   v   h   h   v   v   v   v   v
00040 //
00041 
00042 #ifndef CSL_AMBISONIC_H
00043 #define CSL_AMBISONIC_H
00044 
00045 #include "CSL_Core.h"
00046 #include "CPoint.h"
00047 #include "SpatialSource.h"
00048 #include "SpeakerLayout.h"
00049 
00050 #define HOA_MAX_ORDER 2 // maximum order that the CSL HOA will handle
00051 
00052 namespace csl {
00053 
00056 
00057 class AmbisonicOrder { 
00058 public:
00059     AmbisonicOrder(unsigned hOrder = 0, unsigned vOrder = 0) : horizontalOrder(hOrder), verticalOrder(vOrder) { };
00060     ~AmbisonicOrder() { };
00061     
00062     unsigned horizontalOrder;
00063     unsigned verticalOrder;     
00064     bool isUniform;             
00065 };
00066 
00068 
00069 class AmbisonicUnitGenerator : public UnitGenerator {
00070 public:
00071     
00072     // Constructors & destructor:
00073     AmbisonicUnitGenerator(unsigned order = 0);                 
00074     AmbisonicUnitGenerator(unsigned horder, unsigned vorder);   
00075     AmbisonicUnitGenerator(AmbisonicOrder order); 
00076     virtual ~AmbisonicUnitGenerator();
00077     
00078     AmbisonicOrder order() { return mOrder; }; 
00079 
00080 protected:
00081     void setOrder(AmbisonicOrder order);
00082     
00083     AmbisonicOrder mOrder;              
00084 
00085     // returns the Ambisonic order from the number of Ambisonic channels: M = floor(sqrt(N) - 1)
00086     // NOTE - only works for uniform horizontal and vertical order (whereas ambiguity occurs in hybrid order systems)!
00087     unsigned channelsToUniformOrder(const unsigned channels);
00088 
00090     unsigned greaterOrder(const AmbisonicOrder order);
00091 
00093     unsigned orderToChannels(const AmbisonicOrder order);
00094 
00096     unsigned orderToChannels(unsigned order);
00097 
00099     unsigned orderToHorizontalChannels(const AmbisonicOrder order);
00100 
00102     unsigned orderToVerticalChannels(const AmbisonicOrder order);
00103 
00105     void channelIndexer(unsigned *indexArray);
00106 
00108     void invChannelIndexer(unsigned *indexArray);
00109     
00110 private:
00111 
00112     void initOrder();   // generic initialisation function
00113 
00114 };
00115 
00116 //  AmbisonicEncoder -- Higher Order Ambisonic encoding class
00117 //
00118 //  Higher Order Ambisonic class for positioning mono sound sources into an Ambisonic encoded soundfield.
00119 //  The position information is fed to the encoder as two multichannel framestreams (azimuth and elevation). 
00120 //  It is possible to specify either one uniform Ambisonic order or to define the horizontal and vertical 
00121 //  order separately (hybrid order encoding). If no order(s) is/are specified, first order Ambisonic will be used (B-Format).
00122 
00123 class AmbisonicEncoder : public AmbisonicUnitGenerator {
00124 public:
00125     
00126     AmbisonicEncoder();         
00127     AmbisonicEncoder(SpatialSource &input, unsigned order = 1); 
00128     AmbisonicEncoder(SpatialSource &input, unsigned horder, unsigned vorder); 
00129     
00130     virtual ~AmbisonicEncoder();    
00131 
00132     void setInput(SpatialSource &input);    
00133     SpatialSource *input() { return (SpatialSource *)mInputPort->mUGen; };
00134     
00136     virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
00137         
00138 protected:
00139     SampleBuffer mWeights;          
00140     Port *mInputPort;       
00141     void initialize();          
00142 };
00143 
00145 
00146 typedef enum {
00147     kPSEUDOINVERSE = 0, 
00148     kPROJECTION
00149 } AmbisonicDecoderMethod;
00150 
00152 
00153 typedef enum {
00154     kBASIC = 0, 
00155     kINPHASE, 
00156     kMAXRE
00157 } AmbisonicDecoderFlavour;
00158 
00159 //
00160 //  AmbisonicDecoder -- Higher Order Ambisonic Decoding class
00161 //
00162 //  Higher Order Ambisonic class for decoding an Ambisonic encoded soundfield (e.g. the output of the AmbisonicEncoder or
00163 //  the AmbisonicRotator) to a loudspeaker layout specified by SpeakerLayout. The Ambisonic order at which the decoder
00164 //  oprates is derived by the following criteria: If no order is specified in the constructor, the order of the Ambisonic
00165 //  encoded input is used. This order can be downgraded either by specifying a lower order in the constructor
00166 //  (obviously, it cannot be increased). The decoder might further decrease the given order to match the maximum
00167 //  order reproducable on the available loudspeaker layout. One out of two different decoding methods can be chosen by
00168 //  using the flags kPROJECTION, kPSEUDOINVERSE in the constructor. One out of three available decoder flavors can
00169 //  be applied by using the flags kBASIC, kINPHASE, kMAXRE.
00170 //
00171 
00172 class AmbisonicDecoder : public AmbisonicUnitGenerator {
00173 public:
00174     // Constructors & destructor:
00176     AmbisonicDecoder(AmbisonicUnitGenerator &input, SpeakerLayout *layout = SpeakerLayout::defaultSpeakerLayout(), AmbisonicDecoderMethod method = kPROJECTION, AmbisonicDecoderFlavour flavour = kBASIC);
00178     AmbisonicDecoder(UnitGenerator &input, unsigned order, SpeakerLayout *layout = SpeakerLayout::defaultSpeakerLayout(), AmbisonicDecoderMethod method = kPROJECTION, AmbisonicDecoderFlavour flavour = kBASIC);
00180     AmbisonicDecoder(UnitGenerator &input, unsigned hOrder, unsigned vOrder, SpeakerLayout *layout = SpeakerLayout::defaultSpeakerLayout(), AmbisonicDecoderMethod method = kPROJECTION, AmbisonicDecoderFlavour flavour = kBASIC);
00181     
00182     ~AmbisonicDecoder();    
00183         
00185     virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
00186 
00187 protected:
00188 
00189     Port *mInputPort;
00190     float mNumChannelsInv;      // inverse of the numbers of loudspeakers (used for normalization)
00191     int *mIOChannelMap;         // lookup table from index of actually used Ambisonic channel input Ambisonic channel index
00192     SampleBufferVector mDecodingMatrix; // deccoding matrix D
00193     SpeakerLayout *mSpeakerLayout;              // loudspeaker layout provided by "HOA_SpeakerLayout" class
00194     AmbisonicDecoderMethod mDecodingMethod;     // decoding method: projection or pseudoinverse
00195     AmbisonicDecoderFlavour mDecoderFlavour;    // decoder flavour: basic, in-phase or max-rE
00196 
00197 
00199     void initialize(UnitGenerator &input, AmbisonicDecoderMethod method, AmbisonicDecoderFlavour flavour);
00200     
00201     void asProjection();    
00202     void asPseudoInverse(); 
00203         
00204     void makeInPhase(unsigned greaterOrder);    
00205     void makeMaxRE(unsigned greaterOrder);      
00206 
00207     void makeTransposedReEncodingMatrix(float **transposeMatrix); 
00208 
00209 };
00210 
00211 }
00212 
00213 #endif

Generated on Thu Sep 17 23:14:16 2009 for CSL by  doxygen 1.5.8