ese 519 include files
Dependents: PROJECT_3D_AUDIO COG4050_adxl355_tilt COG4050_adxl355_tilt COG4050_adxl355_tilt_4050
Mixer3D.h@0:5347612e39a3, 2015-04-07 (annotated)
- Committer:
- niv17
- Date:
- Tue Apr 07 21:09:51 2015 +0000
- Revision:
- 0:5347612e39a3
april_7 _ sonic start
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
niv17 | 0:5347612e39a3 | 1 | #include "fft.h" |
niv17 | 0:5347612e39a3 | 2 | #include "complextype.h" |
niv17 | 0:5347612e39a3 | 3 | #include "AudioObj.h" |
niv17 | 0:5347612e39a3 | 4 | #include "World.h" |
niv17 | 0:5347612e39a3 | 5 | #include "mit_hrtf_lib.h" |
niv17 | 0:5347612e39a3 | 6 | |
niv17 | 0:5347612e39a3 | 7 | #ifndef MIXER3D_H |
niv17 | 0:5347612e39a3 | 8 | #define MIXER3D_H |
niv17 | 0:5347612e39a3 | 9 | |
niv17 | 0:5347612e39a3 | 10 | /** |
niv17 | 0:5347612e39a3 | 11 | Certain features of this 3D Mixer class are optimized for Sonic and thus |
niv17 | 0:5347612e39a3 | 12 | include many hard-coded pre-allocations. For this reason, it is not |
niv17 | 0:5347612e39a3 | 13 | recommended to use these methods for purposes other than to Sonic's |
niv17 | 0:5347612e39a3 | 14 | 3D mixing, as they will likely break or give undefined results. |
niv17 | 0:5347612e39a3 | 15 | |
niv17 | 0:5347612e39a3 | 16 | If you wish to make features more general purpose or create your own, it is |
niv17 | 0:5347612e39a3 | 17 | recommended that you define and pre-allocate your own containers as data |
niv17 | 0:5347612e39a3 | 18 | members of the 3D Mixer or make sure they comply with the size restrictions |
niv17 | 0:5347612e39a3 | 19 | of the 3D mixing code. |
niv17 | 0:5347612e39a3 | 20 | */ |
niv17 | 0:5347612e39a3 | 21 | |
niv17 | 0:5347612e39a3 | 22 | #define INVALID_ANGLE 9999 |
niv17 | 0:5347612e39a3 | 23 | #define MAX_GPS_OBJ_DISTANCE 30 // player must be at or within 10m of a GPS audio object to hear it |
niv17 | 0:5347612e39a3 | 24 | |
niv17 | 0:5347612e39a3 | 25 | class Mixer3D |
niv17 | 0:5347612e39a3 | 26 | { |
niv17 | 0:5347612e39a3 | 27 | public: |
niv17 | 0:5347612e39a3 | 28 | Mixer3D(int bufSize, int smpRate, int bitD, World *w); |
niv17 | 0:5347612e39a3 | 29 | ~Mixer3D(); |
niv17 | 0:5347612e39a3 | 30 | |
niv17 | 0:5347612e39a3 | 31 | /** |
niv17 | 0:5347612e39a3 | 32 | Pre: The 3DMixer object must be instantiated and have reference to a list of Sonic AudioObj objects to perform processing. |
niv17 | 0:5347612e39a3 | 33 | Post: Simply call the method and the 3D Mixer will populate the ioDataLeft and ioDataRight arrays with 16-bit signed integer formatted audio data. This |
niv17 | 0:5347612e39a3 | 34 | audio data is the processed result of 3D mixing on the current buffers of data in the audio objects and their current 3D positions. The ioData |
niv17 | 0:5347612e39a3 | 35 | arrays must be equal to the bufferSize of the 3D Mixer. |
niv17 | 0:5347612e39a3 | 36 | */ |
niv17 | 0:5347612e39a3 | 37 | void performMix(short *ioDataLeft, short *ioDataRight); |
niv17 | 0:5347612e39a3 | 38 | |
niv17 | 0:5347612e39a3 | 39 | private: |
niv17 | 0:5347612e39a3 | 40 | /** |
niv17 | 0:5347612e39a3 | 41 | Pre: Azimuth must be an angle between -180 and 180. Elevation must be between -90 and 90. The sample rate must be either 44100, 48000, 88200, or 96000 |
niv17 | 0:5347612e39a3 | 42 | KHz. leftFilter and rightFilter must be pre-allocated according to the number of taps for each sample rate: 128, 140, 256, or 279. |
niv17 | 0:5347612e39a3 | 43 | Post: leftFilter and rightFilter will be filled with complex data in the frequency domain which represent the HRTF filter at a specified Azimuth |
niv17 | 0:5347612e39a3 | 44 | and Elevation. |
niv17 | 0:5347612e39a3 | 45 | */ |
niv17 | 0:5347612e39a3 | 46 | int loadHRTF(int* pAzimuth, int* pElevation, unsigned int samplerate, unsigned int diffused, Complex *&leftFilter, Complex *&rightFilter); |
niv17 | 0:5347612e39a3 | 47 | |
niv17 | 0:5347612e39a3 | 48 | /** |
niv17 | 0:5347612e39a3 | 49 | Pre: The input and filter can be any size relative to each other, as this method will perform self-contained zero-padding. As such, NFFT must be a |
niv17 | 0:5347612e39a3 | 50 | power of 2 equal to or greater than the larger of the two. All three containers must be pre-allocated and the output length must be equal to |
niv17 | 0:5347612e39a3 | 51 | NFFT. Because of the nature of the 3D Mixer, the NFFT maximum size is 2*bufferSize. Additionally, two containers for the frequency domain |
niv17 | 0:5347612e39a3 | 52 | versions of the input and filter (size 2*bufferSize) are used and already pre-allocated by the 3D Mixer class. nSig and nFil are the numerical sizes |
niv17 | 0:5347612e39a3 | 53 | of the input and filter arrays. |
niv17 | 0:5347612e39a3 | 54 | Post: Output will be filled with the result in the time domain of the input and filter being circularly convolved through a frequency domain dot product. |
niv17 | 0:5347612e39a3 | 55 | The output size will be NFFT samples. There is a side effect of fInput and fFilter being populated with the frequency domain data which was used for |
niv17 | 0:5347612e39a3 | 56 | the convolution. |
niv17 | 0:5347612e39a3 | 57 | */ |
niv17 | 0:5347612e39a3 | 58 | void convolution(Complex *input, Complex *filter, Complex *output, long nSig, long nFil, long nFFT); |
niv17 | 0:5347612e39a3 | 59 | |
niv17 | 0:5347612e39a3 | 60 | /** |
niv17 | 0:5347612e39a3 | 61 | Pre: Similar requirements to the normal convolution(), extended to left and right versions of filter and output. As usual, all containers must be |
niv17 | 0:5347612e39a3 | 62 | pre-allocated and nFFT must be at maximum 2*bufferSize. |
niv17 | 0:5347612e39a3 | 63 | Post: The method will call convolution() twice for both left and right audio data, using the leftFilter and rightFilter and storing the results in |
niv17 | 0:5347612e39a3 | 64 | leftOutput and rightOutputThis method will propagate the fInput/fFilter population side effect of convolution(). |
niv17 | 0:5347612e39a3 | 65 | */ |
niv17 | 0:5347612e39a3 | 66 | void stereoConvolution(Complex *input, Complex *leftFilter, Complex *rightFilter, Complex *leftOutput, Complex *rightOutput, long nSig, long nFil, long nFFT); |
niv17 | 0:5347612e39a3 | 67 | |
niv17 | 0:5347612e39a3 | 68 | /** |
niv17 | 0:5347612e39a3 | 69 | * Returns a vector of valid audio objects to mix, i.e. those that are active and within range |
niv17 | 0:5347612e39a3 | 70 | */ |
niv17 | 0:5347612e39a3 | 71 | void computeValidAudioObjects(vector<AudioObj*> &validAudioObjectsOut); |
niv17 | 0:5347612e39a3 | 72 | /** |
niv17 | 0:5347612e39a3 | 73 | Re-computes and stores elevation and azimuth angles for all |
niv17 | 0:5347612e39a3 | 74 | audioObjects in this->myWorld |
niv17 | 0:5347612e39a3 | 75 | */ |
niv17 | 0:5347612e39a3 | 76 | void updateAngles(); |
niv17 | 0:5347612e39a3 | 77 | |
niv17 | 0:5347612e39a3 | 78 | /** |
niv17 | 0:5347612e39a3 | 79 | Returns true if x is a power of two, false otherwise |
niv17 | 0:5347612e39a3 | 80 | */ |
niv17 | 0:5347612e39a3 | 81 | bool isPowerOfTwo(int x); |
niv17 | 0:5347612e39a3 | 82 | |
niv17 | 0:5347612e39a3 | 83 | //Data members |
niv17 | 0:5347612e39a3 | 84 | |
niv17 | 0:5347612e39a3 | 85 | unsigned int bufferSize, //The size of the audio frames. |
niv17 | 0:5347612e39a3 | 86 | sampleRate, //The sample rate of the audio. |
niv17 | 0:5347612e39a3 | 87 | bitDepth, //The bit depth of the audio. |
niv17 | 0:5347612e39a3 | 88 | filterLength; //The MIT KEMAR Filter Size. |
niv17 | 0:5347612e39a3 | 89 | |
niv17 | 0:5347612e39a3 | 90 | World *myWorld; //A pointer to the world. |
niv17 | 0:5347612e39a3 | 91 | Player &player; //A reference to myWorld's player |
niv17 | 0:5347612e39a3 | 92 | |
niv17 | 0:5347612e39a3 | 93 | short *leftFilter, *rightFilter; //Arrays for retrieving the integer formatted filter data from the MIT KEMAR HRTF Database. |
niv17 | 0:5347612e39a3 | 94 | int *prevAzimuths, *prevElevations, |
niv17 | 0:5347612e39a3 | 95 | *azimuths, *elevations; |
niv17 | 0:5347612e39a3 | 96 | |
niv17 | 0:5347612e39a3 | 97 | Complex *inputAO, //Holds the current input of each audio object. |
niv17 | 0:5347612e39a3 | 98 | *overlapInput, //Holds the input of the last iteration in case the filter changed and the tail needs recalculation. |
niv17 | 0:5347612e39a3 | 99 | *fInput, *fFilter, //Data arrays to hold frequency domain representation of an input and filter. Used in convolution(). |
niv17 | 0:5347612e39a3 | 100 | **complexLeftFilter, **complexRightFilter, //Holds the complex datatype versions of the current filter. |
niv17 | 0:5347612e39a3 | 101 | **outputLeft, **outputRight, //Holds the output of each current input with the current filter. |
niv17 | 0:5347612e39a3 | 102 | **overlapLeft,**overlapRight; //Holds the second half of each 2*bufferSize convolution for next iteration. |
niv17 | 0:5347612e39a3 | 103 | }; |
niv17 | 0:5347612e39a3 | 104 | |
niv17 | 0:5347612e39a3 | 105 | #endif |