00001
00043 #ifndef CSL_AMBISONIC_H
00044 #define CSL_AMBISONIC_H
00045
00046 #include "CSL_Core.h"
00047 #include "CPoint.h"
00048 #include "SpatialSource.h"
00049 #include "SpeakerLayout.h"
00050
00051 #define HOA_MAX_ORDER 2 // maximum order that the CSL HOA will handle
00052
00053 namespace csl {
00054
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 class AmbisonicUnitGenerator : public UnitGenerator {
00069 public:
00070
00071
00072 AmbisonicUnitGenerator(unsigned order = 0);
00073 AmbisonicUnitGenerator(unsigned horder, unsigned vorder);
00074 AmbisonicUnitGenerator(AmbisonicOrder order);
00075 virtual ~AmbisonicUnitGenerator();
00076
00077 AmbisonicOrder order() { return mOrder; };
00078
00079 protected:
00080 void setOrder(AmbisonicOrder order);
00081
00082 AmbisonicOrder mOrder;
00083
00084
00085
00086 unsigned channelsToUniformOrder(const unsigned channels);
00087
00089 unsigned greaterOrder(const AmbisonicOrder order);
00090
00092 unsigned orderToChannels(const AmbisonicOrder order);
00093
00095 unsigned orderToChannels(unsigned order);
00096
00098 unsigned orderToHorizontalChannels(const AmbisonicOrder order);
00099
00101 unsigned orderToVerticalChannels(const AmbisonicOrder order);
00102
00104 void channelIndexer(unsigned *indexArray);
00105
00107 void invChannelIndexer(unsigned *indexArray);
00108
00109
00110 private:
00111
00112 void initOrder();
00113
00114 };
00115
00116
00125 class AmbisonicEncoder : public AmbisonicUnitGenerator {
00126 public:
00127
00128 AmbisonicEncoder();
00129 AmbisonicEncoder(SpatSource &input, unsigned order = 1);
00130 AmbisonicEncoder(SpatSource &input, unsigned horder, unsigned vorder);
00131
00132 virtual ~AmbisonicEncoder();
00133
00134 void setInput(SpatSource &input);
00135 SpatSource *input() { return (SpatSource *)mInputPort->mUGen; };
00136
00138 virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
00139
00140 protected:
00141 sample *mWeights;
00142 UGenPort *mInputPort;
00143 void initialize();
00144
00145 };
00146
00147
00148
00150 typedef enum {
00151 kPSEUDOINVERSE = 0,
00152 kPROJECTION
00153 } AmbisonicDecoderMethod;
00154
00156 typedef enum {
00157 kBASIC = 0,
00158 kINPHASE,
00159 kMAXRE
00160 } AmbisonicDecoderFlavour;
00161
00174 class AmbisonicDecoder : public AmbisonicUnitGenerator {
00175 public:
00176
00178 AmbisonicDecoder(AmbisonicUnitGenerator &input, SpeakerLayout *layout = SpeakerLayout::defaultSpeakerLayout(), AmbisonicDecoderMethod method = kPROJECTION, AmbisonicDecoderFlavour flavour = kBASIC);
00180 AmbisonicDecoder(UnitGenerator &input, unsigned order, SpeakerLayout *layout = SpeakerLayout::defaultSpeakerLayout(), AmbisonicDecoderMethod method = kPROJECTION, AmbisonicDecoderFlavour flavour = kBASIC);
00182 AmbisonicDecoder(UnitGenerator &input, unsigned hOrder, unsigned vOrder, SpeakerLayout *layout = SpeakerLayout::defaultSpeakerLayout(), AmbisonicDecoderMethod method = kPROJECTION, AmbisonicDecoderFlavour flavour = kBASIC);
00183
00184 ~AmbisonicDecoder();
00185
00187 virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
00188
00189 protected:
00190
00191 UGenPort *mInputPort;
00192 float mNumChannelsInv;
00193 int *mIOChannelMap;
00194 sample **mDecodingMatrix;
00195 SpeakerLayout *mSpeakerLayout;
00196 AmbisonicDecoderMethod mDecodingMethod;
00197 AmbisonicDecoderFlavour mDecoderFlavour;
00198
00199
00201 void initialize(UnitGenerator &input, AmbisonicDecoderMethod method, AmbisonicDecoderFlavour flavour);
00202
00203 void asProjection();
00204 void asPseudoInverse();
00205
00206 void makeInPhase(unsigned greaterOrder);
00207 void makeMaxRE(unsigned greaterOrder);
00208
00209 void makeTransposedReEncodingMatrix(float **transposeMatrix);
00210
00211 };
00212
00213 }
00214
00215 #endif