diff options
57 files changed, 6011 insertions, 2303 deletions
@@ -1,10 +1,28 @@ +### Emacs ### +*~ + +### XCode ### +## Build generated +build/ +DerivedData/ + +## Various settings *.pbxuser +!default.pbxuser *.mode1v3 +!default.mode1v3 *.mode2v3 -build +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint -build .DS_Store /maximilianTestWindowsVS2010/Debug /maximilianTestWindowsVS2010/ipch @@ -41,7 +41,7 @@ This is in the maximilianTestWindowsVS2010 folder. You will need to install the :::COMMAND LINE COMPILATION IN MACOSX -> g++ -Wall -D__MACOSX_CORE__ -o maximilian main.cpp RtAudio.cpp player.cpp maximilian.cpp -framework CoreAudio -lpthread +> g++ -Wall -D__MACOSX_CORE__ -o maximilian main.cpp RtAudio.cpp player.cpp maximilian.cpp -framework CoreAudio -framework CoreFoundation -lpthread > ./maximilian diff --git a/libs/fft.cpp b/libs/fft.cpp index 85a7aa9..4332d88 100644 --- a/libs/fft.cpp +++ b/libs/fft.cpp @@ -544,8 +544,8 @@ void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float } /* zero negative frequencies */ - memset(in_real+half, half, 0.0); - memset(in_img+half, half, 0.0); + memset(in_real+half, 0, sizeof(float) * half); + memset(in_img+half, 0, sizeof(float) * half); FFT(n, 1, in_real, in_img, out_real, out_img); // second parameter indicates inverse transform diff --git a/libs/maxiGrains.h b/libs/maxiGrains.h index a6b8c52..5fd5beb 100644 --- a/libs/maxiGrains.h +++ b/libs/maxiGrains.h @@ -1,13 +1,13 @@ -#ifndef _MAXI_GRAINS_H -#define _MAXI_GRAINS_H +#ifndef maxiGrains_2_hpp +#define maxiGrains_2_hpp #include "maximilian.h" #if defined(__APPLE_CC__) #include "accelerate/accelerate.h" //Mac users can uncommment the line below to use Apple's accelerate framework for calculating grains. This gives ~300% speed improvement and better sound quality, but doesn't work well on all machines. -//#define MAXIGRAINFAST +//#define MAXIGRAINFAST #endif #include <list> @@ -17,214 +17,184 @@ typedef unsigned long ulong; //window functions from http://en.wikipedia.org/wiki/Window_function#High-_and_moderate-resolution_windows struct hannWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.5 * (1.0 - cos((2.0 * PI * windowPos) / (windowLength - 1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.5 * (1.0 - cos((2.0 * PI * windowPos) / (windowLength - 1))); + } }; //this window can produce clicks struct hammingWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.54 - (0.46 * cos((2.0 * PI * windowPos) / (windowLength - 1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.54 - (0.46 * cos((2.0 * PI * windowPos) / (windowLength - 1))); + } }; struct cosineWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return sin((PI * windowPos) / (windowLength - 1)); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return sin((PI * windowPos) / (windowLength - 1)); + } }; struct rectWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 1; - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 1; + } }; struct triangleWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return (2.0 / (windowLength-1.0)) * (((windowLength-1.0)/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return (2.0 / (windowLength-1.0)) * (((windowLength-1.0)/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); + } }; struct triangleNZWinFunctor { - //non zero end points - inline double operator()(ulong windowLength, ulong windowPos) { - return (2.0 / windowLength) * ((windowLength/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); - } + //non zero end points + inline double operator()(ulong windowLength, ulong windowPos) { + return (2.0 / windowLength) * ((windowLength/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); + } }; struct blackmanHarrisWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.35875 - - (0.48829 * cos((2 * PI * windowPos) / (windowLength-1))) + - (0.14128 * cos((4 * PI * windowPos) / (windowLength-1))) + - (0.01168 * cos((6 * PI * windowPos) / (windowLength-1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.35875 - + (0.48829 * cos((2 * PI * windowPos) / (windowLength-1))) + + (0.14128 * cos((4 * PI * windowPos) / (windowLength-1))) + + (0.01168 * cos((6 * PI * windowPos) / (windowLength-1))); + } }; struct blackmanNutallWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.3635819 - - (0.4891775 * cos((2 * PI * windowPos) / (windowLength-1))) + - (0.1365995 * cos((4 * PI * windowPos) / (windowLength-1))) + - (0.0106411 * cos((6 * PI * windowPos) / (windowLength-1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.3635819 - + (0.4891775 * cos((2 * PI * windowPos) / (windowLength-1))) + + (0.1365995 * cos((4 * PI * windowPos) / (windowLength-1))) + + (0.0106411 * cos((6 * PI * windowPos) / (windowLength-1))); + } }; struct gaussianWinFunctor { - double gausDivisor; + double o; gaussianWinFunctor() { - init(0.3); - } - gaussianWinFunctor(double kurtosis) { - init(kurtosis); + o = 0.02; //compatible with MPTK } - void init(double kurtosis) { - gausDivisor = (-2.0 * kurtosis * kurtosis); + inline double operator()(ulong windowLength, ulong windowPos) { + double p = 1.0/(2.0*o*(windowLength+1)*(windowLength+1)); + double k = (double)windowPos-((double)(windowLength-1))/2.0; + return exp(-k*k*p); } - inline double operator()(ulong windowLength, ulong windowPos) { - double phase = ((windowPos / (double) windowLength) - 0.5) * 2.0; - return exp((phase * phase) / gausDivisor); - } }; template<typename F> class maxiGrainWindowCache { public: - unsigned int cacheSize; - - maxiGrainWindowCache() { - cacheSize = maxiSettings::sampleRate / 2.0; //allocate mem for up to 500ms grains - cache = (double**)malloc(cacheSize * sizeof(double*)); - for(int i=0; i < cacheSize; i++) { - cache[i] = NULL; - } - } - - ~maxiGrainWindowCache() { - for(int i=0; i < cacheSize; i++) { - if(NULL != cache[i]) { - free(cache[i]); - } - } + unsigned int cacheSize; + + maxiGrainWindowCache() { + cacheSize = maxiSettings::sampleRate / 2.0; //allocate mem for up to 500ms grains + cache = (double**)malloc(cacheSize * sizeof(double*)); + for(int i=0; i < cacheSize; i++) { + cache[i] = NULL; + } + } + + ~maxiGrainWindowCache() { + for(int i=0; i < cacheSize; i++) { + if(NULL != cache[i]) { + free(cache[i]); + } + } free(cache); - } - - double* getWindow(const unsigned int length) { - if (NULL == cache[length]) { - cache[length] = (double*)malloc(length * sizeof(double)); - for(int i=0; i < length; i++) { - cache[length][i] = F()(length, i); - } - } - return cache[length]; - } - + } + + double* getWindow(const unsigned int length) { + if (NULL == cache[length]) { + cache[length] = (double*)malloc(length * sizeof(double)); + for(int i=0; i < length; i++) { + cache[length][i] = F()(length, i); + } + } + return cache[length]; + } + private: - double** cache; - + double** cache; + }; class maxiGrainBase { public: - virtual double play() {} + virtual double play() {} virtual ~maxiGrainBase() {} - bool finished; + bool finished; }; -template<typename F> +template<class F, class maxiSample> class maxiGrain : public maxiGrainBase { public: - maxiSample *sample; + maxiSample *sample; double pos; - double dur; - long sampleStartPos; - long sampleIdx; - long sampleDur; - long sampleEndPos; - double freq; - double speed; - double inc; - double frequency; - double* window; - short* buffer; + double dur; + long sampleStartPos; + long sampleIdx; + long sampleDur; + long sampleEndPos; + double freq; + double speed; + double inc; + double frequency; + double* window; + // short* buffer; #if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - double* grainSamples; + // double* grainSamples; #endif - /* - position between 0.0 and 1.0 - duration in seconds - */ - maxiGrain(maxiSample *sample, const double position, const double duration, const double speed, maxiGrainWindowCache<F> *windowCache) :sample(sample), pos(position), dur(duration), speed(speed) - { - buffer = sample->temp; - sampleStartPos = sample->length * pos; - sampleDur = dur * (double)sample->mySampleRate; - sampleDurMinusOne = sampleDur - 1; - sampleIdx = 0; - finished = 0; - freq = 1.0 / dur; - sampleEndPos = min(sample->length, sampleStartPos + sampleDur); - frequency = freq * speed; - if (frequency > 0) { - pos = sampleStartPos; - }else{ - pos = sampleEndPos; - } + /* + position between 0.0 and 1.0 + duration in seconds + */ + maxiGrain(maxiSample *_sample, const double position, const double duration, const double speed, maxiGrainWindowCache<F> *windowCache) :sample(_sample), pos(position), dur(duration), speed(speed) + { + // buffer = sample->temp; + sampleStartPos = (sample->length) * pos; + sampleDur = dur * (double)maxiSettings::sampleRate; + sampleDurMinusOne = sampleDur - 1; + sampleIdx = 0; + finished = 0; + freq = 1.0 / dur; + sampleEndPos = min(sample->length, sampleStartPos + sampleDur); + frequency = freq * speed; + if (frequency > 0) { + pos = sampleStartPos; + }else{ + pos = sampleEndPos; + } if (frequency != 0) { inc = sampleDur/(maxiSettings::sampleRate/frequency); }else inc = 0; - window = windowCache->getWindow(sampleDur); - -#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - //premake the grain using fast vector functions, and quadratic interpolation - double *sourceData = (double*)malloc(sampleDur * sizeof(double)); - short* buffer = (short *)sample->temp; - //convert sample to double data - vDSP_vflt16D(buffer + sampleStartPos, 1, sourceData, 1, min(sampleDur, sample->length - sampleStartPos)); - //todo: wraping code - - grainSamples = (double*)malloc(sampleDur * sizeof(double)); - //make list of interpolation indexes - double* interpIndexes = (double*)malloc(sampleDur * sizeof(double)); - double interpPos = sampleStartPos; - for(int i=0; i < sampleDur; i++) { - interpIndexes[i] = interpPos - sampleStartPos; - interpPos += fabs(inc); - } - vDSP_vqintD(sourceData, interpIndexes, 1, grainSamples, 1, sampleDur, sampleDur); - if (frequency < 0) { - vDSP_vrvrsD(grainSamples,1, sampleDur); - } - static double divFactor = 32767.0; - vDSP_vsdivD(grainSamples, 1, &divFactor, grainSamples, 1, sampleDur); - vDSP_vmulD(grainSamples, 1, window, 1, grainSamples, 1, sampleDur); - delete sourceData, interpIndexes; -#endif - } - - ~maxiGrain() { + window = windowCache->getWindow(sampleDur); + + } + + ~maxiGrain() { #if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - delete[] grainSamples; + delete[] grainSamples; #endif - } - - inline double play() { - double output = 0.0; - if (!finished) { + } + + inline double play() { + double output = 0.0; + if (!finished) { #if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - output = grainSamples[sampleIdx]; + // output = grainSamples[sampleIdx]; #else - envValue = window[sampleIdx]; - double remainder; + envValue = window[sampleIdx]; + double remainder; pos += inc; - if (pos >= sample->length) + if (pos >= sample->length) pos -= sample->length; - else if (pos < 0) + else if (pos < 0) pos += sample->length; long posl = floor(pos); @@ -234,20 +204,21 @@ public: if (b >= sample->length) { b = 0; } - output = (double) ((1-remainder) * buffer[a] + - remainder * buffer[b])/32767.0;//linear interpolation - output *= envValue; + //output = (double) ((1-remainder) * sample->operator[](a) + + // remainder * sample->operator[](b))/32767.0;//linear interpolation + output = (double) ((1-remainder) * sample->temp[a] + remainder * sample->temp[b])/32767.0;//linear interpolation + output *= envValue; #endif - } - sampleIdx++; - if (sampleIdx == sampleDur) finished = true; - return output; - } - -protected: - maxiGrain(); - double envValue; - ulong sampleDurMinusOne; + } + sampleIdx++; + if (sampleIdx == sampleDur) finished = true; + return output; + } + +protected: + maxiGrain(); + double envValue; + ulong sampleDurMinusOne; }; @@ -255,173 +226,64 @@ typedef list<maxiGrainBase*> grainList; class maxiGrainPlayer { public: - grainList grains; - maxiSample *sample; - - maxiGrainPlayer(maxiSample *sample) : sample(sample) { - } - - void addGrain(maxiGrainBase *g) { - grains.push_back(g); - } - - inline double play() { - double total = 0.0; - grainList::iterator it = grains.begin(); - while(it != grains.end()) { - total += (*it)->play(); - if ((*it)->finished) { - delete(*it); - it = grains.erase(it); - }else{ - it++; - } - } - return total; - } -}; - -template<typename F> -class maxiTimestretch { -protected: - double position; -public: - maxiSample *sample; - maxiGrainPlayer *grainPlayer; - maxiGrainWindowCache<F> windowCache; - double randomOffset; - double looper; - - - - maxiTimestretch(maxiSample *sample) : sample(sample) { - position=0; - looper = 0; - grainPlayer = new maxiGrainPlayer(sample); - randomOffset=0; - } - - ~maxiTimestretch() { - delete grainPlayer; - } + grainList grains; + // maxiSample *sample; + // source *sample; - double getNormalisedPosition() { - return position / (double) sample->length; - } - double getPosition() { - return position; - } + // maxiGrainPlayer(maxiSample *sample) : sample(sample) { + // } - void setPosition(double pos) { - position = pos * sample->length; - position = maxiMap::clamp(position, 0, sample->length-1); + // maxiGrainPlayer(source *sample) : sample(sample) { + // } + + void addGrain(maxiGrainBase *g) { + grains.push_back(g); } - - - //play at a speed - inline double play(double speed, double grainLength, int overlaps, double posMod=0.0) { - position = position + speed; - looper++; - if (position > sample->length) position-= sample->length; - if (position < 0) position += sample->length; - double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; - if (looper > cycleLength + randomOffset) { - looper -= (cycleLength + randomOffset); - speed = (speed > 0 ? 1 : -1); - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); - grainPlayer->addGrain(g); - randomOffset = rand() % 10; - } - return grainPlayer->play(); - } - - //provide your own position iteration - inline double play2(double pos, double grainLength, int overlaps) { - looper++; - pos *= sample->length; - if (0 == floor(fmod(looper, grainLength * maxiSettings::sampleRate / overlaps))) { - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(pos / sample->length)),0.0), grainLength, 1, &windowCache); - grainPlayer->addGrain(g); - } - return grainPlayer->play(); - } -}; - -//in maxiTimeStretch, the speed is either 1 or -1, and the actual speed value only affects the grain position -//in maxiPitchShift, speed is uncoupled from position and allowed to set it's value incrementally, resulting in pitchshift. -//with both high speed values and negative speed values there are some terrific artefacts! - -template<typename F> -class maxiPitchShift { -public: - double position; - long cycles; - maxiSample *sample; - maxiGrainPlayer *grainPlayer; - maxiGrainWindowCache<F> windowCache; - double randomOffset; - - maxiPitchShift(maxiSample *sample) : sample(sample) { - position=0; - cycles=0; - grainPlayer = new maxiGrainPlayer(sample); - randomOffset=0; - } - - ~maxiPitchShift() { - delete grainPlayer; - } - - double play(double speed, double grainLength, int overlaps, double posMod=0.0) { - position = position + 1; - cycles++; - if (position > sample->length) position=0; - if (position < 0) position = sample->length; - double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; - double cycleMod = fmod(cycles, cycleLength + randomOffset); - if (0 == floor(cycleMod)) { - // cout << cycleMod << endl; - //speed = (speed > 0 ? 1 : -1); - speed = speed - ((cycleMod / cycleLength) * 0.1); - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); - grainPlayer->addGrain(g); - // cout << grainPlayer->grains.size() << endl; - // randomOffset = rand() % 10; - // randomOffset = rand() % 10; - } - return grainPlayer->play(); - } - + inline double play() { + double total = 0.0; + grainList::iterator it = grains.begin(); + while(it != grains.end()) { + total += (*it)->play(); + if ((*it)->finished) { + delete(*it); + it = grains.erase(it); + }else{ + it++; + } + } + return total; + } }; //and here's maxiPitchStretch. Args to the play function are basically speed for 'pitch' and rate for playback rate. //the rest is the same. -template<typename F> -class maxiPitchStretch { +template<class F, class maxiSample> +class maxiTimePitchStretch { public: - double position; - maxiSample *sample; - maxiGrainPlayer *grainPlayer; - maxiGrainWindowCache<F> windowCache; - double randomOffset; + double position; + maxiSample *sample; + maxiGrainPlayer *grainPlayer; + maxiGrainWindowCache<F> windowCache; + double randomOffset; long loopStart, loopEnd, loopLength; double looper; - - maxiPitchStretch(maxiSample *sample) : sample(sample) { - grainPlayer = new maxiGrainPlayer(sample); - randomOffset=0; + + maxiTimePitchStretch(maxiSample *_sample) : sample(_sample) { + grainPlayer = new maxiGrainPlayer(); + randomOffset=0; loopStart = 0.0; + sample->getLength(); loopEnd = sample->length; - loopLength =sample->length; - position=0; + loopLength = sample->length; + position=0; looper = 0; - } + } double getNormalisedPosition() { - return position / (double) sample->length; + return position / (double) sample->getLength(); } double getPosition() { @@ -430,7 +292,7 @@ public: void setPosition(double pos) { position = pos * sample->length; - position = maxiMap::clamp(position, 0, sample->length-1); + position = maxiMap::clamp<double>(position, 0, sample->length-1); } void setLoopStart(double val) { @@ -442,26 +304,519 @@ public: loopEnd = val * sample->length; loopLength = loopEnd - loopStart; } - - ~maxiPitchStretch() { - delete grainPlayer; - } - - inline double play(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { - position = position + (1 * rate); + + + bool hasEnded() { + return position == loopEnd; + } + + ~maxiTimePitchStretch() { + delete grainPlayer; + } + + inline double play(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { + position = position + rate; + if (position >= loopEnd) position-= loopLength; + if (position < loopStart) position += loopLength; + return playNextGrain(speed, rate, grainLength, overlaps, posMod); + } + + inline double playOnce(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { + position = position + rate; + if (position >= loopEnd) position = loopEnd; + if (position < loopStart) position = loopEnd; + float val = 0; + if (position < loopEnd) + val = playNextGrain(speed, rate, grainLength, overlaps, posMod); + return val; + } + +protected: + inline double playNextGrain(double speed, double rate, double grainLength, int overlaps, double posMod) { looper++; - if (position >= loopEnd) position-= loopLength; - if (position < loopStart) position += loopLength; - double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; + double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; if (looper > cycleLength + randomOffset) { looper -= (cycleLength + randomOffset); - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); - grainPlayer->addGrain(g); + double pos = max(min(static_cast<double>(1.0), (position / sample->length) + posMod),static_cast<double>(0.0)); + maxiGrain<F, maxiSample> *g = new maxiGrain<F, maxiSample>(sample, + pos, + grainLength, speed, &windowCache); + grainPlayer->addGrain(g); randomOffset = rand() % 10; - } - return grainPlayer->play(); - } - + } + return grainPlayer->play(); + } + }; -#endif
\ No newline at end of file + +#endif /* maxiGrains_2_hpp */ + + +// +// +//#ifndef _MAXI_GRAINS_H +//#define _MAXI_GRAINS_H +//#include "maximilian.h" +// +//#if defined(__APPLE_CC__) +//#include "accelerate/accelerate.h" +////Mac users can uncommment the line below to use Apple's accelerate framework for calculating grains. This gives ~300% speed improvement and better sound quality, but doesn't work well on all machines. +//#define MAXIGRAINFAST +//#endif +// +//#include <list> +// +//typedef unsigned long ulong; +// +////window functions from http://en.wikipedia.org/wiki/Window_function#High-_and_moderate-resolution_windows +// +//struct hannWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.5 * (1.0 - cos((2.0 * PI * windowPos) / (windowLength - 1))); +// } +//}; +// +////this window can produce clicks +//struct hammingWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.54 - (0.46 * cos((2.0 * PI * windowPos) / (windowLength - 1))); +// } +//}; +// +// +//struct cosineWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return sin((PI * windowPos) / (windowLength - 1)); +// } +//}; +// +//struct rectWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 1; +// } +//}; +// +//struct triangleWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return (2.0 / (windowLength-1.0)) * (((windowLength-1.0)/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); +// } +//}; +// +//struct triangleNZWinFunctor { +// //non zero end points +// inline double operator()(ulong windowLength, ulong windowPos) { +// return (2.0 / windowLength) * ((windowLength/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); +// } +//}; +// +//struct blackmanHarrisWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.35875 - +// (0.48829 * cos((2 * PI * windowPos) / (windowLength-1))) + +// (0.14128 * cos((4 * PI * windowPos) / (windowLength-1))) + +// (0.01168 * cos((6 * PI * windowPos) / (windowLength-1))); +// } +//}; +// +//struct blackmanNutallWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.3635819 - +// (0.4891775 * cos((2 * PI * windowPos) / (windowLength-1))) + +// (0.1365995 * cos((4 * PI * windowPos) / (windowLength-1))) + +// (0.0106411 * cos((6 * PI * windowPos) / (windowLength-1))); +// } +//}; +// +//struct gaussianWinFunctor { +// double gausDivisor; +// gaussianWinFunctor() { +// init(0.3); +// } +// gaussianWinFunctor(double kurtosis) { +// init(kurtosis); +// } +// void init(double kurtosis) { +// gausDivisor = (-2.0 * kurtosis * kurtosis); +// } +// inline double operator()(ulong windowLength, ulong windowPos) { +// double phase = ((windowPos / (double) windowLength) - 0.5) * 2.0; +// return exp((phase * phase) / gausDivisor); +// } +//}; +// +// +//template<typename F> +//class maxiGrainWindowCache { +//public: +// unsigned int cacheSize; +// +// maxiGrainWindowCache() { +// cacheSize = maxiSettings::sampleRate / 2.0; //allocate mem for up to 500ms grains +// cache = (double**)malloc(cacheSize * sizeof(double*)); +// for(int i=0; i < cacheSize; i++) { +// cache[i] = NULL; +// } +// } +// +// ~maxiGrainWindowCache() { +// for(int i=0; i < cacheSize; i++) { +// if(NULL != cache[i]) { +// free(cache[i]); +// } +// } +// free(cache); +// } +// +// double* getWindow(const unsigned int length) { +// if (NULL == cache[length]) { +// cache[length] = (double*)malloc(length * sizeof(double)); +// for(int i=0; i < length; i++) { +// cache[length][i] = F()(length, i); +// } +// } +// return cache[length]; +// } +// +//private: +// double** cache; +// +//}; +// +//class maxiGrainBase { +//public: +// virtual double play() {} +// virtual ~maxiGrainBase() {} +// bool finished; +//}; +// +//template<typename F> +//class maxiGrain : public maxiGrainBase { +//public: +// maxiSample *sample; +// double pos; +// double dur; +// long sampleStartPos; +// long sampleIdx; +// long sampleDur; +// long sampleEndPos; +// double freq; +// double speed; +// double inc; +// double frequency; +// double* window; +// short* buffer; +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// double* grainSamples; +//#endif +// /* +// position between 0.0 and 1.0 +// duration in seconds +// */ +// maxiGrain(maxiSample *sample, const double position, const double duration, const double speed, maxiGrainWindowCache<F> *windowCache) :sample(sample), pos(position), dur(duration), speed(speed) +// { +// buffer = sample->temp; +// sampleStartPos = sample->length * pos; +// sampleDur = dur * (double)sample->mySampleRate; +// sampleDurMinusOne = sampleDur - 1; +// sampleIdx = 0; +// finished = 0; +// freq = 1.0 / dur; +// sampleEndPos = min(sample->length, sampleStartPos + sampleDur); +// frequency = freq * speed; +// if (frequency > 0) { +// pos = sampleStartPos; +// }else{ +// pos = sampleEndPos; +// } +// if (frequency != 0) { +// inc = sampleDur/(maxiSettings::sampleRate/frequency); +// }else +// inc = 0; +// window = windowCache->getWindow(sampleDur); +// +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// //premake the grain using fast vector functions, and quadratic interpolation +// double *sourceData = (double*)malloc(sampleDur * sizeof(double)); +// short* buffer = (short *)sample->temp; +// //convert sample to double data +// vDSP_vflt16D(buffer + sampleStartPos, 1, sourceData, 1, min(sampleDur, sample->length - sampleStartPos)); +// //todo: wraping code +// +// grainSamples = (double*)malloc(sampleDur * sizeof(double)); +// //make list of interpolation indexes +// double* interpIndexes = (double*)malloc(sampleDur * sizeof(double)); +// double interpPos = sampleStartPos; +// for(int i=0; i < sampleDur; i++) { +// interpIndexes[i] = interpPos - sampleStartPos; +// interpPos += fabs(inc); +// } +// vDSP_vqintD(sourceData, interpIndexes, 1, grainSamples, 1, sampleDur, sampleDur); +// if (frequency < 0) { +// vDSP_vrvrsD(grainSamples,1, sampleDur); +// } +// static double divFactor = 32767.0; +// vDSP_vsdivD(grainSamples, 1, &divFactor, grainSamples, 1, sampleDur); +// vDSP_vmulD(grainSamples, 1, window, 1, grainSamples, 1, sampleDur); +// delete sourceData, interpIndexes; +//#endif +// } +// +// ~maxiGrain() { +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// delete[] grainSamples; +//#endif +// } +// +// inline double play() { +// double output = 0.0; +// if (!finished) { +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// output = grainSamples[sampleIdx]; +//#else +// envValue = window[sampleIdx]; +// double remainder; +// pos += inc; +// if (pos >= sample->length) +// pos -= sample->length; +// else if (pos < 0) +// pos += sample->length; +// +// long posl = floor(pos); +// remainder = pos - posl; +// long a = posl; +// long b = posl+1; +// if (b >= sample->length) { +// b = 0; +// } +// output = (double) ((1-remainder) * buffer[a] + +// remainder * buffer[b])/32767.0;//linear interpolation +// output *= envValue; +//#endif +// } +// sampleIdx++; +// if (sampleIdx == sampleDur) finished = true; +// return output; +// } +// +//protected: +// maxiGrain(); +// double envValue; +// ulong sampleDurMinusOne; +//}; +// +// +//typedef list<maxiGrainBase*> grainList; +// +//class maxiGrainPlayer { +//public: +// grainList grains; +// maxiSample *sample; +// +// maxiGrainPlayer(maxiSample *sample) : sample(sample) { +// } +// +// void addGrain(maxiGrainBase *g) { +// grains.push_back(g); +// } +// +// inline double play() { +// double total = 0.0; +// grainList::iterator it = grains.begin(); +// while(it != grains.end()) { +// total += (*it)->play(); +// if ((*it)->finished) { +// delete(*it); +// it = grains.erase(it); +// }else{ +// it++; +// } +// } +// return total; +// } +//}; +// +//template<typename F> +//class maxiTimestretch { +//protected: +// double position; +//public: +// maxiSample *sample; +// maxiGrainPlayer *grainPlayer; +// maxiGrainWindowCache<F> windowCache; +// double randomOffset; +// double looper; +// +// +// +// maxiTimestretch(maxiSample *sample) : sample(sample) { +// position=0; +// looper = 0; +// grainPlayer = new maxiGrainPlayer(sample); +// randomOffset=0; +// } +// +// ~maxiTimestretch() { +// delete grainPlayer; +// } +// +// double getNormalisedPosition() { +// return position / (double) sample->length; +// } +// +// double getPosition() { +// return position; +// } +// +// void setPosition(double pos) { +// position = pos * sample->length; +// position = maxiMap::clamp<double>(position, 0, sample->length-1); +// } +// +// +// //play at a speed +// inline double play(double speed, double grainLength, int overlaps, double posMod=0.0) { +// position = position + speed; +// looper++; +// if (position > sample->length) position-= sample->length; +// if (position < 0) position += sample->length; +// double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; +// if (looper > cycleLength + randomOffset) { +// looper -= (cycleLength + randomOffset); +// speed = (speed > 0 ? 1 : -1); +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); +// grainPlayer->addGrain(g); +// randomOffset = rand() % 10; +// } +// return grainPlayer->play(); +// } +// +// +// //provide your own position iteration +// inline double play2(double pos, double grainLength, int overlaps) { +// looper++; +// pos *= sample->length; +// if (0 == floor(fmod(looper, grainLength * maxiSettings::sampleRate / overlaps))) { +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(pos / sample->length)),0.0), grainLength, 1, &windowCache); +// grainPlayer->addGrain(g); +// } +// return grainPlayer->play(); +// } +//}; +// +////in maxiTimeStretch, the speed is either 1 or -1, and the actual speed value only affects the grain position +////in maxiPitchShift, speed is uncoupled from position and allowed to set it's value incrementally, resulting in pitchshift. +////with both high speed values and negative speed values there are some terrific artefacts! +// +//template<typename F> +//class maxiPitchShift { +//public: +// double position; +// long cycles; +// maxiSample *sample; +// maxiGrainPlayer *grainPlayer; +// maxiGrainWindowCache<F> windowCache; +// double randomOffset; +// +// maxiPitchShift(maxiSample *sample) : sample(sample) { +// position=0; +// cycles=0; +// grainPlayer = new maxiGrainPlayer(sample); +// randomOffset=0; +// } +// +// ~maxiPitchShift() { +// delete grainPlayer; +// } +// +// double play(double speed, double grainLength, int overlaps, double posMod=0.0) { +// position = position + 1; +// cycles++; +// if (position > sample->length) position=0; +// if (position < 0) position = sample->length; +// double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; +// double cycleMod = fmod(cycles, cycleLength + randomOffset); +// if (0 == floor(cycleMod)) { +// // cout << cycleMod << endl; +// //speed = (speed > 0 ? 1 : -1); +// speed = speed - ((cycleMod / cycleLength) * 0.1); +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); +// grainPlayer->addGrain(g); +// // cout << grainPlayer->grains.size() << endl; +// // randomOffset = rand() % 10; +// // randomOffset = rand() % 10; +// } +// return grainPlayer->play(); +// } +// +//}; +// +////and here's maxiPitchStretch. Args to the play function are basically speed for 'pitch' and rate for playback rate. +////the rest is the same. +// +//template<typename F> +//class maxiPitchStretch { +//public: +// double position; +// maxiSample *sample; +// maxiGrainPlayer *grainPlayer; +// maxiGrainWindowCache<F> windowCache; +// double randomOffset; +// long loopStart, loopEnd, loopLength; +// double looper; +// +// maxiPitchStretch(maxiSample *sample) : sample(sample) { +// grainPlayer = new maxiGrainPlayer(sample); +// randomOffset=0; +// loopStart = 0.0; +// loopEnd = sample->length; +// loopLength =sample->length; +// position=0; +// looper = 0; +// } +// +// double getNormalisedPosition() { +// return position / (double) sample->length; +// } +// +// double getPosition() { +// return position; +// } +// +// void setPosition(double pos) { +// position = pos * sample->length; +// position = maxiMap::clamp<double>(position, 0, sample->length-1); +// } +// +// void setLoopStart(double val) { +// loopStart = val * sample->length; +// loopLength = loopEnd - loopStart; +// } +// +// void setLoopEnd(double val) { +// loopEnd = val * sample->length; +// loopLength = loopEnd - loopStart; +// } +// +// ~maxiPitchStretch() { +// delete grainPlayer; +// } +// +// inline double play(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { +// position = position + (1 * rate); +// looper++; +// if (position >= loopEnd) position-= loopLength; +// if (position < loopStart) position += loopLength; +// double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; +// if (looper > cycleLength + randomOffset) { +// looper -= (cycleLength + randomOffset); +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); +// grainPlayer->addGrain(g); +// randomOffset = rand() % 10; +// } +// return grainPlayer->play(); +// } +// +//}; +// +//#endif
\ No newline at end of file @@ -1,49 +1,88 @@ -//Using BPF equation from http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt +//#include "maximilian.h" +// +//maxiOsc myOsc; +//maxiEnvelope myEnv; +//int counter; +//double vals[12]={1,0.1,0.5,0.0,1.5,0.0,0.1,1,1.0,0.15,1.0,0.1}; +//std::vector<double> rampsA(vals, vals+12); +// +// +//void setup() {//some inits +// +// myEnv.trigger(true); +// +//} +// +//void play(double *output) {//this is where the magic happens. Very slow magic. +// +// counter++; +// +// if (counter ==0 || counter % 330400==0) { +// myEnv.trigger(true); +// } +// +// +// double out = myEnv.ramps(rampsA); +// +// output[0]=myOsc.sinewave(440)*out; +// +// output[1]=output[0]; +//} -#include "maximilian.h" -float xs[3], ys[3]; -float a0, a1, a2, b0, b1, b2; -float f0 = 400; //THE FREQUENCY -float Q = 1.0; +//#include "maximilian.h" +// +//maxiOsc myOsc; +//maxiEnvelope myEnv; +//int counter=0; +// +//void setup() { +//} +// +//void play(double *output) { +// +// +// if (counter ==0 || counter % 17640==0) { +// myEnv.trigger(true); +// } +// +// if (counter % 8821==0) { +// myEnv.trigger(false); +// } +// +// counter++; +// +// double out = myEnv.adsr(0.1,0.2,0.1,3); +// +// output[0]=myOsc.sinewave(440)*out; +// +// output[1]=output[0]; +// +//} -maxiOsc mySwitchableOsc; +#include "maximilian.h" -void setup() {//some inits - double w0 = 2*PI*f0/44100; - double alpha = sin(w0)/(2*Q); - //Band-pass reson: -// b0 = alpha; -// b1 = 0; -// b2 = -1 * alpha; -// a0 = 1 + alpha; -// a1 = -2*cos(w0); -// a2 = 1 - alpha; - - //Notch: - b0 = 1; - b1 = -2*cos(w0); - b2 = 1; - a0 = 1 + alpha; - a1 = -2*cos(w0); - a2 = 1 - alpha; - - //LPF: -// b0 = (1 - cos(w0))/2; -// b1 = 1 - cos(w0); -// b2 = (1 - cos(w0))/2; -// a0 = 1 + alpha; -// a1 = -2*cos(w0); -// a2 = 1 - alpha; +maxiOsc myOsc; +maxiEnvelope myEnv; +int counter; + +void setup() { } void play(double *output) { - xs[0] = mySwitchableOsc.sawn(400); - ys[0] = (b0/a0)*xs[0] + (b1/a0)*xs[1] + (b2/a0)*xs[2] - - (a1/a0)*ys[1] - (a2/a0)*ys[2]; - *output = ys[0]; - ys[2] = ys[1]; ys[1] = ys[0]; - xs[2] = xs[1]; xs[1] = xs[0]; + if (counter ==0 || counter % 8820==0) { + myEnv.trigger(true); + } + + + counter++; + + double out = myEnv.ar(0.01,1); + + output[0]=myOsc.sinewave(440)*out; + + output[1]=output[0]; + } diff --git a/maximilian.cpp b/maximilian.cpp index 8884e52..b0c0b5e 100644 --- a/maximilian.cpp +++ b/maximilian.cpp @@ -364,6 +364,8 @@ double maxiOsc::triangle(double frequency) { } +// don't use this nonsense. Use ramps instead. +// ..er... I mean "This method is deprecated" double maxiEnvelope::line(int numberofsegments,double segments[1000]) { //This is a basic multi-segment ramp generator that you can use for more or less anything. //However, it's not that intuitive. @@ -372,14 +374,14 @@ double maxiEnvelope::line(int numberofsegments,double segments[1000]) { nextval=segments[valindex+2]; currentval=segments[valindex]; if (currentval-amplitude > 0.0000001 && valindex < numberofsegments) { - amplitude += ((currentval-startval)/(maxiSettings::sampleRate/period)); + amplitude += ((currentval-startVal)/(maxiSettings::sampleRate/period)); } else if (currentval-amplitude < -0.0000001 && valindex < numberofsegments) { - amplitude -= (((currentval-startval)*(-1))/(maxiSettings::sampleRate/period)); + amplitude -= (((currentval-startVal)*(-1))/(maxiSettings::sampleRate/period)); } else if (valindex >numberofsegments-1) { valindex=numberofsegments-2; } else { valindex=valindex+2; - startval=currentval; + startVal=currentval; } output=amplitude; @@ -391,7 +393,7 @@ double maxiEnvelope::line(int numberofsegments,double segments[1000]) { return(output); } -//and this +//and this is also deprecated void maxiEnvelope::trigger(int index, double amp) { isPlaying=1;//ok the envelope is being used now. valindex=index; @@ -399,6 +401,195 @@ void maxiEnvelope::trigger(int index, double amp) { } +void maxiEnvelope::trigger(bool noteOn) { + + if (noteOn) trig=1; + if (noteOn==false) trig=0; + +} + +double maxiEnvelope::ramp(double startVal, double endVal, double duration){ + + if (trig!=0) { + phase=startVal; + isPlaying=true; + trig=0; + } + + if (isPlaying) { + + if (startVal<endVal) { + phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./duration))); + if ( phase >= endVal ) phase = endVal; + } + + if (startVal > endVal) { + phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./duration))); + if ( phase <= endVal ) phase = endVal; + } + return(phase); + } else { + + return(0); + + } + + +} + + +double maxiEnvelope::ramps(std::vector<double> rampsArray){ + + if (trig!=0) { + valindex=0; + endVal=rampsArray[valindex+1]; + isPlaying=true; + trig=0; + + } + + if (isPlaying) { + + if (valindex>0 && rampsArray[valindex-1]==rampsArray[valindex+1]) { + period += (1/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if (period>=1) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + period=0; + } + } output=phase; + } + + if (valindex==0 && output==endVal) { + period += (1/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if (period>=1) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + period=0; + } + } output=phase; + } + + if (phase<endVal) { + phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if ( phase >= endVal ) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + + } + } + output=phase; + } + + if (phase > endVal) { + phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if ( phase <= endVal ) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + + } + } output=phase; + } + + return(output); + + } else { + + return(0); + } +} + +double maxiEnvelope::ar(double attack, double release) { + + if (trig!=0) { + //phase=0; + releaseMode=false; + trig=0; + } + + if (phase<1 && releaseMode==false) { + phase += ((1)/(maxiSettings::sampleRate/(1./attack))); + if ( phase >= 1 ) { + phase=1; + releaseMode=true; + }; + } + + if (releaseMode==true) { + phase += ((-1)/(maxiSettings::sampleRate/(1./release))); + if ( phase <= 0 ) phase = 0; + } + + return phase; +} + + +double maxiEnvelope::adsr(double attack, double decay, double sustain, double release) { + + if (trig!=0 && !attackMode) { +// phase=0.; + releaseMode=false; + decayMode=false; + sustainMode=false; + attackMode=true; + trig=0; + } + + if (attackMode) { + phase += ((1)/(maxiSettings::sampleRate/(1./attack))); + + if ( phase >= 1 ) { + phase=1; + attackMode=false; + decayMode=true; + }; + } + + if (decayMode) { + phase += ((-1)/(maxiSettings::sampleRate/(1./decay))); + if ( phase <= sustain ) { + phase=sustain; + decayMode=false; + sustainMode=true; + }; + } + + if (sustainMode) { + + if (noteOn) { + phase=sustain; + } + + if (!noteOn) { + sustainMode=false; + releaseMode=true; + } + } + + if (releaseMode) { + phase += ((-sustain)/(maxiSettings::sampleRate/(1./release))); + if ( phase <= 0 ) { + phase = 0; + releaseMode=false; + } + } + + return phase; +} + + //Delay with feedback maxiDelayline::maxiDelayline() { memset( memory, 0, 88200*sizeof (double) ); @@ -1084,8 +1275,8 @@ double maxiSample::bufferPlay4(unsigned char &bufferin,double frequency, double } -void maxiSample::getLength() { - length=myDataSize*0.5; +long maxiSample::getLength() { + return (length=myDataSize*0.5); } void maxiSample::setLength(unsigned long numSamples) { @@ -2005,6 +2196,325 @@ void maxiSampler::trigger() { } +///************************************************************* +/// +/// Init most variables +/// +///************************************************************* +maxiRecorder::maxiRecorder() : +bufferSize(maxiSettings::sampleRate * 2), +bufferQueueSize(3), +bufferIndex(0), +recordedAmountFrames(0), +threadRunning(false) +{ +} +///************************************************************* +/// +/// Free resources in RAII manner and save to wav when this +/// object lifetime is up! +/// +///************************************************************* +maxiRecorder::~maxiRecorder() +{ + if (isRecording()) saveToWav(); + freeResources(); +} + +///************************************************************* +/// +/// Free resources only if they exist; may be called multiple +/// times in it's lifetime becasuse of destructor. +/// +///************************************************************* +void maxiRecorder::freeResources() +{ + if (savedBuffers.size() > 0) + { + for (int i = 0; i < savedBuffers.size(); ++i) + { + delete[] savedBuffers.front(); + savedBuffers.pop(); + } + } +} + +///************************************************************* +/// +/// Simply return if we are recording or not +/// +///************************************************************* +bool maxiRecorder::isRecording() const +{ + return doRecord; +} + +///************************************************************* +/// +/// Set the filename (and path) +/// +///************************************************************* +void maxiRecorder::setup(std::string _filename) +{ + filename = _filename; +} + +///************************************************************* +/// +/// You don't need to worry calling about this, this runs in a +/// detached thread after calling startRecording() and means +/// we can allocate new memory without interupting the real +/// time audio callback. Rather than have multiple ifdefs to +/// split up the same function to use different OS's threading +/// services I just redefined the thing because it looked +/// cleaner. +/// +/// A pointer to the instanciated object from this class is +/// passed as '_context'. We do this because we are calling this +/// function from a static helper func and need to access object +/// specific variables. +/// +///************************************************************* +#if defined(OS_IS_UNIX) +void* maxiRecorder::update(void* _context) +{ + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + maxiRecorder* _this = static_cast<maxiRecorder*>(_context); + _this->threadRunning = true; + while (_this->doRecord) + { + usleep((long)(10000. / bufferSize / maxiSettings::sampleRate)); + while (_this->bufferQueueSize > _this->bufferQueue.size()) + { + _this->enqueueBuffer(); + } + } + std::cout << "\nFinishing Recording..." << std::endl; + return 0; +} +#elif defined(OS_IS_WIN) +void* maxiRecorder::update(void* _context) +{ + maxiRecorder* _this = static_cast<maxiRecorder*>(_context); + _this->threadRunning = true; + long time = (long)(1000. / bufferSize / maxiSettings::sampleRate); + while (_this->doRecord) + { + Sleep(time); + while (_this->bufferQueueSize > _this->bufferQueue.size()) + { + _this->enqueueBuffer(); + } + } + std::cout << "\nFinishing Recording..." << std::endl; + return 0; +} +#endif + +///************************************************************* +/// +/// This whacks the update method into a detached thread which +/// will ensure there are enough buffers available in the queue. +/// +///************************************************************* +void maxiRecorder::startRecording() +{ + doRecord = true; + for (int i = 0; i < bufferQueueSize; ++i) + { + enqueueBuffer(); + } + +#if defined(OS_IS_UNIX) + if (pthread_create(&daemon, NULL, &maxiRecorder::update_pthread_helper, this) != 0) + std::cout << "pthread created incorrectly" << std::endl; + if (pthread_detach(daemon) != 0) + std::cout << "pthread detached incorrectly" << std::endl; +#elif defined(OS_IS_WIN) + unsigned threadID; + daemonHandle = (HANDLE) _beginthreadex(NULL, 0, &maxiRecorder::update_pthread_helper, (void *) this, 0, &threadID); +#endif + + +} + +///************************************************************* +/// +/// stops the recording thread by allowing the stack to unwind +/// in update() and stops the Windows thread if necessary +/// +///************************************************************* +void maxiRecorder::stopRecording() +{ +#if defined(OS_IS_WIN) + CloseHandle(daemonHandle); +#endif + doRecord = false; +} + +///************************************************************* +/// +/// Shamelessly hacked together largely using this link +/// http://stackoverflow.com/questions/22226872/two-problems- +/// when-writing-to-wav-c +/// +/// I haven't bothered to change the syntax much here and the +/// templated write function was too convenient during my +/// struggle to get my head around wav headers so I've kept it +/// very similar to the attached code. +/// +/// A clear optimisation would be to make getProcessedData() +/// return a vector of shorts to prevent another loop +/// +///************************************************************* +template <typename T> +void maxiRecorder::write(std::ofstream& _stream, const T& _t) { + _stream.write((const char*)&_t, sizeof(T)); +} + +void maxiRecorder::saveToWav() +{ + if (isRecording()) stopRecording(); + if (threadRunning) + { +#if defined(OS_IS_UNIX) + pthread_cancel(daemon); +#endif + threadRunning = false; + } + std::vector<double> pcmData = getProcessedData(); + std::vector<short> pcmDataInt; + + pcmDataInt.resize(pcmData.size()); + + for (int i = 0; i < pcmData.size(); ++i) + pcmDataInt[i] = (short) (pcmData[i] * 3276.7); + + int sampleRate = maxiSettings::sampleRate; + short channels = maxiSettings::channels; + int buffSize = pcmDataInt.size() * 2; + + std::ofstream stream(filename.c_str(), std::ios::binary); + + if (stream.is_open()) + { + /* Header */ + stream.write("RIFF", 4); + write<int>(stream, 36 + buffSize); + stream.write("WAVE", 4); + + /* Format Chunk */ + stream.write("fmt ", 4); + write<int>(stream, 16); + write<short>(stream, 1); + write<short>(stream, channels); + write<int>(stream, sampleRate); + write<int>(stream, sampleRate * channels * sizeof(short)); + write<short>(stream, channels * sizeof(short)); + write<short>(stream, 8 * sizeof(short)); + + /* Data Chunk */ + stream.write("data", 4); + stream.write((const char*) &buffSize, 4); + stream.write((const char*) pcmDataInt.data(), buffSize); + + stream.close(); + + std::cout << "Wrote " << buffSize + << " bytes to " << filename.c_str() + << std::endl; + } + else + { + std::cerr << "Failed to open file: " << strerror(errno) << std::endl; + } +} + +///************************************************************* +/// +/// This takes the queue of user generated arrays and whacks +/// it into a vector of doubles which is easier to transverse +/// and work with. +/// +///************************************************************* +std::vector<double> maxiRecorder::getProcessedData() +{ + std::vector<double> userData; + int dataSize = savedBuffers.size() * bufferSize; + userData.resize(dataSize); + + int savedIndex = 0; + for (int i = 0; i < dataSize; ++i) + { + if (i > 0 && i % bufferSize == 0) + { + savedIndex = 0; + savedBuffers.pop(); + } + + userData[i] = savedBuffers.front()[savedIndex]; + ++savedIndex; + } + + double lastFrame = userData[userData.size() - 1]; + while (lastFrame == 0) + { + userData.pop_back(); + lastFrame = userData[userData.size() - 1]; + } + + return userData; +} + +///************************************************************* +/// +/// Pass the buffer of audio to this method and it will write +/// it to the right place. This method is real-time safe and +/// is overriden for ofx's / port's floats array or maximilian's +/// / rtaudio's double +/// +///************************************************************* +void maxiRecorder::passData(double* _in, int _inBufferSize) +{ + for (int i = 0; i < _inBufferSize; ++i) + { + if (bufferIndex >= bufferSize) + { + bufferQueue.pop(); + bufferIndex = 0; + } + bufferQueue.front()[bufferIndex] = _in[i]; + ++bufferIndex; + ++recordedAmountFrames; + } +} +void maxiRecorder::passData(float* _in, int _inBufferSize) +{ + for (int i = 0; i < _inBufferSize; ++i) + { + if (bufferIndex >= bufferSize) + { + bufferQueue.pop(); + bufferIndex = 0; + } + bufferQueue.front()[bufferIndex] = (double) _in[i]; + ++bufferIndex; + ++recordedAmountFrames; + } +} + +///************************************************************* +/// +/// The method to instanciate new memory and ensure the correct +/// structures have the correct addresses. +/// +///************************************************************* +void maxiRecorder::enqueueBuffer() +{ + double* b = new double[bufferSize]; + bufferQueue.push(b); + savedBuffers.push(b); +} diff --git a/maximilian.h b/maximilian.h index fad99f2..11089fe 100755 --- a/maximilian.h +++ b/maximilian.h @@ -36,15 +36,27 @@ //#define MAXIMILIAN_PORTAUDIO #define MAXIMILIAN_RT_AUDIO - #include <iostream> #include <fstream> #include <string.h> #include <cassert> #include <cstdlib> #include "math.h" +#include <cerrno> +#include <queue> +#include <vector> + +#if !defined(_WIN32) && (defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) +#define OS_IS_UNIX true +#include <pthread.h> +#include <unistd.h> +#endif + #ifdef _WIN32 //|| _WIN64 +#define OS_IS_WIN true #include <algorithm> +#include <Windows.h> +#include <process.h> #endif using namespace std; @@ -98,16 +110,29 @@ public: class maxiEnvelope { - double period; + double period=0; double output; - double startval; + double phase; + double startVal; + double endVal; double currentval; double nextval; + bool noteOn; + bool releaseMode; + bool decayMode; + bool sustainMode; + bool attackMode; int isPlaying; -public: +public: + int trig; double line(int numberofsegments,double segments[100]); + double ramp(double startVal=0, double endVal=1, double duration=1); + double ramps(std::vector<double> rampsArray); + double ar(double attack=0.1, double release=0.1); + double adsr(double attack=0.1, double decay=0.1, double sustain=0.1, double release=0.1); void trigger(int index,double amp); + void trigger(bool noteOn=false); int valindex; double amplitude; @@ -222,7 +247,7 @@ public: short myChannels; int mySampleRate; long length; - void getLength(); + long getLength(); void setLength(unsigned long numSamples); short myBitsPerSample; @@ -797,5 +822,49 @@ public: }; +class maxiRecorder +{ +public: + maxiRecorder(); + ~maxiRecorder(); + + void setup(std::string _filename); + void startRecording(); + void stopRecording(); + bool isRecording() const; + void passData(double* _in, int _inBufferSize); + void passData(float* _in, int _inBufferSize); + void saveToWav(); + +private: + template <typename T> + void write(std::ofstream& _stream, const T& _t); + void* update(void* _context); + std::vector<double> getProcessedData(); + void enqueueBuffer(); + void freeResources(); + bool threadRunning; + const int bufferQueueSize; + const int bufferSize; + long int bufferIndex; + long int recordedAmountFrames; + std::queue<double*> bufferQueue; + std::queue<double*> savedBuffers; + bool doRecord; + std::string filename; +#if defined(OS_IS_UNIX) + pthread_t daemon; + static void* update_pthread_helper(void* _context) +#elif defined(OS_IS_WIN) + HANDLE daemonHandle; + static unsigned __stdcall + update_pthread_helper(void* _context) +#endif + { + maxiRecorder* _this = static_cast<maxiRecorder*>(_context); + _this->update(_this); + return 0; + } +}; #endif diff --git a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/chris.xcuserdatad/UserInterfaceState.xcuserstate b/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/chris.xcuserdatad/UserInterfaceState.xcuserstate Binary files differdeleted file mode 100644 index d556c35..0000000 --- a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/chris.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null diff --git a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/UserInterfaceState.xcuserstate b/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/UserInterfaceState.xcuserstate Binary files differdeleted file mode 100644 index 4816e94..0000000 --- a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null diff --git a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/WorkspaceSettings.xcsettings b/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/WorkspaceSettings.xcsettings deleted file mode 100644 index dd7403b..0000000 --- a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>BuildLocationStyle</key> - <string>UseAppPreferences</string> - <key>CustomBuildLocationType</key> - <string>RelativeToDerivedData</string> - <key>DerivedDataLocationStyle</key> - <string>Default</string> - <key>IssueFilterStyle</key> - <string>ShowActiveSchemeOnly</string> - <key>LiveSourceIssuesEnabled</key> - <true/> -</dict> -</plist> diff --git a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/mick.xcuserdatad/UserInterfaceState.xcuserstate b/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/mick.xcuserdatad/UserInterfaceState.xcuserstate Binary files differdeleted file mode 100644 index a4e927b..0000000 --- a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/mick.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null diff --git a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/mickgrierson.xcuserdatad/UserInterfaceState.xcuserstate b/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/mickgrierson.xcuserdatad/UserInterfaceState.xcuserstate Binary files differdeleted file mode 100644 index 6ab58c6..0000000 --- a/maximilianTest.xcodeproj/project.xcworkspace/xcuserdata/mickgrierson.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null diff --git a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist deleted file mode 100644 index 298fcca..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Bucket - type = "1" - version = "1.0"> - <FileBreakpoints> - <FileBreakpoint - shouldBeEnabled = "No" - ignoreCount = "0" - continueAfterRunningActions = "No" - filePath = "player.cpp" - timestampString = "335806937.962212" - startingColumnNumber = "9223372036854775807" - endingColumnNumber = "9223372036854775807" - startingLineNumber = "69" - endingLineNumber = "69"> - </FileBreakpoint> - </FileBreakpoints> -</Bucket> diff --git a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index 4ebd9fa..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Bucket - type = "1" - version = "2.0"> - <Breakpoints> - <BreakpointProxy - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> - <BreakpointContent - shouldBeEnabled = "No" - ignoreCount = "0" - continueAfterRunningActions = "No" - filePath = "player.cpp" - timestampString = "335806937.962212" - startingColumnNumber = "9223372036854775807" - endingColumnNumber = "9223372036854775807" - startingLineNumber = "69" - endingLineNumber = "69" - landmarkName = "routing(const void *inputBuffer, void *outputBuffer, unsigned long nBufferFrames, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags status, void *userData )" - landmarkType = "7"> - </BreakpointContent> - </BreakpointProxy> - </Breakpoints> -</Bucket> diff --git a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcschemes/xcschememanagement.plist b/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index f2cc5e9..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>SchemeUserState</key> - <dict> - <key>maximilianTest.xcscheme</key> - <dict> - <key>orderHint</key> - <integer>0</integer> - </dict> - </dict> - <key>SuppressBuildableAutocreation</key> - <dict> - <key>8DD76F620486A84900D96B5E</key> - <dict> - <key>primary</key> - <true/> - </dict> - </dict> -</dict> -</plist> diff --git a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index fe2b454..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Bucket - type = "1" - version = "2.0"> -</Bucket> diff --git a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme b/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme deleted file mode 100644 index 903750a..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme +++ /dev/null @@ -1,88 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0630" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "maximilianTest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <Testables> - </Testables> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "maximilianTest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> - </BuildableReference> - </MacroExpansion> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Debug" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - allowLocationSimulation = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "maximilianTest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Release" - debugDocumentVersioning = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "maximilianTest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme~HEAD b/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme~HEAD deleted file mode 100644 index 6198a6c..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme~HEAD +++ /dev/null @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0700" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - buildConfiguration = "Debug" - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> - <Testables> - </Testables> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> - </BuildableReference> - </MacroExpansion> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - buildConfiguration = "Debug" - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - allowLocationSimulation = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/xcschememanagement.plist b/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index f2cc5e9..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/michaelgrierson.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>SchemeUserState</key> - <dict> - <key>maximilianTest.xcscheme</key> - <dict> - <key>orderHint</key> - <integer>0</integer> - </dict> - </dict> - <key>SuppressBuildableAutocreation</key> - <dict> - <key>8DD76F620486A84900D96B5E</key> - <dict> - <key>primary</key> - <true/> - </dict> - </dict> -</dict> -</plist> diff --git a/maximilianTest.xcodeproj/xcuserdata/mick.xcuserdatad/xcschemes/maximilianTest.xcscheme b/maximilianTest.xcodeproj/xcuserdata/mick.xcuserdatad/xcschemes/maximilianTest.xcscheme deleted file mode 100644 index 980a67b..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/mick.xcuserdatad/xcschemes/maximilianTest.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0500" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <Testables> - </Testables> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </MacroExpansion> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Debug" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - allowLocationSimulation = "YES"> - <BuildableProductRunnable> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Release" - debugDocumentVersioning = "YES"> - <BuildableProductRunnable> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/maximilianTest.xcodeproj/xcuserdata/mick.xcuserdatad/xcschemes/xcschememanagement.plist b/maximilianTest.xcodeproj/xcuserdata/mick.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index f2cc5e9..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/mick.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>SchemeUserState</key> - <dict> - <key>maximilianTest.xcscheme</key> - <dict> - <key>orderHint</key> - <integer>0</integer> - </dict> - </dict> - <key>SuppressBuildableAutocreation</key> - <dict> - <key>8DD76F620486A84900D96B5E</key> - <dict> - <key>primary</key> - <true/> - </dict> - </dict> -</dict> -</plist> diff --git a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist deleted file mode 100644 index 05301bc..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Bucket - type = "1" - version = "1.0"> -</Bucket> diff --git a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/maximilianTest 2.xcscheme b/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/maximilianTest 2.xcscheme deleted file mode 100644 index 980a67b..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/maximilianTest 2.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0500" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <Testables> - </Testables> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </MacroExpansion> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Debug" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - allowLocationSimulation = "YES"> - <BuildableProductRunnable> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Release" - debugDocumentVersioning = "YES"> - <BuildableProductRunnable> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/xcschememanagement.plist b/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index e44e838..0000000 --- a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>SchemeUserState</key> - <dict> - <key>maximilianTest 2.xcscheme</key> - <dict> - <key>orderHint</key> - <integer>1</integer> - </dict> - <key>maximilianTest.xcscheme</key> - <dict> - <key>orderHint</key> - <integer>0</integer> - </dict> - </dict> - <key>SuppressBuildableAutocreation</key> - <dict> - <key>8DD76F620486A84900D96B5E</key> - <dict> - <key>primary</key> - <true/> - </dict> - </dict> -</dict> -</plist> diff --git a/maximilian_examples/12.SamplePlayer.cpp b/maximilian_examples/12.SamplePlayer.cpp index 2706f0b..df6b3d2 100755 --- a/maximilian_examples/12.SamplePlayer.cpp +++ b/maximilian_examples/12.SamplePlayer.cpp @@ -3,19 +3,19 @@ maxiSample beats; //We give our sample a name. It's called beats this time. We could have loads of them, but they have to have different names. void setup() {//some inits - - beats.load("/Users/username/somewhere/Maximilian/beat2.wav");//load in your samples. Provide the full path to a wav file. - printf("Summary:\n%s", beats.getSummary());//get info on samples if you like. - + + beats.load("/Users/michaelgrierson/Documents/workspace/Maximilian/beat2.wav");//load in your samples. Provide the full path to a wav file. + printf("Summary:\n%s", beats.getSummary());//get info on samples if you like. + } void play(double *output) {//this is where the magic happens. Very slow magic. - - *output=beats.play();//just play the file. Looping is default for all play functions. - // *output=beats.play(0.69);//play the file with a speed setting. 1. is normal speed. - // *output=beats.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing. - // *output=beats.play4(0.5,0,44100);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing. - - + + //output[0]=beats.play();//just play the file. Looping is default for all play functions. + output[0]=beats.play(0.68);//play the file with a speed setting. 1. is normal speed. + //output[0]=beats.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing. + //output[0]=beats.play4(0.5,0,44100);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing. + + output[1]=output[0]; } diff --git a/maximilian_examples/20.FFT_example.cpp b/maximilian_examples/20.FFT_example.cpp new file mode 100644 index 0000000..b6728d2 --- /dev/null +++ b/maximilian_examples/20.FFT_example.cpp @@ -0,0 +1,31 @@ + +#include "maximilian.h" +#include "libs/maxim.h" + +maxiOsc mySine, myPhasor; // This is the oscillator we will use to generate the test tone +maxiFFT myFFT; + + + +void setup() { + + myFFT.setup(1024, 512, 256); + +} + +void play(double *output) { + + + float myOut=mySine.sinewave(myPhasor.phasor(0.2,100,5000)); + //output[0] is the left output. output[1] is the right output + + if (myFFT.process(myOut)) { + + //if you want you can mess with FFT frame values in here + + } + + output[0]=myOut;//simple as that! + output[1]=output[0]; + +} diff --git a/maximilian_examples/21.Recording.cpp b/maximilian_examples/21.Recording.cpp new file mode 100644 index 0000000..27c9bca --- /dev/null +++ b/maximilian_examples/21.Recording.cpp @@ -0,0 +1,57 @@ +#include "maximilian.h" + +// Here we define a double floating value that will contain our +// frame of lovely maximilian generated audio +double out; + +// Our oscillator to fill our frame up with my favourite wave +maxiOsc osc; + +// Our ramp to modulate the oscillators +maxiOsc ramp; + +// We declare our recorder object here, which will call it's +// default constructor. +maxiRecorder recorder; + +void setup() { + + // Call setup here, make sure you do this so the recorder + // knows where to write the file. Currently the recorder + // will write the wav file to the directory that this file + // is in if you use linux but with mac and windows I + // strongly reccomend putting an absolute file path to the + // directory you want to write to. Also, when in Windows, + // remember to do double '\' characters because they + // count as an escape which will nullify any path you write + recorder.setup("lovesong.wav"); + + // This must be called to start the asynchronous thread to + // manage the recorder's internal memory + recorder.startRecording(); +} + +void play(double *output) { + + // A pulse wave!!! Yay + out = osc.pulse(90, ramp.phasor(.2)); + + // Fill our output buffer + output[0]=out; + output[1]=out; + + // After we have filled our output array, send the array + // and the size of the array (in this case the amount of + // channels, but in ofx or juce you might need to do + // something like channels*bufferSize). + recorder.passData(output, maxiSettings::channels); +} + +// We don't need to worry about telling the recorder to stop; +// when the stack unwinds and the maximillian program stops, +// the recorder will have its destructor called and the wav +// will be written for you. If you would like to do something +// more dynamic, look at the class definition in maximilian.h - +// the api allows for stricter control of the object. + + diff --git a/maximilian_examples/arrays.cpp b/maximilian_examples/arrays.cpp deleted file mode 100644 index 1badd9b..0000000 --- a/maximilian_examples/arrays.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// arrays.cpp -// -// -// Created by Michael Grierson on 14/09/2015. -// -// - -#include "maximilian.h" - -currentChord=0;//some other control variables -int pitch[8]={57,57,59,60};//the bassline for the arpeggio -int chord[8]={0,0,7,2,5,5,0,0};//the root chords for the arpeggio -float currentPitch,leadPitch;//the final pitch variables - -//here's the lead line trigger array, followed by the pitches -int leadLineTrigger[256]={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -int leadLinePitch[15]={69,67,65,64,67,66,64,62,65,64,62,57,55,60,57}; - - - -void setup() {//some inits - -} - -void play(double *output) {//this is where the magic happens. Very slow magic. - - currentCount=(int)timer.phasor(9);//this sets up a metronome that ticks every so often - - if (lastCount!=currentCount) {//if we have a new timer int this sample, play the sound - trigger=1;//play the arpeggiator line - trigger2=leadLineTrigger[playHead%256];//play the lead line - if (trigger2==1) {//if we are going to play a note - leadPitch=mtof.mtof(leadLinePitch[newnote]);//get the next pitch val - newnote++;//and iterate - if (newnote>14) { - newnote=0;//make sure we don't go over the edge of the array - } - } - currentPitch=mtof.mtof(pitch[(playHead%4)]+chord[currentChord%8]);//write the frequency val into currentPitch - playHead++;//iterate the playhead - if (playHead%32==0) {//wrap every 4 bars - currentChord++;//change the chord - } - //cout << "tick\n";//the clock ticks - lastCount=0;//set lastCount to 0 - } - - bassout=filter2.lores(envelope.adsr(bass.saw(currentPitch*0.5)+sound.pulse(currentPitch*0.5,mod.phasor(1)),1,0.9995, 0.25, 0.9995, 1, trigger),9250,2);//new, simple ADSR. - leadout=filter.lores(leadenvelope.ar(lead2.saw(leadPitch*4)+lead.pulse(leadPitch+(leadmod.sinebuf(1.9)*1.5), 0.6), 0.00005, 0.999975, 50000, trigger2),5900,10);//leadline - - delayout=(leadout+(delay.dl(leadout, 14000, 0.8)*0.5))/2;//add some delay - - if(trigger!=0)trigger=0;//set the trigger to off if you want it to trigger immediately next time. - - - output[0]=(bassout+delayout)/2;//sum output - output[1]=(bassout+delayout)/2; - -}
\ No newline at end of file diff --git a/openFrameworks/ofxMaxim/libs/fft.cpp b/openFrameworks/ofxMaxim/libs/fft.cpp index 85a7aa9..6e5e0de 100644 --- a/openFrameworks/ofxMaxim/libs/fft.cpp +++ b/openFrameworks/ofxMaxim/libs/fft.cpp @@ -544,9 +544,12 @@ void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float } /* zero negative frequencies */ - memset(in_real+half, half, 0.0); - memset(in_img+half, half, 0.0); - +// memset(in_real+half, half, 0.0); +// memset(in_img+half, half, 0.0); + + memset(in_real+half, 0.0, sizeof(float) * half); + memset(in_img+half, 0.0, sizeof(float) * half); + FFT(n, 1, in_real, in_img, out_real, out_img); // second parameter indicates inverse transform for (i = 0; i < n; i++) { diff --git a/openFrameworks/ofxMaxim/libs/maxiFFT.h b/openFrameworks/ofxMaxim/libs/maxiFFT.h index d2694f4..53a75c5 100644 --- a/openFrameworks/ofxMaxim/libs/maxiFFT.h +++ b/openFrameworks/ofxMaxim/libs/maxiFFT.h @@ -33,7 +33,7 @@ #ifndef _MAXI_FFT #define _MAXI_FFT -//#define _NO_VDSP //set this if you don't want to use apple's vDSP fft functions +#define _NO_VDSP //set this if you don't want to use apple's vDSP fft functions #include "fft.h" @@ -125,4 +125,4 @@ public: }; -#endif
\ No newline at end of file +#endif diff --git a/openFrameworks/ofxMaxim/libs/maxiGrains.h b/openFrameworks/ofxMaxim/libs/maxiGrains.h index fb3e102..5fd5beb 100644 --- a/openFrameworks/ofxMaxim/libs/maxiGrains.h +++ b/openFrameworks/ofxMaxim/libs/maxiGrains.h @@ -1,13 +1,13 @@ -#ifndef _MAXI_GRAINS_H -#define _MAXI_GRAINS_H +#ifndef maxiGrains_2_hpp +#define maxiGrains_2_hpp #include "maximilian.h" #if defined(__APPLE_CC__) #include "accelerate/accelerate.h" //Mac users can uncommment the line below to use Apple's accelerate framework for calculating grains. This gives ~300% speed improvement and better sound quality, but doesn't work well on all machines. -//#define MAXIGRAINFAST +//#define MAXIGRAINFAST #endif #include <list> @@ -17,214 +17,184 @@ typedef unsigned long ulong; //window functions from http://en.wikipedia.org/wiki/Window_function#High-_and_moderate-resolution_windows struct hannWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.5 * (1.0 - cos((2.0 * PI * windowPos) / (windowLength - 1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.5 * (1.0 - cos((2.0 * PI * windowPos) / (windowLength - 1))); + } }; //this window can produce clicks struct hammingWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.54 - (0.46 * cos((2.0 * PI * windowPos) / (windowLength - 1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.54 - (0.46 * cos((2.0 * PI * windowPos) / (windowLength - 1))); + } }; struct cosineWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return sin((PI * windowPos) / (windowLength - 1)); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return sin((PI * windowPos) / (windowLength - 1)); + } }; struct rectWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 1; - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 1; + } }; struct triangleWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return (2.0 / (windowLength-1.0)) * (((windowLength-1.0)/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return (2.0 / (windowLength-1.0)) * (((windowLength-1.0)/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); + } }; struct triangleNZWinFunctor { - //non zero end points - inline double operator()(ulong windowLength, ulong windowPos) { - return (2.0 / windowLength) * ((windowLength/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); - } + //non zero end points + inline double operator()(ulong windowLength, ulong windowPos) { + return (2.0 / windowLength) * ((windowLength/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); + } }; struct blackmanHarrisWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.35875 - - (0.48829 * cos((2 * PI * windowPos) / (windowLength-1))) + - (0.14128 * cos((4 * PI * windowPos) / (windowLength-1))) + - (0.01168 * cos((6 * PI * windowPos) / (windowLength-1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.35875 - + (0.48829 * cos((2 * PI * windowPos) / (windowLength-1))) + + (0.14128 * cos((4 * PI * windowPos) / (windowLength-1))) + + (0.01168 * cos((6 * PI * windowPos) / (windowLength-1))); + } }; struct blackmanNutallWinFunctor { - inline double operator()(ulong windowLength, ulong windowPos) { - return 0.3635819 - - (0.4891775 * cos((2 * PI * windowPos) / (windowLength-1))) + - (0.1365995 * cos((4 * PI * windowPos) / (windowLength-1))) + - (0.0106411 * cos((6 * PI * windowPos) / (windowLength-1))); - } + inline double operator()(ulong windowLength, ulong windowPos) { + return 0.3635819 - + (0.4891775 * cos((2 * PI * windowPos) / (windowLength-1))) + + (0.1365995 * cos((4 * PI * windowPos) / (windowLength-1))) + + (0.0106411 * cos((6 * PI * windowPos) / (windowLength-1))); + } }; struct gaussianWinFunctor { - double gausDivisor; + double o; gaussianWinFunctor() { - init(0.3); - } - gaussianWinFunctor(double kurtosis) { - init(kurtosis); + o = 0.02; //compatible with MPTK } - void init(double kurtosis) { - gausDivisor = (-2.0 * kurtosis * kurtosis); + inline double operator()(ulong windowLength, ulong windowPos) { + double p = 1.0/(2.0*o*(windowLength+1)*(windowLength+1)); + double k = (double)windowPos-((double)(windowLength-1))/2.0; + return exp(-k*k*p); } - inline double operator()(ulong windowLength, ulong windowPos) { - double phase = ((windowPos / (double) windowLength) - 0.5) * 2.0; - return exp((phase * phase) / gausDivisor); - } }; template<typename F> class maxiGrainWindowCache { public: - unsigned int cacheSize; - - maxiGrainWindowCache() { - cacheSize = maxiSettings::sampleRate / 2.0; //allocate mem for up to 500ms grains - cache = (double**)malloc(cacheSize * sizeof(double*)); - for(int i=0; i < cacheSize; i++) { - cache[i] = NULL; - } - } - - ~maxiGrainWindowCache() { - for(int i=0; i < cacheSize; i++) { - if(NULL != cache[i]) { - free(cache[i]); - } - } + unsigned int cacheSize; + + maxiGrainWindowCache() { + cacheSize = maxiSettings::sampleRate / 2.0; //allocate mem for up to 500ms grains + cache = (double**)malloc(cacheSize * sizeof(double*)); + for(int i=0; i < cacheSize; i++) { + cache[i] = NULL; + } + } + + ~maxiGrainWindowCache() { + for(int i=0; i < cacheSize; i++) { + if(NULL != cache[i]) { + free(cache[i]); + } + } free(cache); - } - - double* getWindow(const unsigned int length) { - if (NULL == cache[length]) { - cache[length] = (double*)malloc(length * sizeof(double)); - for(int i=0; i < length; i++) { - cache[length][i] = F()(length, i); - } - } - return cache[length]; - } - + } + + double* getWindow(const unsigned int length) { + if (NULL == cache[length]) { + cache[length] = (double*)malloc(length * sizeof(double)); + for(int i=0; i < length; i++) { + cache[length][i] = F()(length, i); + } + } + return cache[length]; + } + private: - double** cache; - + double** cache; + }; class maxiGrainBase { public: - virtual double play() {} + virtual double play() {} virtual ~maxiGrainBase() {} - bool finished; + bool finished; }; -template<typename F> +template<class F, class maxiSample> class maxiGrain : public maxiGrainBase { public: - maxiSample *sample; + maxiSample *sample; double pos; - double dur; - long sampleStartPos; - long sampleIdx; - long sampleDur; - long sampleEndPos; - double freq; - double speed; - double inc; - double frequency; - double* window; - short* buffer; + double dur; + long sampleStartPos; + long sampleIdx; + long sampleDur; + long sampleEndPos; + double freq; + double speed; + double inc; + double frequency; + double* window; + // short* buffer; #if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - double* grainSamples; + // double* grainSamples; #endif - /* - position between 0.0 and 1.0 - duration in seconds - */ - maxiGrain(maxiSample *sample, const double position, const double duration, const double speed, maxiGrainWindowCache<F> *windowCache) :sample(sample), pos(position), dur(duration), speed(speed) - { - buffer = sample->temp; - sampleStartPos = sample->length * pos; - sampleDur = dur * (double)sample->mySampleRate; - sampleDurMinusOne = sampleDur - 1; - sampleIdx = 0; - finished = 0; - freq = 1.0 / dur; - sampleEndPos = min(sample->length, sampleStartPos + sampleDur); - frequency = freq * speed; - if (frequency > 0) { - pos = sampleStartPos; - }else{ - pos = sampleEndPos; - } + /* + position between 0.0 and 1.0 + duration in seconds + */ + maxiGrain(maxiSample *_sample, const double position, const double duration, const double speed, maxiGrainWindowCache<F> *windowCache) :sample(_sample), pos(position), dur(duration), speed(speed) + { + // buffer = sample->temp; + sampleStartPos = (sample->length) * pos; + sampleDur = dur * (double)maxiSettings::sampleRate; + sampleDurMinusOne = sampleDur - 1; + sampleIdx = 0; + finished = 0; + freq = 1.0 / dur; + sampleEndPos = min(sample->length, sampleStartPos + sampleDur); + frequency = freq * speed; + if (frequency > 0) { + pos = sampleStartPos; + }else{ + pos = sampleEndPos; + } if (frequency != 0) { inc = sampleDur/(maxiSettings::sampleRate/frequency); }else inc = 0; - window = windowCache->getWindow(sampleDur); - -#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - //premake the grain using fast vector functions, and quadratic interpolation - double *sourceData = (double*)malloc(sampleDur * sizeof(double)); - short* buffer = (short *)sample->temp; - //convert sample to double data - vDSP_vflt16D(buffer + sampleStartPos, 1, sourceData, 1, min(sampleDur, sample->length - sampleStartPos)); - //todo: wraping code - - grainSamples = (double*)malloc(sampleDur * sizeof(double)); - //make list of interpolation indexes - double* interpIndexes = (double*)malloc(sampleDur * sizeof(double)); - double interpPos = sampleStartPos; - for(int i=0; i < sampleDur; i++) { - interpIndexes[i] = interpPos - sampleStartPos; - interpPos += fabs(inc); - } - vDSP_vqintD(sourceData, interpIndexes, 1, grainSamples, 1, sampleDur, sampleDur); - if (frequency < 0) { - vDSP_vrvrsD(grainSamples,1, sampleDur); - } - static double divFactor = 32767.0; - vDSP_vsdivD(grainSamples, 1, &divFactor, grainSamples, 1, sampleDur); - vDSP_vmulD(grainSamples, 1, window, 1, grainSamples, 1, sampleDur); - delete sourceData, interpIndexes; -#endif - } - - ~maxiGrain() { + window = windowCache->getWindow(sampleDur); + + } + + ~maxiGrain() { #if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - delete[] grainSamples; + delete[] grainSamples; #endif - } - - inline double play() { - double output = 0.0; - if (!finished) { + } + + inline double play() { + double output = 0.0; + if (!finished) { #if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) - output = grainSamples[sampleIdx]; + // output = grainSamples[sampleIdx]; #else - envValue = window[sampleIdx]; - double remainder; + envValue = window[sampleIdx]; + double remainder; pos += inc; - if (pos >= sample->length) + if (pos >= sample->length) pos -= sample->length; - else if (pos < 0) + else if (pos < 0) pos += sample->length; long posl = floor(pos); @@ -234,20 +204,21 @@ public: if (b >= sample->length) { b = 0; } - output = (double) ((1-remainder) * buffer[a] + - remainder * buffer[b])/32767.0;//linear interpolation - output *= envValue; + //output = (double) ((1-remainder) * sample->operator[](a) + + // remainder * sample->operator[](b))/32767.0;//linear interpolation + output = (double) ((1-remainder) * sample->temp[a] + remainder * sample->temp[b])/32767.0;//linear interpolation + output *= envValue; #endif - } - sampleIdx++; - if (sampleIdx == sampleDur) finished = true; - return output; - } - -protected: - maxiGrain(); - double envValue; - ulong sampleDurMinusOne; + } + sampleIdx++; + if (sampleIdx == sampleDur) finished = true; + return output; + } + +protected: + maxiGrain(); + double envValue; + ulong sampleDurMinusOne; }; @@ -255,173 +226,64 @@ typedef list<maxiGrainBase*> grainList; class maxiGrainPlayer { public: - grainList grains; - maxiSample *sample; - - maxiGrainPlayer(maxiSample *sample) : sample(sample) { - } - - void addGrain(maxiGrainBase *g) { - grains.push_back(g); - } - - inline double play() { - double total = 0.0; - grainList::iterator it = grains.begin(); - while(it != grains.end()) { - total += (*it)->play(); - if ((*it)->finished) { - delete(*it); - it = grains.erase(it); - }else{ - it++; - } - } - return total; - } -}; - -template<typename F> -class maxiTimestretch { -protected: - double position; -public: - maxiSample *sample; - maxiGrainPlayer *grainPlayer; - maxiGrainWindowCache<F> windowCache; - double randomOffset; - double looper; - - - - maxiTimestretch(maxiSample *sample) : sample(sample) { - position=0; - looper = 0; - grainPlayer = new maxiGrainPlayer(sample); - randomOffset=0; - } - - ~maxiTimestretch() { - delete grainPlayer; - } + grainList grains; + // maxiSample *sample; + // source *sample; - double getNormalisedPosition() { - return position / (double) sample->length; - } - double getPosition() { - return position; - } + // maxiGrainPlayer(maxiSample *sample) : sample(sample) { + // } - void setPosition(double pos) { - position = pos * sample->length; - position = maxiMap::clamp<double>(position, 0, sample->length-1); + // maxiGrainPlayer(source *sample) : sample(sample) { + // } + + void addGrain(maxiGrainBase *g) { + grains.push_back(g); } - - - //play at a speed - inline double play(double speed, double grainLength, int overlaps, double posMod=0.0) { - position = position + speed; - looper++; - if (position > sample->length) position-= sample->length; - if (position < 0) position += sample->length; - double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; - if (looper > cycleLength + randomOffset) { - looper -= (cycleLength + randomOffset); - speed = (speed > 0 ? 1 : -1); - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); - grainPlayer->addGrain(g); - randomOffset = rand() % 10; - } - return grainPlayer->play(); - } - - //provide your own position iteration - inline double play2(double pos, double grainLength, int overlaps) { - looper++; - pos *= sample->length; - if (0 == floor(fmod(looper, grainLength * maxiSettings::sampleRate / overlaps))) { - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(pos / sample->length)),0.0), grainLength, 1, &windowCache); - grainPlayer->addGrain(g); - } - return grainPlayer->play(); - } -}; - -//in maxiTimeStretch, the speed is either 1 or -1, and the actual speed value only affects the grain position -//in maxiPitchShift, speed is uncoupled from position and allowed to set it's value incrementally, resulting in pitchshift. -//with both high speed values and negative speed values there are some terrific artefacts! - -template<typename F> -class maxiPitchShift { -public: - double position; - long cycles; - maxiSample *sample; - maxiGrainPlayer *grainPlayer; - maxiGrainWindowCache<F> windowCache; - double randomOffset; - - maxiPitchShift(maxiSample *sample) : sample(sample) { - position=0; - cycles=0; - grainPlayer = new maxiGrainPlayer(sample); - randomOffset=0; - } - - ~maxiPitchShift() { - delete grainPlayer; - } - - double play(double speed, double grainLength, int overlaps, double posMod=0.0) { - position = position + 1; - cycles++; - if (position > sample->length) position=0; - if (position < 0) position = sample->length; - double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; - double cycleMod = fmod(cycles, cycleLength + randomOffset); - if (0 == floor(cycleMod)) { - // cout << cycleMod << endl; - //speed = (speed > 0 ? 1 : -1); - speed = speed - ((cycleMod / cycleLength) * 0.1); - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); - grainPlayer->addGrain(g); - // cout << grainPlayer->grains.size() << endl; - // randomOffset = rand() % 10; - // randomOffset = rand() % 10; - } - return grainPlayer->play(); - } - + inline double play() { + double total = 0.0; + grainList::iterator it = grains.begin(); + while(it != grains.end()) { + total += (*it)->play(); + if ((*it)->finished) { + delete(*it); + it = grains.erase(it); + }else{ + it++; + } + } + return total; + } }; //and here's maxiPitchStretch. Args to the play function are basically speed for 'pitch' and rate for playback rate. //the rest is the same. -template<typename F> -class maxiPitchStretch { +template<class F, class maxiSample> +class maxiTimePitchStretch { public: - double position; - maxiSample *sample; - maxiGrainPlayer *grainPlayer; - maxiGrainWindowCache<F> windowCache; - double randomOffset; + double position; + maxiSample *sample; + maxiGrainPlayer *grainPlayer; + maxiGrainWindowCache<F> windowCache; + double randomOffset; long loopStart, loopEnd, loopLength; double looper; - - maxiPitchStretch(maxiSample *sample) : sample(sample) { - grainPlayer = new maxiGrainPlayer(sample); - randomOffset=0; + + maxiTimePitchStretch(maxiSample *_sample) : sample(_sample) { + grainPlayer = new maxiGrainPlayer(); + randomOffset=0; loopStart = 0.0; + sample->getLength(); loopEnd = sample->length; - loopLength =sample->length; - position=0; + loopLength = sample->length; + position=0; looper = 0; - } + } double getNormalisedPosition() { - return position / (double) sample->length; + return position / (double) sample->getLength(); } double getPosition() { @@ -442,26 +304,519 @@ public: loopEnd = val * sample->length; loopLength = loopEnd - loopStart; } - - ~maxiPitchStretch() { - delete grainPlayer; - } - - inline double play(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { - position = position + (1 * rate); + + + bool hasEnded() { + return position == loopEnd; + } + + ~maxiTimePitchStretch() { + delete grainPlayer; + } + + inline double play(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { + position = position + rate; + if (position >= loopEnd) position-= loopLength; + if (position < loopStart) position += loopLength; + return playNextGrain(speed, rate, grainLength, overlaps, posMod); + } + + inline double playOnce(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { + position = position + rate; + if (position >= loopEnd) position = loopEnd; + if (position < loopStart) position = loopEnd; + float val = 0; + if (position < loopEnd) + val = playNextGrain(speed, rate, grainLength, overlaps, posMod); + return val; + } + +protected: + inline double playNextGrain(double speed, double rate, double grainLength, int overlaps, double posMod) { looper++; - if (position >= loopEnd) position-= loopLength; - if (position < loopStart) position += loopLength; - double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; + double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; if (looper > cycleLength + randomOffset) { looper -= (cycleLength + randomOffset); - maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); - grainPlayer->addGrain(g); + double pos = max(min(static_cast<double>(1.0), (position / sample->length) + posMod),static_cast<double>(0.0)); + maxiGrain<F, maxiSample> *g = new maxiGrain<F, maxiSample>(sample, + pos, + grainLength, speed, &windowCache); + grainPlayer->addGrain(g); randomOffset = rand() % 10; - } - return grainPlayer->play(); - } - + } + return grainPlayer->play(); + } + }; -#endif
\ No newline at end of file + +#endif /* maxiGrains_2_hpp */ + + +// +// +//#ifndef _MAXI_GRAINS_H +//#define _MAXI_GRAINS_H +//#include "maximilian.h" +// +//#if defined(__APPLE_CC__) +//#include "accelerate/accelerate.h" +////Mac users can uncommment the line below to use Apple's accelerate framework for calculating grains. This gives ~300% speed improvement and better sound quality, but doesn't work well on all machines. +//#define MAXIGRAINFAST +//#endif +// +//#include <list> +// +//typedef unsigned long ulong; +// +////window functions from http://en.wikipedia.org/wiki/Window_function#High-_and_moderate-resolution_windows +// +//struct hannWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.5 * (1.0 - cos((2.0 * PI * windowPos) / (windowLength - 1))); +// } +//}; +// +////this window can produce clicks +//struct hammingWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.54 - (0.46 * cos((2.0 * PI * windowPos) / (windowLength - 1))); +// } +//}; +// +// +//struct cosineWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return sin((PI * windowPos) / (windowLength - 1)); +// } +//}; +// +//struct rectWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 1; +// } +//}; +// +//struct triangleWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return (2.0 / (windowLength-1.0)) * (((windowLength-1.0)/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); +// } +//}; +// +//struct triangleNZWinFunctor { +// //non zero end points +// inline double operator()(ulong windowLength, ulong windowPos) { +// return (2.0 / windowLength) * ((windowLength/2.0) - fabs(windowPos - ((windowLength-1.0)/2.0))); +// } +//}; +// +//struct blackmanHarrisWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.35875 - +// (0.48829 * cos((2 * PI * windowPos) / (windowLength-1))) + +// (0.14128 * cos((4 * PI * windowPos) / (windowLength-1))) + +// (0.01168 * cos((6 * PI * windowPos) / (windowLength-1))); +// } +//}; +// +//struct blackmanNutallWinFunctor { +// inline double operator()(ulong windowLength, ulong windowPos) { +// return 0.3635819 - +// (0.4891775 * cos((2 * PI * windowPos) / (windowLength-1))) + +// (0.1365995 * cos((4 * PI * windowPos) / (windowLength-1))) + +// (0.0106411 * cos((6 * PI * windowPos) / (windowLength-1))); +// } +//}; +// +//struct gaussianWinFunctor { +// double gausDivisor; +// gaussianWinFunctor() { +// init(0.3); +// } +// gaussianWinFunctor(double kurtosis) { +// init(kurtosis); +// } +// void init(double kurtosis) { +// gausDivisor = (-2.0 * kurtosis * kurtosis); +// } +// inline double operator()(ulong windowLength, ulong windowPos) { +// double phase = ((windowPos / (double) windowLength) - 0.5) * 2.0; +// return exp((phase * phase) / gausDivisor); +// } +//}; +// +// +//template<typename F> +//class maxiGrainWindowCache { +//public: +// unsigned int cacheSize; +// +// maxiGrainWindowCache() { +// cacheSize = maxiSettings::sampleRate / 2.0; //allocate mem for up to 500ms grains +// cache = (double**)malloc(cacheSize * sizeof(double*)); +// for(int i=0; i < cacheSize; i++) { +// cache[i] = NULL; +// } +// } +// +// ~maxiGrainWindowCache() { +// for(int i=0; i < cacheSize; i++) { +// if(NULL != cache[i]) { +// free(cache[i]); +// } +// } +// free(cache); +// } +// +// double* getWindow(const unsigned int length) { +// if (NULL == cache[length]) { +// cache[length] = (double*)malloc(length * sizeof(double)); +// for(int i=0; i < length; i++) { +// cache[length][i] = F()(length, i); +// } +// } +// return cache[length]; +// } +// +//private: +// double** cache; +// +//}; +// +//class maxiGrainBase { +//public: +// virtual double play() {} +// virtual ~maxiGrainBase() {} +// bool finished; +//}; +// +//template<typename F> +//class maxiGrain : public maxiGrainBase { +//public: +// maxiSample *sample; +// double pos; +// double dur; +// long sampleStartPos; +// long sampleIdx; +// long sampleDur; +// long sampleEndPos; +// double freq; +// double speed; +// double inc; +// double frequency; +// double* window; +// short* buffer; +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// double* grainSamples; +//#endif +// /* +// position between 0.0 and 1.0 +// duration in seconds +// */ +// maxiGrain(maxiSample *sample, const double position, const double duration, const double speed, maxiGrainWindowCache<F> *windowCache) :sample(sample), pos(position), dur(duration), speed(speed) +// { +// buffer = sample->temp; +// sampleStartPos = sample->length * pos; +// sampleDur = dur * (double)sample->mySampleRate; +// sampleDurMinusOne = sampleDur - 1; +// sampleIdx = 0; +// finished = 0; +// freq = 1.0 / dur; +// sampleEndPos = min(sample->length, sampleStartPos + sampleDur); +// frequency = freq * speed; +// if (frequency > 0) { +// pos = sampleStartPos; +// }else{ +// pos = sampleEndPos; +// } +// if (frequency != 0) { +// inc = sampleDur/(maxiSettings::sampleRate/frequency); +// }else +// inc = 0; +// window = windowCache->getWindow(sampleDur); +// +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// //premake the grain using fast vector functions, and quadratic interpolation +// double *sourceData = (double*)malloc(sampleDur * sizeof(double)); +// short* buffer = (short *)sample->temp; +// //convert sample to double data +// vDSP_vflt16D(buffer + sampleStartPos, 1, sourceData, 1, min(sampleDur, sample->length - sampleStartPos)); +// //todo: wraping code +// +// grainSamples = (double*)malloc(sampleDur * sizeof(double)); +// //make list of interpolation indexes +// double* interpIndexes = (double*)malloc(sampleDur * sizeof(double)); +// double interpPos = sampleStartPos; +// for(int i=0; i < sampleDur; i++) { +// interpIndexes[i] = interpPos - sampleStartPos; +// interpPos += fabs(inc); +// } +// vDSP_vqintD(sourceData, interpIndexes, 1, grainSamples, 1, sampleDur, sampleDur); +// if (frequency < 0) { +// vDSP_vrvrsD(grainSamples,1, sampleDur); +// } +// static double divFactor = 32767.0; +// vDSP_vsdivD(grainSamples, 1, &divFactor, grainSamples, 1, sampleDur); +// vDSP_vmulD(grainSamples, 1, window, 1, grainSamples, 1, sampleDur); +// delete sourceData, interpIndexes; +//#endif +// } +// +// ~maxiGrain() { +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// delete[] grainSamples; +//#endif +// } +// +// inline double play() { +// double output = 0.0; +// if (!finished) { +//#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST) +// output = grainSamples[sampleIdx]; +//#else +// envValue = window[sampleIdx]; +// double remainder; +// pos += inc; +// if (pos >= sample->length) +// pos -= sample->length; +// else if (pos < 0) +// pos += sample->length; +// +// long posl = floor(pos); +// remainder = pos - posl; +// long a = posl; +// long b = posl+1; +// if (b >= sample->length) { +// b = 0; +// } +// output = (double) ((1-remainder) * buffer[a] + +// remainder * buffer[b])/32767.0;//linear interpolation +// output *= envValue; +//#endif +// } +// sampleIdx++; +// if (sampleIdx == sampleDur) finished = true; +// return output; +// } +// +//protected: +// maxiGrain(); +// double envValue; +// ulong sampleDurMinusOne; +//}; +// +// +//typedef list<maxiGrainBase*> grainList; +// +//class maxiGrainPlayer { +//public: +// grainList grains; +// maxiSample *sample; +// +// maxiGrainPlayer(maxiSample *sample) : sample(sample) { +// } +// +// void addGrain(maxiGrainBase *g) { +// grains.push_back(g); +// } +// +// inline double play() { +// double total = 0.0; +// grainList::iterator it = grains.begin(); +// while(it != grains.end()) { +// total += (*it)->play(); +// if ((*it)->finished) { +// delete(*it); +// it = grains.erase(it); +// }else{ +// it++; +// } +// } +// return total; +// } +//}; +// +//template<typename F> +//class maxiTimestretch { +//protected: +// double position; +//public: +// maxiSample *sample; +// maxiGrainPlayer *grainPlayer; +// maxiGrainWindowCache<F> windowCache; +// double randomOffset; +// double looper; +// +// +// +// maxiTimestretch(maxiSample *sample) : sample(sample) { +// position=0; +// looper = 0; +// grainPlayer = new maxiGrainPlayer(sample); +// randomOffset=0; +// } +// +// ~maxiTimestretch() { +// delete grainPlayer; +// } +// +// double getNormalisedPosition() { +// return position / (double) sample->length; +// } +// +// double getPosition() { +// return position; +// } +// +// void setPosition(double pos) { +// position = pos * sample->length; +// position = maxiMap::clamp<double>(position, 0, sample->length-1); +// } +// +// +// //play at a speed +// inline double play(double speed, double grainLength, int overlaps, double posMod=0.0) { +// position = position + speed; +// looper++; +// if (position > sample->length) position-= sample->length; +// if (position < 0) position += sample->length; +// double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; +// if (looper > cycleLength + randomOffset) { +// looper -= (cycleLength + randomOffset); +// speed = (speed > 0 ? 1 : -1); +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); +// grainPlayer->addGrain(g); +// randomOffset = rand() % 10; +// } +// return grainPlayer->play(); +// } +// +// +// //provide your own position iteration +// inline double play2(double pos, double grainLength, int overlaps) { +// looper++; +// pos *= sample->length; +// if (0 == floor(fmod(looper, grainLength * maxiSettings::sampleRate / overlaps))) { +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(pos / sample->length)),0.0), grainLength, 1, &windowCache); +// grainPlayer->addGrain(g); +// } +// return grainPlayer->play(); +// } +//}; +// +////in maxiTimeStretch, the speed is either 1 or -1, and the actual speed value only affects the grain position +////in maxiPitchShift, speed is uncoupled from position and allowed to set it's value incrementally, resulting in pitchshift. +////with both high speed values and negative speed values there are some terrific artefacts! +// +//template<typename F> +//class maxiPitchShift { +//public: +// double position; +// long cycles; +// maxiSample *sample; +// maxiGrainPlayer *grainPlayer; +// maxiGrainWindowCache<F> windowCache; +// double randomOffset; +// +// maxiPitchShift(maxiSample *sample) : sample(sample) { +// position=0; +// cycles=0; +// grainPlayer = new maxiGrainPlayer(sample); +// randomOffset=0; +// } +// +// ~maxiPitchShift() { +// delete grainPlayer; +// } +// +// double play(double speed, double grainLength, int overlaps, double posMod=0.0) { +// position = position + 1; +// cycles++; +// if (position > sample->length) position=0; +// if (position < 0) position = sample->length; +// double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; +// double cycleMod = fmod(cycles, cycleLength + randomOffset); +// if (0 == floor(cycleMod)) { +// // cout << cycleMod << endl; +// //speed = (speed > 0 ? 1 : -1); +// speed = speed - ((cycleMod / cycleLength) * 0.1); +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); +// grainPlayer->addGrain(g); +// // cout << grainPlayer->grains.size() << endl; +// // randomOffset = rand() % 10; +// // randomOffset = rand() % 10; +// } +// return grainPlayer->play(); +// } +// +//}; +// +////and here's maxiPitchStretch. Args to the play function are basically speed for 'pitch' and rate for playback rate. +////the rest is the same. +// +//template<typename F> +//class maxiPitchStretch { +//public: +// double position; +// maxiSample *sample; +// maxiGrainPlayer *grainPlayer; +// maxiGrainWindowCache<F> windowCache; +// double randomOffset; +// long loopStart, loopEnd, loopLength; +// double looper; +// +// maxiPitchStretch(maxiSample *sample) : sample(sample) { +// grainPlayer = new maxiGrainPlayer(sample); +// randomOffset=0; +// loopStart = 0.0; +// loopEnd = sample->length; +// loopLength =sample->length; +// position=0; +// looper = 0; +// } +// +// double getNormalisedPosition() { +// return position / (double) sample->length; +// } +// +// double getPosition() { +// return position; +// } +// +// void setPosition(double pos) { +// position = pos * sample->length; +// position = maxiMap::clamp<double>(position, 0, sample->length-1); +// } +// +// void setLoopStart(double val) { +// loopStart = val * sample->length; +// loopLength = loopEnd - loopStart; +// } +// +// void setLoopEnd(double val) { +// loopEnd = val * sample->length; +// loopLength = loopEnd - loopStart; +// } +// +// ~maxiPitchStretch() { +// delete grainPlayer; +// } +// +// inline double play(double speed, double rate, double grainLength, int overlaps, double posMod=0.0) { +// position = position + (1 * rate); +// looper++; +// if (position >= loopEnd) position-= loopLength; +// if (position < loopStart) position += loopLength; +// double cycleLength = grainLength * maxiSettings::sampleRate / overlaps; +// if (looper > cycleLength + randomOffset) { +// looper -= (cycleLength + randomOffset); +// maxiGrain<F> *g = new maxiGrain<F>(sample, max(min(1.0,(position / sample->length) + posMod),0.0), grainLength, speed, &windowCache); +// grainPlayer->addGrain(g); +// randomOffset = rand() % 10; +// } +// return grainPlayer->play(); +// } +// +//}; +// +//#endif
\ No newline at end of file diff --git a/openFrameworks/ofxMaxim/libs/maximilian.cpp b/openFrameworks/ofxMaxim/libs/maximilian.cpp index 4720503..3391da1 100644 --- a/openFrameworks/ofxMaxim/libs/maximilian.cpp +++ b/openFrameworks/ofxMaxim/libs/maximilian.cpp @@ -16,11 +16,11 @@ * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT @@ -34,16 +34,16 @@ #include "maximilian.h" #include "math.h" -/* Maximilian can be configured to load ogg vorbis format files using the - * loadOgg() method. - * Uncomment the following to include Sean Barrett's Ogg Vorbis decoder. - * If you're on windows, make sure to add the files std_vorbis.c and std_vorbis.h to your project*/ +/* Maximilian can be configured to load ogg vorbis format files using the +* loadOgg() method. +* Uncomment the following to include Sean Barrett's Ogg Vorbis decoder. +* If you're on windows, make sure to add the files std_vorbis.c and std_vorbis.h to your project*/ //#define VORBIS #ifdef VORBIS extern "C" { -#include "stb_vorbis.h" + #include "stb_vorbis.h" } #endif @@ -55,7 +55,7 @@ int maxiSettings::channels = 2; int maxiSettings::bufferSize = 1024; -//this is a 514-point sinewave table that has many uses. +//this is a 514-point sinewave table that has many uses. double sineBuffer[514]={0,0.012268,0.024536,0.036804,0.049042,0.06131,0.073547,0.085785,0.097992,0.1102,0.12241,0.13455,0.1467,0.15884,0.17093,0.18301,0.19507,0.20709,0.21909,0.23105,0.24295,0.25485,0.26669,0.2785,0.29025,0.30197,0.31366,0.32529,0.33685,0.34839,0.35986,0.37128,0.38266,0.39395,0.40521,0.41641,0.42752,0.4386,0.44958,0.46051,0.47137,0.48215,0.49286,0.50351,0.51407,0.52457,0.53497,0.54529,0.55554,0.5657,0.57578,0.58575,0.59567,0.60547,0.6152,0.62482,0.63437,0.6438,0.65314,0.66238,0.67151,0.68057,0.68951,0.69833,0.70706,0.7157,0.72421,0.7326,0.74091,0.74908,0.75717,0.76514,0.77298,0.7807,0.7883,0.79581,0.80316,0.81042,0.81754,0.82455,0.83142,0.8382,0.84482,0.85132,0.8577,0.86392,0.87006,0.87604,0.88187,0.8876,0.89319,0.89862,0.90396,0.90912,0.91415,0.91907,0.92383,0.92847,0.93295,0.93729,0.9415,0.94556,0.94949,0.95325,0.95691,0.96039,0.96375,0.96692,0.97,0.9729,0.97565,0.97827,0.98074,0.98306,0.98523,0.98724,0.98914,0.99084,0.99243,0.99387,0.99515,0.99628,0.99725,0.99808,0.99875,0.99927,0.99966,0.99988,0.99997,0.99988,0.99966,0.99927,0.99875,0.99808,0.99725,0.99628,0.99515,0.99387,0.99243,0.99084,0.98914,0.98724,0.98523,0.98306,0.98074,0.97827,0.97565,0.9729,0.97,0.96692,0.96375,0.96039,0.95691,0.95325,0.94949,0.94556,0.9415,0.93729,0.93295,0.92847,0.92383,0.91907,0.91415,0.90912,0.90396,0.89862,0.89319,0.8876,0.88187,0.87604,0.87006,0.86392,0.8577,0.85132,0.84482,0.8382,0.83142,0.82455,0.81754,0.81042,0.80316,0.79581,0.7883,0.7807,0.77298,0.76514,0.75717,0.74908,0.74091,0.7326,0.72421,0.7157,0.70706,0.69833,0.68951,0.68057,0.67151,0.66238,0.65314,0.6438,0.63437,0.62482,0.6152,0.60547,0.59567,0.58575,0.57578,0.5657,0.55554,0.54529,0.53497,0.52457,0.51407,0.50351,0.49286,0.48215,0.47137,0.46051,0.44958,0.4386,0.42752,0.41641,0.40521,0.39395,0.38266,0.37128,0.35986,0.34839,0.33685,0.32529,0.31366,0.30197,0.29025,0.2785,0.26669,0.25485,0.24295,0.23105,0.21909,0.20709,0.19507,0.18301,0.17093,0.15884,0.1467,0.13455,0.12241,0.1102,0.097992,0.085785,0.073547,0.06131,0.049042,0.036804,0.024536,0.012268,0,-0.012268,-0.024536,-0.036804,-0.049042,-0.06131,-0.073547,-0.085785,-0.097992,-0.1102,-0.12241,-0.13455,-0.1467,-0.15884,-0.17093,-0.18301,-0.19507,-0.20709,-0.21909,-0.23105,-0.24295,-0.25485,-0.26669,-0.2785,-0.29025,-0.30197,-0.31366,-0.32529,-0.33685,-0.34839,-0.35986,-0.37128,-0.38266,-0.39395,-0.40521,-0.41641,-0.42752,-0.4386,-0.44958,-0.46051,-0.47137,-0.48215,-0.49286,-0.50351,-0.51407,-0.52457,-0.53497,-0.54529,-0.55554,-0.5657,-0.57578,-0.58575,-0.59567,-0.60547,-0.6152,-0.62482,-0.63437,-0.6438,-0.65314,-0.66238,-0.67151,-0.68057,-0.68951,-0.69833,-0.70706,-0.7157,-0.72421,-0.7326,-0.74091,-0.74908,-0.75717,-0.76514,-0.77298,-0.7807,-0.7883,-0.79581,-0.80316,-0.81042,-0.81754,-0.82455,-0.83142,-0.8382,-0.84482,-0.85132,-0.8577,-0.86392,-0.87006,-0.87604,-0.88187,-0.8876,-0.89319,-0.89862,-0.90396,-0.90912,-0.91415,-0.91907,-0.92383,-0.92847,-0.93295,-0.93729,-0.9415,-0.94556,-0.94949,-0.95325,-0.95691,-0.96039,-0.96375,-0.96692,-0.97,-0.9729,-0.97565,-0.97827,-0.98074,-0.98306,-0.98523,-0.98724,-0.98914,-0.99084,-0.99243,-0.99387,-0.99515,-0.99628,-0.99725,-0.99808,-0.99875,-0.99927,-0.99966,-0.99988,-0.99997,-0.99988,-0.99966,-0.99927,-0.99875,-0.99808,-0.99725,-0.99628,-0.99515,-0.99387,-0.99243,-0.99084,-0.98914,-0.98724,-0.98523,-0.98306,-0.98074,-0.97827,-0.97565,-0.9729,-0.97,-0.96692,-0.96375,-0.96039,-0.95691,-0.95325,-0.94949,-0.94556,-0.9415,-0.93729,-0.93295,-0.92847,-0.92383,-0.91907,-0.91415,-0.90912,-0.90396,-0.89862,-0.89319,-0.8876,-0.88187,-0.87604,-0.87006,-0.86392,-0.8577,-0.85132,-0.84482,-0.8382,-0.83142,-0.82455,-0.81754,-0.81042,-0.80316,-0.79581,-0.7883,-0.7807,-0.77298,-0.76514,-0.75717,-0.74908,-0.74091,-0.7326,-0.72421,-0.7157,-0.70706,-0.69833,-0.68951,-0.68057,-0.67151,-0.66238,-0.65314,-0.6438,-0.63437,-0.62482,-0.6152,-0.60547,-0.59567,-0.58575,-0.57578,-0.5657,-0.55554,-0.54529,-0.53497,-0.52457,-0.51407,-0.50351,-0.49286,-0.48215,-0.47137,-0.46051,-0.44958,-0.4386,-0.42752,-0.41641,-0.40521,-0.39395,-0.38266,-0.37128,-0.35986,-0.34839,-0.33685,-0.32529,-0.31366,-0.30197,-0.29025,-0.2785,-0.26669,-0.25485,-0.24295,-0.23105,-0.21909,-0.20709,-0.19507,-0.18301,-0.17093,-0.15884,-0.1467,-0.13455,-0.12241,-0.1102,-0.097992,-0.085785,-0.073547,-0.06131,-0.049042,-0.036804,-0.024536,-0.012268,0,0.012268 }; @@ -200,138 +200,138 @@ double mtofarray[129]={0, 8.661957, 9.177024, 9.722718, 10.3, 10.913383, 11.5623 void setup();//use this to do any initialisation if you want. -void play(double *channels);//run dac! +void play(double *channels);//run dac! maxiOsc::maxiOsc(){ //When you create an oscillator, the constructor sets the phase of the oscillator to 0. - phase = 0.0; + phase = 0.0; } double maxiOsc::noise() { //White Noise - //always the same unless you seed it. - float r = rand()/(float)RAND_MAX; - output=r*2-1; - return(output); + //always the same unless you seed it. + float r = rand()/(float)RAND_MAX; + output=r*2-1; + return(output); } void maxiOsc::phaseReset(double phaseIn) { //This allows you to set the phase of the oscillator to anything you like. - phase=phaseIn; - + phase=phaseIn; + } double maxiOsc::sinewave(double frequency) { //This is a sinewave oscillator - output=sin (phase*(TWOPI)); - if ( phase >= 1.0 ) phase -= 1.0; - phase += (1./(maxiSettings::sampleRate/(frequency))); - return(output); - + output=sin (phase*(TWOPI)); + if ( phase >= 1.0 ) phase -= 1.0; + phase += (1./(maxiSettings::sampleRate/(frequency))); + return(output); + } double maxiOsc::sinebuf4(double frequency) { //This is a sinewave oscillator that uses 4 point interpolation on a 514 point buffer - double remainder; - double a,b,c,d,a1,a2,a3; - phase += 512./(maxiSettings::sampleRate/(frequency)); - if ( phase >= 511 ) phase -=512; - remainder = phase - floor(phase); - - if (phase==0) { - a=sineBuffer[(long) 512]; - b=sineBuffer[(long) phase]; - c=sineBuffer[(long) phase+1]; - d=sineBuffer[(long) phase+2]; - - } else { - a=sineBuffer[(long) phase-1]; - b=sineBuffer[(long) phase]; - c=sineBuffer[(long) phase+1]; - d=sineBuffer[(long) phase+2]; - - } - - a1 = 0.5f * (c - a); - a2 = a - 2.5 * b + 2.f * c - 0.5f * d; - a3 = 0.5f * (d - a) + 1.5f * (b - c); - output = double (((a3 * remainder + a2) * remainder + a1) * remainder + b); - return(output); + double remainder; + double a,b,c,d,a1,a2,a3; + phase += 512./(maxiSettings::sampleRate/(frequency)); + if ( phase >= 511 ) phase -=512; + remainder = phase - floor(phase); + + if (phase==0) { + a=sineBuffer[(long) 512]; + b=sineBuffer[(long) phase]; + c=sineBuffer[(long) phase+1]; + d=sineBuffer[(long) phase+2]; + + } else { + a=sineBuffer[(long) phase-1]; + b=sineBuffer[(long) phase]; + c=sineBuffer[(long) phase+1]; + d=sineBuffer[(long) phase+2]; + + } + + a1 = 0.5f * (c - a); + a2 = a - 2.5 * b + 2.f * c - 0.5f * d; + a3 = 0.5f * (d - a) + 1.5f * (b - c); + output = double (((a3 * remainder + a2) * remainder + a1) * remainder + b); + return(output); } double maxiOsc::sinebuf(double frequency) { //specify the frequency of the oscillator in Hz / cps etc. //This is a sinewave oscillator that uses linear interpolation on a 514 point buffer - double remainder; - phase += 512./(maxiSettings::sampleRate/(frequency*chandiv)); - if ( phase >= 511 ) phase -=512; - remainder = phase - floor(phase); - output = (double) ((1-remainder) * sineBuffer[1+ (long) phase] + remainder * sineBuffer[2+(long) phase]); - return(output); + double remainder; + phase += 512./(maxiSettings::sampleRate/(frequency*chandiv)); + if ( phase >= 511 ) phase -=512; + remainder = phase - floor(phase); + output = (double) ((1-remainder) * sineBuffer[1+ (long) phase] + remainder * sineBuffer[2+(long) phase]); + return(output); } double maxiOsc::coswave(double frequency) { //This is a cosine oscillator - output=cos (phase*(TWOPI)); - if ( phase >= 1.0 ) phase -= 1.0; - phase += (1./(maxiSettings::sampleRate/(frequency))); - return(output); - + output=cos (phase*(TWOPI)); + if ( phase >= 1.0 ) phase -= 1.0; + phase += (1./(maxiSettings::sampleRate/(frequency))); + return(output); + } double maxiOsc::phasor(double frequency) { - //This produces a floating point linear ramp between 0 and 1 at the desired frequency - output=phase; - if ( phase >= 1.0 ) phase -= 1.0; - phase += (1./(maxiSettings::sampleRate/(frequency))); - return(output); -} + //This produces a floating point linear ramp between 0 and 1 at the desired frequency + output=phase; + if ( phase >= 1.0 ) phase -= 1.0; + phase += (1./(maxiSettings::sampleRate/(frequency))); + return(output); +} double maxiOsc::square(double frequency) { //This is a square wave - if (phase<0.5) output=-1; - if (phase>0.5) output=1; - if ( phase >= 1.0 ) phase -= 1.0; - phase += (1./(maxiSettings::sampleRate/(frequency))); - return(output); + if (phase<0.5) output=-1; + if (phase>0.5) output=1; + if ( phase >= 1.0 ) phase -= 1.0; + phase += (1./(maxiSettings::sampleRate/(frequency))); + return(output); } double maxiOsc::pulse(double frequency, double duty) { //This is a pulse generator that creates a signal between -1 and 1. - if (duty<0.) duty=0; - if (duty>1.) duty=1; - if ( phase >= 1.0 ) phase -= 1.0; - phase += (1./(maxiSettings::sampleRate/(frequency))); - if (phase<duty) output=-1.; - if (phase>duty) output=1.; - return(output); + if (duty<0.) duty=0; + if (duty>1.) duty=1; + if ( phase >= 1.0 ) phase -= 1.0; + phase += (1./(maxiSettings::sampleRate/(frequency))); + if (phase<duty) output=-1.; + if (phase>duty) output=1.; + return(output); } double maxiOsc::phasor(double frequency, double startphase, double endphase) { - //This is a phasor that takes a value for the start and end of the ramp. - output=phase; - if (phase<startphase) { - phase=startphase; - } - if ( phase >= endphase ) phase = startphase; - phase += ((endphase-startphase)/(maxiSettings::sampleRate/(frequency))); - return(output); + //This is a phasor that takes a value for the start and end of the ramp. + output=phase; + if (phase<startphase) { + phase=startphase; + } + if ( phase >= endphase ) phase = startphase; + phase += ((endphase-startphase)/(maxiSettings::sampleRate/(frequency))); + return(output); } double maxiOsc::saw(double frequency) { - //Sawtooth generator. This is like a phasor but goes between -1 and 1 - output=phase; - if ( phase >= 1.0 ) phase -= 2.0; - phase += (1./(maxiSettings::sampleRate/(frequency))); - return(output); - + //Sawtooth generator. This is like a phasor but goes between -1 and 1 + output=phase; + if ( phase >= 1.0 ) phase -= 2.0; + phase += (1./(maxiSettings::sampleRate/(frequency))); + return(output); + } double maxiOsc::sawn(double frequency) { - //Bandlimited sawtooth generator. Woohoo. + //Bandlimited sawtooth generator. Woohoo. if ( phase >= 0.5 ) phase -= 1.0; phase += (1./(maxiSettings::sampleRate/(frequency))); - double temp=(8820.22/frequency)*phase; + double temp=(8820.22/frequency)*phase; if (temp<-0.5) { temp=-0.5; } @@ -342,206 +342,206 @@ double maxiOsc::sawn(double frequency) { temp+=500.0f; double remainder = temp - floor(temp); output = (double) ((1.0f-remainder) * transition[(long)temp] + remainder * transition[1+(long)temp]) - phase; - return(output); - + return(output); + } double maxiOsc::rect(double frequency, double duty) { - + return (output); } double maxiOsc::triangle(double frequency) { //This is a triangle wave. - if ( phase >= 1.0 ) phase -= 1.0; - phase += (1./(maxiSettings::sampleRate/(frequency))); - if (phase <= 0.5 ) { - output =(phase - 0.25) * 4; - } else { - output =((1.0-phase) - 0.25) * 4; - } - return(output); - -} + if ( phase >= 1.0 ) phase -= 1.0; + phase += (1./(maxiSettings::sampleRate/(frequency))); + if (phase <= 0.5 ) { + output =(phase - 0.25) * 4; + } else { + output =((1.0-phase) - 0.25) * 4; + } + return(output); + +} double maxiEnvelope::line(int numberofsegments,double segments[1000]) { - //This is a basic multi-segment ramp generator that you can use for more or less anything. + //This is a basic multi-segment ramp generator that you can use for more or less anything. //However, it's not that intuitive. if (isPlaying==1) {//only make a sound once you've been triggered - period=4./(segments[valindex+1]*0.0044); - nextval=segments[valindex+2]; - currentval=segments[valindex]; - if (currentval-amplitude > 0.0000001 && valindex < numberofsegments) { - amplitude += ((currentval-startval)/(maxiSettings::sampleRate/period)); - } else if (currentval-amplitude < -0.0000001 && valindex < numberofsegments) { - amplitude -= (((currentval-startval)*(-1))/(maxiSettings::sampleRate/period)); - } else if (valindex >numberofsegments-1) { - valindex=numberofsegments-2; - } else { - valindex=valindex+2; - startval=currentval; - } - output=amplitude; - - } - else { - output=0; - - } - return(output); + period=4./(segments[valindex+1]*0.0044); + nextval=segments[valindex+2]; + currentval=segments[valindex]; + if (currentval-amplitude > 0.0000001 && valindex < numberofsegments) { + amplitude += ((currentval-startval)/(maxiSettings::sampleRate/period)); + } else if (currentval-amplitude < -0.0000001 && valindex < numberofsegments) { + amplitude -= (((currentval-startval)*(-1))/(maxiSettings::sampleRate/period)); + } else if (valindex >numberofsegments-1) { + valindex=numberofsegments-2; + } else { + valindex=valindex+2; + startval=currentval; + } + output=amplitude; + + } + else { + output=0; + + } + return(output); } //and this void maxiEnvelope::trigger(int index, double amp) { - isPlaying=1;//ok the envelope is being used now. - valindex=index; - amplitude=amp; - + isPlaying=1;//ok the envelope is being used now. + valindex=index; + amplitude=amp; + } //Delay with feedback maxiDelayline::maxiDelayline() { - memset( memory, 0, 88200*sizeof (double) ); + memset( memory, 0, 88200*sizeof (double) ); } double maxiDelayline::dl(double input, int size, double feedback) { - if ( phase >=size ) { - phase = 0; - } - output=memory[phase]; - memory[phase]=(memory[phase]*feedback)+(input*feedback)*0.5; - phase+=1; - return(output); - + if ( phase >=size ) { + phase = 0; + } + output=memory[phase]; + memory[phase]=(memory[phase]*feedback)+(input*feedback)*0.5; + phase+=1; + return(output); + } double maxiDelayline::dl(double input, int size, double feedback, int position) { - if ( phase >=size ) phase = 0; - if ( position >=size ) position = 0; - output=memory[position]; - memory[phase]=(memory[phase]*feedback)+(input*feedback)*chandiv; - phase+=1; - return(output); - + if ( phase >=size ) phase = 0; + if ( position >=size ) position = 0; + output=memory[position]; + memory[phase]=(memory[phase]*feedback)+(input*feedback)*chandiv; + phase+=1; + return(output); + } //I particularly like these. cutoff between 0 and 1 double maxiFilter::lopass(double input, double cutoff) { - output=outputs[0] + cutoff*(input-outputs[0]); - outputs[0]=output; - return(output); + output=outputs[0] + cutoff*(input-outputs[0]); + outputs[0]=output; + return(output); } //as above double maxiFilter::hipass(double input, double cutoff) { - output=input-(outputs[0] + cutoff*(input-outputs[0])); - outputs[0]=output; - return(output); + output=input-(outputs[0] + cutoff*(input-outputs[0])); + outputs[0]=output; + return(output); } //awesome. cuttof is freq in hz. res is between 1 and whatever. Watch out! double maxiFilter::lores(double input,double cutoff1, double resonance) { - cutoff=cutoff1; - if (cutoff<10) cutoff=10; - if (cutoff>(maxiSettings::sampleRate)) cutoff=(maxiSettings::sampleRate); - if (resonance<1.) resonance = 1.; - z=cos(TWOPI*cutoff/maxiSettings::sampleRate); - c=2-2*z; - double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); - x=x+(input-y)*c; - y=y+x; - x=x*r; - output=y; - return(output); + cutoff=cutoff1; + if (cutoff<10) cutoff=10; + if (cutoff>(maxiSettings::sampleRate)) cutoff=(maxiSettings::sampleRate); + if (resonance<1.) resonance = 1.; + z=cos(TWOPI*cutoff/maxiSettings::sampleRate); + c=2-2*z; + double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); + x=x+(input-y)*c; + y=y+x; + x=x*r; + output=y; + return(output); } //working hires filter double maxiFilter::hires(double input,double cutoff1, double resonance) { - cutoff=cutoff1; - if (cutoff<10) cutoff=10; - if (cutoff>(maxiSettings::sampleRate)) cutoff=(maxiSettings::sampleRate); - if (resonance<1.) resonance = 1.; - z=cos(TWOPI*cutoff/maxiSettings::sampleRate); - c=2-2*z; - double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); - x=x+(input-y)*c; - y=y+x; - x=x*r; - output=input-y; - return(output); + cutoff=cutoff1; + if (cutoff<10) cutoff=10; + if (cutoff>(maxiSettings::sampleRate)) cutoff=(maxiSettings::sampleRate); + if (resonance<1.) resonance = 1.; + z=cos(TWOPI*cutoff/maxiSettings::sampleRate); + c=2-2*z; + double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); + x=x+(input-y)*c; + y=y+x; + x=x*r; + output=input-y; + return(output); } //This works a bit. Needs attention. double maxiFilter::bandpass(double input,double cutoff1, double resonance) { - cutoff=cutoff1; - if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5); - if (resonance>=1.) resonance=0.999999; - z=cos(TWOPI*cutoff/maxiSettings::sampleRate); - inputs[0] = (1-resonance)*(sqrt(resonance*(resonance-4.0*pow(z,2.0)+2.0)+1)); - inputs[1] = 2*z*resonance; - inputs[2] = pow((resonance*-1),2); - - output=inputs[0]*input+inputs[1]*outputs[1]+inputs[2]*outputs[2]; - outputs[2]=outputs[1]; - outputs[1]=output; - return(output); + cutoff=cutoff1; + if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5); + if (resonance>=1.) resonance=0.999999; + z=cos(TWOPI*cutoff/maxiSettings::sampleRate); + inputs[0] = (1-resonance)*(sqrt(resonance*(resonance-4.0*pow(z,2.0)+2.0)+1)); + inputs[1] = 2*z*resonance; + inputs[2] = pow((resonance*-1),2); + + output=inputs[0]*input+inputs[1]*outputs[1]+inputs[2]*outputs[2]; + outputs[2]=outputs[1]; + outputs[1]=output; + return(output); } //stereo bus double *maxiMix::stereo(double input,double two[2],double x) { - if (x>1) x=1; - if (x<0) x=0; - two[0]=input*sqrt(1.0-x); - two[1]=input*sqrt(x); - return(two); -} + if (x>1) x=1; + if (x<0) x=0; + two[0]=input*sqrt(1.0-x); + two[1]=input*sqrt(x); + return(two); +} //quad bus double *maxiMix::quad(double input,double four[4],double x,double y) { - if (x>1) x=1; - if (x<0) x=0; - if (y>1) y=1; - if (y<0) y=0; - four[0]=input*sqrt((1.0-x)*y); - four[1]=input*sqrt((1.0-x)*(1.0-y)); - four[2]=input*sqrt(x*y); - four[3]=input*sqrt(x*(1.0-y)); - return(four); + if (x>1) x=1; + if (x<0) x=0; + if (y>1) y=1; + if (y<0) y=0; + four[0]=input*sqrt((1.0-x)*y); + four[1]=input*sqrt((1.0-x)*(1.0-y)); + four[2]=input*sqrt(x*y); + four[3]=input*sqrt(x*(1.0-y)); + return(four); } //ambisonic bus double *maxiMix::ambisonic(double input,double eight[8],double x,double y,double z) { - if (x>1) x=1; - if (x<0) x=0; - if (y>1) y=1; - if (y<0) y=0; - if (z>1) y=1; - if (z<0) y=0; - eight[0]=input*(sqrt((1.0-x)*y)*1.0-z); - eight[1]=input*(sqrt((1.0-x)*(1.0-y))*1.0-z); - eight[2]=input*(sqrt(x*y)*1.0-z); - eight[3]=input*(sqrt(x*(1.0-y))*1.0-z); - eight[4]=input*(sqrt((1.0-x)*y)*z); - eight[5]=input*(sqrt((1.0-x)*(1.0-y))*z); - eight[6]=input*sqrt((x*y)*z); - eight[7]=input*sqrt((x*(1.0-y))*z); - return(eight); + if (x>1) x=1; + if (x<0) x=0; + if (y>1) y=1; + if (y<0) y=0; + if (z>1) y=1; + if (z<0) y=0; + eight[0]=input*(sqrt((1.0-x)*y)*1.0-z); + eight[1]=input*(sqrt((1.0-x)*(1.0-y))*1.0-z); + eight[2]=input*(sqrt(x*y)*1.0-z); + eight[3]=input*(sqrt(x*(1.0-y))*1.0-z); + eight[4]=input*(sqrt((1.0-x)*y)*z); + eight[5]=input*(sqrt((1.0-x)*(1.0-y))*z); + eight[6]=input*sqrt((x*y)*z); + eight[7]=input*sqrt((x*(1.0-y))*z); + return(eight); } //This is the maxiSample load function. It just calls read. bool maxiSample::load(string fileName, int channel) { - myPath = fileName; - readChannel=channel; - return read(); + myPath = fileName; + readChannel=channel; + return read(); } // This is for OGG loading bool maxiSample::loadOgg(string fileName, int channel) { #ifdef VORBIS bool result; - readChannel=channel; + readChannel=channel; int channelx; - // cout << fileName << endl; +// cout << fileName << endl; free(temp); myDataSize = stb_vorbis_decode_filename(const_cast<char*>(fileName.c_str()), &channelx, &temp); result = myDataSize > 0; @@ -559,105 +559,105 @@ bool maxiSample::loadOgg(string fileName, int channel) { position++; } } - return result; // this should probably be something more descriptive + return result; // this should probably be something more descriptive #endif return 0; } //This sets the playback position to the start of a sample void maxiSample::trigger() { - position = 0; + position = 0; recordPosition = 0; } //This is the main read function. bool maxiSample::read() { - bool result; - ifstream inFile( myPath.c_str(), ios::in | ios::binary); - result = inFile.is_open(); - if (result) { - bool datafound = false; - inFile.seekg(4, ios::beg); - inFile.read( (char*) &myChunkSize, 4 ); // read the ChunkSize - - inFile.seekg(16, ios::beg); - inFile.read( (char*) &mySubChunk1Size, 4 ); // read the SubChunk1Size - - //inFile.seekg(20, ios::beg); - inFile.read( (char*) &myFormat, sizeof(short) ); // read the file format. This should be 1 for PCM - - //inFile.seekg(22, ios::beg); - inFile.read( (char*) &myChannels, sizeof(short) ); // read the # of channels (1 or 2) - - //inFile.seekg(24, ios::beg); - inFile.read( (char*) &mySampleRate, sizeof(int) ); // read the samplerate - - //inFile.seekg(28, ios::beg); - inFile.read( (char*) &myByteRate, sizeof(int) ); // read the byterate - - //inFile.seekg(32, ios::beg); - inFile.read( (char*) &myBlockAlign, sizeof(short) ); // read the blockalign - - //inFile.seekg(34, ios::beg); - inFile.read( (char*) &myBitsPerSample, sizeof(short) ); // read the bitspersample - - //ignore any extra chunks - char chunkID[5]=""; - chunkID[4] = 0; - int filePos = 20 + mySubChunk1Size; - while(!datafound && !inFile.eof()) { - inFile.seekg(filePos, ios::beg); - inFile.read((char*) &chunkID, sizeof(char) * 4); - inFile.seekg(filePos + 4, ios::beg); - inFile.read( (char*) &myDataSize, sizeof(int) ); // read the size of the data - filePos += 8; - if (strcmp(chunkID,"data") == 0) { - datafound = true; - }else{ - filePos += myDataSize; - } - } - - // read the data chunk - char * myData = (char*) malloc(myDataSize * sizeof(char)); - inFile.seekg(filePos, ios::beg); - inFile.read(myData, myDataSize); - length=myDataSize*(0.5/myChannels); - inFile.close(); // close the input file - + bool result; + ifstream inFile( myPath.c_str(), ios::in | ios::binary); + result = inFile.is_open(); + if (result) { + bool datafound = false; + inFile.seekg(4, ios::beg); + inFile.read( (char*) &myChunkSize, 4 ); // read the ChunkSize + + inFile.seekg(16, ios::beg); + inFile.read( (char*) &mySubChunk1Size, 4 ); // read the SubChunk1Size + + //inFile.seekg(20, ios::beg); + inFile.read( (char*) &myFormat, sizeof(short) ); // read the file format. This should be 1 for PCM + + //inFile.seekg(22, ios::beg); + inFile.read( (char*) &myChannels, sizeof(short) ); // read the # of channels (1 or 2) + + //inFile.seekg(24, ios::beg); + inFile.read( (char*) &mySampleRate, sizeof(int) ); // read the samplerate + + //inFile.seekg(28, ios::beg); + inFile.read( (char*) &myByteRate, sizeof(int) ); // read the byterate + + //inFile.seekg(32, ios::beg); + inFile.read( (char*) &myBlockAlign, sizeof(short) ); // read the blockalign + + //inFile.seekg(34, ios::beg); + inFile.read( (char*) &myBitsPerSample, sizeof(short) ); // read the bitspersample + + //ignore any extra chunks + char chunkID[5]=""; + chunkID[4] = 0; + int filePos = 20 + mySubChunk1Size; + while(!datafound && !inFile.eof()) { + inFile.seekg(filePos, ios::beg); + inFile.read((char*) &chunkID, sizeof(char) * 4); + inFile.seekg(filePos + 4, ios::beg); + inFile.read( (char*) &myDataSize, sizeof(int) ); // read the size of the data + filePos += 8; + if (strcmp(chunkID,"data") == 0) { + datafound = true; + }else{ + filePos += myDataSize; + } + } + + // read the data chunk + char * myData = (char*) malloc(myDataSize * sizeof(char)); + inFile.seekg(filePos, ios::beg); + inFile.read(myData, myDataSize); + length=myDataSize*(0.5/myChannels); + inFile.close(); // close the input file + cout << "Ch: " << myChannels << ", len: " << length << endl; - if (myChannels>1) { - int position=0; - int channel=readChannel*2; - for (int i=channel;i<myDataSize+6;i+=(myChannels*2)) { - myData[position]=myData[i]; - myData[position+1]=myData[i+1]; - position+=2; - } - } + if (myChannels>1) { + int position=0; + int channel=readChannel*2; + for (int i=channel;i<myDataSize+6;i+=(myChannels*2)) { + myData[position]=myData[i]; + myData[position+1]=myData[i+1]; + position+=2; + } + } free(temp); temp = (short*) malloc(myDataSize * sizeof(char)); memcpy(temp, myData, myDataSize * sizeof(char)); free(myData); - - }else { - // cout << "ERROR: Could not load sample: " <<myPath << endl; //This line seems to be hated by windows + + }else { +// cout << "ERROR: Could not load sample: " <<myPath << endl; //This line seems to be hated by windows printf("ERROR: Could not load sample."); - - } - - - return result; // this should probably be something more descriptive + + } + + + return result; // this should probably be something more descriptive } //This plays back at the correct speed. Always loops. double maxiSample::play() { - position++; - if ((long) position >= length) position=0; - output = (double) temp[(long)position]/32767.0; - return output; + position++; + if ((long) position >= length) position=0; + output = (double) temp[(long)position]/32767.0; + return output; } void maxiSample::setPosition(double newPos) { @@ -686,404 +686,404 @@ double maxiSample::playUntil(double end) { //This plays back at the correct speed. Only plays once. To retrigger, you have to manually reset the position double maxiSample::playOnce() { - position++; - if ((long) position<length) + position++; + if ((long) position<length) output = (double) temp[(long)position]/32767.0; else { output=0; } - return output; - + return output; + } //Same as above but takes a speed value specified as a ratio, with 1.0 as original speed double maxiSample::playOnce(double speed) { - position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate)); - double remainder = position - (long) position; - if ((long) position<length) - output = (double) ((1-remainder) * temp[1+ (long) position] + remainder * temp[2+(long) position])/32767;//linear interpolation - else - output=0; - return(output); + position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate)); + double remainder = position - (long) position; + if ((long) position<length) + output = (double) ((1-remainder) * temp[1+ (long) position] + remainder * temp[2+(long) position])/32767;//linear interpolation + else + output=0; + return(output); } //As above but looping double maxiSample::play(double speed) { - double remainder; - long a,b; - position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate)); - if (speed >=0) { - - if ((long) position>=length-1) position=1; - remainder = position - floor(position); - if (position+1<length) { - a=position+1; - - } - else { - a=length-1; - } - if (position+2<length) - { - b=position+2; - } - else { - b=length-1; - } - - output = (double) ((1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation - } else { - if ((long) position<0) position=length; - remainder = position - floor(position); - if (position-1>=0) { - a=position-1; - - } - else { - a=0; - } - if (position-2>=0) { - b=position-2; - } - else { - b=0; - } - output = (double) ((-1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation - } - return(output); + double remainder; + long a,b; + position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate)); + if (speed >=0) { + + if ((long) position>=length-1) position=1; + remainder = position - floor(position); + if (position+1<length) { + a=position+1; + + } + else { + a=length-1; + } + if (position+2<length) + { + b=position+2; + } + else { + b=length-1; + } + + output = (double) ((1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation +} else { + if ((long) position<0) position=length; + remainder = position - floor(position); + if (position-1>=0) { + a=position-1; + + } + else { + a=0; + } + if (position-2>=0) { + b=position-2; + } + else { + b=0; + } + output = (double) ((-1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation + } + return(output); } //placeholder double maxiSample::play(double frequency, double start, double end) { - return play(frequency, start, end, position); + return play(frequency, start, end, position); } //This allows you to say how often a second you want a specific chunk of audio to play double maxiSample::play(double frequency, double start, double end, double &pos) { - double remainder; - if (end>=length) end=length-1; - long a,b; - - if (frequency >0.) { - if (pos<start) { - pos=start; - } - - if ( pos >= end ) pos = start; - pos += ((end-start)/((maxiSettings::sampleRate)/(frequency*chandiv))); - remainder = pos - floor(pos); - long posl = floor(pos); - if (posl+1<length) { - a=posl+1; - - } - else { - a=posl-1; - } - if (posl+2<length) { - b=posl+2; - } - else { - b=length-1; - } - - output = (double) ((1-remainder) * temp[a] + - remainder * temp[b])/32767;//linear interpolation - } else { - frequency*=-1.; - if ( pos <= start ) pos = end; - pos -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); - remainder = pos - floor(pos); - long posl = floor(pos); - if (posl-1>=0) { - a=posl-1; - } - else { - a=0; - } - if (posl-2>=0) { - b=posl-2; - } - else { - b=0; - } - output = (double) ((-1-remainder) * temp[a] + - remainder * temp[b])/32767;//linear interpolation - - } - - return(output); + double remainder; + if (end>=length) end=length-1; + long a,b; + + if (frequency >0.) { + if (pos<start) { + pos=start; + } + + if ( pos >= end ) pos = start; + pos += ((end-start)/((maxiSettings::sampleRate)/(frequency*chandiv))); + remainder = pos - floor(pos); + long posl = floor(pos); + if (posl+1<length) { + a=posl+1; + + } + else { + a=posl-1; + } + if (posl+2<length) { + b=posl+2; + } + else { + b=length-1; + } + + output = (double) ((1-remainder) * temp[a] + + remainder * temp[b])/32767;//linear interpolation + } else { + frequency*=-1.; + if ( pos <= start ) pos = end; + pos -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); + remainder = pos - floor(pos); + long posl = floor(pos); + if (posl-1>=0) { + a=posl-1; + } + else { + a=0; + } + if (posl-2>=0) { + b=posl-2; + } + else { + b=0; + } + output = (double) ((-1-remainder) * temp[a] + + remainder * temp[b])/32767;//linear interpolation + + } + + return(output); } //Same as above. better cubic inerpolation. Cobbled together from various (pd externals, yehar, other places). double maxiSample::play4(double frequency, double start, double end) { - double remainder; - double a,b,c,d,a1,a2,a3; - if (frequency >0.) { - if (position<start) { - position=start; - } - if ( position >= end ) position = start; - position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); - remainder = position - floor(position); - if (position>0) { - a=temp[(int)(floor(position))-1]; - - } else { - a=temp[0]; - - } - - b=temp[(long) position]; - if (position<end-2) { - c=temp[(long) position+1]; - - } else { - c=temp[0]; - - } - if (position<end-3) { - d=temp[(long) position+2]; - - } else { - d=temp[0]; - } - a1 = 0.5f * (c - a); - a2 = a - 2.5 * b + 2.f * c - 0.5f * d; - a3 = 0.5f * (d - a) + 1.5f * (b - c); - output = (double) (((a3 * remainder + a2) * remainder + a1) * remainder + b) / 32767; - - } else { + double remainder; + double a,b,c,d,a1,a2,a3; + if (frequency >0.) { + if (position<start) { + position=start; + } + if ( position >= end ) position = start; + position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); + remainder = position - floor(position); + if (position>0) { + a=temp[(int)(floor(position))-1]; + + } else { + a=temp[0]; + + } + + b=temp[(long) position]; + if (position<end-2) { + c=temp[(long) position+1]; + + } else { + c=temp[0]; + + } + if (position<end-3) { + d=temp[(long) position+2]; + + } else { + d=temp[0]; + } + a1 = 0.5f * (c - a); + a2 = a - 2.5 * b + 2.f * c - 0.5f * d; + a3 = 0.5f * (d - a) + 1.5f * (b - c); + output = (double) (((a3 * remainder + a2) * remainder + a1) * remainder + b) / 32767; + + } else { frequency*=-1.; - if ( position <= start ) position = end; - position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); - remainder = position - floor(position); - if (position>start && position < end-1) { - a=temp[(long) position+1]; - - } else { - a=temp[0]; - - } - - b=temp[(long) position]; - if (position>start) { - c=temp[(long) position-1]; - - } else { - c=temp[0]; - - } - if (position>start+1) { - d=temp[(long) position-2]; - - } else { - d=temp[0]; - } - a1 = 0.5f * (c - a); - a2 = a - 2.5 * b + 2.f * c - 0.5f * d; - a3 = 0.5f * (d - a) + 1.5f * (b - c); - output = (double) (((a3 * remainder + a2) * -remainder + a1) * -remainder + b) / 32767; - - } - - return(output); + if ( position <= start ) position = end; + position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); + remainder = position - floor(position); + if (position>start && position < end-1) { + a=temp[(long) position+1]; + + } else { + a=temp[0]; + + } + + b=temp[(long) position]; + if (position>start) { + c=temp[(long) position-1]; + + } else { + c=temp[0]; + + } + if (position>start+1) { + d=temp[(long) position-2]; + + } else { + d=temp[0]; + } + a1 = 0.5f * (c - a); + a2 = a - 2.5 * b + 2.f * c - 0.5f * d; + a3 = 0.5f * (d - a) + 1.5f * (b - c); + output = (double) (((a3 * remainder + a2) * -remainder + a1) * -remainder + b) / 32767; + + } + + return(output); } //You don't need to worry about this stuff. double maxiSample::bufferPlay(unsigned char &bufferin,long length) { - double remainder; - short* buffer = (short *)&bufferin; - position=(position+1); - remainder = position - (long) position; - if ((long) position>length) position=0; - output = (double) ((1-remainder) * buffer[1+ (long) position] + remainder * buffer[2+(long) position])/32767;//linear interpolation - return(output); + double remainder; + short* buffer = (short *)&bufferin; + position=(position+1); + remainder = position - (long) position; + if ((long) position>length) position=0; + output = (double) ((1-remainder) * buffer[1+ (long) position] + remainder * buffer[2+(long) position])/32767;//linear interpolation + return(output); } double maxiSample::bufferPlay(unsigned char &bufferin,double speed,long length) { - double remainder; - long a,b; - short* buffer = (short *)&bufferin; - position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate)); - if (speed >=0) { - - if ((long) position>=length-1) position=1; - remainder = position - floor(position); - if (position+1<length) { - a=position+1; - - } - else { - a=length-1; - } - if (position+2<length) - { - b=position+2; - } - else { - b=length-1; - } - - output = (double) ((1-remainder) * buffer[a] + remainder * buffer[b])/32767;//linear interpolation - } else { - if ((long) position<0) position=length; - remainder = position - floor(position); - if (position-1>=0) { - a=position-1; - - } - else { - a=0; - } - if (position-2>=0) { - b=position-2; - } - else { - b=0; - } - output = (double) ((-1-remainder) * buffer[a] + remainder * buffer[b])/32767;//linear interpolation - } - return(output); + double remainder; + long a,b; + short* buffer = (short *)&bufferin; + position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate)); + if (speed >=0) { + + if ((long) position>=length-1) position=1; + remainder = position - floor(position); + if (position+1<length) { + a=position+1; + + } + else { + a=length-1; + } + if (position+2<length) + { + b=position+2; + } + else { + b=length-1; + } + + output = (double) ((1-remainder) * buffer[a] + remainder * buffer[b])/32767;//linear interpolation + } else { + if ((long) position<0) position=length; + remainder = position - floor(position); + if (position-1>=0) { + a=position-1; + + } + else { + a=0; + } + if (position-2>=0) { + b=position-2; + } + else { + b=0; + } + output = (double) ((-1-remainder) * buffer[a] + remainder * buffer[b])/32767;//linear interpolation + } + return(output); } double maxiSample::bufferPlay(unsigned char &bufferin,double frequency, double start, double end) { - double remainder; - length=end; - long a,b; - short* buffer = (short *)&bufferin; - if (frequency >0.) { - if (position<start) { - position=start; - } - - if ( position >= end ) position = start; - position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); - remainder = position - floor(position); - long pos = floor(position); - if (pos+1<length) { - a=pos+1; - - } - else { - a=pos-1; - } - if (pos+2<length) { - b=pos+2; - } - else { - b=length-1; - } - - output = (double) ((1-remainder) * buffer[a] + - remainder * buffer[b])/32767;//linear interpolation - } else { + double remainder; + length=end; + long a,b; + short* buffer = (short *)&bufferin; + if (frequency >0.) { + if (position<start) { + position=start; + } + + if ( position >= end ) position = start; + position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); + remainder = position - floor(position); + long pos = floor(position); + if (pos+1<length) { + a=pos+1; + + } + else { + a=pos-1; + } + if (pos+2<length) { + b=pos+2; + } + else { + b=length-1; + } + + output = (double) ((1-remainder) * buffer[a] + + remainder * buffer[b])/32767;//linear interpolation + } else { frequency*=-1.; - if ( position <= start ) position = end; - position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); - remainder = position - floor(position); - long pos = floor(position); - if (pos-1>=0) { - a=pos-1; - } - else { - a=0; - } - if (pos-2>=0) { - b=pos-2; - } - else { - b=0; - } - output = (double) ((-1-remainder) * buffer[a] + - remainder * buffer[b])/32767;//linear interpolation - - } - - return(output); + if ( position <= start ) position = end; + position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); + remainder = position - floor(position); + long pos = floor(position); + if (pos-1>=0) { + a=pos-1; + } + else { + a=0; + } + if (pos-2>=0) { + b=pos-2; + } + else { + b=0; + } + output = (double) ((-1-remainder) * buffer[a] + + remainder * buffer[b])/32767;//linear interpolation + + } + + return(output); } //better cubic inerpolation. Cobbled together from various (pd externals, yehar, other places). double maxiSample::bufferPlay4(unsigned char &bufferin,double frequency, double start, double end) { - double remainder; - double a,b,c,d,a1,a2,a3; - short* buffer = (short*)&bufferin; - if (frequency >0.) { - if (position<start) { - position=start; - } - if ( position >= end ) position = start; - position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); - remainder = position - floor(position); - if (position>0) { - a=buffer[(int)(floor(position))-1]; - - } else { - a=buffer[0]; - - } - - b=buffer[(long) position]; - if (position<end-2) { - c=buffer[(long) position+1]; - - } else { - c=buffer[0]; - - } - if (position<end-3) { - d=buffer[(long) position+2]; - - } else { - d=buffer[0]; - } - a1 = 0.5f * (c - a); - a2 = a - 2.5 * b + 2.f * c - 0.5f * d; - a3 = 0.5f * (d - a) + 1.5f * (b - c); - output = (double) (((a3 * remainder + a2) * remainder + a1) * remainder + b) / 32767; - - } else { + double remainder; + double a,b,c,d,a1,a2,a3; + short* buffer = (short*)&bufferin; + if (frequency >0.) { + if (position<start) { + position=start; + } + if ( position >= end ) position = start; + position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); + remainder = position - floor(position); + if (position>0) { + a=buffer[(int)(floor(position))-1]; + + } else { + a=buffer[0]; + + } + + b=buffer[(long) position]; + if (position<end-2) { + c=buffer[(long) position+1]; + + } else { + c=buffer[0]; + + } + if (position<end-3) { + d=buffer[(long) position+2]; + + } else { + d=buffer[0]; + } + a1 = 0.5f * (c - a); + a2 = a - 2.5 * b + 2.f * c - 0.5f * d; + a3 = 0.5f * (d - a) + 1.5f * (b - c); + output = (double) (((a3 * remainder + a2) * remainder + a1) * remainder + b) / 32767; + + } else { frequency*=-1.; - if ( position <= start ) position = end; - position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); - remainder = position - floor(position); - if (position>start && position < end-1) { - a=buffer[(long) position+1]; - - } else { - a=buffer[0]; - - } - - b=buffer[(long) position]; - if (position>start) { - c=buffer[(long) position-1]; - - } else { - c=buffer[0]; - - } - if (position>start+1) { - d=buffer[(long) position-2]; - - } else { - d=buffer[0]; - } - a1 = 0.5f * (c - a); - a2 = a - 2.5 * b + 2.f * c - 0.5f * d; - a3 = 0.5f * (d - a) + 1.5f * (b - c); - output = (double) (((a3 * remainder + a2) * -remainder + a1) * -remainder + b) / 32767; - - } - - return(output); + if ( position <= start ) position = end; + position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv))); + remainder = position - floor(position); + if (position>start && position < end-1) { + a=buffer[(long) position+1]; + + } else { + a=buffer[0]; + + } + + b=buffer[(long) position]; + if (position>start) { + c=buffer[(long) position-1]; + + } else { + c=buffer[0]; + + } + if (position>start+1) { + d=buffer[(long) position-2]; + + } else { + d=buffer[0]; + } + a1 = 0.5f * (c - a); + a2 = a - 2.5 * b + 2.f * c - 0.5f * d; + a3 = 0.5f * (d - a) + 1.5f * (b - c); + output = (double) (((a3 * remainder + a2) * -remainder + a1) * -remainder + b) / 32767; + + } + + return(output); } -void maxiSample::getLength() { - length=myDataSize*0.5; +long maxiSample::getLength() { + return (length=myDataSize*0.5); } void maxiSample::setLength(unsigned long numSamples) { @@ -1175,77 +1175,77 @@ void maxiSample::autoTrim(float alpha, float threshold, bool trimStart, bool tri -/* OK this compressor and gate are now ready to use. The envelopes, like all the envelopes in this recent update, use stupid algorithms for +/* OK this compressor and gate are now ready to use. The envelopes, like all the envelopes in this recent update, use stupid algorithms for incrementing - consequently a long attack is something like 0.0001 and a long release is like 0.9999. Annoyingly, a short attack is 0.1, and a short release is 0.99. I'll sort this out laters */ double maxiDyn::gate(double input, double threshold, long holdtime, double attack, double release) { - - if (fabs(input)>threshold && attackphase!=1){ - holdcount=0; - releasephase=0; - attackphase=1; - if(amplitude==0) amplitude=0.01; - } - - if (attackphase==1 && amplitude<1) { - amplitude*=(1+attack); - output=input*amplitude; - } - - if (amplitude>=1) { - attackphase=0; - holdphase=1; - } - - if (holdcount<holdtime && holdphase==1) { - output=input; - holdcount++; - } - - if (holdcount==holdtime) { - holdphase=0; - releasephase=1; - } - - if (releasephase==1 && amplitude>0.) { - output=input*(amplitude*=release); - - } - - return output; + + if (fabs(input)>threshold && attackphase!=1){ + holdcount=0; + releasephase=0; + attackphase=1; + if(amplitude==0) amplitude=0.01; + } + + if (attackphase==1 && amplitude<1) { + amplitude*=(1+attack); + output=input*amplitude; + } + + if (amplitude>=1) { + attackphase=0; + holdphase=1; + } + + if (holdcount<holdtime && holdphase==1) { + output=input; + holdcount++; + } + + if (holdcount==holdtime) { + holdphase=0; + releasephase=1; + } + + if (releasephase==1 && amplitude>0.) { + output=input*(amplitude*=release); + + } + + return output; } double maxiDyn::compressor(double input, double ratio, double threshold, double attack, double release) { - - if (fabs(input)>threshold && attackphase!=1){ - holdcount=0; - releasephase=0; - attackphase=1; - if(currentRatio==0) currentRatio=ratio; - } - - if (attackphase==1 && currentRatio<ratio-1) { - currentRatio*=(1+attack); - } - - if (currentRatio>=ratio-1) { - attackphase=0; - releasephase=1; - } - - if (releasephase==1 && currentRatio>0.) { - currentRatio*=release; - } - - if (input>0.) { - output = input/(1.+currentRatio); - } else { - output = input/(1.+currentRatio); - } - - return output*(1+log(ratio)); + + if (fabs(input)>threshold && attackphase!=1){ + holdcount=0; + releasephase=0; + attackphase=1; + if(currentRatio==0) currentRatio=ratio; + } + + if (attackphase==1 && currentRatio<ratio-1) { + currentRatio*=(1+attack); + } + + if (currentRatio>=ratio-1) { + attackphase=0; + releasephase=1; + } + + if (releasephase==1 && currentRatio>0.) { + currentRatio*=release; + } + + if (input>0.) { + output = input/(1.+currentRatio); + } else { + output = input/(1.+currentRatio); + } + + return output*(1+log(ratio)); } double maxiDyn::compress(double input) { @@ -1284,44 +1284,44 @@ double maxiDyn::compress(double input) { It takes mental numbers for attack and release tho. Basically, they're exponentials. I'll map them out later so that it's a bit more intuitive */ double maxiEnv::ar(double input, double attack, double release, long holdtime, int trigger) { - - if (trigger==1 && attackphase!=1 && holdphase!=1){ - holdcount=0; - releasephase=0; - attackphase=1; - } - - if (attackphase==1) { - amplitude+=(1*attack); - output=input*amplitude; - } - - if (amplitude>=1) { - amplitude=1; - attackphase=0; - holdphase=1; - } - - if (holdcount<holdtime && holdphase==1) { - output=input; - holdcount++; - } - - if (holdcount==holdtime && trigger==1) { - output=input; - } - - if (holdcount==holdtime && trigger!=1) { - holdphase=0; - releasephase=1; - } - - if (releasephase==1 && amplitude>0.) { - output=input*(amplitude*=release); - - } - - return output; + + if (trigger==1 && attackphase!=1 && holdphase!=1){ + holdcount=0; + releasephase=0; + attackphase=1; + } + + if (attackphase==1) { + amplitude+=(1*attack); + output=input*amplitude; + } + + if (amplitude>=1) { + amplitude=1; + attackphase=0; + holdphase=1; + } + + if (holdcount<holdtime && holdphase==1) { + output=input; + holdcount++; + } + + if (holdcount==holdtime && trigger==1) { + output=input; + } + + if (holdcount==holdtime && trigger!=1) { + holdphase=0; + releasephase=1; + } + + if (releasephase==1 && amplitude>0.) { + output=input*(amplitude*=release); + + } + + return output; } /* adsr. It's not bad, very simple to use*/ @@ -1467,8 +1467,8 @@ void maxiDyn::setRatio(double ratioF) { double convert::mtof(int midinote) { - - return mtofarray[midinote]; + + return mtofarray[midinote]; } @@ -1477,7 +1477,7 @@ template<> void maxiEnvelopeFollower::setAttack(double attackMS) { } template<> void maxiEnvelopeFollower::setRelease(double releaseMS) { - release = pow( 0.01, 1.0 / ( releaseMS * maxiSettings::sampleRate * 0.001 ) ); + release = pow( 0.01, 1.0 / ( releaseMS * maxiSettings::sampleRate * 0.001 ) ); } double pitchRatios[256]= {0.0006517771980725,0.0006905338959768,0.0007315951515920, 0.0007750981021672, 0.0008211878011934, 0.0008700182079338, 0.0009217521874234, 0.0009765623835847, 0.0010346318595111, 0.0010961542138830, 0.0011613349197432, 0.0012303915573284, 0.0013035543961450, 0.0013810677919537, 0.0014631903031841, 0.0015501962043345, 0.0016423756023869, 0.0017400364158675, 0.0018435043748468, 0.0019531247671694, 0.0020692637190223, 0.0021923084277660, 0.0023226698394865, 0.0024607831146568, 0.0026071087922901, 0.0027621355839074, 0.0029263808391988, 0.0031003924086690, 0.0032847514376044, 0.0034800728317350, 0.0036870087496936, 0.0039062497671694, 0.0041385274380445, 0.0043846168555319, 0.0046453396789730, 0.0049215662293136, 0.0052142175845802, 0.0055242711678147, 0.0058527616783977, 0.0062007848173380, 0.0065695028752089, 0.0069601456634700, 0.0073740174993873, 0.0078124995343387, 0.0082770548760891, 0.0087692337110639, 0.0092906802892685, 0.0098431324586272, 0.0104284351691604, 0.0110485423356295, 0.0117055233567953, 0.0124015696346760, 0.0131390057504177, 0.0139202913269401, 0.0147480349987745, 0.0156249990686774, 0.0165541097521782, 0.0175384692847729, 0.0185813605785370, 0.0196862649172544, 0.0208568722009659, 0.0220970865339041, 0.0234110467135906, 0.0248031392693520, 0.0262780115008354, 0.0278405826538801, 0.0294960699975491, 0.0312499981373549, 0.0331082195043564, 0.0350769385695457, 0.0371627211570740, 0.0393725298345089, 0.0417137444019318, 0.0441941730678082, 0.0468220934271812, 0.0496062822639942, 0.0525560230016708, 0.0556811690330505, 0.0589921437203884, 0.0624999962747097, 0.0662164390087128, 0.0701538771390915, 0.0743254423141479, 0.0787450596690178, 0.0834274888038635, 0.0883883461356163, 0.0936441868543625, 0.0992125645279884, 0.1051120460033417, 0.1113623380661011, 0.1179842874407768, 0.1249999925494194, 0.1324328780174255, 0.1403077542781830, 0.1486508846282959, 0.1574901193380356, 0.1668549776077271, 0.1767766922712326, 0.1872883737087250, 0.1984251290559769, 0.2102240920066833, 0.2227246761322021, 0.2359685748815536, 0.2500000000000000, 0.2648657560348511, 0.2806155085563660, 0.2973017692565918, 0.3149802684783936, 0.3337099552154541, 0.3535533845424652, 0.3745767772197723, 0.3968502581119537, 0.4204482138156891, 0.4454493522644043, 0.4719371497631073, 0.5000000000000000, 0.5297315716743469, 0.5612310171127319, 0.5946035385131836, 0.6299605369567871, 0.6674199104309082, 0.7071067690849304, 0.7491535544395447, 0.7937005162239075, 0.8408964276313782, 0.8908987045288086, 0.9438742995262146, 1.0000000000000000, 1.0594631433486938, 1.1224620342254639, 1.1892070770263672, 1.2599210739135742, 1.3348398208618164, 1.4142135381698608, 1.4983071088790894, 1.5874010324478149, 1.6817928552627563, 1.7817974090576172, 1.8877485990524292, 2.0000000000000000, 2.1189262866973877, 2.2449240684509277, 2.3784141540527344, 2.5198421478271484, 2.6696796417236328, 2.8284270763397217, 2.9966142177581787, 3.1748020648956299, 3.3635857105255127, 3.5635950565338135, 3.7754974365234375, 4.0000000000000000, 4.2378525733947754, 4.4898481369018555, 4.7568287849426270, 5.0396842956542969, 5.3393597602844238, 5.6568546295166016, 5.9932284355163574, 6.3496046066284180, 6.7271714210510254, 7.1271901130676270, 7.5509948730468750, 8.0000000000000000, 8.4757051467895508, 8.9796962738037109, 9.5136575698852539, 10.0793685913085938, 10.6787195205688477, 11.3137092590332031, 11.9864568710327148, 12.6992092132568359, 13.4543428421020508, 14.2543802261352539, 15.1019897460937500, 16.0000000000000000, 16.9514102935791016, 17.9593944549560547, 19.0273151397705078, 20.1587371826171875, 21.3574390411376953, 22.6274185180664062, 23.9729137420654297, 25.3984184265136719, 26.9086875915527344, 28.5087604522705078, 30.2039794921875000, 32.0000000000000000, 33.9028205871582031, 35.9187889099121094, 38.0546302795410156, 40.3174743652343750, 42.7148780822753906, 45.2548370361328125, 47.9458274841308594, 50.7968368530273438, 53.8173751831054688, 57.0175209045410156, 60.4079589843750000, 64.0000076293945312, 67.8056411743164062, 71.8375778198242188, 76.1092605590820312, 80.6349563598632812, 85.4297561645507812, 90.5096740722656250, 95.8916625976562500, 101.5936737060546875, 107.6347503662109375, 114.0350418090820312, 120.8159179687500000, 128.0000152587890625, 135.6112823486328125, 143.6751556396484375, 152.2185211181640625, 161.2699127197265625, 170.8595123291015625, 181.0193481445312500, 191.7833251953125000, 203.1873474121093750, 215.2695007324218750, 228.0700836181640625, 241.6318511962890625, 256.0000305175781250, 271.2225646972656250, 287.3503112792968750, 304.4370422363281250, 322.5398254394531250, 341.7190246582031250, 362.0386962890625000, 383.5666503906250000, 406.3746948242187500, 430.5390014648437500, 456.1401977539062500, 483.2637023925781250, 512.0000610351562500, 542.4451293945312500, 574.7006225585937500, 608.8740844726562500, 645.0796508789062500, 683.4380493164062500, 724.0773925781250000, 767.1333007812500000, 812.7494506835937500, 861.0780029296875000, 912.2803955078125000, 966.5274047851562500, 1024.0001220703125000, 1084.8903808593750000, 1149.4012451171875000, 1217.7481689453125000, 1290.1593017578125000, 1366.8762207031250000, 1448.1549072265625000, 1534.2666015625000000, 1625.4989013671875000}; @@ -2003,6 +2003,325 @@ void maxiSampler::trigger() { } +///************************************************************* +/// +/// Init most variables +/// +///************************************************************* +maxiRecorder::maxiRecorder() : +bufferSize(maxiSettings::sampleRate * 2), +bufferQueueSize(3), +bufferIndex(0), +recordedAmountFrames(0), +threadRunning(false) +{ + +} + +///************************************************************* +/// +/// Free resources in RAII manner and save to wav when this +/// object lifetime is up! +/// +///************************************************************* +maxiRecorder::~maxiRecorder() +{ + if (isRecording()) saveToWav(); + freeResources(); +} + +///************************************************************* +/// +/// Free resources only if they exist; may be called multiple +/// times in it's lifetime becasuse of destructor. +/// +///************************************************************* +void maxiRecorder::freeResources() +{ + if (savedBuffers.size() > 0) + { + for (int i = 0; i < savedBuffers.size(); ++i) + { + delete[] savedBuffers.front(); + savedBuffers.pop(); + } + } +} + +///************************************************************* +/// +/// Simply return if we are recording or not +/// +///************************************************************* +bool maxiRecorder::isRecording() const +{ + return doRecord; +} +///************************************************************* +/// +/// Set the filename (and path) +/// +///************************************************************* +void maxiRecorder::setup(std::string _filename) +{ + filename = _filename; +} +///************************************************************* +/// +/// You don't need to worry calling about this, this runs in a +/// detached thread after calling startRecording() and means +/// we can allocate new memory without interupting the real +/// time audio callback. Rather than have multiple ifdefs to +/// split up the same function to use different OS's threading +/// services I just redefined the thing because it looked +/// cleaner. +/// +/// A pointer to the instanciated object from this class is +/// passed as '_context'. We do this because we are calling this +/// function from a static helper func and need to access object +/// specific variables. +/// +///************************************************************* +#if defined(OS_IS_UNIX) +void* maxiRecorder::update(void* _context) +{ + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + maxiRecorder* _this = static_cast<maxiRecorder*>(_context); + _this->threadRunning = true; + while (_this->doRecord) + { + usleep((long)(10000. / bufferSize / maxiSettings::sampleRate)); + while (_this->bufferQueueSize > _this->bufferQueue.size()) + { + _this->enqueueBuffer(); + } + } + std::cout << "\nFinishing Recording..." << std::endl; + return 0; +} +#elif defined(OS_IS_WIN) +void* maxiRecorder::update(void* _context) +{ + maxiRecorder* _this = static_cast<maxiRecorder*>(_context); + _this->threadRunning = true; + long time = (long)(1000. / bufferSize / maxiSettings::sampleRate); + while (_this->doRecord) + { + Sleep(time); + while (_this->bufferQueueSize > _this->bufferQueue.size()) + { + _this->enqueueBuffer(); + } + } + std::cout << "\nFinishing Recording..." << std::endl; + return 0; +} +#endif + +///************************************************************* +/// +/// This whacks the update method into a detached thread which +/// will ensure there are enough buffers available in the queue. +/// +///************************************************************* +void maxiRecorder::startRecording() +{ + doRecord = true; + for (int i = 0; i < bufferQueueSize; ++i) + { + enqueueBuffer(); + } + +#if defined(OS_IS_UNIX) + if (pthread_create(&daemon, NULL, &maxiRecorder::update_pthread_helper, this) != 0) + std::cout << "pthread created incorrectly" << std::endl; + if (pthread_detach(daemon) != 0) + std::cout << "pthread detached incorrectly" << std::endl; +#elif defined(OS_IS_WIN) + unsigned threadID; + daemonHandle = (HANDLE) _beginthreadex(NULL, 0, &maxiRecorder::update_pthread_helper, (void *) this, 0, &threadID); +#endif + + +} + +///************************************************************* +/// +/// stops the recording thread by allowing the stack to unwind +/// in update() and stops the Windows thread if necessary +/// +///************************************************************* +void maxiRecorder::stopRecording() +{ +#if defined(OS_IS_WIN) + CloseHandle(daemonHandle); +#endif + doRecord = false; +} + +///************************************************************* +/// +/// Shamelessly hacked together largely using this link +/// http://stackoverflow.com/questions/22226872/two-problems- +/// when-writing-to-wav-c +/// +/// I haven't bothered to change the syntax much here and the +/// templated write function was too convenient during my +/// struggle to get my head around wav headers so I've kept it +/// very similar to the attached code. +/// +/// A clear optimisation would be to make getProcessedData() +/// return a vector of shorts to prevent another loop +/// +///************************************************************* +template <typename T> +void maxiRecorder::write(std::ofstream& _stream, const T& _t) { + _stream.write((const char*)&_t, sizeof(T)); +} + +void maxiRecorder::saveToWav() +{ + if (isRecording()) stopRecording(); + if (threadRunning) + { +#if defined(OS_IS_UNIX) + pthread_cancel(daemon); +#endif + threadRunning = false; + } + std::vector<double> pcmData = getProcessedData(); + std::vector<short> pcmDataInt; + + pcmDataInt.resize(pcmData.size()); + + for (int i = 0; i < pcmData.size(); ++i) + pcmDataInt[i] = (short) (pcmData[i] * 3276.7); + + int sampleRate = maxiSettings::sampleRate; + short channels = maxiSettings::channels; + int buffSize = pcmDataInt.size() * 2; + + std::ofstream stream(filename.c_str(), std::ios::binary); + + if (stream.is_open()) + { + /* Header */ + stream.write("RIFF", 4); + write<int>(stream, 36 + buffSize); + stream.write("WAVE", 4); + + /* Format Chunk */ + stream.write("fmt ", 4); + write<int>(stream, 16); + write<short>(stream, 1); + write<short>(stream, channels); + write<int>(stream, sampleRate); + write<int>(stream, sampleRate * channels * sizeof(short)); + write<short>(stream, channels * sizeof(short)); + write<short>(stream, 8 * sizeof(short)); + + /* Data Chunk */ + stream.write("data", 4); + stream.write((const char*) &buffSize, 4); + stream.write((const char*) pcmDataInt.data(), buffSize); + + stream.close(); + + std::cout << "Wrote " << buffSize + << " bytes to " << filename.c_str() + << std::endl; + } + else + { + std::cerr << "Failed to open file: " << strerror(errno) << std::endl; + } +} + +///************************************************************* +/// +/// This takes the queue of user generated arrays and whacks +/// it into a vector of doubles which is easier to transverse +/// and work with. +/// +///************************************************************* +std::vector<double> maxiRecorder::getProcessedData() +{ + std::vector<double> userData; + int dataSize = savedBuffers.size() * bufferSize; + userData.resize(dataSize); + + int savedIndex = 0; + for (int i = 0; i < dataSize; ++i) + { + if (i > 0 && i % bufferSize == 0) + { + savedIndex = 0; + savedBuffers.pop(); + } + + userData[i] = savedBuffers.front()[savedIndex]; + ++savedIndex; + } + + double lastFrame = userData[userData.size() - 1]; + while (lastFrame == 0) + { + userData.pop_back(); + lastFrame = userData[userData.size() - 1]; + } + + return userData; +} + +///************************************************************* +/// +/// Pass the buffer of audio to this method and it will write +/// it to the right place. This method is real-time safe and +/// is overriden for ofx's / port's floats array or maximilian's +/// / rtaudio's double +/// +///************************************************************* +void maxiRecorder::passData(double* _in, int _inBufferSize) +{ + for (int i = 0; i < _inBufferSize; ++i) + { + if (bufferIndex >= bufferSize) + { + bufferQueue.pop(); + bufferIndex = 0; + } + bufferQueue.front()[bufferIndex] = _in[i]; + ++bufferIndex; + ++recordedAmountFrames; + } +} +void maxiRecorder::passData(float* _in, int _inBufferSize) +{ + for (int i = 0; i < _inBufferSize; ++i) + { + if (bufferIndex >= bufferSize) + { + bufferQueue.pop(); + bufferIndex = 0; + } + bufferQueue.front()[bufferIndex] = (double) _in[i]; + ++bufferIndex; + ++recordedAmountFrames; + } +} + +///************************************************************* +/// +/// The method to instanciate new memory and ensure the correct +/// structures have the correct addresses. +/// +///************************************************************* +void maxiRecorder::enqueueBuffer() +{ + double* b = new double[bufferSize]; + bufferQueue.push(b); + savedBuffers.push(b); +} diff --git a/openFrameworks/ofxMaxim/libs/maximilian.h b/openFrameworks/ofxMaxim/libs/maximilian.h index c9266df..d2db173 100755 --- a/openFrameworks/ofxMaxim/libs/maximilian.h +++ b/openFrameworks/ofxMaxim/libs/maximilian.h @@ -6,7 +6,7 @@ * Copyright 2009 Mick Grierson & Strangeloop Limited. All rights reserved. * Thanks to the Goldsmiths Creative Computing Team. * Special thanks to Arturo Castro for the PortAudio implementation. - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -15,11 +15,11 @@ * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT @@ -36,14 +36,26 @@ //#define MAXIMILIAN_PORTAUDIO #define MAXIMILIAN_RT_AUDIO - #include <iostream> #include <fstream> #include <string.h> #include <cstdlib> #include "math.h" +#include <cerrno> +#include <queue> +#include <vector> + +#if !defined(_WIN32) && (defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) +#define OS_IS_UNIX true +#include <pthread.h> +#include <unistd.h> +#endif + #ifdef _WIN32 //|| _WIN64 +#define OS_IS_WIN true #include <algorithm> +#include <Windows.h> +#include <process.h> #endif using namespace std; @@ -54,191 +66,191 @@ using namespace std; class maxiSettings { public: - static int sampleRate; - static int channels; - static int bufferSize; - static void setup(int initSampleRate, int initChannels, int initBufferSize) { - maxiSettings::sampleRate = initSampleRate; - maxiSettings::channels = initChannels; - maxiSettings::bufferSize = initBufferSize; - } + static int sampleRate; + static int channels; + static int bufferSize; + static void setup(int initSampleRate, int initChannels, int initBufferSize) { + maxiSettings::sampleRate = initSampleRate; + maxiSettings::channels = initChannels; + maxiSettings::bufferSize = initBufferSize; + } }; class maxiOsc { - - double frequency; - double phase; - double startphase; - double endphase; - double output; - double tri; - - + + double frequency; + double phase; + double startphase; + double endphase; + double output; + double tri; + + public: - maxiOsc(); - double sinewave(double frequency); - double coswave(double frequency); - double phasor(double frequency); - double phasor(double frequency, double startphase, double endphase); - double saw(double frequency); - double triangle(double frequency); - double square(double frequency); - double pulse(double frequency, double duty); - double noise(); - double sinebuf(double frequency); - double sinebuf4(double frequency); + maxiOsc(); + double sinewave(double frequency); + double coswave(double frequency); + double phasor(double frequency); + double phasor(double frequency, double startphase, double endphase); + double saw(double frequency); + double triangle(double frequency); + double square(double frequency); + double pulse(double frequency, double duty); + double noise(); + double sinebuf(double frequency); + double sinebuf4(double frequency); double sawn(double frequency); double rect(double frequency, double duty=0.5); - void phaseReset(double phaseIn); - + void phaseReset(double phaseIn); + }; class maxiEnvelope { - - double period; - double output; - double startval; - double currentval; - double nextval; - int isPlaying; - -public: - double line(int numberofsegments,double segments[100]); - void trigger(int index,double amp); - int valindex; - double amplitude; - + + double period; + double output; + double startval; + double currentval; + double nextval; + int isPlaying; + +public: + double line(int numberofsegments,double segments[100]); + void trigger(int index,double amp); + int valindex; + double amplitude; + }; class maxiDelayline { - double frequency; - int phase; - double startphase; - double endphase; - double output; - double memory[88200]; - + double frequency; + int phase; + double startphase; + double endphase; + double output; + double memory[88200]; + public: - maxiDelayline(); - double dl(double input, int size, double feedback); - double dl(double input, int size, double feedback, int position); - - + maxiDelayline(); + double dl(double input, int size, double feedback); + double dl(double input, int size, double feedback, int position); + + }; -class maxiFilter { - double gain; - double input; - double output; - double inputs[10]; - double outputs[10]; - double cutoff1; - double x;//speed - double y;//pos - double z;//pole - double c;//filter coefficient +class maxiFilter { + double gain; + double input; + double output; + double inputs[10]; + double outputs[10]; + double cutoff1; + double x;//speed + double y;//pos + double z;//pole + double c;//filter coefficient public: - maxiFilter():x(0.0), y(0.0), z(0.0), c(0.0){}; - double cutoff; - double resonance; - double lores(double input,double cutoff1, double resonance); - double hires(double input,double cutoff1, double resonance); - double bandpass(double input,double cutoff1, double resonance); - double lopass(double input,double cutoff); - double hipass(double input,double cutoff); - + maxiFilter():x(0.0), y(0.0), z(0.0), c(0.0){}; + double cutoff; + double resonance; + double lores(double input,double cutoff1, double resonance); + double hires(double input,double cutoff1, double resonance); + double bandpass(double input,double cutoff1, double resonance); + double lopass(double input,double cutoff); + double hipass(double input,double cutoff); + }; class maxiMix { - double input; - double two[2]; - double four[4]; - double eight[8]; + double input; + double two[2]; + double four[4]; + double eight[8]; public: - double x; - double y; - double z; - double *stereo(double input,double two[2],double x); - double *quad(double input,double four[4], double x,double y); - double *ambisonic(double input,double eight[8],double x,double y, double z); - + double x; + double y; + double z; + double *stereo(double input,double two[2],double x); + double *quad(double input,double four[4], double x,double y); + double *ambisonic(double input,double eight[8],double x,double y, double z); + }; //lagging with an exponential moving average //a lower alpha value gives a slower lag -template <class T> +template <class T> class maxiLagExp { public: - T alpha, alphaReciprocal; - T val; - - maxiLagExp() { - init(0.5, 0.0); - }; - - maxiLagExp(T initAlpha, T initVal) { - init(initAlpha, initVal); - } - - void init(T initAlpha, T initVal) { - alpha = initAlpha; - alphaReciprocal = 1.0 - alpha; - val = initVal; - } - - inline void addSample(T newVal) { - val = (alpha * newVal) + (alphaReciprocal * val); - } - - inline T value() { - return val; - } + T alpha, alphaReciprocal; + T val; + + maxiLagExp() { + init(0.5, 0.0); + }; + + maxiLagExp(T initAlpha, T initVal) { + init(initAlpha, initVal); + } + + void init(T initAlpha, T initVal) { + alpha = initAlpha; + alphaReciprocal = 1.0 - alpha; + val = initVal; + } + + inline void addSample(T newVal) { + val = (alpha * newVal) + (alphaReciprocal * val); + } + + inline T value() { + return val; + } }; class maxiSample { - + private: - string myPath; - int myChunkSize; - int mySubChunk1Size; - int readChannel; - short myFormat; - int myByteRate; - short myBlockAlign; - double position, recordPosition; - double speed; - double output; + string myPath; + int myChunkSize; + int mySubChunk1Size; + int readChannel; + short myFormat; + int myByteRate; + short myBlockAlign; + double position, recordPosition; + double speed; + double output; maxiLagExp<double> loopRecordLag; - + public: - int myDataSize; - short myChannels; - int mySampleRate; - long length; - void getLength(); - void setLength(unsigned long numSamples); + int myDataSize; + short myChannels; + int mySampleRate; + long length; + long getLength(); + void setLength(unsigned long numSamples); short myBitsPerSample; - - - // char* myData; + + +// char* myData; short* temp; - - // get/set for the Path property - - ~maxiSample() - { - // if (myData) free(myData); + + // get/set for the Path property + + ~maxiSample() + { +// if (myData) free(myData); if (temp) free(temp); printf("freeing SampleData"); - - } - + + } + maxiSample():temp(NULL),position(0), recordPosition(0), myChannels(1), mySampleRate(maxiSettings::sampleRate) {}; maxiSample& operator=(const maxiSample &source) { @@ -255,17 +267,17 @@ public: length = source.length; return *this; } - - bool load(string fileName, int channel=0); + + bool load(string fileName, int channel=0); bool loadOgg(string filename,int channel=0); - - void trigger(); - - // read a wav file into this class - bool read(); - - //read an ogg file into this class using stb_vorbis + + void trigger(); + + // read a wav file into this class + bool read(); + + //read an ogg file into this class using stb_vorbis bool readOgg(); void loopRecord(double newSample, const bool recordEnabled, const double recordMix, double start = 0.0, double end = 1.0) { @@ -317,8 +329,8 @@ public: return save(myPath); } - bool save(string filename) - { + bool save(string filename) + { fstream myFile (filename.c_str(), ios::out | ios::binary); // write the wav file per the wav file format @@ -339,16 +351,16 @@ public: myFile.write ((char*) temp, myDataSize); return true; - } - - // return a printable summary of the wav file - char *getSummary() - { - char *summary = new char[250]; - sprintf(summary, " Format: %d\n Channels: %d\n SampleRate: %d\n ByteRate: %d\n BlockAlign: %d\n BitsPerSample: %d\n DataSize: %d\n", myFormat, myChannels, mySampleRate, myByteRate, myBlockAlign, myBitsPerSample, myDataSize); - std::cout << myDataSize; - return summary; - } + } + + // return a printable summary of the wav file + char *getSummary() + { + char *summary = new char[250]; + sprintf(summary, " Format: %d\n Channels: %d\n SampleRate: %d\n ByteRate: %d\n BlockAlign: %d\n BitsPerSample: %d\n DataSize: %d\n", myFormat, myChannels, mySampleRate, myByteRate, myBlockAlign, myBitsPerSample, myDataSize); + std::cout << myDataSize; + return summary; + } void normalise(float maxLevel = 0.99); //0 < maxLevel < 1.0 void autoTrim(float alpha = 0.3, float threshold = 6000, bool trimStart = true, bool trimEnd = true); //alpha of lag filter (lower == slower reaction), threshold to mark start and end, < 32767 @@ -384,63 +396,63 @@ public: } return v; } - + }; class maxiDyn { - - + + public: - // double gate(double input, double threshold=0.9, long holdtime=1, double attack=1, double release=0.9995); - // double compressor(double input, double ratio, double threshold=0.9, double attack=1, double release=0.9995); +// double gate(double input, double threshold=0.9, long holdtime=1, double attack=1, double release=0.9995); +// double compressor(double input, double ratio, double threshold=0.9, double attack=1, double release=0.9995); double gate(double input, double threshold=0.9, long holdtime=1, double attack=1, double release=0.9995); double compressor(double input, double ratio, double threshold=0.9, double attack=1, double release=0.9995); double compress(double input); double input; - double ratio; - double currentRatio; - double threshold; - double output; - double attack; - double release; - double amplitude; + double ratio; + double currentRatio; + double threshold; + double output; + double attack; + double release; + double amplitude; void setAttack(double attackMS); void setRelease(double releaseMS); void setThreshold(double thresholdI); void setRatio(double ratioF); - long holdtime; - long holdcount; - int attackphase,holdphase,releasephase; + long holdtime; + long holdcount; + int attackphase,holdphase,releasephase; }; class maxiEnv { - - + + public: - double ar(double input, double attack=1, double release=0.9, long holdtime=1, int trigger=0); - double adsr(double input, double attack=1, double decay=0.99, double sustain=0.125, double release=0.9, long holdtime=1, int trigger=0); + double ar(double input, double attack=1, double release=0.9, long holdtime=1, int trigger=0); + double adsr(double input, double attack=1, double decay=0.99, double sustain=0.125, double release=0.9, long holdtime=1, int trigger=0); double adsr(double input,int trigger); - double input; - double output; - double attack; - double decay; - double sustain; - double release; - double amplitude; + double input; + double output; + double attack; + double decay; + double sustain; + double release; + double amplitude; void setAttack(double attackMS); void setRelease(double releaseMS); void setDecay(double decayMS); void setSustain(double sustainL); - int trigger; - long holdtime=1; - long holdcount; - int attackphase,decayphase,sustainphase,holdphase,releasephase; + int trigger; + long holdtime=1; + long holdcount; + int attackphase,decayphase,sustainphase,holdphase,releasephase; }; class convert { public: - double mtof(int midinote); + double mtof(int midinote); }; @@ -481,7 +493,7 @@ public: double flange(const double input, const unsigned int delay, const double feedback, const double speed, const double depth); maxiDelayline dl; maxiOsc lfo; - + }; inline double maxiFlanger::flange(const double input, const unsigned int delay, const double feedback, const double speed, const double depth) @@ -489,7 +501,7 @@ inline double maxiFlanger::flange(const double input, const unsigned int delay, //todo: needs fixing double output; double lfoVal = lfo.triangle(speed); - output = dl.dl(input, delay + (lfoVal * depth * delay) + 1, feedback) ; + output = dl.dl(input, delay + (lfoVal * depth * delay) + 1, feedback) ; double normalise = (1 - fabs(output)); output *= normalise; return (output + input) / 2.0; @@ -514,8 +526,8 @@ inline double maxiChorus::chorus(const double input, const unsigned int delay, c double output1, output2; double lfoVal = lfo.noise(); lfoVal = lopass.lores(lfoVal, speed, 1.0) * 2.0; - output1 = dl.dl(input, delay + (lfoVal * depth * delay) + 1, feedback) ; - output2 = dl2.dl(input, (delay + (lfoVal * depth * delay * 1.02) + 1) * 0.98, feedback * 0.99) ; + output1 = dl.dl(input, delay + (lfoVal * depth * delay) + 1, feedback) ; + output2 = dl2.dl(input, (delay + (lfoVal * depth * delay * 1.02) + 1) * 0.98, feedback * 0.99) ; output1 *= (1.0 - fabs(output1)); output2 *= (1.0 - fabs(output2)); return (output1 + output2 + input) / 3.0; @@ -796,5 +808,49 @@ public: }; +class maxiRecorder +{ +public: + maxiRecorder(); + ~maxiRecorder(); + + void setup(std::string _filename); + void startRecording(); + void stopRecording(); + bool isRecording() const; + void passData(double* _in, int _inBufferSize); + void passData(float* _in, int _inBufferSize); + void saveToWav(); + +private: + template <typename T> + void write(std::ofstream& _stream, const T& _t); + void* update(void* _context); + std::vector<double> getProcessedData(); + void enqueueBuffer(); + void freeResources(); + bool threadRunning; + const int bufferQueueSize; + const int bufferSize; + long int bufferIndex; + long int recordedAmountFrames; + std::queue<double*> bufferQueue; + std::queue<double*> savedBuffers; + bool doRecord; + std::string filename; +#if defined(OS_IS_UNIX) + pthread_t daemon; + static void* update_pthread_helper(void* _context) +#elif defined(OS_IS_WIN) + HANDLE daemonHandle; + static unsigned __stdcall + update_pthread_helper(void* _context) +#endif + { + maxiRecorder* _this = static_cast<maxiRecorder*>(_context); + _this->update(_this); + return 0; + } +}; #endif diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/Makefile b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/Makefile new file mode 100644 index 0000000..8d8e4c0 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/Makefile @@ -0,0 +1,13 @@ +# Attempt to load a config.make file. +# If none is found, project defaults in config.project.make will be used. +ifneq ($(wildcard config.make),) + include config.make +endif + +# make sure the the OF_ROOT location is defined +ifndef OF_ROOT + OF_ROOT=$(realpath ../../..) +endif + +# call the project makefile! +include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/Project.xcconfig b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/Project.xcconfig new file mode 100644 index 0000000..e570b15 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/Project.xcconfig @@ -0,0 +1,17 @@ +//THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT. +//THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED +OF_PATH = ../../.. + +//THIS HAS ALL THE HEADER AND LIBS FOR OF CORE +#include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig" + +//ICONS - NEW IN 0072 +ICON_NAME_DEBUG = icon-debug.icns +ICON_NAME_RELEASE = icon.icns +ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/ + +//IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to: +//ICON_FILE_PATH = bin/data/ + +OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS) +HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS) diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/addons.make b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/addons.make new file mode 100644 index 0000000..328952e --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/addons.make @@ -0,0 +1,2 @@ +ofxMaxim +ofxOsc diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/.gitkeep b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/.gitkeep diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/24620__anamorphosis__GMB_Kantilan_1.wav b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/24620__anamorphosis__GMB_Kantilan_1.wav Binary files differnew file mode 100755 index 0000000..81666d1 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/24620__anamorphosis__GMB_Kantilan_1.wav diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/2630__Jovica__133_bpm_ATTACK_LOOP_04_electrified_analog_kit_variation_16_mono.wav b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/2630__Jovica__133_bpm_ATTACK_LOOP_04_electrified_analog_kit_variation_16_mono.wav Binary files differnew file mode 100755 index 0000000..490d9ea --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/2630__Jovica__133_bpm_ATTACK_LOOP_04_electrified_analog_kit_variation_16_mono.wav diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/26393__brfindla__Calango1berimbau.wav b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/26393__brfindla__Calango1berimbau.wav Binary files differnew file mode 100755 index 0000000..a9c93a4 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/26393__brfindla__Calango1berimbau.wav diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/59210__suonho__abstract_electrofunkbreakbeats_124bpm_mono.wav b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/59210__suonho__abstract_electrofunkbreakbeats_124bpm_mono.wav Binary files differnew file mode 100755 index 0000000..b23c5f0 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/59210__suonho__abstract_electrofunkbreakbeats_124bpm_mono.wav diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/68373__juskiddink__Cello_open_string_bowed.wav b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/68373__juskiddink__Cello_open_string_bowed.wav Binary files differnew file mode 100755 index 0000000..19064f2 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/68373__juskiddink__Cello_open_string_bowed.wav diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/71515__Microscopia__Wilhelm_Bruder_Sohne_Organ.wav b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/71515__Microscopia__Wilhelm_Bruder_Sohne_Organ.wav Binary files differnew file mode 100755 index 0000000..98860be --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/71515__Microscopia__Wilhelm_Bruder_Sohne_Organ.wav diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/beat2.wav b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/beat2.wav Binary files differnew file mode 100755 index 0000000..c71cee6 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/bin/data/beat2.wav diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/config.make b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/config.make new file mode 100644 index 0000000..df10f64 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/config.make @@ -0,0 +1,142 @@ +################################################################################ +# CONFIGURE PROJECT MAKEFILE (optional) +# This file is where we make project specific configurations. +################################################################################ + +################################################################################ +# OF ROOT +# The location of your root openFrameworks installation +# (default) OF_ROOT = ../../.. +################################################################################ +# OF_ROOT = ../../.. + +################################################################################ +# PROJECT ROOT +# The location of the project - a starting place for searching for files +# (default) PROJECT_ROOT = . (this directory) +# +################################################################################ +# PROJECT_ROOT = . + +################################################################################ +# PROJECT SPECIFIC CHECKS +# This is a project defined section to create internal makefile flags to +# conditionally enable or disable the addition of various features within +# this makefile. For instance, if you want to make changes based on whether +# GTK is installed, one might test that here and create a variable to check. +################################################################################ +# None + +################################################################################ +# PROJECT EXTERNAL SOURCE PATHS +# These are fully qualified paths that are not within the PROJECT_ROOT folder. +# Like source folders in the PROJECT_ROOT, these paths are subject to +# exlclusion via the PROJECT_EXLCUSIONS list. +# +# (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_EXTERNAL_SOURCE_PATHS = + +################################################################################ +# PROJECT EXCLUSIONS +# These makefiles assume that all folders in your current project directory +# and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations +# to look for source code. The any folders or files that match any of the +# items in the PROJECT_EXCLUSIONS list below will be ignored. +# +# Each item in the PROJECT_EXCLUSIONS list will be treated as a complete +# string unless teh user adds a wildcard (%) operator to match subdirectories. +# GNU make only allows one wildcard for matching. The second wildcard (%) is +# treated literally. +# +# (default) PROJECT_EXCLUSIONS = (blank) +# +# Will automatically exclude the following: +# +# $(PROJECT_ROOT)/bin% +# $(PROJECT_ROOT)/obj% +# $(PROJECT_ROOT)/%.xcodeproj +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_EXCLUSIONS = + +################################################################################ +# PROJECT LINKER FLAGS +# These flags will be sent to the linker when compiling the executable. +# +# (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +# Currently, shared libraries that are needed are copied to the +# $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to +# add a runtime path to search for those shared libraries, since they aren't +# incorporated directly into the final executable application binary. +# TODO: should this be a default setting? +# PROJECT_LDFLAGS=-Wl,-rpath=./libs + +################################################################################ +# PROJECT DEFINES +# Create a space-delimited list of DEFINES. The list will be converted into +# CFLAGS with the "-D" flag later in the makefile. +# +# (default) PROJECT_DEFINES = (blank) +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_DEFINES = + +################################################################################ +# PROJECT CFLAGS +# This is a list of fully qualified CFLAGS required when compiling for this +# project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS +# defined in your platform specific core configuration files. These flags are +# presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. +# +# (default) PROJECT_CFLAGS = (blank) +# +# Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in +# your platform specific configuration file will be applied by default and +# further flags here may not be needed. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_CFLAGS = + +################################################################################ +# PROJECT OPTIMIZATION CFLAGS +# These are lists of CFLAGS that are target-specific. While any flags could +# be conditionally added, they are usually limited to optimization flags. +# These flags are added BEFORE the PROJECT_CFLAGS. +# +# PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. +# +# (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) +# +# PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. +# +# (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) +# +# Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the +# PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration +# file will be applied by default and further optimization flags here may not +# be needed. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_OPTIMIZATION_CFLAGS_RELEASE = +# PROJECT_OPTIMIZATION_CFLAGS_DEBUG = + +################################################################################ +# PROJECT COMPILERS +# Custom compilers can be set for CC and CXX +# (default) PROJECT_CXX = (blank) +# (default) PROJECT_CC = (blank) +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_CXX = +# PROJECT_CC = diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/project.pbxproj b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/project.pbxproj new file mode 100644 index 0000000..755dcd2 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/project.pbxproj @@ -0,0 +1,1904 @@ +<?xml version="1.0"?> +<plist version="1.0"> + <dict> + <key>archiveVersion</key> + <string>1</string> + <key>classes</key> + <dict /> + <key>objectVersion</key> + <string>46</string> + <key>objects</key> + <dict> + <key>C6937888E126BADC8777423B</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscTypes.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscTypes.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>879A251454401BC0B6E4F238</key> + <dict> + <key>fileRef</key> + <string>D9BFFBBF4CC43DEE890B3C3E</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>D9BFFBBF4CC43DEE890B3C3E</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscTypes.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscTypes.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>20F35AFADAF0068B067E713F</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscReceivedElements.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscReceivedElements.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>0546D1A38E13BD319CC9755B</key> + <dict> + <key>fileRef</key> + <string>9BF3AA0D4FAA89D0F8A0E545</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>9BF3AA0D4FAA89D0F8A0E545</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscReceivedElements.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscReceivedElements.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>4E95FB446A9C9C6F0DE12D75</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscPrintReceivedElements.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscPrintReceivedElements.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>C4782ECC372420ACE0615B74</key> + <dict> + <key>fileRef</key> + <string>BC8881B3C8C0A1C45F042E7A</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>BC8881B3C8C0A1C45F042E7A</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscPrintReceivedElements.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscPrintReceivedElements.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>6B65E6930994CC4B2D2B8B33</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscPacketListener.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscPacketListener.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>029684CF678F70F6D3537A29</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscOutboundPacketStream.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscOutboundPacketStream.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>62545D179C94265CA1389D4A</key> + <dict> + <key>fileRef</key> + <string>63A47AC60FFAFC3BF093EC0F</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>63A47AC60FFAFC3BF093EC0F</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscOutboundPacketStream.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscOutboundPacketStream.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>A2AAA8CA403479E6FCDF920E</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscHostEndianness.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscHostEndianness.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>F4F5B6B8BA2BD52C646ED908</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>OscException.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/OscException.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>30CB364908817057B430D528</key> + <dict> + <key>children</key> + <array> + <string>AE335EB4709BFD4671EEAC84</string> + <string>F4F5B6B8BA2BD52C646ED908</string> + <string>A2AAA8CA403479E6FCDF920E</string> + <string>63A47AC60FFAFC3BF093EC0F</string> + <string>029684CF678F70F6D3537A29</string> + <string>6B65E6930994CC4B2D2B8B33</string> + <string>BC8881B3C8C0A1C45F042E7A</string> + <string>4E95FB446A9C9C6F0DE12D75</string> + <string>9BF3AA0D4FAA89D0F8A0E545</string> + <string>20F35AFADAF0068B067E713F</string> + <string>D9BFFBBF4CC43DEE890B3C3E</string> + <string>C6937888E126BADC8777423B</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>osc</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>AE335EB4709BFD4671EEAC84</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>MessageMappingOscPacketListener.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc/MessageMappingOscPacketListener.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>2FD4B0329909D3527F003494</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>UdpSocket.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/UdpSocket.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>444657A12E59D0ED86981498</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>TimerListener.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/TimerListener.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>510CAFE035E576A4E1502D52</key> + <dict> + <key>fileRef</key> + <string>E6DEF695B88BA5FAACEAA937</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>E6DEF695B88BA5FAACEAA937</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>UdpSocket.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/posix/UdpSocket.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>641362CA659FAFEE4E81001B</key> + <dict> + <key>children</key> + <array> + <string>3B361208CD4107E479F04E7B</string> + <string>E6DEF695B88BA5FAACEAA937</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>posix</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>67FE4C7B15C2F0478C8126C2</key> + <dict> + <key>fileRef</key> + <string>3B361208CD4107E479F04E7B</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>3B361208CD4107E479F04E7B</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>NetworkingUtils.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/posix/NetworkingUtils.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>23640F57DF6C4BB6BFC5DA4C</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>PacketListener.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/PacketListener.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>F7FBC56859535E597B24BB91</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>NetworkingUtils.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/NetworkingUtils.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>48974F980F51769171D0B2F5</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>IpEndpointName.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/IpEndpointName.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>FF8CDF57858E9B94E3237115</key> + <dict> + <key>children</key> + <array> + <string>ADD194746185E2DA11468377</string> + <string>48974F980F51769171D0B2F5</string> + <string>F7FBC56859535E597B24BB91</string> + <string>23640F57DF6C4BB6BFC5DA4C</string> + <string>641362CA659FAFEE4E81001B</string> + <string>444657A12E59D0ED86981498</string> + <string>2FD4B0329909D3527F003494</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>ip</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>D27B2221A225CA523C019676</key> + <dict> + <key>children</key> + <array> + <string>FF8CDF57858E9B94E3237115</string> + <string>30CB364908817057B430D528</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>src</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>86D2677079A3AF4A5A88E29A</key> + <dict> + <key>children</key> + <array> + <string>D27B2221A225CA523C019676</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>oscpack</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>38871A5825686AE018EC2BF0</key> + <dict> + <key>children</key> + <array> + <string>86D2677079A3AF4A5A88E29A</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>libs</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>ADE367465D2A8EBAD4C7A8D9</key> + <dict> + <key>fileRef</key> + <string>ADD194746185E2DA11468377</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>ADD194746185E2DA11468377</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>IpEndpointName.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/IpEndpointName.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>9F7986DC4EB05E75FCE2C777</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscSender.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscSender.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>8F5205AEF8861EF234F0651A</key> + <dict> + <key>fileRef</key> + <string>81967292BFC87A0144BD32C6</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>81967292BFC87A0144BD32C6</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscSender.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscSender.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>8C75AFC8774A62495DD53464</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscReceiver.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscReceiver.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>640279EE111671BD026CB013</key> + <dict> + <key>fileRef</key> + <string>C2FAC65C491D4231379F3298</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>C2FAC65C491D4231379F3298</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscReceiver.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscReceiver.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>B31C608870ECEB2490A93736</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscParameterSync.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscParameterSync.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>4ADB88E2FB52E76A471065DE</key> + <dict> + <key>fileRef</key> + <string>0AED834CE4DEC5260AF302A2</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>0AED834CE4DEC5260AF302A2</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscParameterSync.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscParameterSync.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>C58862C6D212C8E8A83810F4</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscMessage.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscMessage.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>5864AD82E20F15536D054EA3</key> + <dict> + <key>fileRef</key> + <string>DF49D76C45D5DB505A234880</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>DF49D76C45D5DB505A234880</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscMessage.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscMessage.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>8B30E93FD3D3475EED522A0E</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscBundle.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscBundle.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>72A929D3561B8232A182ABFC</key> + <dict> + <key>fileRef</key> + <string>65EEFA3DA3526E9CDD9C21F9</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>65EEFA3DA3526E9CDD9C21F9</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscBundle.cpp</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscBundle.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>7689F8A0F3D0B7635A8C3104</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOscArg.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOscArg.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>BD2F1A9F8D0C05EDB29122D0</key> + <dict> + <key>children</key> + <array> + <string>00D6D32B84B099226431108C</string> + <string>7689F8A0F3D0B7635A8C3104</string> + <string>65EEFA3DA3526E9CDD9C21F9</string> + <string>8B30E93FD3D3475EED522A0E</string> + <string>DF49D76C45D5DB505A234880</string> + <string>C58862C6D212C8E8A83810F4</string> + <string>0AED834CE4DEC5260AF302A2</string> + <string>B31C608870ECEB2490A93736</string> + <string>C2FAC65C491D4231379F3298</string> + <string>8C75AFC8774A62495DD53464</string> + <string>81967292BFC87A0144BD32C6</string> + <string>9F7986DC4EB05E75FCE2C777</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>src</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>E6053AB7FEC63D5F83825B88</key> + <dict> + <key>children</key> + <array> + <string>BD2F1A9F8D0C05EDB29122D0</string> + <string>38871A5825686AE018EC2BF0</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>ofxOsc</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>00D6D32B84B099226431108C</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxOsc.h</string> + <key>path</key> + <string>../../../addons/ofxOsc/src/ofxOsc.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>B2F326FA07783558EF3CDD2A</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>stb_vorbis.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/stb_vorbis.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>9514C2D90467055B1447D074</key> + <dict> + <key>fileRef</key> + <string>80CD68E0DDF2C60D2715CC78</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>80CD68E0DDF2C60D2715CC78</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.c</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>stb_vorbis.c</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/stb_vorbis.c</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>B34D3539DB6F889A78540F7C</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>sineTable.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/sineTable.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>95C3AC11BE0AC7EC464D2A36</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maximilian.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maximilian.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>22F21CE3B902225374BA1CA2</key> + <dict> + <key>fileRef</key> + <string>87D3A0051CCB2C0F0ECA139E</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>87D3A0051CCB2C0F0ECA139E</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maximilian.cpp</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maximilian.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>D1C864AE2FE539BE7FD1F628</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiMFCC.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiMFCC.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>083FB2094A4DE99F5A60397A</key> + <dict> + <key>fileRef</key> + <string>440B2B891BD019685EF360B8</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>440B2B891BD019685EF360B8</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiMFCC.cpp</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiMFCC.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>4CFB659E40D3D3DC5A3E9478</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiGrains.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiGrains.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>AF0580829426DC6BCA135A5C</key> + <dict> + <key>fileRef</key> + <string>9D2FB19B70632A6F86622D94</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>9D2FB19B70632A6F86622D94</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiGrains.cpp</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiGrains.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>EFA729F2F65D97F65DB52E44</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiFFT.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiFFT.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>96084990AF216648B8B98E00</key> + <dict> + <key>fileRef</key> + <string>6A4EE0E35ED739A31CD0153E</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>6A4EE0E35ED739A31CD0153E</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiFFT.cpp</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiFFT.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>A67372B9CAED43269F8D42D3</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiBark.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiBark.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>ABA8875AF0C06690CC0B92B1</key> + <dict> + <key>fileRef</key> + <string>9B9936002B519C1290F25FEC</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>9B9936002B519C1290F25FEC</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiBark.cpp</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiBark.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>7D2CBAA6529BCE46CA661E02</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiAtoms.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiAtoms.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>5C4A4AA5D4784DF23EA43038</key> + <dict> + <key>fileRef</key> + <string>1EFA3ACBB8D16CC0DA1E79C6</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>1EFA3ACBB8D16CC0DA1E79C6</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>maxiAtoms.cpp</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/maxiAtoms.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>BA5114869056DFF1A50CFA4A</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>fft.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/fft.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>4ACC32F17B7623DA048865D1</key> + <dict> + <key>children</key> + <array> + <string>F3C78E7AB53E01022E9374A3</string> + <string>BA5114869056DFF1A50CFA4A</string> + <string>1EFA3ACBB8D16CC0DA1E79C6</string> + <string>7D2CBAA6529BCE46CA661E02</string> + <string>9B9936002B519C1290F25FEC</string> + <string>A67372B9CAED43269F8D42D3</string> + <string>6A4EE0E35ED739A31CD0153E</string> + <string>EFA729F2F65D97F65DB52E44</string> + <string>9D2FB19B70632A6F86622D94</string> + <string>4CFB659E40D3D3DC5A3E9478</string> + <string>440B2B891BD019685EF360B8</string> + <string>D1C864AE2FE539BE7FD1F628</string> + <string>87D3A0051CCB2C0F0ECA139E</string> + <string>95C3AC11BE0AC7EC464D2A36</string> + <string>B34D3539DB6F889A78540F7C</string> + <string>80CD68E0DDF2C60D2715CC78</string> + <string>B2F326FA07783558EF3CDD2A</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>libs</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>0FCED26D40D46CF89A58E54C</key> + <dict> + <key>fileRef</key> + <string>F3C78E7AB53E01022E9374A3</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>F3C78E7AB53E01022E9374A3</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>fft.cpp</string> + <key>path</key> + <string>../../../addons/ofxMaxim/libs/fft.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>8F6BFB59AB6D0A458C2F3C53</key> + <dict> + <key>children</key> + <array> + <string>9312F3864ED05FC3E847FF69</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>src</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>6234D3BCE87D1C3BA2230F19</key> + <dict> + <key>children</key> + <array> + <string>8F6BFB59AB6D0A458C2F3C53</string> + <string>4ACC32F17B7623DA048865D1</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>ofxMaxim</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>9312F3864ED05FC3E847FF69</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.c.h</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofxMaxim.h</string> + <key>path</key> + <string>../../../addons/ofxMaxim/src/ofxMaxim.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>6948EE371B920CB800B5AC1A</key> + <dict> + <key>children</key> + <array /> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>local_addons</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>8466F1851C04CA0E00918B1C</key> + <dict> + <key>buildActionMask</key> + <string>12</string> + <key>files</key> + <array /> + <key>inputPaths</key> + <array /> + <key>isa</key> + <string>PBXShellScriptBuildPhase</string> + <key>outputPaths</key> + <array /> + <key>runOnlyForDeploymentPostprocessing</key> + <string>0</string> + <key>shellPath</key> + <string>/bin/sh</string> + <key>shellScript</key> + <string># ---- Code Sign App Package ---- + +# WARNING: You may have to run Clean in Xcode after changing CODE_SIGN_IDENTITY! + +# Verify that $CODE_SIGN_IDENTITY is set +if [ -z "${CODE_SIGN_IDENTITY}" ] ; then +echo "CODE_SIGN_IDENTITY needs to be set for framework code-signing" +exit 0 +fi + +if [ -z "${CODE_SIGN_ENTITLEMENTS}" ] ; then +echo "CODE_SIGN_ENTITLEMENTS needs to be set for framework code-signing!" + +if [ "${CONFIGURATION}" = "Release" ] ; then +exit 1 +else +# Code-signing is optional for non-release builds. +exit 0 +fi +fi + +ITEMS="" + +FRAMEWORKS_DIR="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +echo "$FRAMEWORKS_DIR" +if [ -d "$FRAMEWORKS_DIR" ] ; then +FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle" | sed -e "s/\(.*framework\)/\1\/Versions\/A\//") +RESULT=$? +if [[ $RESULT != 0 ]] ; then +exit 1 +fi + +ITEMS="${FRAMEWORKS}" +fi + +LOGINITEMS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems/" +if [ -d "$LOGINITEMS_DIR" ] ; then +LOGINITEMS=$(find "${LOGINITEMS_DIR}" -depth -type d -name "*.app") +RESULT=$? +if [[ $RESULT != 0 ]] ; then +exit 1 +fi + +ITEMS="${ITEMS}"$'\n'"${LOGINITEMS}" +fi + +# Prefer the expanded name, if available. +CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}" +if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then +# Fall back to old behavior. +CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}" +fi + +echo "Identity:" +echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}" + +echo "Entitlements:" +echo "${CODE_SIGN_ENTITLEMENTS}" + +echo "Found:" +echo "${ITEMS}" + +# Change the Internal Field Separator (IFS) so that spaces in paths will not cause problems below. +SAVED_IFS=$IFS +IFS=$(echo -en "\n\b") + +# Loop through all items. +for ITEM in $ITEMS; +do +echo "Signing '${ITEM}'" +codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" --entitlements "${CODE_SIGN_ENTITLEMENTS}" "${ITEM}" +RESULT=$? +if [[ $RESULT != 0 ]] ; then +echo "Failed to sign '${ITEM}'." +IFS=$SAVED_IFS +exit 1 +fi +done + +# Restore $IFS. +IFS=$SAVED_IFS +</string> + </dict> + <key>BB4B014C10F69532006C3DED</key> + <dict> + <key>children</key> + <array> + <string>6234D3BCE87D1C3BA2230F19</string> + <string>E6053AB7FEC63D5F83825B88</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>addons</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>E4328143138ABC890047C5CB</key> + <dict> + <key>isa</key> + <string>PBXFileReference</string> + <key>lastKnownFileType</key> + <string>wrapper.pb-project</string> + <key>name</key> + <string>openFrameworksLib.xcodeproj</string> + <key>path</key> + <string>../../../libs/openFrameworksCompiled/project/osx/openFrameworksLib.xcodeproj</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>E4328144138ABC890047C5CB</key> + <dict> + <key>children</key> + <array> + <string>E4328148138ABC890047C5CB</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>Products</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>E4328147138ABC890047C5CB</key> + <dict> + <key>containerPortal</key> + <string>E4328143138ABC890047C5CB</string> + <key>isa</key> + <string>PBXContainerItemProxy</string> + <key>proxyType</key> + <string>2</string> + <key>remoteGlobalIDString</key> + <string>E4B27C1510CBEB8E00536013</string> + <key>remoteInfo</key> + <string>openFrameworks</string> + </dict> + <key>E4328148138ABC890047C5CB</key> + <dict> + <key>fileType</key> + <string>archive.ar</string> + <key>isa</key> + <string>PBXReferenceProxy</string> + <key>path</key> + <string>openFrameworksDebug.a</string> + <key>remoteRef</key> + <string>E4328147138ABC890047C5CB</string> + <key>sourceTree</key> + <string>BUILT_PRODUCTS_DIR</string> + </dict> + <key>E4328149138ABC9F0047C5CB</key> + <dict> + <key>fileRef</key> + <string>E4328148138ABC890047C5CB</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>E4B69B4A0A3A1720003C02F2</key> + <dict> + <key>children</key> + <array> + <string>E4B6FCAD0C3E899E008CF71C</string> + <string>E4EB6923138AFD0F00A09F29</string> + <string>E4B69E1C0A3A1BDC003C02F2</string> + <string>E4EEC9E9138DF44700A80321</string> + <string>BB4B014C10F69532006C3DED</string> + <string>6948EE371B920CB800B5AC1A</string> + <string>E4B69B5B0A3A1756003C02F2</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>E4B69B4C0A3A1720003C02F2</key> + <dict> + <key>attributes</key> + <dict> + <key>LastUpgradeCheck</key> + <string>0600</string> + </dict> + <key>buildConfigurationList</key> + <string>E4B69B4D0A3A1720003C02F2</string> + <key>compatibilityVersion</key> + <string>Xcode 3.2</string> + <key>developmentRegion</key> + <string>English</string> + <key>hasScannedForEncodings</key> + <string>0</string> + <key>isa</key> + <string>PBXProject</string> + <key>knownRegions</key> + <array> + <string>English</string> + <string>Japanese</string> + <string>French</string> + <string>German</string> + </array> + <key>mainGroup</key> + <string>E4B69B4A0A3A1720003C02F2</string> + <key>productRefGroup</key> + <string>E4B69B4A0A3A1720003C02F2</string> + <key>projectDirPath</key> + <string /> + <key>projectReferences</key> + <array> + <dict> + <key>ProductGroup</key> + <string>E4328144138ABC890047C5CB</string> + <key>ProjectRef</key> + <string>E4328143138ABC890047C5CB</string> + </dict> + </array> + <key>projectRoot</key> + <string /> + <key>targets</key> + <array> + <string>E4B69B5A0A3A1756003C02F2</string> + </array> + </dict> + <key>E4B69B4D0A3A1720003C02F2</key> + <dict> + <key>buildConfigurations</key> + <array> + <string>E4B69B4E0A3A1720003C02F2</string> + <string>E4B69B4F0A3A1720003C02F2</string> + </array> + <key>defaultConfigurationIsVisible</key> + <string>0</string> + <key>defaultConfigurationName</key> + <string>Release</string> + <key>isa</key> + <string>XCConfigurationList</string> + </dict> + <key>E4B69B4E0A3A1720003C02F2</key> + <dict> + <key>baseConfigurationReference</key> + <string>E4EB6923138AFD0F00A09F29</string> + <key>buildSettings</key> + <dict> + <key>HEADER_SEARCH_PATHS</key> + <array> + <string>$(OF_CORE_HEADERS)</string> + <string>../../../addons/ofxMaxim/libs</string> + <string>../../../addons/ofxMaxim/src</string> + <string>../../../addons/ofxOsc/libs</string> + <string>../../../addons/ofxOsc/libs/oscpack</string> + <string>../../../addons/ofxOsc/libs/oscpack/src</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/posix</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/win32</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc</string> + <string>../../../addons/ofxOsc/src</string> + </array> + <key>CONFIGURATION_BUILD_DIR</key> + <string>$(SRCROOT)/bin/</string> + <key>COPY_PHASE_STRIP</key> + <string>NO</string> + <key>DEAD_CODE_STRIPPING</key> + <string>YES</string> + <key>GCC_AUTO_VECTORIZATION</key> + <string>YES</string> + <key>GCC_ENABLE_SSE3_EXTENSIONS</key> + <string>YES</string> + <key>GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS</key> + <string>YES</string> + <key>GCC_INLINES_ARE_PRIVATE_EXTERN</key> + <string>NO</string> + <key>GCC_OPTIMIZATION_LEVEL</key> + <string>0</string> + <key>GCC_SYMBOLS_PRIVATE_EXTERN</key> + <string>NO</string> + <key>GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS</key> + <string>YES</string> + <key>GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO</key> + <string>NO</string> + <key>GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL</key> + <string>NO</string> + <key>GCC_WARN_UNINITIALIZED_AUTOS</key> + <string>NO</string> + <key>GCC_WARN_UNUSED_VALUE</key> + <string>NO</string> + <key>GCC_WARN_UNUSED_VARIABLE</key> + <string>NO</string> + <key>MACOSX_DEPLOYMENT_TARGET</key> + <string>10.8</string> + <key>ONLY_ACTIVE_ARCH</key> + <string>YES</string> + <key>OTHER_CPLUSPLUSFLAGS</key> + <array> + <string>-D__MACOSX_CORE__</string> + <string>-mtune=native</string> + </array> + <key>SDKROOT</key> + <string>macosx</string> + </dict> + <key>isa</key> + <string>XCBuildConfiguration</string> + <key>name</key> + <string>Debug</string> + </dict> + <key>E4B69B4F0A3A1720003C02F2</key> + <dict> + <key>baseConfigurationReference</key> + <string>E4EB6923138AFD0F00A09F29</string> + <key>buildSettings</key> + <dict> + <key>HEADER_SEARCH_PATHS</key> + <array> + <string>$(OF_CORE_HEADERS)</string> + <string>../../../addons/ofxMaxim/libs</string> + <string>../../../addons/ofxMaxim/src</string> + <string>../../../addons/ofxOsc/libs</string> + <string>../../../addons/ofxOsc/libs/oscpack</string> + <string>../../../addons/ofxOsc/libs/oscpack/src</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/posix</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/win32</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc</string> + <string>../../../addons/ofxOsc/src</string> + </array> + <key>CONFIGURATION_BUILD_DIR</key> + <string>$(SRCROOT)/bin/</string> + <key>COPY_PHASE_STRIP</key> + <string>YES</string> + <key>DEAD_CODE_STRIPPING</key> + <string>YES</string> + <key>GCC_AUTO_VECTORIZATION</key> + <string>YES</string> + <key>GCC_ENABLE_SSE3_EXTENSIONS</key> + <string>YES</string> + <key>GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS</key> + <string>YES</string> + <key>GCC_INLINES_ARE_PRIVATE_EXTERN</key> + <string>NO</string> + <key>GCC_OPTIMIZATION_LEVEL</key> + <string>3</string> + <key>GCC_SYMBOLS_PRIVATE_EXTERN</key> + <string>NO</string> + <key>GCC_UNROLL_LOOPS</key> + <string>YES</string> + <key>GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS</key> + <string>YES</string> + <key>GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO</key> + <string>NO</string> + <key>GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL</key> + <string>NO</string> + <key>GCC_WARN_UNINITIALIZED_AUTOS</key> + <string>NO</string> + <key>GCC_WARN_UNUSED_VALUE</key> + <string>NO</string> + <key>GCC_WARN_UNUSED_VARIABLE</key> + <string>NO</string> + <key>MACOSX_DEPLOYMENT_TARGET</key> + <string>10.8</string> + <key>OTHER_CPLUSPLUSFLAGS</key> + <array> + <string>-D__MACOSX_CORE__</string> + <string>-mtune=native</string> + </array> + <key>SDKROOT</key> + <string>macosx</string> + </dict> + <key>isa</key> + <string>XCBuildConfiguration</string> + <key>name</key> + <string>Release</string> + </dict> + <key>E4B69B580A3A1756003C02F2</key> + <dict> + <key>buildActionMask</key> + <string>2147483647</string> + <key>files</key> + <array> + <string>E4B69E200A3A1BDC003C02F2</string> + <string>E4B69E210A3A1BDC003C02F2</string> + <string>0FCED26D40D46CF89A58E54C</string> + <string>5C4A4AA5D4784DF23EA43038</string> + <string>ABA8875AF0C06690CC0B92B1</string> + <string>96084990AF216648B8B98E00</string> + <string>AF0580829426DC6BCA135A5C</string> + <string>083FB2094A4DE99F5A60397A</string> + <string>22F21CE3B902225374BA1CA2</string> + <string>9514C2D90467055B1447D074</string> + <string>72A929D3561B8232A182ABFC</string> + <string>5864AD82E20F15536D054EA3</string> + <string>4ADB88E2FB52E76A471065DE</string> + <string>640279EE111671BD026CB013</string> + <string>8F5205AEF8861EF234F0651A</string> + <string>ADE367465D2A8EBAD4C7A8D9</string> + <string>67FE4C7B15C2F0478C8126C2</string> + <string>510CAFE035E576A4E1502D52</string> + <string>62545D179C94265CA1389D4A</string> + <string>C4782ECC372420ACE0615B74</string> + <string>0546D1A38E13BD319CC9755B</string> + <string>879A251454401BC0B6E4F238</string> + </array> + <key>isa</key> + <string>PBXSourcesBuildPhase</string> + <key>runOnlyForDeploymentPostprocessing</key> + <string>0</string> + </dict> + <key>E4B69B590A3A1756003C02F2</key> + <dict> + <key>buildActionMask</key> + <string>2147483647</string> + <key>files</key> + <array> + <string>E4328149138ABC9F0047C5CB</string> + </array> + <key>isa</key> + <string>PBXFrameworksBuildPhase</string> + <key>runOnlyForDeploymentPostprocessing</key> + <string>0</string> + </dict> + <key>E4B69B5A0A3A1756003C02F2</key> + <dict> + <key>buildConfigurationList</key> + <string>E4B69B5F0A3A1757003C02F2</string> + <key>buildPhases</key> + <array> + <string>E4B69B580A3A1756003C02F2</string> + <string>E4B69B590A3A1756003C02F2</string> + <string>E4B6FFFD0C3F9AB9008CF71C</string> + <string>E4C2427710CC5ABF004149E2</string> + <string>8466F1851C04CA0E00918B1C</string> + </array> + <key>buildRules</key> + <array /> + <key>dependencies</key> + <array> + <string>E4EEB9AC138B136A00A80321</string> + </array> + <key>isa</key> + <string>PBXNativeTarget</string> + <key>name</key> + <string>granular0_92</string> + <key>productName</key> + <string>myOFApp</string> + <key>productReference</key> + <string>E4B69B5B0A3A1756003C02F2</string> + <key>productType</key> + <string>com.apple.product-type.application</string> + </dict> + <key>E4B69B5B0A3A1756003C02F2</key> + <dict> + <key>explicitFileType</key> + <string>wrapper.application</string> + <key>includeInIndex</key> + <string>0</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>path</key> + <string>granular0_92Debug.app</string> + <key>sourceTree</key> + <string>BUILT_PRODUCTS_DIR</string> + </dict> + <key>E4B69B5F0A3A1757003C02F2</key> + <dict> + <key>buildConfigurations</key> + <array> + <string>E4B69B600A3A1757003C02F2</string> + <string>E4B69B610A3A1757003C02F2</string> + </array> + <key>defaultConfigurationIsVisible</key> + <string>0</string> + <key>defaultConfigurationName</key> + <string>Release</string> + <key>isa</key> + <string>XCConfigurationList</string> + </dict> + <key>E4B69B600A3A1757003C02F2</key> + <dict> + <key>baseConfigurationReference</key> + <string>E4EB6923138AFD0F00A09F29</string> + <key>buildSettings</key> + <dict> + <key>HEADER_SEARCH_PATHS</key> + <array> + <string>$(OF_CORE_HEADERS)</string> + <string>../../../addons/ofxMaxim/libs</string> + <string>../../../addons/ofxMaxim/src</string> + <string>../../../addons/ofxOsc/libs</string> + <string>../../../addons/ofxOsc/libs/oscpack</string> + <string>../../../addons/ofxOsc/libs/oscpack/src</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/posix</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/win32</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc</string> + <string>../../../addons/ofxOsc/src</string> + </array> + <key>COMBINE_HIDPI_IMAGES</key> + <string>YES</string> + <key>COPY_PHASE_STRIP</key> + <string>NO</string> + <key>FRAMEWORK_SEARCH_PATHS</key> + <array> + <string>$(inherited)</string> + <string>$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)</string> + </array> + <key>FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1</key> + <string>"$(SRCROOT)/../../../libs/glut/lib/osx"</string> + <key>GCC_DYNAMIC_NO_PIC</key> + <string>NO</string> + <key>GCC_GENERATE_DEBUGGING_SYMBOLS</key> + <string>YES</string> + <key>GCC_MODEL_TUNING</key> + <string>NONE</string> + <key>ICON</key> + <string>$(ICON_NAME_DEBUG)</string> + <key>ICON_FILE</key> + <string>$(ICON_FILE_PATH)$(ICON)</string> + <key>INFOPLIST_FILE</key> + <string>openFrameworks-Info.plist</string> + <key>INSTALL_PATH</key> + <string>/Applications</string> + <key>LIBRARY_SEARCH_PATHS</key> + <string>$(inherited)</string> + <key>PRODUCT_NAME</key> + <string>$(TARGET_NAME)Debug</string> + <key>WRAPPER_EXTENSION</key> + <string>app</string> + </dict> + <key>isa</key> + <string>XCBuildConfiguration</string> + <key>name</key> + <string>Debug</string> + </dict> + <key>E4B69B610A3A1757003C02F2</key> + <dict> + <key>baseConfigurationReference</key> + <string>E4EB6923138AFD0F00A09F29</string> + <key>buildSettings</key> + <dict> + <key>HEADER_SEARCH_PATHS</key> + <array> + <string>$(OF_CORE_HEADERS)</string> + <string>../../../addons/ofxMaxim/libs</string> + <string>../../../addons/ofxMaxim/src</string> + <string>../../../addons/ofxOsc/libs</string> + <string>../../../addons/ofxOsc/libs/oscpack</string> + <string>../../../addons/ofxOsc/libs/oscpack/src</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/posix</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/ip/win32</string> + <string>../../../addons/ofxOsc/libs/oscpack/src/osc</string> + <string>../../../addons/ofxOsc/src</string> + </array> + <key>COMBINE_HIDPI_IMAGES</key> + <string>YES</string> + <key>COPY_PHASE_STRIP</key> + <string>YES</string> + <key>FRAMEWORK_SEARCH_PATHS</key> + <array> + <string>$(inherited)</string> + <string>$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)</string> + </array> + <key>FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1</key> + <string>"$(SRCROOT)/../../../libs/glut/lib/osx"</string> + <key>GCC_GENERATE_DEBUGGING_SYMBOLS</key> + <string>YES</string> + <key>GCC_MODEL_TUNING</key> + <string>NONE</string> + <key>ICON</key> + <string>$(ICON_NAME_RELEASE)</string> + <key>ICON_FILE</key> + <string>$(ICON_FILE_PATH)$(ICON)</string> + <key>INFOPLIST_FILE</key> + <string>openFrameworks-Info.plist</string> + <key>INSTALL_PATH</key> + <string>/Applications</string> + <key>LIBRARY_SEARCH_PATHS</key> + <string>$(inherited)</string> + <key>PRODUCT_NAME</key> + <string>$(TARGET_NAME)</string> + <key>WRAPPER_EXTENSION</key> + <string>app</string> + <key>baseConfigurationReference</key> + <string>E4EB6923138AFD0F00A09F29</string> + </dict> + <key>isa</key> + <string>XCBuildConfiguration</string> + <key>name</key> + <string>Release</string> + </dict> + <key>E4B69E1C0A3A1BDC003C02F2</key> + <dict> + <key>children</key> + <array> + <string>E4B69E1D0A3A1BDC003C02F2</string> + <string>E4B69E1E0A3A1BDC003C02F2</string> + <string>E4B69E1F0A3A1BDC003C02F2</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>path</key> + <string>src</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>E4B69E1D0A3A1BDC003C02F2</key> + <dict> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>lastKnownFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>name</key> + <string>main.cpp</string> + <key>path</key> + <string>src/main.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>E4B69E1E0A3A1BDC003C02F2</key> + <dict> + <key>explicitFileType</key> + <string>sourcecode.cpp.cpp</string> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>name</key> + <string>ofApp.cpp</string> + <key>path</key> + <string>src/ofApp.cpp</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>E4B69E1F0A3A1BDC003C02F2</key> + <dict> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>lastKnownFileType</key> + <string>sourcecode.c.h</string> + <key>name</key> + <string>ofApp.h</string> + <key>path</key> + <string>src/ofApp.h</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>E4B69E200A3A1BDC003C02F2</key> + <dict> + <key>fileRef</key> + <string>E4B69E1D0A3A1BDC003C02F2</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>E4B69E210A3A1BDC003C02F2</key> + <dict> + <key>fileRef</key> + <string>E4B69E1E0A3A1BDC003C02F2</string> + <key>isa</key> + <string>PBXBuildFile</string> + </dict> + <key>E4B6FCAD0C3E899E008CF71C</key> + <dict> + <key>fileEncoding</key> + <string>30</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>lastKnownFileType</key> + <string>text.plist.xml</string> + <key>path</key> + <string>openFrameworks-Info.plist</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>E4B6FFFD0C3F9AB9008CF71C</key> + <dict> + <key>buildActionMask</key> + <string>2147483647</string> + <key>files</key> + <array /> + <key>inputPaths</key> + <array /> + <key>isa</key> + <string>PBXShellScriptBuildPhase</string> + <key>outputPaths</key> + <array /> + <key>runOnlyForDeploymentPostprocessing</key> + <string>0</string> + <key>shellPath</key> + <string>/bin/sh</string> + <key>shellScript</key> + <string>mkdir -p "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/" +# Copy default icon file into App/Resources +rsync -aved "$ICON_FILE" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/" +# Copy bin/data into App/Resources +rsync -avz --exclude='.DS_Store' "${SRCROOT}/bin/data/" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/data/" +# Copy libfmod and change install directory for fmod to run +rsync -aved ../../../libs/fmodex/lib/osx/libfmodex.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/"; +install_name_tool -change @executable_path/libfmodex.dylib @executable_path/../Frameworks/libfmodex.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME"; +# Copy GLUT framework (must remove for AppStore submissions) +rsync -aved ../../../libs/glut/lib/osx/GLUT.framework "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/" +</string> + </dict> + <key>E4C2427710CC5ABF004149E2</key> + <dict> + <key>buildActionMask</key> + <string>2147483647</string> + <key>dstPath</key> + <string /> + <key>dstSubfolderSpec</key> + <string>10</string> + <key>files</key> + <array /> + <key>isa</key> + <string>PBXCopyFilesBuildPhase</string> + <key>runOnlyForDeploymentPostprocessing</key> + <string>0</string> + </dict> + <key>E4EB691F138AFCF100A09F29</key> + <dict> + <key>fileEncoding</key> + <string>4</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>lastKnownFileType</key> + <string>text.xcconfig</string> + <key>name</key> + <string>CoreOF.xcconfig</string> + <key>path</key> + <string>../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig</string> + <key>sourceTree</key> + <string>SOURCE_ROOT</string> + </dict> + <key>E4EB6923138AFD0F00A09F29</key> + <dict> + <key>fileEncoding</key> + <string>4</string> + <key>isa</key> + <string>PBXFileReference</string> + <key>lastKnownFileType</key> + <string>text.xcconfig</string> + <key>path</key> + <string>Project.xcconfig</string> + <key>sourceTree</key> + <string><group></string> + </dict> + <key>E4EEB9AB138B136A00A80321</key> + <dict> + <key>containerPortal</key> + <string>E4328143138ABC890047C5CB</string> + <key>isa</key> + <string>PBXContainerItemProxy</string> + <key>proxyType</key> + <string>1</string> + <key>remoteGlobalIDString</key> + <string>E4B27C1410CBEB8E00536013</string> + <key>remoteInfo</key> + <string>openFrameworks</string> + </dict> + <key>E4EEB9AC138B136A00A80321</key> + <dict> + <key>isa</key> + <string>PBXTargetDependency</string> + <key>name</key> + <string>openFrameworks</string> + <key>targetProxy</key> + <string>E4EEB9AB138B136A00A80321</string> + </dict> + <key>E4EEC9E9138DF44700A80321</key> + <dict> + <key>children</key> + <array> + <string>E4EB691F138AFCF100A09F29</string> + <string>E4328143138ABC890047C5CB</string> + </array> + <key>isa</key> + <string>PBXGroup</string> + <key>name</key> + <string>openFrameworks</string> + <key>sourceTree</key> + <string><group></string> + </dict> + </dict> + <key>rootObject</key> + <string>E4B69B4C0A3A1720003C02F2</string> + </dict> +</plist> diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "self:"> + </FileRef> +</Workspace> diff --git a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/xcshareddata/xcschemes/granular0_92 Debug.xcscheme index d891c7f..6f7c747 100644 --- a/maximilianTest.xcodeproj/xcuserdata/mickgrierson.xcuserdatad/xcschemes/maximilianTest.xcscheme +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/xcshareddata/xcschemes/granular0_92 Debug.xcscheme @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <Scheme + LastUpgradeVersion = "0600" version = "1.3"> <BuildAction parallelizeBuildables = "YES" @@ -13,10 +14,10 @@ buildForAnalyzing = "YES"> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </BuildActionEntry> </BuildActionEntries> @@ -31,10 +32,10 @@ <MacroExpansion> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </MacroExpansion> </TestAction> @@ -50,10 +51,10 @@ <BuildableProductRunnable> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </BuildableProductRunnable> <AdditionalOptions> @@ -63,15 +64,15 @@ shouldUseLaunchSchemeArgsEnv = "YES" savedToolIdentifier = "" useCustomWorkingDirectory = "NO" - buildConfiguration = "Release" + buildConfiguration = "Debug" debugDocumentVersioning = "YES"> <BuildableProductRunnable> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </BuildableProductRunnable> </ProfileAction> @@ -79,7 +80,7 @@ buildConfiguration = "Debug"> </AnalyzeAction> <ArchiveAction - buildConfiguration = "Release" + buildConfiguration = "Debug" revealArchiveInOrganizer = "YES"> </ArchiveAction> </Scheme> diff --git a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcschemes/maximilianTest.xcscheme b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/xcshareddata/xcschemes/granular0_92 Release.xcscheme index 980a67b..19fd904 100644 --- a/maximilianTest.xcodeproj/xcuserdata/chris.xcuserdatad/xcschemes/maximilianTest.xcscheme +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/granular0_92.xcodeproj/xcshareddata/xcschemes/granular0_92 Release.xcscheme @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <Scheme - LastUpgradeVersion = "0500" + LastUpgradeVersion = "0600" version = "1.3"> <BuildAction parallelizeBuildables = "YES" @@ -14,10 +14,10 @@ buildForAnalyzing = "YES"> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </BuildActionEntry> </BuildActionEntries> @@ -26,16 +26,16 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> + buildConfiguration = "Release"> <Testables> </Testables> <MacroExpansion> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </MacroExpansion> </TestAction> @@ -44,17 +44,17 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle = "0" useCustomWorkingDirectory = "NO" - buildConfiguration = "Debug" + buildConfiguration = "Release" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" allowLocationSimulation = "YES"> <BuildableProductRunnable> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </BuildableProductRunnable> <AdditionalOptions> @@ -69,15 +69,15 @@ <BuildableProductRunnable> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "8DD76F620486A84900D96B5E" - BuildableName = "rtaudiotest" - BlueprintName = "maximilianTest" - ReferencedContainer = "container:maximilianTest_10.8.xcodeproj"> + BlueprintIdentifier = "E4B69B5A0A3A1756003C02F2" + BuildableName = "granular0_92.app" + BlueprintName = "granular0_92" + ReferencedContainer = "container:granular0_92.xcodeproj"> </BuildableReference> </BuildableProductRunnable> </ProfileAction> <AnalyzeAction - buildConfiguration = "Debug"> + buildConfiguration = "Release"> </AnalyzeAction> <ArchiveAction buildConfiguration = "Release" diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/openFrameworks-Info.plist b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/openFrameworks-Info.plist new file mode 100644 index 0000000..8d64d2b --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/openFrameworks-Info.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>cc.openFrameworks.ofapp</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>CFBundleIconFile</key> + <string>${ICON}</string> +</dict> +</plist> diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/main.cpp b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/main.cpp new file mode 100644 index 0000000..e57370b --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/main.cpp @@ -0,0 +1,13 @@ +#include "ofMain.h" +#include "ofApp.h" + +//======================================================================== +int main( ){ + ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context + + // this kicks off the running of my app + // can be OF_WINDOW or OF_FULLSCREEN + // pass in width and height too: + ofRunApp(new ofApp()); + +} diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/ofApp.cpp b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/ofApp.cpp new file mode 100644 index 0000000..52ae7b0 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/ofApp.cpp @@ -0,0 +1,268 @@ +/* This is an example of how to integrate maximilain into openFrameworks, + including using audio received for input and audio requested for output. + + + You can copy and paste this and use it as a starting example. + + */ + +#include "ofApp.h" +//#include "maximilian.h"/* include the lib */ +#include "time.h" + + +//-------------------------------------------------------------- +void ofApp::setup(){ + + /* This is stuff you always need.*/ + + sender.setup(HOST, SENDPORT); + receiver.setup(RECEIVEPORT); + + + //samples from http://freesound.org + samp.load(ofToDataPath("2630__Jovica__133_bpm_ATTACK_LOOP_04_electrified_analog_kit_variation_16_mono.wav")); + samp2.load(ofToDataPath("24620__anamorphosis__GMB_Kantilan_1.wav")); + samp3.load(ofToDataPath("26393__brfindla__Calango1berimbau.wav")); + samp4.load(ofToDataPath("68373__juskiddink__Cello_open_string_bowed.wav")); + samp5.load(ofToDataPath("71515__Microscopia__Wilhelm_Bruder_Sohne_Organ.wav")); + // samp5.load(ofToDataPath("sine1sec.wav")); + + + ofEnableAlphaBlending(); + ofSetupScreen(); + ofBackground(0, 0, 0); + ofSetFrameRate(60); + + sampleRate = 44100; /* Sampling Rate */ + bufferSize = 512; /* Buffer Size. you have to fill this buffer with sound using the for loop in the audioOut method */ + + + + ts = new maxiTimePitchStretch<grainPlayerWin, maxiSample>(&samp); + ts2 = new maxiTimePitchStretch<grainPlayerWin, maxiSample>(&samp2); + ts3 = new maxiTimePitchStretch<grainPlayerWin, maxiSample>(&samp3); + ts4 = new maxiTimePitchStretch<grainPlayerWin, maxiSample>(&samp4); + ts5 = new maxiTimePitchStretch<grainPlayerWin, maxiSample>(&samp5); + stretches.push_back(ts); + stretches.push_back(ts2); + stretches.push_back(ts3); + stretches.push_back(ts4); + stretches.push_back(ts5); + speed = 1; + grainLength = 0.05; + current=0; + + fft.setup(1024, 512, 256); + oct.setup(44100, 1024, 10); + + int current = 0; + ofxMaxiSettings::setup(sampleRate, 2, initialBufferSize); + + ofSetVerticalSync(true); + ofEnableAlphaBlending(); + ofEnableSmoothing(); + + /* Anything that you would normally find/put in maximilian's setup() method needs to go here. For example, Sample loading. + + */ + + ofSetSphereResolution(5); + + isTraining=true; + + ofBackground(0,0,0); + + ofSoundStreamSetup(2,2,this, sampleRate, bufferSize, 4); /* this has to happen at the end of setup - it switches on the DAC */ + + +} + +//-------------------------------------------------------------- +void ofApp::update(){ + + //WEKINATOR + if (!isTraining) { + + + while(receiver.hasWaitingMessages()){ + // get the next message + ofxOscMessage m; + receiver.getNextMessage(&m); + + // check for mouse moved message + if(m.getAddress() == "/wek/outputs"){ + + cout << m.getArgAsFloat(0); + speed = ((double ) m.getArgAsFloat(0) * 4.0) - 2.0; + grainLength = (m.getArgAsFloat(1) * 0.1) + 0.001; + pos = ((double) m.getArgAsFloat(0) * 2.0); + + } + } + + } + + +} + +//-------------------------------------------------------------- +void ofApp::draw(){ + + /* You can use any of the data from audio received and audiorequested to draw stuff here. + Importantly, most people just use the input and output arrays defined above. + Clever people don't do this. This bit of code shows that by default, each signal is going to flip + between -1 and 1. You need to account for this somehow. Get the absolute value for example. + */ + + ofSetColor(160,32,240, 150); + ofDrawBitmapString(":: ofxMaxim Granular Timestretching Example ::", 10,20); + ofDrawBitmapString("Move the mouse left to right to change playback speed and direction.", 10,40); + ofDrawBitmapString("Move the mouse up and down to change the grain length.", 10,60); + ofDrawBitmapString("Click to cycle through samples.", 10,80); + + stringstream s; + s << "Speed: " << speed; + ofDrawBitmapString(s.str(), 10,750); + s.str(""); + s << "Grain length: " << round(grainLength*1000.0) << " ms"; + ofDrawBitmapString(s.str(), 180,750); + + ofNoFill(); + for(int i=0; i < oct.nAverages; i++) { + ofSetColor(200 + ((int)(ofGetFrameNum() * 0.8) % 255), + 100 + ((int)(ofGetFrameNum() * 1.4) % 255), + ofGetFrameNum() % 255, + oct.averages[i] / 20.0 * 255.0); + glPushMatrix(); + glTranslatef(ofGetWidth()/2,ofGetHeight()/2, 0); + glRotatef(0.01 * ofGetFrameNum() * speed * i, 0.01 * ofGetFrameNum() * speed * i,0.01 * ofGetFrameNum() * speed * i, 0); + ofDrawSphere(0, 0, i * 5); + glPopMatrix(); + } + + + + +} + +//-------------------------------------------------------------- +void ofApp::audioOut(float * output, int bufferSize, int nChannels) { + + + for (int i = 0; i < bufferSize; i++){ + + /* Stick your maximilian 'play()' code in here ! Declare your objects in testApp.h. + + For information on how maximilian works, take a look at the example code at + + http://www.maximilian.strangeloop.co.uk + + under 'Tutorials'. + + */ + + + wave = stretches[current]->play(1.,speed, grainLength, 4, 0); + + if (fft.process(wave)) { + oct.calculate(fft.magnitudes); + } + + //play result + mymix.stereo(wave, outputs, 0.5); + output[i*nChannels ] = outputs[0]; /* You may end up with lots of outputs. add them here */ + output[i*nChannels + 1] = outputs[1]; + + + + /* You may end up with lots of outputs. add them here */ + + + } + +} + +//-------------------------------------------------------------- +void ofApp::audioIn(float * input, int bufferSize, int nChannels){ + + // samples are "interleaved" + for(int i = 0; i < bufferSize; i++){ + /* you can also grab the data out of the arrays*/ + + } + +} + + +//-------------------------------------------------------------- +void ofApp::keyPressed(int key){ + + isTraining=!isTraining; + + cout << isTraining; + +} + +//-------------------------------------------------------------- +void ofApp::keyReleased(int key){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseMoved(int x, int y){ + + float x1 = myFilter.lopass(x,0.25); + float y1 = myFilter2.lopass(y,0.25); + + if (isTraining) { + + speed = ((double ) x1 / ofGetWidth() * 4.0) - 2.0; + grainLength = ((double) y1 / ofGetHeight() * 0.1) + 0.001; + if (grainLength < 0.01 ) grainLength = 0.01; + if (grainLength > 0.4 ) grainLength = 0.4; + pos = ((double) x1 / ofGetWidth() * 2.0); + // cout << pos << endl; + + ofxOscMessage m; + m.setAddress("/wekinator/control/outputs"); + m.addFloatArg((float)x/ofGetWidth()); + m.addFloatArg((float)y/ofGetHeight()); + m.addFloatArg((float)current/stretches.size()-1); + sender.sendMessage(m); + cout << "messageSent" << "\n"; + } + + +} + +//-------------------------------------------------------------- +void ofApp::mouseDragged(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::mousePressed(int x, int y, int button){ + if (++current > stretches.size()-1) current = 0; + +} + +//-------------------------------------------------------------- +void ofApp::mouseReleased(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::windowResized(int w, int h){ + +} + +//-------------------------------------------------------------- +void ofApp::gotMessage(ofMessage msg){ + +} + +//-------------------------------------------------------------- +void ofApp::dragEvent(ofDragInfo dragInfo){ + +} diff --git a/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/ofApp.h b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/ofApp.h new file mode 100644 index 0000000..a1d4d64 --- /dev/null +++ b/openFrameworks/openFrameworksExamples/OSX/OF0.9.2_OSX_Granular0_92/src/ofApp.h @@ -0,0 +1,79 @@ +#pragma once + +#include "ofMain.h" +#include "ofxMaxim.h" +#include "ofxMaxim.h" +#include "maxiGrains.h" +#include "ofxOsc.h" +#include <sys/time.h> + +#define HOST "localhost" +#define RECEIVEPORT 12000 +#define SENDPORT 6448 + +typedef hannWinFunctor grainPlayerWin; + + +class ofApp : public ofBaseApp{ + +public: + void setup(); + void update(); + void draw(); + void keyPressed(int key); + void keyReleased(int key); + void mouseMoved(int x, int y); + void mouseDragged(int x, int y, int button); + void mousePressed(int x, int y, int button); + void mouseReleased(int x, int y, int button); + void windowResized(int w, int h); + void dragEvent(ofDragInfo dragInfo); + void gotMessage(ofMessage msg); + + + void audioOut(float * output, int bufferSize, int nChannels); + void audioIn(float * input, int bufferSize, int nChannels); + + int bufferSize; + + /* stick you maximilian declarations below + + For information on how maximilian works, take a look at the example code at + + http://www.maximilian.strangeloop.co.uk + + under 'Tutorials'. + + + */ + + + int initialBufferSize; /* buffer size */ + int sampleRate; + + + /* stick your maximilian stuff below */ + + double wave,sample,outputs[2]; + maxiSample samp, samp2, samp3, samp4, samp5; + vector<maxiTimePitchStretch<grainPlayerWin, maxiSample>*> stretches; + maxiMix mymix; + maxiTimePitchStretch<grainPlayerWin, maxiSample> *ts, *ts2, *ts3, *ts4, *ts5; + double speed, grainLength; + + ofxMaxiFFT fft; + ofxMaxiFFTOctaveAnalyzer oct; + int current; + double pos; + + //osc + ofxOscSender sender; + ofxOscReceiver receiver; + + ofxMaxiFilter myFilter, myFilter2; + + bool isTraining; + +}; + + diff --git a/openFrameworks/openFrameworksExamples/OSX/OF_0.9.0_OSX_XCode7_mySketch_maxim/src/ofApp.cpp b/openFrameworks/openFrameworksExamples/OSX/OF_0.9.0_OSX_XCode7_mySketch_maxim/src/ofApp.cpp index b3607f3..ef25823 100644 --- a/openFrameworks/openFrameworksExamples/OSX/OF_0.9.0_OSX_XCode7_mySketch_maxim/src/ofApp.cpp +++ b/openFrameworks/openFrameworksExamples/OSX/OF_0.9.0_OSX_XCode7_mySketch_maxim/src/ofApp.cpp @@ -57,7 +57,7 @@ void ofApp::draw(){ //-------------------------------------------------------------- void ofApp::audioOut(float * output, int bufferSize, int nChannels) { - + for (int i = 0; i < bufferSize; i++){ @@ -73,7 +73,6 @@ void ofApp::audioOut(float * output, int bufferSize, int nChannels) { //make 'wave' equal something noisy - double wave = mySample.play(0.5); output[i*nChannels ] = wave; /* You may end up with lots of outputs. add them here */ diff --git a/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/UserInterfaceState.xcuserstate b/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/UserInterfaceState.xcuserstate Binary files differdeleted file mode 100644 index f94fcd8..0000000 --- a/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/michaelgrierson.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null diff --git a/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/mick.xcuserdatad/UserInterfaceState.xcuserstate b/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/mick.xcuserdatad/UserInterfaceState.xcuserstate Binary files differdeleted file mode 100755 index b0e5321..0000000 --- a/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/mick.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null diff --git a/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/rollingsound.xcuserdatad/UserInterfaceState.xcuserstate b/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/rollingsound.xcuserdatad/UserInterfaceState.xcuserstate Binary files differdeleted file mode 100644 index b2d29bd..0000000 --- a/openFrameworks/openFrameworksExamples/iOS/maximFeatureExtractor0.8.4/maximExample.xcodeproj/project.xcworkspace/xcuserdata/rollingsound.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null |
