ese 519 include files
Dependents: PROJECT_3D_AUDIO COG4050_adxl355_tilt COG4050_adxl355_tilt COG4050_adxl355_tilt_4050
Revision 0:5347612e39a3, committed 2015-04-07
- Comitter:
- niv17
- Date:
- Tue Apr 07 21:09:51 2015 +0000
- Commit message:
- april_7 _ sonic start
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AudioObj.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,110 @@ +#ifndef AUDIOOBJ_H +#define AUDIOOBJ_H + +#include <stdexcept> +#include "location.h" +#include "velocity.h" +#include "complextype.h" +#include "CircularBuffer.h" +#include "WavObject.h" + +using namespace std; + +// TODO: move CIRC_BUF_SIZE to Sonic.h +#define BUFFER_CAPACITY 65000 // This will be capacity of circular buffer and also size of memory allocated in wavObject + +class AudioObj { + +private: + + friend class Mixer3D; + friend class World; + + Location location; + Velocity velocity; + + bool active; + float volume; + bool repeat; + bool isCompleted; // true if a non-repeated object has completed, false otherwise + bool backgroundObject; // if true, not mixed binaurally + bool gpsObject; // TODO: better way with inheritance and polymorphism? + + CircularBuffer<Complex> circularBuffer; + WavObject wavObject; + + void loadCircularBuffer(); + bool fillAudioData(Complex *, unsigned int); + + +public: + + // Creates a new audio object at the world's origin, {0,0,0}. + + // TODO: Get rid of hard-coded values in AudioObj constructor + AudioObj(const std::string wavFileName, bool isBackgroundIn=false) : active(true), isCompleted(false), volume(1), repeat(true), circularBuffer(BUFFER_CAPACITY), wavObject(BUFFER_CAPACITY, wavFileName), backgroundObject(isBackgroundIn) { + wavObject.loadMoreData(32768, repeat); + circularBuffer.write(wavObject.complexTempData, 32768); + } + + AudioObj(const std::string wavFileName, const Location& loc, bool isGpsObjectIn=false) : location(loc), active(true), isCompleted(false), volume(1), repeat(true), circularBuffer(BUFFER_CAPACITY), wavObject(BUFFER_CAPACITY, wavFileName), gpsObject(isGpsObjectIn) { + wavObject.loadMoreData(32768, repeat); + circularBuffer.write(wavObject.complexTempData, 32768); + } + + // TODO: Support Gps audio objects with velocity + // TODO: Condense AudioObj constructors using optional, default parameters. + // Creates a new audio object at the location specified by the parameter. + AudioObj(const std::string wavFileName, const Location& loc, const Velocity& vel) : location(loc), velocity(vel), active(true), isCompleted(false), volume(1), repeat(true), circularBuffer(BUFFER_CAPACITY), wavObject(BUFFER_CAPACITY, wavFileName) { + wavObject.loadMoreData(32768, repeat); + circularBuffer.write(wavObject.complexTempData, 32768); + } + + ~AudioObj () { } + + // Returns the array of the object's location. + Location getLocation() const; + + // Changes the object's location to that which is specifies in the parameter. + void setLocation (const Location& loc); + void setLocation (float x, float y, float z); + + Velocity getVelocity() const; + + void setVelocity (const Velocity& vel); + void setVelocity (float dx, float dy, float dz); + + // Returns the volume of the audio object. + // This will be a value from 0 to 1. + float getVolume() const; + + // Sets the volume of the audio object. This will only accept values from 0 to 1. + void setVolume(float vol); + + // Sets the volume of the audio object to a random value in the range + // [0.01, 1]. + void setRandomVolume(); + + // Returns whether or not the object is active + bool isActive() const; + + // Changes whether or not the object is active + void setActive(bool active); + + bool isGpsObject() const; + + bool isBackgroundObject() const; + + void setRepeat(bool rep); + + // Plays audio object exactly once. Reloads input buffer if necessary. Will restart if currently playing. + void playOnceFromBeginning(); + + // Resets to the beginning and activates + void restart(); + + // For pre-loading, but not yet starting, from the beginning + void loadFromBeginning(); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CircBuff.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,146 @@ +// +// CircBuff.h +// +// +// Created by Philadelphia Game Lab on 6/30/14. +// +// + +#ifndef _CircBuff_h +#define _CircBuff_h + +#include <stddef.h> +#include <atomic> +#include <stdio.h> +#include <stdlib.h> +//#include <sndfile.h> +#include <iostream> +#include <fstream> +#include <cstring> +#include <string> + +template <class T> +class CircBuff{ +protected: + /*Declaring variables for use by circular buffer functions + _begIndex is buffer head, 3DMixer will read from here + _endIndex is buffer tail, buffer will write from wav file here + _capacity is circular buffer capacity + */ + size_t _begIndex, _endIndex, _capacity; + + //_size is the current size of the buffer, amount of data written to buffer + std::atomic<size_t>_size; + + //pointer to circular buffer, start writing data from here + T *_data; + +public: + CircBuff(size_t capacity) + : _begIndex(0) + , _endIndex(0) + , _size(0) + , _capacity(capacity) + { + _data = new T[capacity*sizeof(T)]; + } + + ~CircBuff() + { + delete[] _data; + } + + //Define write audio data to circular buffer + size_t write(T *dataPtr, size_t samples); + size_t writeSizeRemaining(); + size_t readSizeRemaining(); + template <class V> + size_t read(V *dataPtr, size_t samples); +}; + +template <class T> +size_t CircBuff<T>::write(T *dataPtr, size_t samples) +{ + size_t capacity = _capacity; + size_t samples_to_write = std::min(samples, capacity-_size); + + _size += samples_to_write; + //writing to buffer + + if (samples_to_write <= capacity - _endIndex) { + for(int i = 0; i < samples_to_write; i++) { + _data[_endIndex+i] = dataPtr[i]; + } + _endIndex += samples_to_write; + if (_endIndex == capacity) { + _endIndex = 0; + } + } else { + size_t size1 = capacity - _endIndex; + for(int i = 0; i < size1; i++) { + _data[_endIndex+i] = dataPtr[i]; + } + size_t size2 = samples_to_write - size1; + for(int i = 0; i < size2; i++) { + _data[i] = dataPtr[i+size1]; + } + _endIndex = size2; + } + + return samples_to_write; +} + +template <class T> +size_t CircBuff<T>::writeSizeRemaining() +{ + return (_capacity - _size); +} + +template <class T> +size_t CircBuff<T>::readSizeRemaining() +{ + return _size; +} + +template <class T> template <class V> +size_t CircBuff<T>::read(V *dataPtr, size_t samples) +{ + if (samples == 0){ + return 0; + } + size_t capacity = _capacity; + size_t samples_to_read; + if (samples >= _size){ + samples_to_read = _size; + }else{ + samples_to_read = samples; + } + // Read in a single step + if (samples_to_read <= capacity - _begIndex){ + for(int i = 0; i < samples_to_read; i++) { + dataPtr[i] = _data[_begIndex+i]; + } + + _begIndex += samples_to_read; + if (_begIndex == capacity){ + _begIndex = 0; + } + }else{ + size_t size_1 = capacity - _begIndex; + for(int i = 0; i < size_1; i++) { + dataPtr[i] = _data[_begIndex+i]; + } + size_t size_2 = samples_to_read - size_1; + + for(int i = 0; i < size_2; i++) { + dataPtr[i+size_1] = _data[i]; + } + _begIndex = size_2; + } + _size -= samples_to_read; + return samples_to_read; +} + + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CircularBuffer.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,155 @@ +// +// CircularBuffer.h +// +// +// Created by Philadelphia Game Lab on 6/30/14. +// +// + +#ifndef _CircularBuffer_h +#define _CircularBuffer_h + +#include <stddef.h> +//#include <atomic> +#include <stdio.h> +#include <stdlib.h> +//#include <sndfile.h> +#include <iostream> +#include <fstream> +#include <cstring> +#include <string> + +template <class T> +class CircularBuffer{ +protected: + /*Declaring variables for use by circular buffer functions + _begIndex is buffer head, 3DMixer will read from here + _endIndex is buffer tail, buffer will write from wav file here + _capacity is circular buffer capacity + */ + size_t _begIndex, _endIndex, _capacity; + + //_size is the current size of the buffer, amount of data written to buffer + // std::atomic<size_t> _size; + size_t _size; + //pointer to circular buffer, start writing data from here + T *_data; + +public: + CircularBuffer(size_t capacity) + : _begIndex(0) + , _endIndex(0) + , _size(0) + , _capacity(capacity) + { + _data = new T[capacity*sizeof(T)]; + } + + ~CircularBuffer() + { + delete[] _data; + } + + //Define write audio data to circular buffer + size_t write(T *dataPtr, size_t samples); + size_t writeSizeRemaining(); + size_t readSizeRemaining(); + template <class V> + size_t read(V *dataPtr, size_t samples); + + void clear(); +}; + +template <class T> +size_t CircularBuffer<T>::write(T *dataPtr, size_t samples) +{ + size_t capacity = _capacity; + size_t samples_to_write = std::min(samples, capacity-_size); + + _size += samples_to_write; + //writing to buffer + + if (samples_to_write <= capacity - _endIndex) { + // samples to write will fit in buffer without wrapping + for(int i = 0; i < samples_to_write; i++) { + _data[_endIndex+i] = dataPtr[i]; + } + _endIndex += samples_to_write; + if (_endIndex == capacity) { + _endIndex = 0; + } + } else { + // TODO: pretty sure this can be done with modulo arithmetic... + size_t size1 = capacity - _endIndex; + for(int i = 0; i < size1; i++) { + _data[_endIndex+i] = dataPtr[i]; + } + size_t size2 = samples_to_write - size1; + for(int i = 0; i < size2; i++) { + _data[i] = dataPtr[i+size1]; + } + _endIndex = size2; + } + + return samples_to_write; +} + +template <class T> +size_t CircularBuffer<T>::writeSizeRemaining() +{ + return (_capacity - _size); +} + +template <class T> +size_t CircularBuffer<T>::readSizeRemaining() +{ + return _size; +} + +template <class T> template <class V> +size_t CircularBuffer<T>::read(V *dataPtr, size_t samples) +{ + if (samples == 0){ + return 0; + } + size_t capacity = _capacity; + size_t samples_to_read; + if (samples >= _size){ + samples_to_read = _size; + }else{ + samples_to_read = samples; + } + // Read in a single step + if (samples_to_read <= capacity - _begIndex){ + for(int i = 0; i < samples_to_read; i++) { + dataPtr[i] = _data[_begIndex+i]; + } + + _begIndex += samples_to_read; + if (_begIndex == capacity){ + _begIndex = 0; + } + }else{ + size_t size_1 = capacity - _begIndex; + for(int i = 0; i < size_1; i++) { + dataPtr[i] = _data[_begIndex+i]; + } + size_t size_2 = samples_to_read - size_1; + + for(int i = 0; i < size_2; i++) { + dataPtr[i+size_1] = _data[i]; + } + _begIndex = size_2; + } + _size -= samples_to_read; + return samples_to_read; +} + +template <class T> +void CircularBuffer<T>::clear() { + _size = 0; + _begIndex = 0; + _endIndex = 0; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Mixer3D.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,105 @@ +#include "fft.h" +#include "complextype.h" +#include "AudioObj.h" +#include "World.h" +#include "mit_hrtf_lib.h" + +#ifndef MIXER3D_H +#define MIXER3D_H + +/** +Certain features of this 3D Mixer class are optimized for Sonic and thus +include many hard-coded pre-allocations. For this reason, it is not +recommended to use these methods for purposes other than to Sonic's +3D mixing, as they will likely break or give undefined results. + +If you wish to make features more general purpose or create your own, it is +recommended that you define and pre-allocate your own containers as data +members of the 3D Mixer or make sure they comply with the size restrictions +of the 3D mixing code. +*/ + +#define INVALID_ANGLE 9999 +#define MAX_GPS_OBJ_DISTANCE 30 // player must be at or within 10m of a GPS audio object to hear it + +class Mixer3D +{ +public: + Mixer3D(int bufSize, int smpRate, int bitD, World *w); + ~Mixer3D(); + + /** + Pre: The 3DMixer object must be instantiated and have reference to a list of Sonic AudioObj objects to perform processing. + 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 + 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 + arrays must be equal to the bufferSize of the 3D Mixer. + */ + void performMix(short *ioDataLeft, short *ioDataRight); + +private: + /** + 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 + KHz. leftFilter and rightFilter must be pre-allocated according to the number of taps for each sample rate: 128, 140, 256, or 279. + Post: leftFilter and rightFilter will be filled with complex data in the frequency domain which represent the HRTF filter at a specified Azimuth + and Elevation. + */ + int loadHRTF(int* pAzimuth, int* pElevation, unsigned int samplerate, unsigned int diffused, Complex *&leftFilter, Complex *&rightFilter); + + /** + 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 + 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 + NFFT. Because of the nature of the 3D Mixer, the NFFT maximum size is 2*bufferSize. Additionally, two containers for the frequency domain + 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 + of the input and filter arrays. + 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. + 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 + the convolution. + */ + void convolution(Complex *input, Complex *filter, Complex *output, long nSig, long nFil, long nFFT); + + /** + Pre: Similar requirements to the normal convolution(), extended to left and right versions of filter and output. As usual, all containers must be + pre-allocated and nFFT must be at maximum 2*bufferSize. + Post: The method will call convolution() twice for both left and right audio data, using the leftFilter and rightFilter and storing the results in + leftOutput and rightOutputThis method will propagate the fInput/fFilter population side effect of convolution(). + */ + void stereoConvolution(Complex *input, Complex *leftFilter, Complex *rightFilter, Complex *leftOutput, Complex *rightOutput, long nSig, long nFil, long nFFT); + + /** + * Returns a vector of valid audio objects to mix, i.e. those that are active and within range + */ + void computeValidAudioObjects(vector<AudioObj*> &validAudioObjectsOut); + /** + Re-computes and stores elevation and azimuth angles for all + audioObjects in this->myWorld + */ + void updateAngles(); + + /** + Returns true if x is a power of two, false otherwise + */ + bool isPowerOfTwo(int x); + + //Data members + + unsigned int bufferSize, //The size of the audio frames. + sampleRate, //The sample rate of the audio. + bitDepth, //The bit depth of the audio. + filterLength; //The MIT KEMAR Filter Size. + + World *myWorld; //A pointer to the world. + Player &player; //A reference to myWorld's player + + short *leftFilter, *rightFilter; //Arrays for retrieving the integer formatted filter data from the MIT KEMAR HRTF Database. + int *prevAzimuths, *prevElevations, + *azimuths, *elevations; + + Complex *inputAO, //Holds the current input of each audio object. + *overlapInput, //Holds the input of the last iteration in case the filter changed and the tail needs recalculation. + *fInput, *fFilter, //Data arrays to hold frequency domain representation of an input and filter. Used in convolution(). + **complexLeftFilter, **complexRightFilter, //Holds the complex datatype versions of the current filter. + **outputLeft, **outputRight, //Holds the output of each current input with the current filter. + **overlapLeft,**overlapRight; //Holds the second half of each 2*bufferSize convolution for next iteration. +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WavObject.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,95 @@ +// +// WavObject.h +// Demo +// +// Created by Philadelphia Game Lab on 7/7/14. +// Copyright (c) 2014 Philadelphia Game Lab. All rights reserved. +// + +#ifndef WAVOBJECT_H +#define WAVOBJECT_H + +#include <string> +#include "complextype.h" +#include <cmath> +#include <math.h> +#include <iostream> + +//using std::complex; + +class WavObject { + + FILE* soundFile; + struct + { + long n; + int sampleRate; + int bitDepth; + int nChannels; + }wavFileData; + long startOfWavData; + long endOfWavData; + +public: + + //Struct that holds RIFF data of Wave File. + //RIFF data is meta data info that holds ID, size and format of WAVE file. + struct RIFF_Header { + char chunkID[4]; + unsigned int chunkSize; + char format[4]; + }; + + //Struct that holds format subchunk data for WAVE file. + struct WAVE_Format { + unsigned int subChunkSize; + short audioFormat; + short nChannels; + unsigned int sampleRate; + unsigned int byteRate; + short blockAlign; + short bitsPerSample; + }; + + //Struct that holds data of WAVE file. + struct WAVE_Data { + long subChunk2Size; + }; + + //Struct to hold subchunkID + struct CHUNK_ID { + char chunkID[4]; + }; + + + WAVE_Format wave_format; + RIFF_Header riff_header; + WAVE_Data wave_data; + CHUNK_ID chunk_id; + + short *shortTempData; + Complex *complexTempData; + + + WavObject (unsigned int size,const std::string wavFileName) : shortTempData(new short[size]), complexTempData(new Complex[size]) { + extractWavHeader(wavFileName); + } + + Complex *loadCmpWavData(const std::string fname, long *size, int *smpFreq, int *bitDepth, int *channels); + void extractWavHeader (const std::string fname); + + // returns false if end of file reached and no repeat, true otherwise + bool loadMoreData(unsigned int size, bool repeat); + + void seekToBeginning(); + + ~WavObject () { + delete[] shortTempData; + delete[] complexTempData; + if (soundFile) + fclose(soundFile); + } + +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/World.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,105 @@ +#ifndef WORLD_H +#define WORLD_H + +#include <stdexcept> +#include <vector> +#include "pthread.h" +#include <unistd.h> + +#include "location.h" +#include "velocity.h" +#include "AudioObj.h" +#include "Player.h" + +// TODO: Move AUDIO_OBJECT_LOAD_INTERVAL to Sonic.h +#define AUDIO_OBJECT_LOAD_INTERVAL 10000 // interval at which input is loaded into audio object buffers + +using namespace std; + +// TODO: finish documenting World class +class World { + + Player player; + vector<AudioObj *> objList; + float threshold; + pthread_t writeThread; + bool isWriteThreadCreated; + + static void *writeAudioObjects (void *); + + public: + static const int MAX_OBJ = 20; + + //Constructors + + /** + Default constructor creates a player at the world's origin, {0,0,0}. + */ + World() : threshold(0.05), isWriteThreadCreated(false) {} + + /** + Creates a player at the + location specified by the first parameter, + and sets the player's bearing specified by + the second parameter. + */ + World(const Location& loc, const Velocity& vel, float bear) : player(Player(loc,vel, bear)), threshold(0.05), isWriteThreadCreated(false) {} + + ~World(); + + //Getters + float getPlayerBearing(); + + /** + Returns a reference to the player. + */ + Player& getPlayer(); + + /** + Returns a reference to the audio object at the + specified index. + */ + AudioObj* getAudioObj(size_t index) const; + + /** + Returns the array of the player's location. + */ + Location getPlayerLocation() const; + void getPlayerLocation(float &xOut, float &yOut, float &zOut); + void getPlayerGpsLocation(float &latitudeOut, float &longitudeOut, float &altitudeOut); + /** + Returns the number of audio objects in the world. + */ + int getNumObj(); + + // Setters + void setPlayerLocation(float x, float y, float z); + void setPlayerGpsLocation(float latitude, float longitude, float altitude); + void setPlayerBearing(float bearing); + + /** + Adds an audio object to the world. Returns the + index of the created object. Sets the location + of the created object at the world's origin, {0,0,0}. + */ + AudioObj* addAudioObj(const std::string wavFileName, bool isBackgroundObject=false); + + + AudioObj* addAudioObj(const std::string wavFileName, const Location& loc, bool isGpsObject=false); + + /** + Adds an audio object to the world. Returns the + index of the created object. Sets the location + of the created object at the location specified + by the parameter. + */ + AudioObj* addAudioObj(const std::string wavFileName, const Location& loc, const Velocity& vel); + + AudioObj* addBackgroundAudioObj(const std::string wavFileName); + + void createWriteThread(); + + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/complex.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,233 @@ +// complex.h - declaration of class +// of complex number +// +// The code is property of LIBROW +// You can use it on your own +// When utilizing credit LIBROW site + +#ifndef COMPLEX_H +#define COMPLEX_H + +class complex +{ +protected: + // Internal presentation - real and imaginary parts + double m_re; + double m_im; + +public: + // Imaginary unity + static const complex i; + static const complex j; + + // Constructors + complex(): m_re(0.), m_im(0.) {} + complex(double re, double im): m_re(re), m_im(im) {} + complex(double val): m_re(val), m_im(0.) {} + + // Assignment + complex& operator= (const double val) + { + m_re = val; + m_im = 0.; + return *this; + } + + // Basic operations - taking parts + double re() const { return m_re; } + double im() const { return m_im; } + + // Conjugate number + complex conjugate() const + { + return complex(m_re, -m_im); + } + + // Norm + double norm() const + { + return m_re * m_re + m_im * m_im; + } + + // Arithmetic operations + complex operator+ (const complex& other) const + { + return complex(m_re + other.m_re, m_im + other.m_im); + } + + complex operator- (const complex& other) const + { + return complex(m_re - other.m_re, m_im - other.m_im); + } + + complex operator* (const complex& other) const + { + return complex(m_re * other.m_re - m_im * other.m_im, + m_re * other.m_im + m_im * other.m_re); + } + + complex operator/ (const complex& other) const + { + const double denominator = other.m_re * other.m_re + other.m_im * other.m_im; + return complex((m_re * other.m_re + m_im * other.m_im) / denominator, + (m_im * other.m_re - m_re * other.m_im) / denominator); + } + + complex& operator+= (const complex& other) + { + m_re += other.m_re; + m_im += other.m_im; + return *this; + } + + complex& operator-= (const complex& other) + { + m_re -= other.m_re; + m_im -= other.m_im; + return *this; + } + + complex& operator*= (const complex& other) + { + const double temp = m_re; + m_re = m_re * other.m_re - m_im * other.m_im; + m_im = m_im * other.m_re + temp * other.m_im; + return *this; + } + + complex& operator/= (const complex& other) + { + const double denominator = other.m_re * other.m_re + other.m_im * other.m_im; + const double temp = m_re; + m_re = (m_re * other.m_re + m_im * other.m_im) / denominator; + m_im = (m_im * other.m_re - temp * other.m_im) / denominator; + return *this; + } + + complex& operator++ () + { + ++m_re; + return *this; + } + + complex operator++ (int) + { + complex temp(*this); + ++m_re; + return temp; + } + + complex& operator-- () + { + --m_re; + return *this; + } + + complex operator-- (int) + { + complex temp(*this); + --m_re; + return temp; + } + + complex operator+ (const double val) const + { + return complex(m_re + val, m_im); + } + + complex operator- (const double val) const + { + return complex(m_re - val, m_im); + } + + complex operator* (const double val) const + { + return complex(m_re * val, m_im * val); + } + + complex operator/ (const double val) const + { + return complex(m_re / val, m_im / val); + } + + complex& operator+= (const double val) + { + m_re += val; + return *this; + } + + complex& operator-= (const double val) + { + m_re -= val; + return *this; + } + + complex& operator*= (const double val) + { + m_re *= val; + m_im *= val; + return *this; + } + + complex& operator/= (const double val) + { + m_re /= val; + m_im /= val; + return *this; + } + + friend complex operator+ (const double left, const complex& right) + { + return complex(left + right.m_re, right.m_im); + } + + friend complex operator- (const double left, const complex& right) + { + return complex(left - right.m_re, -right.m_im); + } + + friend complex operator* (const double left, const complex& right) + { + return complex(left * right.m_re, left * right.m_im); + } + + friend complex operator/ (const double left, const complex& right) + { + const double denominator = right.m_re * right.m_re + right.m_im * right.m_im; + return complex(left * right.m_re / denominator, + -left * right.m_im / denominator); + } + + // Boolean operators + bool operator== (const complex &other) const + { + return m_re == other.m_re && m_im == other.m_im; + } + + bool operator!= (const complex &other) const + { + return m_re != other.m_re || m_im != other.m_im; + } + + bool operator== (const double val) const + { + return m_re == val && m_im == 0.; + } + + bool operator!= (const double val) const + { + return m_re != val || m_im != 0.; + } + + friend bool operator== (const double left, const complex& right) + { + return left == right.m_re && right.m_im == 0.; + } + + friend bool operator!= (const double left, const complex& right) + { + return left != right.m_re || right.m_im != 0.; + } +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/complextype.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,13 @@ +#ifndef HAVE_COMPLEXTYPE_H__ +#define HAVE_COMPLEXTYPE_H__ +// This file is part of the FXT library. +// Copyright (C) 2010 Joerg Arndt +// License: GNU General Public License version 3 or later, +// see the file COPYING.txt in the main directory. + +#include <complex> + +using std::complex; +typedef complex<double> Complex; + +#endif //defined HAVE_COMPLEXTYPE_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fft.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,74 @@ +// fft.h - declaration of class +// of fast Fourier transform - FFT +// +// The code is property of LIBROW +// You can use it on your own +// When utilizing credit LIBROW site + +#ifndef FFT_H +#define FFT_H + +//#include "complex.h" +#include "complextype.h" +#include <string> + +class CFFT +{ + public: + //Convolution functions + //NFFT is the FFT size (will be modified if invalid!), nSIG is the size for the input, NFIL is the size of the filter + //Zero padding is automatically taken care of in the convolution function. + //T means the function returns result in time domain; F is the result in the frequency domain. + static Complex* convolutionF(const Complex *input,const Complex *filter, long nSIG, long NFIL, long &NFFT); + static Complex* convolutionT(const Complex *input,const Complex *filter, long nSIG, long NFIL, long &NFFT); + static Complex* stereoConvMonoInputF(const Complex *input, const Complex *filterLeft, const Complex *filterRight, long nSIG, long NFILL, long NFILR, long &NFFT); + static Complex* stereoConvMonoInputT(const Complex *input, const Complex *filterLeft, const Complex *filterRight, long nSIG,long NFILL, long NFILR, long &NFFT); + static Complex* stereoConvStereoInputF(const Complex *input, const Complex *filterLeft, const Complex *filterRight, long nSIG, long NFILL, long NFILR, long &NFFT); + static Complex* stereoConvStereoInputT(const Complex *input, const Complex *filterLeft, const Complex *filterRight, long nSIG, long NFILL, long NFILR, long &NFFT); + + + //storing the an array into a text file + //filename is the file name you want to store the data into + //datatype represents the data you wanna store: real/real+imag/amplitude + static void storingData(Complex *data, int NFFT, std::string temp, char datatype); + + // FORWARD FOURIER TRANSFORM + // Input - input data + // Output - transform result + // N - length of both input data and result + static bool Forward(const Complex *const Input, Complex *const Output, const unsigned int N); + + // FORWARD FOURIER TRANSFORM, INPLACE VERSION + // Data - both input data and output + // N - length of input data + static bool Forward(Complex *const Data, const unsigned int N); + + // INVERSE FOURIER TRANSFORM + // Input - input data + // Output - transform result + // N - length of both input data and result + // Scale - if to scale result + static bool Inverse(const Complex *const Input, Complex *const Output, const unsigned int N, const bool Scale = true); + + // INVERSE FOURIER TRANSFORM, INPLACE VERSION + // Data - both input data and output + // N - length of both input data and result + // Scale - if to scale result + static bool Inverse(Complex *const Data, const unsigned int N, const bool Scale = true); + + protected: + // Rearrange function and its inplace version + static void Rearrange(const Complex *const Input, Complex *const Output, const unsigned int N); + + static void Rearrange(Complex *Data, const unsigned int N); + + + + // FFT implementation + static void Perform(Complex *const Data, const unsigned int N, const bool Inverse = false); + + // Scaling of inverse FFT result + static void Scale(Complex *const Data, const unsigned int N); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/location.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,25 @@ +#ifndef LOCATION_H +#define LOCATION_H + +#pragma once + +#include <stdexcept> + +using namespace std; + +class Location { + float x; + float y; + float z; +public: + Location () : x(0), y(0), z(0) {} + Location (float x0, float y0, float z0) : x(x0), y(y0), z(z0) {} + Location& operator= (const Location&); + Location& operator+=(const Location&); + bool operator< (const Location&) const; + float getX (void) const; + float getY (void) const; + float getZ (void) const; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mit_hrtf_filter.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,131 @@ +/*############################################################################*/ +/*# #*/ +/*# MIT HRTF C Library #*/ +/*# Copyright � 2007 Aristotel Digenis #*/ +/*# #*/ +/*# Filename: mit_hrtf_filter.h #*/ +/*# Version: 0.1 #*/ +/*# Date: 04/05/2007 #*/ +/*# Author(s): Aristotel Digenis (adigenis@users.sourceforge.net) #*/ +/*# Credit: Bill Gardner and Keith Martin #*/ +/*# Licence: GNU Library or Lesser General Public License (LGPL) #*/ +/*# #*/ +/*############################################################################*/ + + +#ifndef MIT_HRTF_FILTER_H +#define MIT_HRTF_FILTER_H + +#define MIT_HRTF_AZI_POSITIONS_00 37 +#define MIT_HRTF_AZI_POSITIONS_10 37 +#define MIT_HRTF_AZI_POSITIONS_20 37 +#define MIT_HRTF_AZI_POSITIONS_30 31 +#define MIT_HRTF_AZI_POSITIONS_40 29 +#define MIT_HRTF_AZI_POSITIONS_50 23 +#define MIT_HRTF_AZI_POSITIONS_60 19 +#define MIT_HRTF_AZI_POSITIONS_70 13 +#define MIT_HRTF_AZI_POSITIONS_80 7 +#define MIT_HRTF_AZI_POSITIONS_90 1 + +#define MIT_HRTF_44_TAPS 128 +#define MIT_HRTF_48_TAPS 140 +#define MIT_HRTF_88_TAPS 256 +#define MIT_HRTF_96_TAPS 279 + +typedef struct mit_hrtf_filter_44_str +{ + short left[MIT_HRTF_44_TAPS]; + short right[MIT_HRTF_44_TAPS]; +}mit_hrtf_filter_44; + +typedef struct mit_hrtf_filter_48_str +{ + short left[MIT_HRTF_48_TAPS]; + short right[MIT_HRTF_48_TAPS]; +}mit_hrtf_filter_48; + +typedef struct mit_hrtf_filter_88_str +{ + short left[MIT_HRTF_88_TAPS]; + short right[MIT_HRTF_88_TAPS]; +}mit_hrtf_filter_88; + +typedef struct mit_hrtf_filter_96_str +{ + short left[MIT_HRTF_96_TAPS]; + short right[MIT_HRTF_96_TAPS]; +}mit_hrtf_filter_96; + +typedef struct mit_hrtf_filter_set_44_str +{ + mit_hrtf_filter_44 e_10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_44 e_20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_44 e_30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_44 e_40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_44 e00[MIT_HRTF_AZI_POSITIONS_00]; + mit_hrtf_filter_44 e10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_44 e20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_44 e30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_44 e40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_44 e50[MIT_HRTF_AZI_POSITIONS_50]; + mit_hrtf_filter_44 e60[MIT_HRTF_AZI_POSITIONS_60]; + mit_hrtf_filter_44 e70[MIT_HRTF_AZI_POSITIONS_70]; + mit_hrtf_filter_44 e80[MIT_HRTF_AZI_POSITIONS_80]; + mit_hrtf_filter_44 e90[MIT_HRTF_AZI_POSITIONS_90]; +}mit_hrtf_filter_set_44; + +typedef struct mit_hrtf_filter_set_48_str +{ + mit_hrtf_filter_48 e_10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_48 e_20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_48 e_30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_48 e_40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_48 e00[MIT_HRTF_AZI_POSITIONS_00]; + mit_hrtf_filter_48 e10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_48 e20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_48 e30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_48 e40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_48 e50[MIT_HRTF_AZI_POSITIONS_50]; + mit_hrtf_filter_48 e60[MIT_HRTF_AZI_POSITIONS_60]; + mit_hrtf_filter_48 e70[MIT_HRTF_AZI_POSITIONS_70]; + mit_hrtf_filter_48 e80[MIT_HRTF_AZI_POSITIONS_80]; + mit_hrtf_filter_48 e90[MIT_HRTF_AZI_POSITIONS_90]; +}mit_hrtf_filter_set_48; + +typedef struct mit_hrtf_filter_set_88_str +{ + mit_hrtf_filter_88 e_10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_88 e_20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_88 e_30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_88 e_40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_88 e00[MIT_HRTF_AZI_POSITIONS_00]; + mit_hrtf_filter_88 e10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_88 e20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_88 e30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_88 e40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_88 e50[MIT_HRTF_AZI_POSITIONS_50]; + mit_hrtf_filter_88 e60[MIT_HRTF_AZI_POSITIONS_60]; + mit_hrtf_filter_88 e70[MIT_HRTF_AZI_POSITIONS_70]; + mit_hrtf_filter_88 e80[MIT_HRTF_AZI_POSITIONS_80]; + mit_hrtf_filter_88 e90[MIT_HRTF_AZI_POSITIONS_90]; +}mit_hrtf_filter_set_88; + +typedef struct mit_hrtf_filter_set_96_str +{ + mit_hrtf_filter_96 e_10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_96 e_20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_96 e_30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_96 e_40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_96 e00[MIT_HRTF_AZI_POSITIONS_00]; + mit_hrtf_filter_96 e10[MIT_HRTF_AZI_POSITIONS_10]; + mit_hrtf_filter_96 e20[MIT_HRTF_AZI_POSITIONS_20]; + mit_hrtf_filter_96 e30[MIT_HRTF_AZI_POSITIONS_30]; + mit_hrtf_filter_96 e40[MIT_HRTF_AZI_POSITIONS_40]; + mit_hrtf_filter_96 e50[MIT_HRTF_AZI_POSITIONS_50]; + mit_hrtf_filter_96 e60[MIT_HRTF_AZI_POSITIONS_60]; + mit_hrtf_filter_96 e70[MIT_HRTF_AZI_POSITIONS_70]; + mit_hrtf_filter_96 e80[MIT_HRTF_AZI_POSITIONS_80]; + mit_hrtf_filter_96 e90[MIT_HRTF_AZI_POSITIONS_90]; +}mit_hrtf_filter_set_96; + +#endif // _MIT_HRTF_FILTER_H \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/velocity.h Tue Apr 07 21:09:51 2015 +0000 @@ -0,0 +1,24 @@ +#ifndef VELOCITY_H +#define VELOCITY_H + +#pragma once + +#include <stdexcept> + +using namespace std; + +class Velocity { + float dx; + float dy; + float dz; +public: + Velocity () : dx(0), dy(0), dz(0) {} + Velocity (float dx0, float dy0, float dz0) : dx(dx0), dy(dy0), dz(dz0) {} + Velocity& operator= (const Velocity&); + Velocity& operator+=(const Velocity&); + bool operator< (const Velocity&) const; + float getdX (void) const; + float getdY (void) const; + float getdZ (void) const; +}; +#endif \ No newline at end of file