diff --git a/+binaural~-help.pd b/+binaural~-help.pd new file mode 100644 index 0000000..0ca32bb --- /dev/null +++ b/+binaural~-help.pd @@ -0,0 +1,112 @@ +#N canvas 292 235 885 452 10; +#X floatatom 27 322 10 20 20000 0 - - -; +#X floatatom 227 325 5 0 200 0 - - -; +#X obj 230 306 hsl 128 15 -12 12 0 0 empty bin-gain-set empty -2 -8 +0 10 -228856 -1 -1 6350 1; +#X obj 30 304 hsl 128 15 -180 180 0 0 empty bin-angle-set empty -2 +-8 0 10 -228856 -1 -1 6350 1; +#X obj 635 139 bng 15 250 50 0 bin_openfile empty open-sound-file 17 +7 0 12 -4034 -1 -1; +#N canvas 884 52 294 244 init 0; +#X msg 97 88 0; +#X msg 64 150 \; pd dsp 1 \;; +#X obj 31 -8 loadbang; +#X obj 97 109 s bin-gain-set; +#X obj 31 15 t b b b; +#X msg 137 58 0; +#X obj 137 79 s bin-angle-set; +#X connect 0 0 3 0; +#X connect 2 0 4 0; +#X connect 4 0 1 0; +#X connect 4 1 0 0; +#X connect 4 2 5 0; +#X connect 5 0 6 0; +#X restore 759 66 pd init; +#X obj 22 35 cnv 15 500 90 empty empty empty 20 12 0 14 -228856 -66577 +0; +#X obj 650 216 r bin; +#X obj 27 360 s bin; +#X obj 635 249 +binaural~; +#N canvas 832 124 499 290 binaural 0; +#X text 20 31 angle - This is where you set the position of the sound. +The angle can be varied from -180 degrees to 180 degrees. 0 degrees +is straight ahead \, 90 is to the right \, -90 is to the left \, 180 +and -180 are both directly behind the listener.; +#X text 20 121 filter one/filter two - These buttons allow you to select +between two binaural filter sets. filter one is derived from Bill Gardner +and Keith Martin's measurements of the KEMAR dummy head microphone +at the MIT Media Lab (http://sound.media.mit.edu/KEMAR.html). The diffuse-field +equalized HRTFs are used in this plugin. filter two is the original +SoundHack binaural filter developed by Dr. Durand Begault.; +#X restore 675 45 pd binaural details; +#X obj 635 286 dac~; +#X msg 27 340 angle \$1; +#X text 50 287 -180 to 180 degrees; +#X msg 227 344 gain \$1; +#X text 246 287 -12 to 12 dB; +#X obj 418 324 hradio 15 1 0 2 empty empty empty 0 -8 0 10 -262144 +-1 -1 0; +#X msg 418 344 filterSet \$1; +#X obj 27 245 line; +#X obj 27 168 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 27 189 metro 2000; +#X msg 27 210 -180 \, 180 2000; +#X text 25 8 +binaural~; +#X text 27 39 +binaural~ is a filter which places a sound at a specific +position around the listener's head. It does this by using filters +which simulate the filtering effect of the head and outer ear for sounds +at all angles. The filters in +binaural~ are optimized for headphones +and are only for 0 degree elevation at a 44100 sample rate.; +#N canvas 135 177 667 386 bin_soundfile 0; +#N canvas 0 22 450 300 (subpatch) 0; +#X array bin_soundfile 188893 float 2; +#X coords 0 1 188893 -1 200 140 1; +#X restore 34 32 graph; +#X obj 286 33 openpanel; +#X obj 286 96 soundfiler; +#X obj 286 181 phasor~ 0.5; +#X obj 286 208 *~; +#X obj 72 289 /; +#X obj 72 242 t b f; +#X obj 72 265 samplerate~; +#X obj 286 274 outlet~; +#X obj 72 219 r bin_filelength; +#X obj 72 316 s bin_phasorfreq; +#X obj 286 11 r bin_openfile; +#X msg 286 64 read -resize -maxsize 2e+06 \$1 bin_soundfile; +#X obj 286 121 s bin_filelength; +#X obj 286 156 r bin_phasorfreq; +#X obj 328 208 r bin_filelength; +#X obj 286 232 tabread4~ bin_soundfile; +#X connect 1 0 12 0; +#X connect 2 0 13 0; +#X connect 3 0 4 0; +#X connect 4 0 16 0; +#X connect 5 0 10 0; +#X connect 6 0 7 0; +#X connect 6 1 5 1; +#X connect 7 0 5 0; +#X connect 9 0 6 0; +#X connect 11 0 1 0; +#X connect 12 0 2 0; +#X connect 14 0 3 0; +#X connect 15 0 4 1; +#X connect 16 0 8 0; +#X restore 635 169 pd bin_soundfile; +#X connect 0 0 12 0; +#X connect 1 0 14 0; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X connect 7 0 9 0; +#X connect 9 0 11 0; +#X connect 9 1 11 1; +#X connect 12 0 8 0; +#X connect 14 0 8 0; +#X connect 16 0 17 0; +#X connect 17 0 8 0; +#X connect 18 0 3 0; +#X connect 19 0 20 0; +#X connect 20 0 21 0; +#X connect 21 0 18 0; +#X connect 24 0 9 0; diff --git a/+binaural~.c b/+binaural~.c index 1e94d72..198323a 100644 --- a/+binaural~.c +++ b/+binaural~.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "m_pd.h" #ifdef NT #pragma warning( disable : 4244 ) @@ -33,7 +33,7 @@ enum }; -typedef struct +typedef struct { float azimuth; float elevation; @@ -41,7 +41,7 @@ typedef struct float *farEar; }hrtfPosition; -typedef struct +typedef struct { long numPositions; float gain; @@ -52,7 +52,7 @@ typedef struct typedef struct _binaural { - + t_object x_obj; t_float x_f; //current sample t_float azimuth; @@ -60,7 +60,7 @@ typedef struct _binaural t_float sampleRate; t_int bufferPosition; - + long filterSet; float currentAzimuth; int lastFilterFilled; @@ -104,7 +104,7 @@ static void binaural_azimuth(t_binaural *x, t_float value) { if(value<-180.0||value>180.0) { - error("angle value must be between -180 and 180"); + pd_error(x, "angle value must be between -180 and 180"); return; } else @@ -114,8 +114,8 @@ static void binaural_azimuth(t_binaural *x, t_float value) } static void binaural_gain(t_binaural *x, t_float value) -{ - +{ + x->gain = powf(10.f, (value * 0.05f)); } @@ -150,8 +150,8 @@ void binaural_ProcessMotion(t_binaural *x) // fade between 3 filters. too much processing though. instead, i will cross fade up // to the position, then next block will start at the position and go a little faster // hopefully this cheat will be clean. - - // a - get ready for a new position + + // a - get ready for a new position binaural_newImpulse(x); // b - get new samples and FFT @@ -174,7 +174,7 @@ void binaural_ProcessMotion(t_binaural *x) mayer_realifft(x->sizeFFT, x->outLeftSpectra); memcpy(x->outputLeftA, x->outLeftSpectra, x->sizeFFT * sizeof(float)); - + // left high angle x->outLeftSpectra[0] = x->impulseLeftBSpectra[0] * x->inSpectra[0]; // DC Component x->outLeftSpectra[x->halfSizeFFT] = x->impulseLeftBSpectra[x->halfSizeFFT] * x->inSpectra[x->halfSizeFFT]; // Nyquist Frequency @@ -186,7 +186,7 @@ void binaural_ProcessMotion(t_binaural *x) mayer_realifft(x->sizeFFT, x->outLeftSpectra); memcpy(x->outputLeftB, x->outLeftSpectra, x->sizeFFT * sizeof(float)); - + // right low angle x->outRightSpectra[0] = x->impulseRightASpectra[0] * x->inSpectra[0]; // DC Component x->outRightSpectra[x->halfSizeFFT] = x->impulseRightASpectra[x->halfSizeFFT] * x->inSpectra[x->halfSizeFFT]; // Nyquist Frequency @@ -198,7 +198,7 @@ void binaural_ProcessMotion(t_binaural *x) mayer_realifft(x->sizeFFT, x->outRightSpectra); memcpy(x->outputRightA, x->outRightSpectra, x->sizeFFT * sizeof(float)); - + // right high angle x->outRightSpectra[0] = x->impulseRightBSpectra[0] * x->inSpectra[0]; // DC Component x->outRightSpectra[x->halfSizeFFT] = x->impulseRightBSpectra[x->halfSizeFFT] * x->inSpectra[x->halfSizeFFT]; // Nyquist Frequency @@ -222,7 +222,7 @@ void binaural_ProcessMotion(t_binaural *x) x->outputRightB[n] = x->outputRightB[n] + x->overlapRightB[n]; x->overlapRightB[n] = x->outputRightB[x->sizeImpulse + n]; } - // e - write stuff out + // e - write stuff out for(i = 0; i < x->sizeImpulse; i++) { *(x->outBufferL+i) = (*(x->outputLeftA+i) + ((*(x->outputLeftB+i) - *(x->outputLeftA+i)) * x->mix)) * x->gain; @@ -236,7 +236,7 @@ short binaural_newImpulse(t_binaural *x) { long n; float rotatedAzimuth; - + switch(x->filterSet) { case 0: @@ -246,13 +246,13 @@ short binaural_newImpulse(t_binaural *x) x->currentFilter = &x->filterTwo; break; } - + // go from -180 - 0 - 180 to 0 - 360 if(x->azimuth < 0) rotatedAzimuth = x->azimuth + 360.0f; else rotatedAzimuth = x->azimuth; - + // if(filterSwitch == false) // return(false); // filterSwitch = false; @@ -278,7 +278,7 @@ short binaural_newImpulse(t_binaural *x) } // without limits // currentAzimuth = rotatedAzimuth; - + while(x->currentAzimuth >= 360.0f) x->currentAzimuth -= 360.0f; while(x->currentAzimuth < 0.0f) @@ -295,7 +295,7 @@ short binaural_newImpulse(t_binaural *x) mayer_realfft(x->sizeFFT, x->impulseLeftB); memcpy(x->impulseLeftBSpectra, x->impulseLeftB, x->sizeFFT * sizeof(float)); - + mayer_realfft(x->sizeFFT, x->impulseRightB); memcpy(x->impulseRightBSpectra, x->impulseRightB, x->sizeFFT * sizeof(float)); @@ -313,7 +313,7 @@ short binaural_newImpulse(t_binaural *x) } mayer_realfft(x->sizeFFT, x->impulseLeftA); memcpy(x->impulseLeftASpectra, x->impulseLeftA, x->sizeFFT * sizeof(float)); - + mayer_realfft(x->sizeFFT, x->impulseRightA); memcpy(x->impulseRightASpectra, x->impulseRightA, x->sizeFFT * sizeof(float)); @@ -404,7 +404,7 @@ void binaural_findImpulse(t_binaural *x, float *pImpulseL, float *pImpulseR, flo } else { - if((x->currentFilter->position[i].azimuth <= (360.0f - pAzimuth)) + if((x->currentFilter->position[i].azimuth <= (360.0f - pAzimuth)) && (x->currentFilter->position[j].azimuth >= (360.0f - pAzimuth))) { // we have a match for filter one and two @@ -421,7 +421,7 @@ void binaural_findImpulse(t_binaural *x, float *pImpulseL, float *pImpulseR, flo } } } - + binaural_mixImpulse(filterOneL, filterTwoL, pImpulseL, ratio); binaural_mixImpulse(filterOneR, filterTwoR, pImpulseR, ratio); } @@ -429,7 +429,7 @@ void binaural_findImpulse(t_binaural *x, float *pImpulseL, float *pImpulseR, flo void binaural_copyImpulse(float source[], float target[], long delay) { long m, n; - + for(n = 0; n < delay; n++) target[n] = 0.0; for(m = 0; n < BINAURAL_BLOCK_SIZE; n++, m++) @@ -447,7 +447,7 @@ void binaural_mixImpulse(float sourceA[], float sourceB[], float target[], float void binaural_initHRTF(t_binaural *x) { - + // read in HRTF KEMAR x->filterOne.numPositions = 37; x->filterOne.gain = 0.2630891791f; @@ -638,7 +638,7 @@ void binaural_initHRTF(t_binaural *x) x->filterOne.position[36].elevation = 0.0f; x->filterOne.position[36].nearEar = H0e180aright; x->filterOne.position[36].farEar = H0e180aleft; -/* +/* // read in HRTF D filterOne.numPositions = 36; filterOne.gain = 0.4510151663f; @@ -823,7 +823,7 @@ void binaural_initHRTF(t_binaural *x) filterOne.position[35].elevation = 0.0f; filterOne.position[35].nearEar = d180l; filterOne.position[35].farEar = d180r; -*/ +*/ // read in HRTF C x->filterTwo.numPositions = 7; x->filterTwo.gain = 0.5405306362f; @@ -870,7 +870,7 @@ static void *binaural_new(t_floatarg f) { long sizeConvolution, i; float Pi, twoPi; - + t_binaural *x = (t_binaural *)pd_new(binaural_class); outlet_new(&x->x_obj, gensym("signal")); @@ -920,7 +920,7 @@ static void *binaural_new(t_floatarg f) x->impulseRightBSpectra = (float *) malloc(sizeof(float) * x->sizeFFT); x->outLeftSpectra = (float *) malloc(sizeof(float) * x->sizeFFT); x->outRightSpectra = (float *) malloc(sizeof(float) * x->sizeFFT); - + x->height = EAR_LEVEL; /*if(allocMem() == false) return(false);*/ @@ -934,7 +934,7 @@ static void *binaural_new(t_floatarg f) x->currentFilter = &x->filterOne; binaural_azimuth(x, f); - + return (x); } @@ -951,12 +951,12 @@ static t_int *binaural_perform(t_int *w) int i, framesLeft, processframes; - + framesLeft = sampleframes; while (framesLeft > 0) { // how many frames can we process now - // with this we insure that we stop on the + // with this we insure that we stop on the // BINAURAL_BLOCK_SIZE boundary if(framesLeft+x->bufferPosition < BINAURAL_BLOCK_SIZE) processframes = framesLeft; @@ -968,7 +968,7 @@ static t_int *binaural_perform(t_int *w) { outL[i] = x->outBufferL[i+x->bufferPosition]; outR[i] = x->outBufferR[i+x->bufferPosition]; - } + } x->bufferPosition += processframes; // if over the midpoint boundry, we process a new block if(x->bufferPosition == BINAURAL_BLOCK_SIZE) @@ -988,7 +988,7 @@ static t_int *binaural_perform(t_int *w) // while (n-- > 0) // { - // *outL++ = *in++; + // *outL++ = *in++; //*outR++ = *in++; // } return (w+6); @@ -1001,7 +1001,7 @@ static void binaural_dsp(t_binaural *x, t_signal **sp) } -static void binaural_free(t_binaural *x) +static void binaural_free(t_binaural *x) { if(x->inBuffer != 0) free(x->inBuffer); if(x->outBufferL != 0) free(x->outBufferL); @@ -1011,32 +1011,32 @@ static void binaural_free(t_binaural *x) if(x->impulseRightA != 0) free(x->impulseRightA); if(x->impulseLeftB != 0) free(x->impulseLeftB); if(x->impulseRightB != 0) free(x->impulseRightB); - + if(x->inputDouble != 0) free(x->inputDouble); - + if(x->outputLeftA != 0) free(x->outputLeftA); if(x->outputRightA != 0) free(x->outputRightA); if(x->outputLeftB != 0) free(x->outputLeftB); if(x->outputRightB != 0) free(x->outputRightB); - + if(x->overlapLeftA != 0) free(x->overlapLeftA); if(x->overlapRightA != 0) free(x->overlapRightA); if(x->overlapLeftB != 0) free(x->overlapLeftB); if(x->overlapRightB != 0) free(x->overlapRightB); - + if(x->inSpectra != 0) free(x->inSpectra); - + if(x->impulseLeftASpectra != 0) free(x->impulseLeftASpectra); if(x->impulseRightASpectra != 0) free(x->impulseRightASpectra); if(x->impulseLeftBSpectra != 0) free(x->impulseLeftBSpectra); if(x->impulseRightBSpectra != 0) free(x->impulseRightBSpectra); - + if(x->outLeftSpectra != 0) free(x->outLeftSpectra); if(x->outRightSpectra != 0) free(x->outRightSpectra); if(x->filterOne.position != 0) free(x->filterOne.position); if(x->filterTwo.position != 0) free(x->filterTwo.position); - + x->outBufferL = x->outBufferR = x->inBuffer = 0; x->impulseRightA = x->impulseLeftA = x->impulseRightB = x->impulseLeftB = 0; x->outputRightA = x->outputLeftA = x->outputRightB = x->outputLeftB = x->inputDouble = 0; @@ -1057,4 +1057,3 @@ void setup_0x2bbinaural_tilde(void) class_addmethod(binaural_class, (t_method)binaural_filterSet, gensym("filterSet"), A_DEFFLOAT, 0); } - diff --git a/+bubbler~.c b/+bubbler~.c index a1f1fcd..b5f14ce 100644 --- a/+bubbler~.c +++ b/+bubbler~.c @@ -35,17 +35,17 @@ typedef struct singleGrain typedef struct _bubbler_tilde { t_object x_obj; - + uint32_t x_randSeed; float x_sr; - float x_n; - + float x_n; + t_singleGrain x_grain[8]; - + float x_delay[DELAYSIZE]; long x_delayMask; long x_delaySize; - + long x_readPos; long x_writePos; long x_currentSample; @@ -56,17 +56,17 @@ typedef struct _bubbler_tilde float x_timeInc; float x_timeVariation; float x_fTimeVariation; - + float x_feedback; float x_fFeedback; float x_filterFreq; float x_fFilterFreq; float x_resonance; float x_fResonance; - + float x_density; float x_fDensity; - + float x_grainSpacing; float x_grainSize; float x_fGrain_size; @@ -76,14 +76,14 @@ typedef struct _bubbler_tilde float x_fGrainStartVariation; float x_grainReversal; float x_fGrainReversal; - + float x_octave; float x_fOctave; float x_octaveVariation; float x_fOctaveVariation; - + int x_just; - + long x_numNotes; long x_pitchOn[12]; float x_pitch[12]; @@ -93,12 +93,12 @@ typedef struct _bubbler_tilde float X2; float Y1; float Y2; - + float dcOut1; float dcIn1; - + float x_f; - + } t_bubbler_tilde; @@ -125,9 +125,9 @@ static float bubbler_tilde_hermite(float xx, float yy0, float yy1, float yy2, fl static void bubbler_tilde_time(t_bubbler_tilde *x, t_floatarg t) -{ +{ if(t>10000.0 || t<1.0) - error("time value must be >= 1.0 ms and <= 10000.0 ms."); + pd_error(x, "time value must be >= 1.0 ms and <= 10000.0 ms."); else { x->x_time = t/1000.0; //convert to seconds @@ -136,148 +136,148 @@ static void bubbler_tilde_time(t_bubbler_tilde *x, t_floatarg t) } static void bubbler_tilde_time_vari(t_bubbler_tilde *x, t_floatarg tv) -{ +{ if(tv>100.0 || tv<0.0) - error("timeVariation value must be >= 0%% and <= 100%%."); + pd_error(x, "timeVariation value must be >= 0%% and <= 100%%."); else x->x_timeVariation = tv/100; } static void bubbler_tilde_feedback(t_bubbler_tilde *x, t_floatarg f) -{ +{ if(f>200.0 || f<0.0) - error("feedback value must be >= 0%% and <= 200%%."); + pd_error(x, "feedback value must be >= 0%% and <= 200%%."); else x->x_feedback = f/200; } static void bubbler_tilde_filter_freq(t_bubbler_tilde *x, t_floatarg ff) -{ +{ if(ff>20000.0 || ff<20.0) - error("filterFreq value must be >= 20 Hz and <= 20000 Hz."); + pd_error(x, "filterFreq value must be >= 20 Hz and <= 20000 Hz."); else x->x_filterFreq = ff; } static void bubbler_tilde_resonance(t_bubbler_tilde *x, t_floatarg r) -{ +{ if(r>100 || r<0) - error("resonance value must be >= 0%% and <= 100%%."); + pd_error(x, "resonance value must be >= 0%% and <= 100%%."); else x->x_resonance = r/100.0; } static void bubbler_tilde_density(t_bubbler_tilde *x, t_floatarg d) -{ +{ if(d>200 || d<0) - error("density value must be >= 0%% and <= 200%%."); + pd_error(x, "density value must be >= 0%% and <= 200%%."); else x->x_density = d/200.0; } static void bubbler_tilde_grain_size(t_bubbler_tilde *x, t_floatarg g) -{ +{ if(g>50 || g<0) - error("grainSize value must be >= 0%% and <= 50%%."); + pd_error(x, "grainSize value must be >= 0%% and <= 50%%."); else x->x_grainSize = g/50.0; } static void bubbler_tilde_grain_start_vari(t_bubbler_tilde *x, t_floatarg gs) -{ +{ if(gs>100 || gs<0) - error("grainStartVariation value must be >= 0%% and <= 100%%."); + pd_error(x, "grainStartVariation value must be >= 0%% and <= 100%%."); else x->x_grainStartVariation = gs/100.0; } static void bubbler_tilde_octave(t_bubbler_tilde *x, t_floatarg o) -{ +{ if(o > 4.0 || o < -4.0) - error("octave value must be >= -4.0 and <= 4.0."); + pd_error(x, "octave value must be >= -4.0 and <= 4.0."); else x->x_octave = o; } static void bubbler_tilde_oct_vari(t_bubbler_tilde *x, t_floatarg ov) -{ +{ if(ov>2.0 || ov<0.0) - error("octaveVariation value must be >= 0.0 and <= 2.0."); + pd_error(x, "octaveVariation value must be >= 0.0 and <= 2.0."); else x->x_octaveVariation = ov; } static void bubbler_tilde_grain_reversal(t_bubbler_tilde *x, t_floatarg gr) -{ +{ if(gr>100 || gr<0) - error("grainReversal value must be >= 0%% and <= 100%%."); + pd_error(x, "grainReversal value must be >= 0%% and <= 100%%."); else x->x_grainReversal = gr/100.0; } static void bubbler_tilde_12tet(t_bubbler_tilde *x) -{ +{ x->x_just = 0; post("12tet intonation."); } static void bubbler_tilde_just(t_bubbler_tilde *x) -{ +{ x->x_just = 1; post("just intonation."); } static void bubbler_tilde_pitchOn(t_bubbler_tilde *x, t_float note, t_float vel) -{ +{ int i, mod_note; t_float octave; if(note<0) { - error("note values must be positive"); + pd_error(x, "note values must be positive"); return; } else mod_note = (int)note%12; - + if(vel<0) vel=0.0; if(x->x_pitch[mod_note] == 0.0f && vel>0) - { + { octave = (int)(note/12) - 5; x->x_octave = octave; - + //add a note x->x_pitch[mod_note] = 1.0f; - + // safety: clip numNotes to 0-11 for pitchOn if(x->x_numNotes < 0) x->x_numNotes = 0; else if(x->x_numNotes > 11) x->x_numNotes = 11; - + x->x_pitchOn[x->x_numNotes] = mod_note; x->x_numNotes++; } else if(x->x_pitch[mod_note] == 1.0f && vel==0) - { + { // delete a note x->x_pitch[mod_note] = 0.0f; for(i=0; i<12; i++) - { + { if(x->x_pitchOn[i] != mod_note) ; else { for(; i<11; i++) x->x_pitchOn[i] = x->x_pitchOn[i+1]; - + x->x_pitchOn[i] = 0.0; break; } } - + x->x_numNotes--; } } @@ -293,7 +293,7 @@ static void *bubbler_tilde_new() bubbler_tilde_randomULong(&x->x_randSeed); x->x_sr = 44100.0; x->x_n = 64.0; - + for(i=0; i<8; i++) { x->x_grain[i].start = 0; @@ -310,42 +310,42 @@ static void *bubbler_tilde_new() for(i=0; ix_delay[i] = 0.0; - + x->x_delaySize = DELAYSIZE; x->x_delayMask = x->x_delaySize - 1; - + x->x_readPos = x->x_writePos = 0.0; x->x_currentSample = x->x_lastGrainSample = 0.0; x->x_time = x->x_fTime = 8.32; x->x_timeInc = (x->x_time - x->x_fTime) /(x->x_sr * 0.1f); x->x_timeVariation = x->x_fTimeVariation = 0.0; - + x->x_feedback = x->x_fFeedback = 0.0; x->x_filterFreq = x->x_fFilterFreq = 20000.0; x->x_resonance = x->x_fResonance = 0.5; - + x->x_density = x->x_fDensity = 0.8; x->x_grainSpacing = 0.0; x->x_grainSize = x->x_fGrain_size = 0.2; x->x_grainSizeVariation = x->x_fGrainSizeVariation = 0.0; x->x_grainStartVariation = x->x_fGrainStartVariation = 0.0; x->x_grainReversal = x->x_fGrainReversal = 0.0; - + x->x_octave = x->x_fOctave = 0.0; x->x_octaveVariation = x->x_fOctaveVariation = 0.0; x->x_just = 0; // 0 is 12tet, 1 is just - + for(i=0; i<12; i++) x->x_pitch[i]=0.0; for(i=0; i<12; i++) x->x_pitchOn[i]=0.0; - - + + for(i=0; i<13; i++) x->x_scale[0][i] = pow(2.0, (float)i/12.0); - + x->x_scale[1][0] = 1.0; x->x_scale[1][1] = 16.0/15.0; x->x_scale[1][2] = 9.0/8.0; @@ -359,18 +359,18 @@ static void *bubbler_tilde_new() x->x_scale[1][10] = 7.0/4.0; x->x_scale[1][11] = 15.0/8.0; x->x_scale[1][12] = 2.0; - + // biquad filter stuff x->X1 = x->X2 = x->Y1 = x->Y2 = 0.0; x->dcOut1 = x->dcIn1 = 0.0f; - + return(void *)x; }; static t_int *bubbler_tilde_perform(t_int *w) { t_bubbler_tilde *x = (t_bubbler_tilde *)(w[1]); - + t_sample *mainInput = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); @@ -387,7 +387,7 @@ static t_int *bubbler_tilde_perform(t_int *w) // feedback filter variables float filterFreq, filterReson, f0, C; float A1, A2, A3, B1, B2; - + float feedbackInc, grainSizeInc, grainSizeVariInc, grainStartVariInc, tempTime, timeVariInc, densityInc, octaveInc, octaveVariationInc, reverseGrainInc; float oneOverFrames; float clipFactor = 1.0f; @@ -395,15 +395,15 @@ static t_int *bubbler_tilde_perform(t_int *w) float grainOut; float floatNote; - + float dcOut0, dcIn0, dcR; - + float delayFrac; long delayLong; frames = (long)n; oneOverFrames = 1.0/(float)frames; - + // set up for parameter interpolation // graindelay time interpolation set in setParameter feedbackInc = (x->x_feedback - x->x_fFeedback) * oneOverFrames; @@ -415,11 +415,11 @@ static t_int *bubbler_tilde_perform(t_int *w) octaveInc = (x->x_octave - x->x_fOctave) * oneOverFrames; octaveVariationInc = (x->x_octaveVariation - x->x_fOctaveVariation) * oneOverFrames; reverseGrainInc = (x->x_grainReversal - x->x_fGrainReversal) * oneOverFrames; - + twoPi = 8.0 * atan(1.0); x->x_fResonance = x->x_resonance; x->x_fFilterFreq = x->x_filterFreq; - + dcR = 1.0f - (126.0f/x->x_sr); // filter coefficients get calculated only once per block filterFreq = x->x_fFilterFreq; @@ -430,9 +430,9 @@ static t_int *bubbler_tilde_perform(t_int *w) if(filterFreq > x->x_sr * 0.5) filterFreq = x->x_sr * 0.5; f0 = filterFreq/x->x_sr; - if(f0 < 0.1) + if(f0 < 0.1) C = 1.0 / (f0 * M_PI); - else + else C = tan((0.5 - f0) * M_PI); A1 = 1.0 / ( 1.0 + filterReson * C + C * C); A2 = 2.0 * A1; @@ -442,14 +442,14 @@ static t_int *bubbler_tilde_perform(t_int *w) // graindelay processing loop for(frame = 0; frame < frames; frame++, x->x_currentSample++) - { + { // 2 - determine the graindelay time and the readPos delayTime = (x->x_fTime * x->x_sr) + 2.0; - + delayLong = (long)delayTime; delayFrac = delayTime - (float)delayLong; delayFrac = 1.0 - delayFrac; - + // 0 - do we create a new grain // chances of grain creation // 1 grain every duration(samples)/density samples @@ -461,7 +461,7 @@ static t_int *bubbler_tilde_perform(t_int *w) grainSamples = x->x_fGrain_size * 0.5f * delayTime; if(x->x_fDensity > 0.0f) x->x_grainSpacing = grainSamples/(8.0f * x->x_fDensity); - else + else x->x_grainSpacing = 1000000000000000000000000000000000.0f; if(x->x_lastGrainSample + x->x_grainSpacing < x->x_currentSample) @@ -507,13 +507,13 @@ static t_int *bubbler_tilde_perform(t_int *w) octave = x->x_octave; pitchOffset = (long)(octave + octaveVariation); pitch = x->x_pitchOn[(long)floatNote]; - + // safety: clip pitch to 0-12 range for x_scale if(pitch < 0) pitch = 0; else if(pitch > 12) pitch = 12; - + freqRatio = x->x_scale[x->x_just][pitch]; if(x->x_numNotes == 0) x->x_grain[i].increment = powf(2.0, (float)pitchOffset); @@ -530,7 +530,7 @@ static t_int *bubbler_tilde_perform(t_int *w) reversal = (((float)x->x_randSeed/4294967296.0)); if(reversal < x->x_fGrainReversal) x->x_grain[i].increment = x->x_grain[i].increment * -1.0; - + break; } } @@ -553,7 +553,7 @@ static t_int *bubbler_tilde_perform(t_int *w) inInd = (x->x_readPos + 0) & x->x_delayMask; inp1Ind = (x->x_readPos + 1) & x->x_delayMask; inp2Ind = (x->x_readPos + 2) & x->x_delayMask; - + if(inm1Ind >= DELAYSIZE) { inm1Ind = DELAYSIZE-1; @@ -574,12 +574,12 @@ static t_int *bubbler_tilde_perform(t_int *w) inp2Ind = DELAYSIZE-1; post("over"); }; - + inm1 = x->x_delay[inm1Ind]; in = x->x_delay[inInd]; inp1 = x->x_delay[inp1Ind]; inp2 = x->x_delay[inp2Ind]; - + grainOut = bubbler_tilde_hermite(delayFrac, inm1, in, inp1, inp2); } if(x->x_grain[i].attackend == x->x_grain[i].decaystart) @@ -591,14 +591,14 @@ static t_int *bubbler_tilde_perform(t_int *w) output += grainOut * 0.5; // in vst this is only if(kMonoMode) - x->x_grain[i].readPos += x->x_grain[i].increment; + x->x_grain[i].readPos += x->x_grain[i].increment; while(x->x_grain[i].readPos > (float)x->x_delaySize) x->x_grain[i].readPos -= (float)x->x_delaySize; while(x->x_grain[i].readPos < 0.0) x->x_grain[i].readPos += (float)x->x_delaySize; } } - + feedback = x->x_fFeedback * 2.0f; preFilter = ((output * feedback) + *(mainInput+frame)); // here's where we filter @@ -610,20 +610,20 @@ static t_int *bubbler_tilde_perform(t_int *w) // bypass the filter if the frequency is high if(x->x_fFilterFreq > 19000) // used to be 0.95 for 0-1 range preClip = preFilter; - + dcIn0 = preClip; dcOut0 = dcIn0 - x->dcIn1 + dcR * x->dcOut1; x->dcOut1 = dcOut0; x->dcIn1 = dcIn0; preClip = dcOut0; - -// the new arctan softclip - *(x->x_delay+x->x_writePos) = atan( preClip * clipFactor )/clipFactor + 0.000001f; + +// the new arctan softclip + *(x->x_delay+x->x_writePos) = atan( preClip * clipFactor )/clipFactor + 0.000001f; *(out+frame) = output; - + x->x_writePos++; x->x_writePos &= x->x_delayMask; - + // interpolate x->x_fFeedback += feedbackInc; @@ -641,7 +641,7 @@ static t_int *bubbler_tilde_perform(t_int *w) if(x->x_currentSample > x->x_grain[i].end) x->x_grain[i].active = 0; } - + // a test to see if tempTime has gone past pTime if((tempTime - x->x_time) * (x->x_fTime - x->x_time) < 0.0) { @@ -651,7 +651,7 @@ static t_int *bubbler_tilde_perform(t_int *w) else x->x_fTime = tempTime; }; - + x->x_fFeedback = x->x_feedback; x->x_fTimeVariation = x->x_timeVariation; x->x_fGrain_size = x->x_grainSize; @@ -661,8 +661,8 @@ static t_int *bubbler_tilde_perform(t_int *w) x->x_fOctave = x->x_octave; x->x_fOctaveVariation = x->x_octaveVariation; x->x_fGrainReversal = x->x_grainReversal; - - + + return(w + 5); }; @@ -686,7 +686,7 @@ static void bubbler_tilde_dsp(t_bubbler_tilde *x, t_signal **sp) void setup_0x2bbubbler_tilde(void) { - bubbler_tilde_class = + bubbler_tilde_class = class_new( gensym("+bubbler~"), (t_newmethod)bubbler_tilde_new, @@ -706,7 +706,7 @@ void setup_0x2bbubbler_tilde(void) ); class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_time, gensym("time"), A_DEFFLOAT, @@ -714,15 +714,15 @@ void setup_0x2bbubbler_tilde(void) ); class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_time_vari, gensym("timeVariation"), A_DEFFLOAT, 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_feedback, gensym("feedback"), A_DEFFLOAT, @@ -730,7 +730,7 @@ void setup_0x2bbubbler_tilde(void) ); class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_filter_freq, gensym("filterFreq"), A_DEFFLOAT, @@ -738,7 +738,7 @@ void setup_0x2bbubbler_tilde(void) ); class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_resonance, gensym("resonance"), A_DEFFLOAT, @@ -746,7 +746,7 @@ void setup_0x2bbubbler_tilde(void) ); class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_density, gensym("density"), A_DEFFLOAT, @@ -754,65 +754,65 @@ void setup_0x2bbubbler_tilde(void) ); class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_grain_size, gensym("grainSize"), A_DEFFLOAT, 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_grain_start_vari, gensym("grainStartVariation"), A_DEFFLOAT, 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_octave, gensym("octave"), A_DEFFLOAT, 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_oct_vari, gensym("octaveVariation"), A_DEFFLOAT, 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_grain_reversal, gensym("grainReversal"), A_DEFFLOAT, 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_12tet, gensym("12tet"), 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_just, gensym("just"), 0 ); - + class_addmethod( - bubbler_tilde_class, + bubbler_tilde_class, (t_method)bubbler_tilde_pitchOn, gensym("pitchOn"), A_DEFFLOAT, A_DEFFLOAT, 0 ); -} \ No newline at end of file +} diff --git a/+chebyshev~.c b/+chebyshev~.c index 47fb0e2..c4c2814 100644 --- a/+chebyshev~.c +++ b/+chebyshev~.c @@ -24,60 +24,60 @@ typedef struct _chebyshev_tilde float x_dbFive; float x_dbSeven; float x_gain; - float x_f; + float x_f; } t_chebyshev_tilde; static void chebyshev_tilde_p1(t_chebyshev_tilde *x, t_floatarg p1) -{ +{ if(p1 > 0.0 || p1 < -60.0) - error("value must be >= -60.0dB and <= 0.0dB."); + pd_error(x, "value must be >= -60.0dB and <= 0.0dB."); else x->x_dbOne = pow(10.0f, p1 * 0.05); } static void chebyshev_tilde_p2(t_chebyshev_tilde *x, t_floatarg p2) -{ +{ if(p2 > 00.0 || p2 < -60.0) - error("value must be >= -60.0dB and <= 0.0dB."); + pd_error(x, "value must be >= -60.0dB and <= 0.0dB."); else x->x_dbTwo = pow(10.0f, p2 * 0.05); } static void chebyshev_tilde_p3(t_chebyshev_tilde *x, t_floatarg p3) -{ +{ if(p3 > 00.0 || p3 < -60.0) - error("value must be >= -60.0dB and <= 0.0dB."); + pd_error(x, "value must be >= -60.0dB and <= 0.0dB."); else x->x_dbThree = pow(10.0f, p3 * 0.05); } static void chebyshev_tilde_p4(t_chebyshev_tilde *x, t_floatarg p4) -{ +{ if(p4 > 00.0 || p4 < -60.0) - error("value must be >= -60.0dB and <= 0.0dB."); + pd_error(x, "value must be >= -60.0dB and <= 0.0dB."); else x->x_dbFour = pow(10.0f, p4 * 0.05); } static void chebyshev_tilde_p5(t_chebyshev_tilde *x, t_floatarg p5) -{ +{ if(p5 > 00.0 || p5 < -60.0) - error("value must be >= -60.0dB and <= 0.0dB."); + pd_error(x, "value must be >= -60.0dB and <= 0.0dB."); else x->x_dbFive = pow(10.0f, p5 * 0.05); } static void chebyshev_tilde_p7(t_chebyshev_tilde *x, t_floatarg p7) -{ +{ if(p7 > 00.0 || p7 < -60.0) - error("value must be >= -60.0dB and <= 0.0dB."); + pd_error(x, "value must be >= -60.0dB and <= 0.0dB."); else x->x_dbSeven = pow(10.0f, p7 * 0.05); } static void *chebyshev_tilde_new() -{ +{ t_chebyshev_tilde *x = (t_chebyshev_tilde *)pd_new(chebyshev_tilde_class); outlet_new(&x->x_obj, &s_signal); @@ -88,14 +88,14 @@ static void *chebyshev_tilde_new() x->x_dbFive = 0.0; x->x_dbSeven = 0.0; x->x_gain = 0.0; - + return(void *)x; }; static t_int *chebyshev_tilde_perform(t_int *w) { t_chebyshev_tilde *x = (t_chebyshev_tilde *)(w[1]); - + t_sample *in = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); @@ -104,7 +104,7 @@ static t_int *chebyshev_tilde_perform(t_int *w) float poly1, poly2, poly3, poly4, poly5, poly7, square; float dbOne, dbTwo, dbThree, dbFour, dbFive, dbSeven; float gain; - + //local copies of dataspace variables: dbOne = x->x_dbOne; dbTwo = x->x_dbTwo; @@ -113,22 +113,22 @@ static t_int *chebyshev_tilde_perform(t_int *w) dbFive = x->x_dbFive; dbSeven = x->x_dbSeven; gain = x->x_gain; - + gainOne = pow(10.0f, ((dbOne * 3.f) - 3.f)); gainTwo = pow(10.0f, ((dbTwo * 3.f) - 3.f)); gainThree = pow(10.0f, ((dbThree * 3.f) - 3.f)); gainFour = pow(10.0f, ((dbFour * 3.f) - 3.f)); gainFive = pow(10.0f, ((dbFive * 3.f) - 3.f)); gainSeven = pow(10.0f, ((dbSeven * 3.f) - 3.f)); - + gainSum = gainOne + gainTwo + gainThree + gainFour + gainFive + gainSeven; if(gainSum == 0.0f) x->x_gain = gain = 0.0f; else x->x_gain = gain = 1.0f/gainSum; - - while(n--) + + while(n--) { float inputSample = *in++; float outputSample; @@ -142,14 +142,14 @@ static t_int *chebyshev_tilde_perform(t_int *w) poly5 = ((((16.f * square) - 20.f) * square) + 5.f) * inputSample; // poly6 = (((((32.f * square) - 48.f) * square) + 18.f) * square) - 1.f; poly7 = ((((((64.f * square) - 112.f) * square) + 56.f) * square) - 7.f) * inputSample; - - outputSample = (gainOne * poly1) + (gainTwo * poly2) + (gainThree * poly3) + (gainFour * poly4) + + outputSample = (gainOne * poly1) + (gainTwo * poly2) + (gainThree * poly3) + (gainFour * poly4) + (gainFive * poly5) + (gainSeven * poly7); - outputSample *= gain; - + outputSample *= gain; + *out++ = outputSample; }; - + return(w + 5); }; @@ -173,7 +173,7 @@ static void chebyshev_tilde_dsp(t_chebyshev_tilde *x, t_signal **sp) void setup_0x2bchebyshev_tilde(void) { - chebyshev_tilde_class = + chebyshev_tilde_class = class_new( gensym("+chebyshev~"), (t_newmethod)chebyshev_tilde_new, @@ -193,7 +193,7 @@ void setup_0x2bchebyshev_tilde(void) ); class_addmethod( - chebyshev_tilde_class, + chebyshev_tilde_class, (t_method)chebyshev_tilde_p1, gensym("p1"), A_DEFFLOAT, @@ -201,7 +201,7 @@ void setup_0x2bchebyshev_tilde(void) ); class_addmethod( - chebyshev_tilde_class, + chebyshev_tilde_class, (t_method)chebyshev_tilde_p2, gensym("p2"), A_DEFFLOAT, @@ -209,7 +209,7 @@ void setup_0x2bchebyshev_tilde(void) ); class_addmethod( - chebyshev_tilde_class, + chebyshev_tilde_class, (t_method)chebyshev_tilde_p3, gensym("p3"), A_DEFFLOAT, @@ -217,7 +217,7 @@ void setup_0x2bchebyshev_tilde(void) ); class_addmethod( - chebyshev_tilde_class, + chebyshev_tilde_class, (t_method)chebyshev_tilde_p4, gensym("p4"), A_DEFFLOAT, @@ -225,7 +225,7 @@ void setup_0x2bchebyshev_tilde(void) ); class_addmethod( - chebyshev_tilde_class, + chebyshev_tilde_class, (t_method)chebyshev_tilde_p5, gensym("p5"), A_DEFFLOAT, @@ -233,10 +233,10 @@ void setup_0x2bchebyshev_tilde(void) ); class_addmethod( - chebyshev_tilde_class, + chebyshev_tilde_class, (t_method)chebyshev_tilde_p7, gensym("p7"), A_DEFFLOAT, 0 ); -} \ No newline at end of file +} diff --git a/+compand~.c b/+compand~.c index a5bb7c9..967708d 100644 --- a/+compand~.c +++ b/+compand~.c @@ -55,12 +55,12 @@ static void compand_tilde_compInitGainTable(t_compand_tilde *x) { insignal = (i + 1) *.0001220703125f; // i+1/8192 indecibel = 20.0f * log10(insignal); - + if(insignal <= x->x_compSoftLowThreshold) x->x_compGainTable[i] = 1.0f; else if(insignal > x->x_compSoftLowThreshold && insignal <= x->x_compSoftHighThreshold) { - gaindecibel = ((x->x_threshold - indecibel) + gaindecibel = ((x->x_threshold - indecibel) * (1.0f - x->x_ratio)) * ((indecibel - x->x_compDBSoftLowThreshold)/(x->x_softKnee * 12.0f)); x->x_compGainTable[i] = pow(10.0f, gaindecibel * 0.05f); } @@ -80,7 +80,7 @@ static void compand_tilde_compInitGainTable(t_compand_tilde *x) x->x_compGainTable[i] = 1.0f; else if(insignal > x->x_compSoftLowThreshold && insignal <= x->x_compSoftHighThreshold) { - gaindecibel = ((indecibel - x->x_threshold) + gaindecibel = ((indecibel - x->x_threshold) * (x->x_ratio - 1.0f)) * ((x->x_compSoftHighThreshold - indecibel)/(x->x_softKnee * 12.0f)); x->x_compGainTable[i] = pow(10.0f, gaindecibel * 0.05f); } @@ -113,18 +113,18 @@ static float compand_tilde_compRMSDetect(t_compand_tilde *x, float in) x->x_compRMSPosition = 0; if(x->x_compRMSPosition < 0) x->x_compRMSPosition = 0; - + // FIRST: square the new sample // in range -1.0 to 1.0 // square range 0.0 to 1.0 square = in * in; - + // SECOND: add to array to calculate mean // arraytotal range 0.0 to comprmsarrarysize x->x_compRMSArrayTotal = x->x_compRMSArrayTotal - x->x_compSquareArray[x->x_compRMSPosition] + square; x->x_compSquareArray[x->x_compRMSPosition] = square; x->x_compRMSPosition++; - + // THIRD: meansquare needs to be scaled up to 65535 for root table lookup meansquare = (int32_t)(x->x_compRMSArrayTotal * x->x_compRMSScale); if(meansquare > 65535) @@ -136,37 +136,37 @@ static float compand_tilde_compRMSDetect(t_compand_tilde *x, float in) static void compand_tilde_ratio(t_compand_tilde *x, t_floatarg value) -{ +{ if(value > 10.0) { // expansion - error("ratio value must be >= 0.01 and <= 10.0"); + pd_error(x, "ratio value must be >= 0.01 and <= 10.0"); value = 10.0; } else if(value < 0.01) { // compression - error("ratio value must be >= 0.01 and <= 10.0"); + pd_error(x, "ratio value must be >= 0.01 and <= 10.0"); value = 0.01; }; - - x->x_ratio = value; + + x->x_ratio = value; compand_tilde_compInitGainTable(x); } static void compand_tilde_threshold(t_compand_tilde *x, t_floatarg threshold) { float compLinearThreshold; - - + + if(threshold > 0.0 || threshold < -96.0) - error("threshold value must be >= -96.0dB and <= 0.0dB."); + pd_error(x, "threshold value must be >= -96.0dB and <= 0.0dB."); else x->x_threshold = threshold; compLinearThreshold = pow(10.0f, (x->x_threshold * 0.05f)); - + if(x->x_softKnee == 0.0f) { x->x_compSoftLowThreshold = x->x_compSoftHighThreshold = compLinearThreshold; @@ -185,9 +185,9 @@ static void compand_tilde_threshold(t_compand_tilde *x, t_floatarg threshold) } static void compand_tilde_attack(t_compand_tilde *x, t_floatarg attack) -{ +{ if(attack > 100.0 || attack < 1.0) - error("attack value must be >= 1.0ms and <= 100.0ms."); + pd_error(x, "attack value must be >= 1.0ms and <= 100.0ms."); else x->x_attack = attack/1000; @@ -196,9 +196,9 @@ static void compand_tilde_attack(t_compand_tilde *x, t_floatarg attack) } static void compand_tilde_release(t_compand_tilde *x, t_floatarg release) -{ +{ if(release > 2000.0 || release < 100.0) - error("release value must be >= 100ms and <= 2000.0ms."); + pd_error(x, "release value must be >= 100ms and <= 2000.0ms."); else x->x_release = release/1000; @@ -207,9 +207,9 @@ static void compand_tilde_release(t_compand_tilde *x, t_floatarg release) } static void compand_tilde_softKnee(t_compand_tilde *x, t_floatarg softKnee) -{ +{ if(softKnee > 1.0 || softKnee < 0.0) - error("softKnee value must be >= 0.0 and <= 1.0."); + pd_error(x, "softKnee value must be >= 0.0 and <= 1.0."); else x->x_softKnee = softKnee; @@ -217,22 +217,22 @@ static void compand_tilde_softKnee(t_compand_tilde *x, t_floatarg softKnee) } static void compand_tilde_makeupGain(t_compand_tilde *x, t_floatarg makeupGain) -{ +{ if(makeupGain > 60.0 || makeupGain < 0.0) - error("makeupGain value must be >= 0.0dB and <= 60.0dB."); + pd_error(x, "makeupGain value must be >= 0.0dB and <= 60.0dB."); else x->x_makeupGain = pow(10.0f, makeupGain*0.05f); } static void compand_tilde_rms_detect(t_compand_tilde *x, t_floatarg rms) -{ +{ if(rms > 1.0) rms=1.0; else if(rms < 0.0) rms=0.0; else x->x_RMSLevelDetect = rms; - + if(x->x_RMSLevelDetect==1) post("RMS Level Detect Mode."); else @@ -240,14 +240,14 @@ static void compand_tilde_rms_detect(t_compand_tilde *x, t_floatarg rms) } static void *compand_tilde_new() -{ +{ t_compand_tilde *x = (t_compand_tilde *)pd_new(compand_tilde_class); int i; inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ratio")); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("threshold")); outlet_new(&x->x_obj, &s_signal); - + x->x_sr = 44100.0; x->x_n = 64.0; x->x_compReleaseLevel = 0.0; @@ -269,7 +269,7 @@ static void *compand_tilde_new() for(i=0; i<8192; i++) x->x_compGainTable[i] = 0.0; - + x->x_ratio = 39.0f/42.0f; x->x_gain = 1.0; x->x_RMSLevelDetect = 0; @@ -287,21 +287,21 @@ static void *compand_tilde_new() // init compGainTable compand_tilde_compInitGainTable(x); - + return(void *)x; }; static t_int *compand_tilde_perform(t_int *w) { t_compand_tilde *x = (t_compand_tilde *)(w[1]); - + t_sample *in1 = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); float level, gainmix, flevelindex; int32_t levelindex, sample; - + for(sample=0; samplex_compReleaseLevel *= x->x_compReleaseMult; @@ -311,7 +311,7 @@ static t_int *compand_tilde_perform(t_int *w) else level = compand_tilde_compPeakDetect(*(in1+sample)); // release algorithm before attack algorithm - + if(level > 1.0) level = 1.0; if(level < x->x_compReleaseLevel) @@ -322,7 +322,7 @@ static t_int *compand_tilde_perform(t_int *w) x->x_compReleaseLevel = x->x_compAttackLevel = 0.00001f; else x->x_compReleaseLevel = x->x_compAttackLevel = level; - + flevelindex = level * 8191.0f; levelindex = (int32_t)flevelindex; @@ -330,7 +330,7 @@ static t_int *compand_tilde_perform(t_int *w) if(levelindex == 8191) x->x_gain = x->x_gain * 0.5f + 0.5f * x->x_compGainTable[levelindex]; else - x->x_gain = x->x_gain * 0.5f + 0.5f * (x->x_compGainTable[levelindex] + x->x_gain = x->x_gain * 0.5f + 0.5f * (x->x_compGainTable[levelindex] + (x->x_compGainTable[levelindex+1] - x->x_compGainTable[levelindex]) * gainmix); *(out + sample) = *(in1 + sample) * x->x_gain * x->x_makeupGain; }; @@ -359,7 +359,7 @@ static void compand_tilde_dsp(t_compand_tilde *x, t_signal **sp) // unusual name for setup routine to allow for "+". void setup_0x2bcompand_tilde(void) { - compand_tilde_class = + compand_tilde_class = class_new( gensym("+compand~"), (t_newmethod)compand_tilde_new, @@ -379,7 +379,7 @@ void setup_0x2bcompand_tilde(void) ); class_addmethod( - compand_tilde_class, + compand_tilde_class, (t_method)compand_tilde_ratio, gensym("ratio"), A_DEFFLOAT, @@ -387,7 +387,7 @@ void setup_0x2bcompand_tilde(void) ); class_addmethod( - compand_tilde_class, + compand_tilde_class, (t_method)compand_tilde_threshold, gensym("threshold"), A_DEFFLOAT, @@ -395,7 +395,7 @@ void setup_0x2bcompand_tilde(void) ); class_addmethod( - compand_tilde_class, + compand_tilde_class, (t_method)compand_tilde_attack, gensym("attack"), A_DEFFLOAT, @@ -403,15 +403,15 @@ void setup_0x2bcompand_tilde(void) ); class_addmethod( - compand_tilde_class, + compand_tilde_class, (t_method)compand_tilde_release, gensym("release"), A_DEFFLOAT, 0 ); - + class_addmethod( - compand_tilde_class, + compand_tilde_class, (t_method)compand_tilde_softKnee, gensym("softKnee"), A_DEFFLOAT, @@ -419,7 +419,7 @@ void setup_0x2bcompand_tilde(void) ); class_addmethod( - compand_tilde_class, + compand_tilde_class, (t_method)compand_tilde_makeupGain, gensym("makeupGain"), A_DEFFLOAT, @@ -427,10 +427,10 @@ void setup_0x2bcompand_tilde(void) ); class_addmethod( - compand_tilde_class, + compand_tilde_class, (t_method)compand_tilde_rms_detect, gensym("rmsDetect"), A_DEFFLOAT, 0 ); -} \ No newline at end of file +} diff --git a/+decimate~.c b/+decimate~.c index 8042268..d40649b 100644 --- a/+decimate~.c +++ b/+decimate~.c @@ -31,16 +31,16 @@ typedef struct _decimate_tilde static void decimate_tilde_depth(t_decimate_tilde *x, t_floatarg d) -{ +{ unsigned long mask, bit; long i, bitDepth; - + if(d>32.0 || d<1.0) - error("depth value must be >= 1.0 and <= 24.0."); + pd_error(x, "depth value must be >= 1.0 and <= 24.0."); else { bitDepth = (long)d; - x->x_maskMix = d - bitDepth; + x->x_maskMix = d - bitDepth; mask = 0; for(i = 0, bit = 0x80000000UL; i < bitDepth; i++) { @@ -55,13 +55,13 @@ static void decimate_tilde_depth(t_decimate_tilde *x, t_floatarg d) bit = bit>>1; } x->x_lMask2 = mask; - }; + }; } static void decimate_tilde_folds(t_decimate_tilde *x, t_floatarg f) -{ +{ if(f>8.0 || f<0.0) - error("folds value must be between 0 and 8."); + pd_error(x, "folds value must be between 0 and 8."); else { x->x_avg = powf(2.0, f); @@ -70,7 +70,7 @@ static void decimate_tilde_folds(t_decimate_tilde *x, t_floatarg f) } static void *decimate_tilde_new() -{ +{ t_decimate_tilde *x = (t_decimate_tilde *)pd_new(decimate_tilde_class); int i; @@ -90,7 +90,7 @@ static void *decimate_tilde_new() // init out buffer for(i=0; ix_outBuffer[i] = 0.0; - + x->x_n = 64; x->x_block = STDBLOCK; x->x_lMask = 0xffffffff; @@ -108,7 +108,7 @@ static t_int *decimate_tilde_perform(t_int *w) float tmp, maskMix, avgScale; int32_t longTmp, lMask, lMask2; t_decimate_tilde *x = (t_decimate_tilde *)(w[1]); - + t_sample *in1 = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); @@ -116,7 +116,7 @@ static t_int *decimate_tilde_perform(t_int *w) // grab a pointer to outBuffer for the final while(n--) pOutBuffer = x->x_outBuffer; - + // rename dataspace variables locally block = x->x_block; avg = (int)x->x_avg; @@ -132,37 +132,37 @@ static t_int *decimate_tilde_perform(t_int *w) // shift signal buffer contents back. for(i=0; i<(block-n); i++) x->x_inBuffer[i] = x->x_inBuffer[i+n]; - + // write new block to end of signal buffer. for(i=0; ix_inBuffer[block-n+i] = in1[i]; - + for(i=0; ix_inBuffer[i+j]; tmp *= avgScale; // avoid divides using precomputed avgScale - + for(j=0, longTmp=0; jx_outBuffer[i+j] = (float)longTmp * 0.0000000004656612875245797f; }; - }; + }; + - while(n--) *out++ = *pOutBuffer++; - + return(w+5); }; static void decimate_tilde_dsp(t_decimate_tilde *x, t_signal **sp) { int i; - + dsp_add( decimate_tilde_perform, 4, @@ -171,7 +171,7 @@ static void decimate_tilde_dsp(t_decimate_tilde *x, t_signal **sp) sp[1]->s_vec, sp[0]->s_n ); - + // update blocksize if it has changed if(x->x_n != sp[0]->s_n) { @@ -179,36 +179,36 @@ static void decimate_tilde_dsp(t_decimate_tilde *x, t_signal **sp) { // resize signal buffer x->x_inBuffer = (t_sample *)t_resizebytes(x->x_inBuffer, x->x_block * sizeof(t_sample), sp[0]->s_n * sizeof(t_sample)); - + // init signal buffer for(i=0; is_n; i++) x->x_inBuffer[i] = 0.0; // resize out buffer x->x_outBuffer = (t_sample *)t_resizebytes(x->x_outBuffer, x->x_block * sizeof(t_sample), sp[0]->s_n * sizeof(t_sample)); - + // init out buffer for(i=0; is_n; i++) x->x_outBuffer[i] = 0.0; - + x->x_block = sp[0]->s_n; } else if( (sp[0]->s_n <= STDBLOCK) && (x->x_n > STDBLOCK) ) { // resize signal buffer x->x_inBuffer = (t_sample *)t_resizebytes(x->x_inBuffer, x->x_block * sizeof(t_sample), STDBLOCK * sizeof(t_sample)); - + // init signal buffer for(i=0; ix_inBuffer[i] = 0.0; // resize out buffer x->x_outBuffer = (t_sample *)t_resizebytes(x->x_outBuffer, x->x_block * sizeof(t_sample), STDBLOCK * sizeof(t_sample)); - + // init out buffer for(i=0; ix_outBuffer[i] = 0.0; - + x->x_block = STDBLOCK; }; @@ -231,7 +231,7 @@ static void decimate_tilde_free(t_decimate_tilde *x) // unusual name for setup routine to allow for "+". void setup_0x2bdecimate_tilde(void) { - decimate_tilde_class = + decimate_tilde_class = class_new( gensym("+decimate~"), (t_newmethod)decimate_tilde_new, @@ -251,7 +251,7 @@ void setup_0x2bdecimate_tilde(void) ); class_addmethod( - decimate_tilde_class, + decimate_tilde_class, (t_method)decimate_tilde_depth, gensym("depth"), A_DEFFLOAT, @@ -259,10 +259,10 @@ void setup_0x2bdecimate_tilde(void) ); class_addmethod( - decimate_tilde_class, + decimate_tilde_class, (t_method)decimate_tilde_folds, gensym("folds"), A_DEFFLOAT, 0 ); -} \ No newline at end of file +} diff --git a/+delay~.c b/+delay~.c index 840d144..76bc6c6 100644 --- a/+delay~.c +++ b/+delay~.c @@ -26,27 +26,27 @@ typedef struct _delay_tilde float x_sr; float x_n; float x_oneOverFrames; - + float x_envelopeModulate; float x_fEnvelopeModulate; long x_envelopePosition; long x_envelopeArraySize; float x_envelopeArrayTotal; float x_envelopeArray[ENVARRAYSIZE]; - + long x_readPos; long x_readPos2; long x_writePos; long x_delaySize; long x_delayMask; - + float x_time; float x_fTime; float x_timeInc; - + float x_feedback; float x_fFeedback; - + float x_lfoOut; float x_lfoOut2; float x_lfoRandInc; @@ -58,14 +58,14 @@ typedef struct _delay_tilde float x_modSpeed; float x_fModSpeed; float x_modDepth; - float x_fModDepth; + float x_fModDepth; float x_depthInc; int x_depthIncTicks; float x_modPhase; float x_fModPhase; float x_modShape; float x_fModShape; - + float x_delay[LFOTABLESIZE]; float x_lfoWaveform[LFOTABLESIZE]; float x_sineWaveform[LFOTABLESIZE]; @@ -73,7 +73,7 @@ typedef struct _delay_tilde float x_triWaveform[LFOTABLESIZE]; float x_rampUpWaveform[LFOTABLESIZE]; float x_rampDownWaveform[LFOTABLESIZE]; - + float x_filterFreq; float x_fFilterFreq; float x_resonance; @@ -86,10 +86,10 @@ typedef struct _delay_tilde float X1; float X2; float Y1; - float Y2; + float Y2; float dcOut1; float dcIn1; - + float x_f; } t_delay_tilde; @@ -104,13 +104,13 @@ static float delay_tilde_envelopeFollower(t_delay_tilde *x, float in) // FIRST: rectify the input if(in < 0.0) in = -in; - + // SECOND: add to array to calculate mean x->x_envelopeArrayTotal = x->x_envelopeArrayTotal - x->x_envelopeArray[x->x_envelopePosition] + in; - + x->x_envelopeArray[x->x_envelopePosition] = in; x->x_envelopePosition++; - + // THIRD: mean is total/arraysize return(x->x_envelopeArrayTotal/(float)x->x_envelopeArraySize); }; @@ -130,9 +130,9 @@ static float delay_tilde_hermite(float xx, float yy0, float yy1, float yy2, floa /***************** UTILITY FUNCTIONS *****************/ static void delay_tilde_time(t_delay_tilde *x, t_floatarg t) -{ +{ if(t>5000.0 || t<1.0) - error("time value must be >= 1.0 ms and <= 5000.0 ms."); + pd_error(x, "time value must be >= 1.0 ms and <= 5000.0 ms."); else { // must fix this - it's scaled twice below x->x_time = t/1000.0; // convert from ms to sec @@ -141,29 +141,29 @@ static void delay_tilde_time(t_delay_tilde *x, t_floatarg t) } static void delay_tilde_feedback(t_delay_tilde *x, t_floatarg f) -{ +{ if(f>200.0 || f<0.0) - error("feedback value must be >= 0%% and <= 200%%."); + pd_error(x, "feedback value must be >= 0%% and <= 200%%."); else x->x_feedback = f/200.0; } static void delay_tilde_modSpeed(t_delay_tilde *x, t_floatarg f) -{ +{ if(f>10.0 || f<0.01) - error("lfoFreq value must be >= 0.01 Hz and <= 10.0 Hz."); + pd_error(x, "lfoFreq value must be >= 0.01 Hz and <= 10.0 Hz."); else x->x_modSpeed = f; } static void delay_tilde_modDepth(t_delay_tilde *x, t_floatarg d) -{ +{ float diff; - + diff = (x->x_modDepth - x->x_fModDepth); - + if(d>100.0 || d<0.0) - error("lfoDepth value must be >= 0.0%% and <= 100.0%%."); + pd_error(x, "lfoDepth value must be >= 0.0%% and <= 100.0%%."); else { x->x_modDepth = d/100.0; @@ -175,9 +175,9 @@ static void delay_tilde_modDepth(t_delay_tilde *x, t_floatarg d) static void delay_tilde_modShape(t_delay_tilde *x, t_floatarg s) { int i; - + if(s>5.0 || s<0.0) - error("lfoShape value must be either 0, 1, 2, 3, 4, or 5."); + pd_error(x, "lfoShape value must be either 0, 1, 2, 3, 4, or 5."); else { x->x_modShape = s/5.0; @@ -198,29 +198,29 @@ static void delay_tilde_modShape(t_delay_tilde *x, t_floatarg s) for(i=0; ix_lfoTableSize; i++) x->x_lfoWaveform[i] = x->x_rampDownWaveform[i]; }; - + } static void delay_tilde_lfoPhase(t_delay_tilde *x, t_floatarg p) -{ +{ if(p>180.0 || p < -180.0) - error("lfoPhase value must be >= -180 deg and <= 180 deg."); + pd_error(x, "lfoPhase value must be >= -180 deg and <= 180 deg."); else x->x_lfoPhase = (180.0+p)/360.0; } static void delay_tilde_filterFreq(t_delay_tilde *x, t_floatarg ff) -{ +{ if(ff>20000.0 || ff<20.0) - error("filterFreq value must be >= 20 Hz and <= 20000 Hz."); + pd_error(x, "filterFreq value must be >= 20 Hz and <= 20000 Hz."); else x->x_filterFreq = ff; } static void delay_tilde_resonance(t_delay_tilde *x, t_floatarg r) -{ +{ if(r>100 || r<0) - error("resonance value must be >= 0%% and <= 100%%."); + pd_error(x, "resonance value must be >= 0%% and <= 100%%."); else x->x_resonance = r/100.0; } @@ -228,7 +228,7 @@ static void delay_tilde_resonance(t_delay_tilde *x, t_floatarg r) static void delay_tilde_feedbackSwitch(t_delay_tilde *x, t_floatarg f) { if(f>1 || f<0) - error("feedbackSwitch value must be 0 or 1."); + pd_error(x, "feedbackSwitch value must be 0 or 1."); else x->x_feedbackSwitch = (int)f; } @@ -236,15 +236,15 @@ static void delay_tilde_feedbackSwitch(t_delay_tilde *x, t_floatarg f) static void delay_tilde_freeze(t_delay_tilde *x, t_floatarg f) { if(f>1 || f<0) - error("freeze value must be 0 or 1."); + pd_error(x, "freeze value must be 0 or 1."); else x->x_freeze = (int)f; } static void delay_tilde_heads(t_delay_tilde *x, t_floatarg h) -{ +{ if(h>2.0 || h<1.0) - error("head value must be 1 or 2."); + pd_error(x, "head value must be 1 or 2."); else x->x_twoHead = (int)h-1; } @@ -255,35 +255,35 @@ static void *delay_tilde_new() int i; outlet_new(&x->x_obj, &s_signal); - + x->x_twoPi = 2.0*M_PI; x->x_sr = 44100.0; x->x_n = 64.0; x->x_oneOverFrames = 1.0f/x->x_n; - + x->x_envelopeModulate = x->x_fEnvelopeModulate = 0.0; x->x_envelopePosition = 0; x->x_envelopeArraySize = ENVARRAYSIZE; x->x_envelopeArrayTotal = 0.0; - + for(i=0; ix_envelopeArray[i] = 0.0; - + x->x_readPos = x->x_readPos2 = x->x_writePos = 0.0; x->x_delaySize = 1048576; x->x_delayMask = 1048576-1; - + x->x_time = x->x_fTime = 0.1; // 100 ms x->x_timeInc = 0.0; x->x_feedback = x->x_fFeedback = 0.5; - + x->x_lfoOut = x->x_lfoOut2 = 0.0; x->x_lfoRandInc = 0.0; x->x_lfoPhase = x->x_lfoPhase2 = 0.75; x->x_lfoIncrement = 0.0; - x->x_lfoTableSize = 1048576; + x->x_lfoTableSize = 1048576; x->x_modSpeed = x->x_fModSpeed = 0.2; x->x_modDepth = x->x_fModDepth = 0.0; @@ -314,10 +314,10 @@ static void *delay_tilde_new() for(; ix_lfoTableSize; i++) x->x_triWaveform[i] = 3.0f - ((float)i/(float)x->x_lfoTableSize * 4.0); - + for(i=0; ix_lfoTableSize; i++) x->x_rampUpWaveform[i] = ((float)i/(float)x->x_lfoTableSize * 2.0) - 1.0f; - + for(i=0; ix_lfoTableSize; i++) x->x_rampDownWaveform[i] = 1.0 - ((float)i/(float)x->x_lfoTableSize * 2.0); @@ -327,25 +327,25 @@ static void *delay_tilde_new() x->x_filterFreq = x->x_fFilterFreq = 20000.0; x->x_resonance = x->x_fResonance = 0.5; x->x_feedbackSwitch = 1.0; // 1 is on, 0 is off - + x->x_freeze = 0; x->x_twoHead = 0; // 1 or 2 heads // biquad filter stuff x->X1 = x->X2 = x->Y1 = x->Y2 = 0.0; x->dcOut1 = x->dcIn1 = 0.0f; - + return(void *)x; }; static t_int *delay_tilde_perform(t_int *w) { t_delay_tilde *x = (t_delay_tilde *)(w[1]); - + t_sample *in1 = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); - + long frame; float delayTime, delayTimeL; float output = 0.0; @@ -366,14 +366,14 @@ static t_int *delay_tilde_perform(t_int *w) float delayFracL = 0.0; float delayFrac2L = 0.0; long delayLong; - + // set up for parameter interpolation // delay time interpolation set in setParameter feedbackInc = (x->x_feedback - x->x_fFeedback) * x->x_oneOverFrames; speedInc = (x->x_modSpeed - x->x_fModSpeed) * x->x_oneOverFrames; envModInc = (x->x_envelopeModulate - x->x_fEnvelopeModulate) * x->x_oneOverFrames; lfoPhaseInc = (x->x_modPhase - x->x_fModPhase) * x->x_oneOverFrames; - + x->x_fModShape = x->x_modShape; x->x_fResonance = x->x_resonance; x->x_fFilterFreq = x->x_filterFreq; @@ -388,9 +388,9 @@ static t_int *delay_tilde_perform(t_int *w) filterFreq = x->x_sr * 0.5; f0 = filterFreq/x->x_sr; - if(f0 < 0.1) + if(f0 < 0.1) C = 1.0 / (f0 * M_PI); - else + else C = tan((0.5 - f0) * M_PI); A1 = 1.0 / ( 1.0 + filterReson * C + C * C); A2 = 2.0 * A1; @@ -406,7 +406,7 @@ static t_int *delay_tilde_perform(t_int *w) envelopeModulate = delay_tilde_envelopeFollower(x, *(in1+frame)) * ((x->x_fEnvelopeModulate*6.0)); if(envelopeModulate > 1.0f) envelopeModulate = 1.0f; - + // 1 - calculate lfo output lfoFreq = x->x_fModSpeed; @@ -414,10 +414,10 @@ static t_int *delay_tilde_perform(t_int *w) lfoPeriodPerSample = lfoFreq/x->x_sr; x->x_lfoIncrement = lfoPeriodPerSample * x->x_lfoTableSize; - + // we need a separate bit of code for random ramps // we use random when fModShape is between 0.75 and 1.0 - + if(x->x_fModShape > 0.83333333333f) { x->x_lfoOut += x->x_lfoRandInc; @@ -468,7 +468,7 @@ static t_int *delay_tilde_perform(t_int *w) // a two sample buffer for the hermite interpolation delayTimeL = delayTime + (delayTime * x->x_lfoOut); delayTimeL = delayTimeL + 2.0 - (delayTimeL * envelopeModulate); - + if(x->x_twoHead == 1) { delayTime2L = delayTime + (delayTime * x->x_lfoOut2); @@ -489,12 +489,12 @@ static t_int *delay_tilde_perform(t_int *w) x->x_readPos2 = x->x_writePos - delayLong; x->x_readPos2 &= x->x_delayMask; } - + if(x->x_feedbackSwitch == 1) feedback = ((x->x_fFeedback * 2.0f)); else feedback = -((x->x_fFeedback * 2.0f)); - + // 3 - calculate left channel if(x->x_freeze == 0) { @@ -533,7 +533,7 @@ static t_int *delay_tilde_perform(t_int *w) if(x->x_fFilterFreq > 19000) preClip = preFilter; - + if(feedback > 1.0f) { dcIn0 = preClip; @@ -543,8 +543,8 @@ static t_int *delay_tilde_perform(t_int *w) preClip = dcOut0; } - // the new arctan softclip - *(x->x_delay+x->x_writePos) = atan( preClip * clipFactor )/clipFactor + 0.000001f; + // the new arctan softclip + *(x->x_delay+x->x_writePos) = atan( preClip * clipFactor )/clipFactor + 0.000001f; *(out+frame) = output; } else @@ -554,8 +554,8 @@ static t_int *delay_tilde_perform(t_int *w) // feedback doesn't matter output = *(x->x_delay+x->x_writePos) = *(x->x_delay + x->x_readPos); *(out+frame) = output; - } - + } + x->x_writePos++; x->x_writePos &= x->x_delayMask; @@ -577,11 +577,11 @@ static t_int *delay_tilde_perform(t_int *w) else x->x_fTime = tempTime; } - + x->x_fEnvelopeModulate = x->x_envelopeModulate; x->x_fFeedback = x->x_feedback; x->x_fModSpeed = x->x_modSpeed; - + if( x->x_depthIncTicks==0 ) { x->x_fModDepth = x->x_modDepth; @@ -589,9 +589,9 @@ static t_int *delay_tilde_perform(t_int *w) } else x->x_depthIncTicks--; - + x->x_fModPhase = x->x_modPhase; - + return(w + 5); }; @@ -617,7 +617,7 @@ static void delay_tilde_dsp(t_delay_tilde *x, t_signal **sp) void setup_0x2bdelay_tilde(void) { - delay_tilde_class = + delay_tilde_class = class_new( gensym("+delay~"), (t_newmethod)delay_tilde_new, @@ -637,7 +637,7 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_time, gensym("time"), A_DEFFLOAT, @@ -645,7 +645,7 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_feedback, gensym("feedback"), A_DEFFLOAT, @@ -653,15 +653,15 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_modSpeed, gensym("lfoFreq"), A_DEFFLOAT, 0 ); - + class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_modDepth, gensym("lfoDepth"), A_DEFFLOAT, @@ -669,7 +669,7 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_modShape, gensym("lfoShape"), A_DEFFLOAT, @@ -677,7 +677,7 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_lfoPhase, gensym("lfoPhase"), A_DEFFLOAT, @@ -685,7 +685,7 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_filterFreq, gensym("filterFreq"), A_DEFFLOAT, @@ -693,7 +693,7 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_resonance, gensym("resonance"), A_DEFFLOAT, @@ -701,15 +701,15 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_feedbackSwitch, gensym("feedbackSwitch"), A_DEFFLOAT, 0 ); - + class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_freeze, gensym("freeze"), A_DEFFLOAT, @@ -717,10 +717,10 @@ void setup_0x2bdelay_tilde(void) ); class_addmethod( - delay_tilde_class, + delay_tilde_class, (t_method)delay_tilde_heads, gensym("heads"), A_DEFFLOAT, 0 ); -} \ No newline at end of file +} diff --git a/+matrix~.c b/+matrix~.c index 2360dd2..b2771ae 100644 --- a/+matrix~.c +++ b/+matrix~.c @@ -20,27 +20,27 @@ typedef struct _matrix_tilde float x_midGain; float x_sideGain; int x_direction; - float x_f; + float x_f; } t_matrix_tilde; static void matrix_tilde_midGain(t_matrix_tilde *x, t_floatarg mg) -{ +{ if(mg > 12.0 || mg < -12.0) - error("value must be >= -12.0dB and <= 12.0dB."); + pd_error(x, "value must be >= -12.0dB and <= 12.0dB."); else x->x_midGain = pow(10.0, mg*0.05); } static void matrix_tilde_sideGain(t_matrix_tilde *x, t_floatarg sg) -{ +{ if(sg > 12.0 || sg < -12.0) - error("value must be >= -12.0dB and <= 12.0dB."); + pd_error(x, "value must be >= -12.0dB and <= 12.0dB."); else x->x_sideGain = pow(10.0, sg*0.05); } static void matrix_tilde_direction(t_matrix_tilde *x, t_floatarg d) -{ +{ if(d > 1.0) x->x_direction = 1; else if(d < 0.0) @@ -63,14 +63,14 @@ static void *matrix_tilde_new() x->x_n = 64.0; x->x_midGain = x->x_sideGain = 1.0; x->x_direction = 0; - + return(void *)x; }; static t_int *matrix_tilde_perform(t_int *w) { t_matrix_tilde *x = (t_matrix_tilde *)(w[1]); - + t_sample *in1 = (t_sample *)(w[2]); t_sample *in2 = (t_sample *)(w[3]); t_sample *out1 = (t_sample *)(w[4]); @@ -82,7 +82,7 @@ static t_int *matrix_tilde_perform(t_int *w) float mid, side, left, right; framesLeft = n; - + // LR to MS - false - 0 // MS to LR - true - 1 if(x->x_direction == 0) @@ -106,7 +106,7 @@ static t_int *matrix_tilde_perform(t_int *w) out2[frame] = (mid * x->x_midGain) - (side * x->x_sideGain); // r = m - s } } - + return(w + 7); }; @@ -132,7 +132,7 @@ static void matrix_tilde_dsp(t_matrix_tilde *x, t_signal **sp) void setup_0x2bmatrix_tilde(void) { - matrix_tilde_class = + matrix_tilde_class = class_new( gensym("+matrix~"), (t_newmethod)matrix_tilde_new, @@ -152,7 +152,7 @@ void setup_0x2bmatrix_tilde(void) ); class_addmethod( - matrix_tilde_class, + matrix_tilde_class, (t_method)matrix_tilde_midGain, gensym("midGain"), A_DEFFLOAT, @@ -160,7 +160,7 @@ void setup_0x2bmatrix_tilde(void) ); class_addmethod( - matrix_tilde_class, + matrix_tilde_class, (t_method)matrix_tilde_sideGain, gensym("sideGain"), A_DEFFLOAT, @@ -168,10 +168,10 @@ void setup_0x2bmatrix_tilde(void) ); class_addmethod( - matrix_tilde_class, + matrix_tilde_class, (t_method)matrix_tilde_direction, gensym("direction"), A_DEFFLOAT, 0 ); -} \ No newline at end of file +} diff --git a/+morphfilter~.c b/+morphfilter~.c index f3a218f..4460f0f 100644 --- a/+morphfilter~.c +++ b/+morphfilter~.c @@ -34,7 +34,7 @@ typedef struct _morphfilter_tilde { t_object x_obj; /* obligatory header */ t_float gain; /* might be neccesary to do some gain compensation */ - + t_float sampleRate; t_int bufferPosition; t_int impulseSize; @@ -48,35 +48,35 @@ typedef struct _morphfilter_tilde long inputTime, outputTime; float pi, twoPi; float *filterSpectra; - + float *dbTable1; float *dbTable2; float *filterLearn; - + float *gainTable; float *tiltTable; float *squareLevel; - - // These are the user defined tables + + // These are the user defined tables int x_array_points1; int x_array_points2; t_symbol *x_arrayname1; t_symbol *x_arrayname2; - - + + t_float depthFilter; t_float tilt; - + t_float learning; t_float learnValue; t_float learnFrames; - + int indexFilter; t_float numberFilter; - + struct mfilter filter[2]; - + } t_morphfilter_tilde; @@ -84,24 +84,24 @@ typedef struct _morphfilter_tilde void morphfilter_tilde_setDepth(t_morphfilter_tilde *x, t_float f) { if(f>2.0 || f<-2.0) - error("depth value must be >= -2 and <= 2."); + pd_error(x, "depth value must be >= -2 and <= 2."); else - x->depthFilter = f; + x->depthFilter = f; } void morphfilter_tilde_morph(t_morphfilter_tilde *x, t_float value) { - if(value <= 1 && value >= 0) + if(value <= 1 && value >= 0) { x->numberFilter = value; } else - error("morph value must be >= 0 and <= 1."); - + pd_error(x, "morph value must be >= 0 and <= 1."); + if(x->numberFilter >= 0.5f) x->indexFilter = 1; else x->indexFilter = 0; - + // filterTableL = filter[indexFilter].linTableL; // filterTableR = filter[indexFilter].linTableR; // mixFilter(); @@ -113,34 +113,34 @@ void morphfilter_tilde_tilt(t_morphfilter_tilde *x , t_float value) { int i; float tiltBasis; - - if ((value <= 3) && (value >= -3)) - { - x->tilt = value; + + if ((value <= 3) && (value >= -3)) + { + x->tilt = value; tiltBasis = log10f((float)x->halfSizeFFT) * 20.0f * 0.5f; for(i=0; i <= x->halfSizeFFT; i++) x->tiltTable[i] = powf(10.0f, ((log10f((float)i+1) * 20.0f) - tiltBasis) * (x->tilt/tiltBasis)); - - } + + } else - error("tilt value must be >= -3 and <= 3."); - + pd_error(x, "tilt value must be >= -3 and <= 3."); + } - + void morphfilter_tilde_set(t_morphfilter_tilde *x, t_symbol *s1, t_symbol *s2) { t_garray *a1; t_garray *a2; int old_array_points1; int old_array_points2; - + x->x_arrayname1 = 0; x->x_arrayname2 = 0; - + old_array_points1 = x->x_array_points1; - old_array_points2 = x->x_array_points2; - + old_array_points2 = x->x_array_points2; + if(!(a1 = (t_garray *)pd_findbyclass(s1, garray_class))) { x->filter[0].x_vec = 0; @@ -157,7 +157,7 @@ void morphfilter_tilde_set(t_morphfilter_tilde *x, t_symbol *s1, t_symbol *s2) { garray_resize( (t_garray *)pd_findbyclass(x->x_arrayname1,garray_class), 513.0); garray_getfloatwords(a1, &x->x_array_points1, &x->filter[0].x_vec); } - + if(!(a2 = (t_garray *)pd_findbyclass(s2, garray_class))) { x->filter[1].x_vec = 0; @@ -174,7 +174,7 @@ void morphfilter_tilde_set(t_morphfilter_tilde *x, t_symbol *s1, t_symbol *s2) { garray_resize( (t_garray *)pd_findbyclass(x->x_arrayname1,garray_class), 513.0); garray_getfloatwords(a2, &x->x_array_points2, &x->filter[1].x_vec); } - + } @@ -185,7 +185,7 @@ void morphfilter_tilde_mixFilter(t_morphfilter_tilde *x) { // should be faster // negative depths should invert the filter shape first f = (1.0f - f) // zero depth should result in a straight line of 1.0f - + int i; float dbValue; if(x->filter[0].x_vec == 0 || x->filter[1].x_vec == 0) @@ -202,11 +202,11 @@ void morphfilter_tilde_mixFilter(t_morphfilter_tilde *x) { } */ // modified = false; // } - - + + for(i = 0; i <= x->halfSizeFFT; i++) // mix the two values { - dbValue = x->depthFilter * (x->filter[0].x_vec[i].w_float * (1.0f - x->numberFilter) + x->filter[1].x_vec[i].w_float * x->numberFilter); + dbValue = x->depthFilter * (x->filter[0].x_vec[i].w_float * (1.0f - x->numberFilter) + x->filter[1].x_vec[i].w_float * x->numberFilter); x->filterSpectra[i] = powf(10.0f, dbValue * 0.05f); } } @@ -224,15 +224,15 @@ void morphfilter_tilde_initHammingWindows ( t_morphfilter_tilde *x ) { void morphfilter_tilde_scaleWindows (t_morphfilter_tilde *x) { long i; float a, b, sum, analFactor, synthFactor; - + a = 0.54f; b = 0.46f; sum = 0.0f; for (i = 0; i < x->sizeFFT; i++) sum += x->analysisWindow[i]; - + synthFactor = analFactor = 2.0f/sum; - + for (i = 0; i < x->sizeFFT; i++) { x->analysisWindow[i] *= analFactor; x->synthesisWindow[i] *= synthFactor; @@ -249,7 +249,7 @@ void morphfilter_tilde_scaleWindows (t_morphfilter_tilde *x) { } -void morphfilter_tilde_setLearn (t_morphfilter_tilde *x, t_float valIn) +void morphfilter_tilde_setLearn (t_morphfilter_tilde *x, t_float valIn) { int i; @@ -259,13 +259,13 @@ void morphfilter_tilde_setLearn (t_morphfilter_tilde *x, t_float valIn) // start filter learning if(x->learnValue > 0.5f && x->learning == FALSE) { - for(i=0; i <= x->halfSizeFFT; i++) + for(i=0; i <= x->halfSizeFFT; i++) { x->filter[ x->indexFilter].x_vec[i].w_float = 0.0f; x->filterLearn[i] = 0.0f; } - + x->learning = TRUE; } @@ -289,10 +289,10 @@ void morphfilter_tilde_setLearn (t_morphfilter_tilde *x, t_float valIn) if(x->filterLearn[i] < filterLow) filterLow = x->filterLearn[i]; } - + float filterRangeAdjust = 2.4f/(filterHigh-filterLow); - for(i=0; i <= x->halfSizeFFT; i++) + for(i=0; i <= x->halfSizeFFT; i++) { float temp = (x->filterLearn[i] - filterHigh) * filterRangeAdjust; x->filter[x->indexFilter].x_vec[i].w_float = (temp * 20.f) + 24.0f; @@ -318,25 +318,25 @@ void *morphfilter_tilde_new(t_symbol *table1, t_symbol *table2) { inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"),gensym("interptVal")); // make this float inlet? outlet_new(&x->x_obj, gensym("signal")); - + // add method to set table names - - // expects 2 table names + + // expects 2 table names x->x_arrayname1 = 0; x->x_arrayname2 = 0; x->filter[0].x_vec = x->filter[1].x_vec = 0; - - if(table1 && table2) { - x->x_array_points1 = 0; - x->x_array_points2 = 0; - morphfilter_tilde_set(x,table1, table2); + + if(table1 && table2) { + x->x_array_points1 = 0; + x->x_array_points2 = 0; + morphfilter_tilde_set(x,table1, table2); } - + x->gain = 1.0f; /* might be neccesary to do some gain compensation */ x->bufferPosition = 0; x->inputTime = x->outputTime = 0; - + x->sizeFFT = kSizeFFT; x->blockSize = x->sizeFFT >> 2; x->halfSizeFFT = x->sizeFFT >> 1; @@ -346,12 +346,12 @@ void *morphfilter_tilde_new(t_symbol *table1, t_symbol *table2) { x->learning = FALSE; x->learnValue = 0; x->learnFrames = 0; - + // lots of memory to set up // first - preset all pointers to zero x->outBuffer = x->inBuffer = x->inWindowed = x->inShift = x->outShift = 0; // second - allocate a huge number of pointers - + x->inBuffer = (float *) malloc(sizeof(float) * x->sizeFFT); x->inWindowed = (float *) malloc(sizeof(float) * x->sizeFFT); x->inShift = (float *) malloc(sizeof(float) * x->sizeFFT); @@ -360,13 +360,13 @@ void *morphfilter_tilde_new(t_symbol *table1, t_symbol *table2) { x->synthesisWindow = (float *) malloc(sizeof(float) * x->sizeFFT); x->analysisWindow = (float *) malloc(sizeof(float) * x->sizeFFT); x->filterSpectra = (float *) malloc(sizeof(float) * x->sizeFFT); - - + + x->gainTable = (float *) malloc(sizeof(float) * x->sizeFFT); x->tiltTable = (float *) malloc(sizeof(float) * x->sizeFFT); - + x->filterLearn = (float *) malloc(sizeof(float) * x->sizeFFT); - x->squareLevel = (float *) malloc(sizeof(float) * x->sizeFFT); + x->squareLevel = (float *) malloc(sizeof(float) * x->sizeFFT); // third - zero out all the memory for(i = 0; isizeFFT; i++) { @@ -374,40 +374,40 @@ void *morphfilter_tilde_new(t_symbol *table1, t_symbol *table2) { x->filterSpectra[i] = 0.0; } // fourth - set up the FFT and windows - morphfilter_tilde_initHammingWindows( x ); // + morphfilter_tilde_initHammingWindows( x ); // morphfilter_tilde_scaleWindows(x); // these we keep - + x->depthFilter = 0.0f; x->indexFilter = 0; x->numberFilter = 0.0f; - + x->tilt = 0.0f; float tiltBasis = log10f((float) x->halfSizeFFT) * 20.0f * 0.5f; for(i = 0; i <= x->halfSizeFFT; i++) x->tiltTable[i] = powf(10.0f, ((log10f((float)i+1) * 20.0f) - tiltBasis) * (x->tilt/tiltBasis)); - - + + // this is how you access values in table: x->x_vec[i].w_float - + return (x); } void morphfilter_tilde_processSpect(t_morphfilter_tilde *x) { long i; - - + + // if peak detection is on, the filter is based on the peak value plus the filter value // the range of filter values changes in the GUI from 0 to -96 (no peak) to +/- 48 (peak), // so we can just combine the filter with the peak - + // first - get the levels for all bands and identify the peaks // left channel - + if(x->learning == TRUE && x->learnValue != 0.0f) { - + x->squareLevel[0] = x->inWindowed[0] * x->inWindowed[0]; x->squareLevel[x->halfSizeFFT] = x->inWindowed[x->halfSizeFFT] * x->inWindowed[x->halfSizeFFT]; @@ -421,33 +421,33 @@ void morphfilter_tilde_processSpect(t_morphfilter_tilde *x) { if(x->learnFrames > 3000) x->learnValue = 0.0f; - + } - - + + // x->filter[indexFilter].x_vec[i].w_float = x->filter[indexFilter].dbTable[i]; - // if(modified) + // if(modified) // { - - + + morphfilter_tilde_mixFilter(x); - - + + // } - - + + // now we reset the gain table, multiplying by the attackFactor or releaseFactor depending on whether // above or below the filter - - + + for(i = 0; i <= x->halfSizeFFT; i++) x->gainTable[i] = (x->gainTable[i] * 0.6f) + (x->filterSpectra[i] * x->tiltTable[i] * 0.4f); - - + + // c - gain the spectra x->outShift[0] = x->inWindowed[0] * x->gainTable[0]; // DC Component x->outShift[x->halfSizeFFT] = x->inWindowed[x->halfSizeFFT] * x->gainTable[x->halfSizeFFT]; // Nyquist Frequency - + for(i = 1; i < x->halfSizeFFT; ++i) { x->outShift[i] = x->inWindowed[i] * x->gainTable[i]; @@ -460,12 +460,12 @@ void morphfilter_tilde_block(t_morphfilter_tilde *x) { long i; // long j; long maskFFT = x->sizeFFT - 1; - + // shift data in the outBuffer toward the beginning of the buffer memcpy(x->outBuffer, x->outBuffer+x->blockSize, (x->sizeFFT - x->blockSize) * sizeof(float)); // zero out the end of the outBuffer memset(x->outBuffer+(x->sizeFFT - x->blockSize), 0, x->blockSize * sizeof(float)); - + // shift data in the inShift buffer toward the beginning of the buffer memcpy(x->inShift, x->inShift+x->blockSize, (x->sizeFFT - x->blockSize) * sizeof(float)); // put new samples in the end of the buffer @@ -477,14 +477,14 @@ void morphfilter_tilde_block(t_morphfilter_tilde *x) { ++(x->inputTime); x->inputTime = x->inputTime & maskFFT; } - + mayer_realfft(x->sizeFFT, x->inWindowed); - - // use averaged table later, for now, this is just straight table 1 + + // use averaged table later, for now, this is just straight table 1 morphfilter_tilde_processSpect(x); - + mayer_realifft(x->sizeFFT, x->outShift); - + // now copy the output into the output buffer, multiplying by the window for(i = 0; i < x->sizeFFT; i++) { *(x->outBuffer + i) += *(x->outShift + x->outputTime) * *(x->synthesisWindow + i); @@ -502,28 +502,28 @@ void morphfilter_tilde_block(t_morphfilter_tilde *x) { It's called with a single pointer "w" which is our location in the DSP call list. We return a new "w" which will point to the next item after us. Meanwhile, w[0] is just a pointer to dsp-perform itself - (no use to us), w[1] and w[2] are the input and output vector + (no use to us), w[1] and w[2] are the input and output vector locations, and w[3] is the number of points to calculate. */ static t_int *morphfilter_tilde_perform(t_int *w) { - + t_morphfilter_tilde *x = (t_morphfilter_tilde *)(w[1]); t_sample *in = (t_float *)(w[2]); // t_float *freqResponse = (t_float *)(w[3]); t_sample *out = (t_float *)(w[3]); int n = (int)(w[4]); - + // i like counting from zero, so i use sample to count the offset from // the start of the in and out blocks int i; // long frames; long framesLeft, processframes; long bandsPerIndex; - + // gotta copy things from the filter input first off // since the block size doesn't always match the number of frequency bands // lets adjust in our copy bandsPerIndex = kHalfSizeFFT/n; - + // if(bandsPerIndex <= 1) // memcpy(x->filterSpectra, freqResponse, n); // else @@ -534,12 +534,12 @@ static t_int *morphfilter_tilde_perform(t_int *w) { // for(j=0; jfilterSpectra+(i*bandsPerIndex)+j) = *(freqResponse+i); // } - + // framesLeft is the number of samples that have to be copied from *in // this loop continues to copy from in until no samples are left framesLeft = n; - + while ( framesLeft > 0 ) { if (framesLeft + x->bufferPosition < x->blockSize) processframes = framesLeft; @@ -548,10 +548,10 @@ static t_int *morphfilter_tilde_perform(t_int *w) { // flush out previous output, copy in new input... // x->bufferPosition is used as a way to keep track of position in both // x->inBuffer and x->outBuffer - + memcpy(x->inBuffer+(x->bufferPosition), in, processframes * sizeof(float)); - for (i=0; ioutBuffer[i+x->bufferPosition] * x->gain; if(out[i] > 1000.0f) @@ -559,7 +559,7 @@ static t_int *morphfilter_tilde_perform(t_int *w) { else if(out[i] < -1000.0f) out[i] = -1000.0f; } - // increment in and out pointers + // increment in and out pointers out += processframes; in += processframes; // increment bufferPostion, if the bufferPosition hits the blockSize (1/4 of FFT size) @@ -580,11 +580,11 @@ static t_int *morphfilter_tilde_perform(t_int *w) { void morphfilter_tilde_dsp(t_morphfilter_tilde *x, t_signal **sp) { x->sampleRate = sp[0]->s_sr; - + dsp_add(morphfilter_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); } - - + + // since we allocated some memory, we need a delete function static void morphfilter_tilde_free(t_morphfilter_tilde *x) { if(x->inBuffer != 0) free(x->inBuffer); @@ -593,17 +593,17 @@ static void morphfilter_tilde_free(t_morphfilter_tilde *x) { if(x->inShift != 0) free(x->inShift); if(x->outShift != 0) free(x->outShift); if(x->filterSpectra != 0) free(x->filterSpectra); - + if(x->analysisWindow != 0) free(x->analysisWindow); if(x->synthesisWindow != 0) free(x->synthesisWindow); - + if(x->dbTable1 != 0) free(x->dbTable1); if(x->dbTable2 != 0) free(x->dbTable2); if(x->gainTable != 0) free(x->gainTable); if(x->tiltTable != 0) free(x->tiltTable); - + if(x->filterLearn != 0) free(x->filterLearn); - if(x->squareLevel != 0) free(x->squareLevel); + if(x->squareLevel != 0) free(x->squareLevel); /* if(x->filter[0].dbTable != 0) free(x->filter[0].dbTable); if(x->filter[1].dbTable != 0) free(x->filter[1].dbTable); @@ -611,43 +611,43 @@ static void morphfilter_tilde_free(t_morphfilter_tilde *x) { if(x->filter[0].linTable != 0) free(x->filter[0].linTable); if(x->filter[1].linTable != 0) free(x->filter[1].linTable); - */ + */ /* if(x->filter[0].x_vec != 0) free(x->filter[0].x_vec); if(x->filter[1].x_vec != 0) free(x->filter[1].x_vec); */ } -/* this routine, which must have exactly this name (with the "~" replaced +/* this routine, which must have exactly this name (with the "~" replaced * by "_tilde) is called when the code is first loaded, and tells Pd how to build the "class". */ - + void setup_0x2bmorphfilter_tilde(void) { - morphfilter_tilde_class = class_new(gensym("+morphfilter~"), - (t_newmethod)morphfilter_tilde_new, + morphfilter_tilde_class = class_new(gensym("+morphfilter~"), + (t_newmethod)morphfilter_tilde_new, (t_method)morphfilter_tilde_free, - sizeof(t_morphfilter_tilde), - CLASS_DEFAULT, + sizeof(t_morphfilter_tilde), + CLASS_DEFAULT, A_DEFSYMBOL, A_DEFSYMBOL, 0); /* this is magic to declare that the leftmost, "main" inlet * takes signals; other signal inlets are done differently... */ - /* also installs delay_time as the leftmost inlet float */ + /* also installs delay_time as the leftmost inlet float */ CLASS_MAINSIGNALIN(morphfilter_tilde_class, t_morphfilter_tilde, gain); /* here we tell Pd about the "dsp" method, which is called back when DSP is turned on. */ - class_addmethod(morphfilter_tilde_class, (t_method) morphfilter_tilde_dsp, + class_addmethod(morphfilter_tilde_class, (t_method) morphfilter_tilde_dsp, gensym("dsp"), (t_atomtype)0); - + class_addmethod(morphfilter_tilde_class, (t_method) morphfilter_tilde_set, gensym("set"), A_SYMBOL, A_SYMBOL, 0); class_addmethod(morphfilter_tilde_class, (t_method) morphfilter_tilde_setLearn, gensym("learn"), A_DEFFLOAT,0); // class_addmethod(morphfilter_tilde_class, (t_method) morphfilter_tilde_interptVal, gensym("interptVal"), A_DEFFLOAT, 0); - + class_addmethod(morphfilter_tilde_class, (t_method)morphfilter_tilde_setDepth, gensym("depth"), A_DEFFLOAT,0); class_addmethod(morphfilter_tilde_class, (t_method)morphfilter_tilde_morph, gensym("morph"), A_DEFFLOAT, 0); - class_addmethod(morphfilter_tilde_class, (t_method)morphfilter_tilde_tilt, gensym("tilt"), A_DEFFLOAT, 0); -} \ No newline at end of file + class_addmethod(morphfilter_tilde_class, (t_method)morphfilter_tilde_tilt, gensym("tilt"), A_DEFFLOAT, 0); +} diff --git a/+pitchdelay~.c b/+pitchdelay~.c index 7cf7885..cd124a0 100644 --- a/+pitchdelay~.c +++ b/+pitchdelay~.c @@ -63,9 +63,9 @@ static float pitchdelay_tilde_hermite(float xx, float yy0, float yy1, float yy2, static void pitchdelay_tilde_time(t_pitchdelay_tilde *x, t_floatarg t) -{ +{ if(t>5000.0 || t<1.0) - error("time value must be >= 1.0 ms and <= 5000.0 ms."); + pd_error(x, "time value must be >= 1.0 ms and <= 5000.0 ms."); else { x->x_time = t/1000.0; @@ -75,37 +75,37 @@ static void pitchdelay_tilde_time(t_pitchdelay_tilde *x, t_floatarg t) // need discrete just/eq temp steps static void pitchdelay_tilde_pitchFactor(t_pitchdelay_tilde *x, t_floatarg pf) -{ +{ if( pf>34 || pf<0 ) - error("pitchFactor values must between 0 and 1200 cents."); + pd_error(x, "pitchFactor values must between 0 and 1200 cents."); else x->x_pitchShift = pf; // 0-34 for indexing into pitchFactor } static void pitchdelay_tilde_feedback(t_pitchdelay_tilde *x, t_floatarg f) -{ +{ if(f>200.0 || f<0.0) - error("feedback value must be >= 0%% and <= 200%%."); + pd_error(x, "feedback value must be >= 0%% and <= 200%%."); else x->x_feedback = f/200.0; } static void pitchdelay_tilde_octave(t_pitchdelay_tilde *x, t_floatarg o) -{ +{ if(o > 3.0 || o < -3.0) - error("octave value must be >= -3.0 and <= 3.0."); + pd_error(x, "octave value must be >= -3.0 and <= 3.0."); else x->x_octave = o; } static void pitchdelay_tilde_loopDepth(t_pitchdelay_tilde *x, t_floatarg d) -{ +{ float diff; - + diff = (x->x_loopDepth - x->x_fLoopDepth); - + if(d>100.0 || d<10.0) - error("lfoDepth value must be >= 10.0%% and <= 100.0%%."); + pd_error(x, "lfoDepth value must be >= 10.0%% and <= 100.0%%."); else { x->x_loopDepth = d/100.0; @@ -115,7 +115,7 @@ static void pitchdelay_tilde_loopDepth(t_pitchdelay_tilde *x, t_floatarg d) } static void *pitchdelay_tilde_new() -{ +{ t_pitchdelay_tilde *x = (t_pitchdelay_tilde *)pd_new(pitchdelay_tilde_class); int i; @@ -123,7 +123,7 @@ static void *pitchdelay_tilde_new() x->x_sr = 44100.0; x->x_n = 64.0; - + for(i=0; ix_delay[i] = 0.0; @@ -136,7 +136,7 @@ static void *pitchdelay_tilde_new() x->x_time = x->x_fTime = 0.3; x->x_timeInc = 0.0; - + x->x_pitchFactor[0] = 1.0f; x->x_pitchFactor[1] = pow(2.0, 1.0/12.0); //1.05946 x->x_pitchFactor[2] = 16.0f/15.0f; //1.06666 @@ -172,14 +172,14 @@ static void *pitchdelay_tilde_new() x->x_pitchFactor[32] = 15.0f/8.0f; //1.875 x->x_pitchFactor[33] = pow(2.0, 11.0/12.0); //1.88774 x->x_pitchFactor[34] = 2.0f/1.0f; //2.0 - + x->x_pitchShift = 0; x->x_feedback = x->x_fFeedback = 0.5; x->x_octave = 0; x->x_loopDepth = x->x_fLoopDepth = 0.25; x->x_depthInc = 0.0; x->x_depthIncTicks = 0; - + x->x_rampTableSize = DELAYSIZE; x->x_rampIncrement = 0.0f; x->x_rampPhaseA = 0.0f; @@ -189,14 +189,14 @@ static void *pitchdelay_tilde_new() x->x_readPosA = x->x_readPosB = x->x_writePos = 0.0; x->x_dcIn1 = x->x_dcOut1 = 0.0; - + return(void *)x; }; static t_int *pitchdelay_tilde_perform(t_int *w) { t_pitchdelay_tilde *x = (t_pitchdelay_tilde *)(w[1]); - + t_sample *in1 = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); @@ -206,7 +206,7 @@ static t_int *pitchdelay_tilde_perform(t_int *w) float outputA, delayTime, delayTimeA, delayTimeB; float outputB; float preClip; - + float dcOut0, dcIn0, dcR; float feedbackInc, tempTime; float oneOverFrames = 1.0/(float)n; @@ -218,30 +218,30 @@ static t_int *pitchdelay_tilde_perform(t_int *w) float delayFracB; float octave; long delayLong; - + dcR = 1.0f - (126.0f/x->x_sr); // set up for parameter interpolation // delay time interpolation set in setParameter feedbackInc = (x->x_feedback - x->x_fFeedback) * oneOverFrames; - + index = x->x_pitchShift; octave = x->x_octave; x->x_rampIncrement = (x->x_pitchFactor[index] * pow(2.0, octave)) - 1.0f; - + // delay processing loop for(frame = 0; frame < n; frame++) { // 2 - determine the delay time and the readPos delayTime = x->x_fTime * x->x_sr; - + if(x->x_fLoopDepth < 0.01f) x->x_fLoopDepth = 0.01f; - + x->x_rampOutA += x->x_rampIncrement; x->x_rampOutB = x->x_rampOutA + (delayTime * x->x_fLoopDepth); - + // calculate lowest and highest delay maxDelayMod = delayTime * x->x_fLoopDepth; minDelayMod = -maxDelayMod; @@ -253,7 +253,7 @@ static t_int *pitchdelay_tilde_perform(t_int *w) x->x_rampOutA += (2.0f * maxDelayMod); while(x->x_rampOutB <= minDelayMod) x->x_rampOutB += (2.0f * maxDelayMod); - + x->x_rampPhaseA = x->x_rampTableSize*(x->x_rampOutA + maxDelayMod)/(2.0f*maxDelayMod); x->x_rampPhaseB = x->x_rampTableSize*(x->x_rampOutB + maxDelayMod)/(2.0f*maxDelayMod); while(x->x_rampPhaseA>=x->x_rampTableSize) @@ -267,7 +267,7 @@ static t_int *pitchdelay_tilde_perform(t_int *w) // a two sample buffer for the hermite interpolation delayTimeA = delayTime - x->x_rampOutA + 2.0f; delayTimeB = delayTime - x->x_rampOutB + 2.0f; - + delayLong = (long)delayTimeA; delayFracA = delayTimeA - (float)delayLong; @@ -283,9 +283,9 @@ static t_int *pitchdelay_tilde_perform(t_int *w) delayFracB = 1.0 - delayFracB; x->x_readPosB = x->x_writePos - delayLong; x->x_readPosB &= x->x_delayMask; - + feedback = ((x->x_fFeedback * 2.0f)); - + // 3 calculate output // our hermite spline function // we grab the 2 points before and 2 points after the @@ -316,17 +316,17 @@ static t_int *pitchdelay_tilde_perform(t_int *w) x->x_dcIn1 = dcIn0; preClip = dcOut0; - // the new arctan softclip - *(x->x_delay+x->x_writePos) = atan( preClip * clipFactor )/clipFactor + 0.000001f; + // the new arctan softclip + *(x->x_delay+x->x_writePos) = atan( preClip * clipFactor )/clipFactor + 0.000001f; *(out+frame) = outputA; - + x->x_writePos++; x->x_writePos &= x->x_delayMask; - + // interpolate x->x_fFeedback += feedbackInc; x->x_fLoopDepth += x->x_depthInc; - + tempTime = x->x_fTime + x->x_timeInc; // a test to see if tempTime has gone past pTime @@ -337,7 +337,7 @@ static t_int *pitchdelay_tilde_perform(t_int *w) } else x->x_fTime = tempTime; - + }; if( x->x_depthIncTicks==0 ) @@ -347,9 +347,9 @@ static t_int *pitchdelay_tilde_perform(t_int *w) } else x->x_depthIncTicks--; - + x->x_fFeedback = x->x_feedback; - + return(w + 5); }; @@ -373,7 +373,7 @@ static void pitchdelay_tilde_dsp(t_pitchdelay_tilde *x, t_signal **sp) void setup_0x2bpitchdelay_tilde(void) { - pitchdelay_tilde_class = + pitchdelay_tilde_class = class_new( gensym("+pitchdelay~"), (t_newmethod)pitchdelay_tilde_new, @@ -393,7 +393,7 @@ void setup_0x2bpitchdelay_tilde(void) ); class_addmethod( - pitchdelay_tilde_class, + pitchdelay_tilde_class, (t_method)pitchdelay_tilde_time, gensym("time"), A_DEFFLOAT, @@ -401,7 +401,7 @@ void setup_0x2bpitchdelay_tilde(void) ); class_addmethod( - pitchdelay_tilde_class, + pitchdelay_tilde_class, (t_method)pitchdelay_tilde_pitchFactor, gensym("pitchFactor"), A_DEFFLOAT, @@ -409,15 +409,15 @@ void setup_0x2bpitchdelay_tilde(void) ); class_addmethod( - pitchdelay_tilde_class, + pitchdelay_tilde_class, (t_method)pitchdelay_tilde_feedback, gensym("feedback"), A_DEFFLOAT, 0 ); - + class_addmethod( - pitchdelay_tilde_class, + pitchdelay_tilde_class, (t_method)pitchdelay_tilde_octave, gensym("octave"), A_DEFFLOAT, @@ -425,10 +425,10 @@ void setup_0x2bpitchdelay_tilde(void) ); class_addmethod( - pitchdelay_tilde_class, + pitchdelay_tilde_class, (t_method)pitchdelay_tilde_loopDepth, gensym("loopDepth"), A_DEFFLOAT, 0 ); -} \ No newline at end of file +} diff --git a/+spectralcompand~.c b/+spectralcompand~.c index 5b09076..0da804c 100644 --- a/+spectralcompand~.c +++ b/+spectralcompand~.c @@ -29,7 +29,7 @@ enum typedef struct _spectralcompand_tilde { t_object x_obj; /* obligatory header */ - + t_float sampleRate; t_int bufferPosition; double denormalValue; @@ -41,10 +41,10 @@ typedef struct _spectralcompand_tilde long halfSizeFFT, sizeFFT; long inputTime, outputTime; float pi, twoPi; - + // these use the external table int x_array_points; - t_symbol *x_arrayname; + t_symbol *x_arrayname; t_word *gainTweak; // external parameters @@ -55,7 +55,7 @@ typedef struct _spectralcompand_tilde t_float attack; t_float release; t_float tilt; - + // internal parameters t_float invert; t_float learning; @@ -66,7 +66,7 @@ typedef struct _spectralcompand_tilde t_float attackFactor; t_float releaseFactor; t_float makeupGain; - + // internal tables float *threshLearn; @@ -75,23 +75,23 @@ typedef struct _spectralcompand_tilde float *squareLevel; float *innerTweak; float *linearTweak; - + float *gainIncrements; float *levelIncrements; - - + + } t_spectralcompand_tilde; /*these functions clip incoming parameter values*/ -void spectralcompand_tilde_set(t_spectralcompand_tilde *x, t_symbol *s) +void spectralcompand_tilde_set(t_spectralcompand_tilde *x, t_symbol *s) { t_garray *a; int old_array_points; int i; - + old_array_points = x->x_array_points; - + if(!(a = (t_garray *)pd_findbyclass(s, garray_class))) { pd_error(x, "%s: no such array", s->s_name); @@ -102,7 +102,7 @@ void spectralcompand_tilde_set(t_spectralcompand_tilde *x, t_symbol *s) pd_error(x, "%s: bad template for spectralcompand", s->s_name); x->gainTweak = 0; } - else + else { x->x_arrayname = s; garray_resize((t_garray *)pd_findbyclass(x->x_arrayname,garray_class), 513.0); @@ -111,14 +111,14 @@ void spectralcompand_tilde_set(t_spectralcompand_tilde *x, t_symbol *s) garray_usedindsp(a); for(i = 0; i <= x->halfSizeFFT; i++) x->innerTweak[i] = x->gainTweak[i].w_float = 1.0f; - } + } } void spectralcompand_tilde_learnpeak(t_spectralcompand_tilde *x, t_float value) { int i; float threshPeak; - + x->peakLearnValue = value; // start threshold learning if(x->peakLearnValue > 0.5f && x->learning == FALSE) @@ -156,10 +156,10 @@ void spectralcompand_tilde_learnpeak(t_spectralcompand_tilde *x, t_float value) garray_redraw((t_garray *)pd_findbyclass(x->x_arrayname,garray_class)); } -void spectralcompand_tilde_learnavg(t_spectralcompand_tilde *x, t_float value) +void spectralcompand_tilde_learnavg(t_spectralcompand_tilde *x, t_float value) { int i; - + float threshPeak; x->averageLearnValue = value; @@ -194,24 +194,24 @@ void spectralcompand_tilde_learnavg(t_spectralcompand_tilde *x, t_float value) } x->learnFrames = 0; x->learning = FALSE; - } + } if(x->gainTweak != 0) garray_redraw((t_garray *)pd_findbyclass(x->x_arrayname,garray_class)); } // 1 equals TRUE, 0 equals FALSE -void spectralcompand_tilde_invert(t_spectralcompand_tilde *x, t_float value) +void spectralcompand_tilde_invert(t_spectralcompand_tilde *x, t_float value) { - if(value <= 1 && value >= 0) + if(value <= 1 && value >= 0) x->invertValue = value; else - error("invert value must be 0 or 1"); - + pd_error(x, "invert value must be 0 or 1"); + if(x->invertValue >= 0.5f) x->invert = TRUE; else x->invert = FALSE; - + } void spectralcompand_tilde_thresh(t_spectralcompand_tilde *x, t_float f) @@ -221,11 +221,11 @@ void spectralcompand_tilde_thresh(t_spectralcompand_tilde *x, t_float f) if(f>0.0 || f<-96.0) { - error("threshold value must be >= -96 and <= 0."); + pd_error(x, "threshold value must be >= -96 and <= 0."); return; } else - x->thresholdValue = f; + x->thresholdValue = f; x->threshold = powf(10.f, x->thresholdValue * 0.05f); x->thresholdSquare = x->threshold * x->threshold; if(x->ratio >= 1.0f) @@ -254,23 +254,23 @@ void spectralcompand_tilde_thresh(t_spectralcompand_tilde *x, t_float f) } } -void spectralcompand_tilde_ratio(t_spectralcompand_tilde *x, t_float value) +void spectralcompand_tilde_ratio(t_spectralcompand_tilde *x, t_float value) { long i; float dbLevel, level; if(value > 5.0) { // expansion - error("ratio value must be >= 0.2 and <= 5.0"); + pd_error(x, "ratio value must be >= 0.2 and <= 5.0"); value = 5.0; } else if(value < 0.01) { // compression - error("ratio value must be >= 0.2 and <= 5.0"); + pd_error(x, "ratio value must be >= 0.2 and <= 5.0"); value = 0.2; } - x->ratio = value; + x->ratio = value; if(x->ratio >= 1.0) { for(i = 0; i < kLevelIncrements; i++) @@ -298,14 +298,14 @@ void spectralcompand_tilde_ratio(t_spectralcompand_tilde *x, t_float value) } void spectralcompand_tilde_attack(t_spectralcompand_tilde *x, t_float f) -{ +{ if(f<0.0) { - error("attack above 0 seconds"); + pd_error(x, "attack above 0 seconds"); return; } else - x->attack = f; + x->attack = f; if(x->attack == 0.0f) x->attackFactor = 1.0f/0.001f; else @@ -313,14 +313,14 @@ void spectralcompand_tilde_attack(t_spectralcompand_tilde *x, t_float f) } void spectralcompand_tilde_release(t_spectralcompand_tilde *x, t_float f) -{ +{ if(f<0.0) { - error("attack above 0 seconds"); + pd_error(x, "attack above 0 seconds"); return; } else - x->release = f; + x->release = f; if(x->release == 0.0f) x->releaseFactor = 0.001f; else @@ -331,32 +331,32 @@ void spectralcompand_tilde_tilt(t_spectralcompand_tilde *x , t_float value) { int i; float tiltBasis; - - if ((value <= 6) && (value >= -6)) - { - x->tilt = value; + + if ((value <= 6) && (value >= -6)) + { + x->tilt = value; tiltBasis = log10f((float)x->halfSizeFFT) * 20.0f * 0.5f; - + for(i=0; i <= x->halfSizeFFT; i++) x->tiltTable[i] = powf(10.0f, ((log10f((float)i+1) * 20.0f) - tiltBasis) * (x->tilt/tiltBasis)); - - } + + } else - error("tilt between -6 and 6 db/oct."); + pd_error(x, "tilt between -6 and 6 db/oct."); } void spectralcompand_tilde_gain(t_spectralcompand_tilde *x , t_float value) { - if ((value <= 24) && (value >= -24)) + if ((value <= 24) && (value >= -24)) x->makeupGain = powf(10.f, value * 0.05f); else - error("gain between -24 and 24 db"); + pd_error(x, "gain between -24 and 24 db"); } -void spectralcompand_tilde_initHammingWindows ( t_spectralcompand_tilde *x ) +void spectralcompand_tilde_initHammingWindows ( t_spectralcompand_tilde *x ) { long N, k; N = x->sizeFFT; @@ -369,15 +369,15 @@ void spectralcompand_tilde_initHammingWindows ( t_spectralcompand_tilde *x ) void spectralcompand_tilde_scaleWindows (t_spectralcompand_tilde *x) { long i; float a, b, sum, analFactor, synthFactor; - + a = 0.54f; b = 0.46f; sum = 0.0f; for (i = 0; i < x->sizeFFT; i++) sum += x->analysisWindow[i]; - + synthFactor = analFactor = 2.0f/sum; - + for (i = 0; i < x->sizeFFT; i++) { x->analysisWindow[i] *= analFactor; x->synthesisWindow[i] *= synthFactor; @@ -396,17 +396,17 @@ void spectralcompand_tilde_scaleWindows (t_spectralcompand_tilde *x) { -void *spectralcompand_tilde_new(t_symbol *table) +void *spectralcompand_tilde_new(t_symbol *table) { long i; t_spectralcompand_tilde *x = (t_spectralcompand_tilde *)pd_new(spectralcompand_tilde_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"),gensym("interptVal")); // make this float inlet? outlet_new(&x->x_obj, gensym("signal")); - + // add method to set table names - - // expects 1 table names + + // expects 1 table names x->gainTweak = 0; @@ -420,12 +420,12 @@ void *spectralcompand_tilde_new(t_symbol *table) x->pi = 4.0f * atanf(1.0f); x->twoPi = 8.0f * atanf(1.0f); - + // lots of memory to set up // first - preset all pointers to zero x->outBuffer = x->inBuffer = x->inWindowed = x->inShift = x->outShift = 0; // second - allocate a huge number of pointers - + x->inBuffer = (float *) malloc(sizeof(float) * x->sizeFFT); x->inWindowed = (float *) malloc(sizeof(float) * x->sizeFFT); x->inShift = (float *) malloc(sizeof(float) * x->sizeFFT); @@ -433,14 +433,14 @@ void *spectralcompand_tilde_new(t_symbol *table) x->outBuffer = (float *) malloc(sizeof(float) * x->sizeFFT); x->synthesisWindow = (float *) malloc(sizeof(float) * x->sizeFFT); x->analysisWindow = (float *) malloc(sizeof(float) * x->sizeFFT); - + // third - zero out all the memory for(i = 0; isizeFFT; i++) x->inBuffer[i] = x->outBuffer[i] = x->inShift[i] = x->outShift[i] = 0.0; - + // spectralcompand specific stuff x->gainTable = (float *) malloc(sizeof(float) * x->sizeFFT); - x->squareLevel = (float *) malloc(sizeof(float) * x->sizeFFT); + x->squareLevel = (float *) malloc(sizeof(float) * x->sizeFFT); x->tiltTable = (float *) malloc(sizeof(float) * x->sizeFFT); x->threshLearn = (float *) malloc(sizeof(float) * x->sizeFFT); @@ -463,11 +463,11 @@ void *spectralcompand_tilde_new(t_symbol *table) x->innerTweak[i] = 0.0f; x->linearTweak[i] = 1.0f; } - + // fourth - set up the FFT and windows - spectralcompand_tilde_initHammingWindows(x); // + spectralcompand_tilde_initHammingWindows(x); // spectralcompand_tilde_scaleWindows(x); // these we keep - + x->averageLearnValue = 0.0f; x->peakLearnValue = 0.0; x->learning = FALSE; @@ -477,22 +477,22 @@ void *spectralcompand_tilde_new(t_symbol *table) spectralcompand_tilde_attack(x, 0.1); spectralcompand_tilde_release(x, 0.5); spectralcompand_tilde_tilt(x, 0.0); - spectralcompand_tilde_gain(x, 0.0); - if(table) - { - x->x_array_points = 0; - spectralcompand_tilde_set(x,table); + spectralcompand_tilde_gain(x, 0.0); + if(table) + { + x->x_array_points = 0; + spectralcompand_tilde_set(x,table); } - + return (x); } -void spectralcompand_tilde_processSpect(t_spectralcompand_tilde *x) -{ +void spectralcompand_tilde_processSpect(t_spectralcompand_tilde *x) +{ long i, j; float gain; - + // first - get the levels for all bands and identify the peaks // left channel x->squareLevel[0] = x->inWindowed[0] * x->inWindowed[0]; @@ -517,12 +517,12 @@ void spectralcompand_tilde_processSpect(t_spectralcompand_tilde *x) if(x->learnFrames > 40) x->learning = FALSE; } - - // now we reset the gain table, multiplying by the attackFactor or releaseFactor depending on whether + + // now we reset the gain table, multiplying by the attackFactor or releaseFactor depending on whether // above or below the threshold for(i = 0; i <= x->halfSizeFFT; i++) { - + if((((x->squareLevel[i] * x->linearTweak[i] * x->tiltTable[i] * x->tiltTable[i]) < (x->thresholdSquare)) && (x->ratio >= 1.0f)) || (((x->squareLevel[i] * x->linearTweak[i] * x->tiltTable[i] * x->tiltTable[i]) > (x->thresholdSquare )) && (x->ratio < 1.0f))) { @@ -572,7 +572,7 @@ void spectralcompand_tilde_block(t_spectralcompand_tilde *x) { // long j; long maskFFT = x->sizeFFT - 1; float tweakSum; - + if(x->gainTweak != 0) { tweakSum = 0.0f; @@ -588,13 +588,13 @@ void spectralcompand_tilde_block(t_spectralcompand_tilde *x) { } } - - + + // shift data in the outBuffer toward the beginning of the buffer memcpy(x->outBuffer, x->outBuffer+x->blockSize, (x->sizeFFT - x->blockSize) * sizeof(float)); // zero out the end of the outBuffer memset(x->outBuffer+(x->sizeFFT - x->blockSize), 0, x->blockSize * sizeof(float)); - + // shift data in the inShift buffer toward the beginning of the buffer memcpy(x->inShift, x->inShift+x->blockSize, (x->sizeFFT - x->blockSize) * sizeof(float)); // put new samples in the end of the buffer @@ -606,14 +606,14 @@ void spectralcompand_tilde_block(t_spectralcompand_tilde *x) { ++(x->inputTime); x->inputTime = x->inputTime & maskFFT; } - + mayer_realfft(x->sizeFFT, x->inWindowed); - - // use averaged table later, for now, this is just straight table 1 + + // use averaged table later, for now, this is just straight table 1 spectralcompand_tilde_processSpect(x); - + mayer_realifft(x->sizeFFT, x->outShift); - + // now copy the output into the output buffer, multiplying by the window for(i = 0; i < x->sizeFFT; i++) { *(x->outBuffer + i) += *(x->outShift + x->outputTime) * *(x->synthesisWindow + i); @@ -631,34 +631,34 @@ void spectralcompand_tilde_block(t_spectralcompand_tilde *x) { It's called with a single pointer "w" which is our location in the DSP call list. We return a new "w" which will point to the next item after us. Meanwhile, w[0] is just a pointer to dsp-perform itself - (no use to us), w[1] and w[2] are the input and output vector + (no use to us), w[1] and w[2] are the input and output vector locations, and w[3] is the number of points to calculate. */ static t_int *spectralcompand_tilde_perform(t_int *w) { - + t_spectralcompand_tilde *x = (t_spectralcompand_tilde *)(w[1]); t_sample *in = (t_float *)(w[2]); // t_float *freqResponse = (t_float *)(w[3]); t_sample *out = (t_float *)(w[3]); int n = (int)(w[4]); - + // i like counting from zero, so i use sample to count the offset from // the start of the in and out blocks int i; // long frames; long framesLeft, processframes; long bandsPerIndex; - + // gotta copy things from the filter input first off // since the block size doesn't always match the number of frequency bands // lets adjust in our copy bandsPerIndex = kHalfSizeFFT/n; - - + + // framesLeft is the number of samples that have to be copied from *in // this loop continues to copy from in until no samples are left framesLeft = n; - + while ( framesLeft > 0 ) { if (framesLeft + x->bufferPosition < x->blockSize) processframes = framesLeft; @@ -667,10 +667,10 @@ static t_int *spectralcompand_tilde_perform(t_int *w) { // flush out previous output, copy in new input... // x->bufferPosition is used as a way to keep track of position in both // x->inBuffer and x->outBuffer - + memcpy(x->inBuffer+(x->bufferPosition), in, processframes * sizeof(float)); - for (i=0; ioutBuffer[i+x->bufferPosition] * x->makeupGain; if(out[i] > 1000.0f) @@ -678,7 +678,7 @@ static t_int *spectralcompand_tilde_perform(t_int *w) { else if(out[i] < -1000.0f) out[i] = -1000.0f; } - // increment in and out pointers + // increment in and out pointers out += processframes; in += processframes; // increment bufferPostion, if the bufferPosition hits the blockSize (1/4 of FFT size) @@ -699,68 +699,68 @@ static t_int *spectralcompand_tilde_perform(t_int *w) { void spectralcompand_tilde_dsp(t_spectralcompand_tilde *x, t_signal **sp) { x->sampleRate = sp[0]->s_sr; - + dsp_add(spectralcompand_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); } - - + + // since we allocated some memory, we need a delete function -static void spectralcompand_tilde_free(t_spectralcompand_tilde *x) +static void spectralcompand_tilde_free(t_spectralcompand_tilde *x) { if(x->inBuffer != 0) free(x->inBuffer); if(x->inWindowed != 0) free(x->inWindowed); if(x->outBuffer != 0) free(x->outBuffer); if(x->inShift != 0) free(x->inShift); if(x->outShift != 0) free(x->outShift); - + if(x->analysisWindow != 0) free(x->analysisWindow); if(x->synthesisWindow != 0) free(x->synthesisWindow); - + if(x->gainTable != 0) free(x->gainTable); if(x->tiltTable != 0) free(x->tiltTable); - + if(x->threshLearn != 0) free(x->threshLearn); - if(x->squareLevel != 0) free(x->squareLevel); + if(x->squareLevel != 0) free(x->squareLevel); if(x->levelIncrements != 0) free(x->levelIncrements); - if(x->gainIncrements != 0) free(x->gainIncrements); + if(x->gainIncrements != 0) free(x->gainIncrements); // spectralcompand external specific stuff - if(x->innerTweak != 0) free(x->innerTweak); - if(x->linearTweak != 0) free(x->linearTweak); + if(x->innerTweak != 0) free(x->innerTweak); + if(x->linearTweak != 0) free(x->linearTweak); } -/* this routine, which must have exactly this name (with the "~" replaced +/* this routine, which must have exactly this name (with the "~" replaced * by "_tilde) is called when the code is first loaded, and tells Pd how to build the "class". */ - + void setup_0x2bspectralcompand_tilde(void) { - spectralcompand_tilde_class = class_new(gensym("+spectralcompand~"), - (t_newmethod)spectralcompand_tilde_new, + spectralcompand_tilde_class = class_new(gensym("+spectralcompand~"), + (t_newmethod)spectralcompand_tilde_new, (t_method)spectralcompand_tilde_free, - sizeof(t_spectralcompand_tilde), - CLASS_DEFAULT, + sizeof(t_spectralcompand_tilde), + CLASS_DEFAULT, A_DEFSYMBOL, 0); /* this is magic to declare that the leftmost, "main" inlet * takes signals; other signal inlets are done differently... */ - /* also installs delay_time as the leftmost inlet float */ + /* also installs delay_time as the leftmost inlet float */ CLASS_MAINSIGNALIN(spectralcompand_tilde_class, t_spectralcompand_tilde, makeupGain); /* here we tell Pd about the "dsp" method, which is called back when DSP is turned on. */ class_addmethod(spectralcompand_tilde_class, (t_method) spectralcompand_tilde_dsp, gensym("dsp"), (t_atomtype)0); - + /* a set function to set a threshold table */ class_addmethod(spectralcompand_tilde_class, (t_method) spectralcompand_tilde_set, gensym("set"), A_SYMBOL, 0); class_addmethod(spectralcompand_tilde_class, (t_method) spectralcompand_tilde_learnpeak, gensym("learnpeak"), A_DEFFLOAT,0); class_addmethod(spectralcompand_tilde_class, (t_method) spectralcompand_tilde_learnavg, gensym("learnavg"), A_DEFFLOAT,0); class_addmethod(spectralcompand_tilde_class, (t_method) spectralcompand_tilde_invert, gensym("invert"), A_DEFFLOAT,0); - + class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_thresh, gensym("threshold"), A_DEFFLOAT, 0); class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_ratio, gensym("ratio"), A_DEFFLOAT,0); class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_attack, gensym("attack"), A_DEFFLOAT,0); class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_release, gensym("release"), A_DEFFLOAT,0); - class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_tilt, gensym("tilt"), A_DEFFLOAT, 0); - class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_gain, gensym("gain"), A_DEFFLOAT, 0); -} \ No newline at end of file + class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_tilt, gensym("tilt"), A_DEFFLOAT, 0); + class_addmethod(spectralcompand_tilde_class, (t_method)spectralcompand_tilde_gain, gensym("gain"), A_DEFFLOAT, 0); +} diff --git a/+spectralgate~.c b/+spectralgate~.c index 5af84af..6a945f6 100644 --- a/+spectralgate~.c +++ b/+spectralgate~.c @@ -37,14 +37,14 @@ enum typedef struct _spectralgate { - t_object x_obj; /* obligatory header */ + t_object x_obj; /* obligatory header */ t_float sampleRate; long blockSize; - + t_int bufferPosition; t_float gain; - + // FFT stuff float *inBuffer, *outBuffer, *inWindowed; float *analysisWindow, *synthesisWindow; @@ -58,21 +58,21 @@ typedef struct _spectralgate t_word *gainTweak; int x_array_points; t_symbol *x_arrayname; - - + + /* Parameter variables from setParameter */ - + t_float typeValue; t_float learnValue; t_float learnFrames; - + t_float * threshTable; t_float * threshLearn; t_float learning; t_float resetValue; t_float threshAverage; - + t_float peakTrackValue; t_float peakTrack; t_float thresholdValue; @@ -85,34 +85,34 @@ typedef struct _spectralgate t_float gateGain; t_float highGain; t_float lowGain; - + t_float makeupGainValue; t_float makeupGain; - + t_float tiltValue; t_float tilt; t_float tiltBasis; t_float releaseFactor; t_float attackFactor; - + t_float type; - + /* internal tables */ t_float * tiltTable; t_float * squareLevel; - t_float * gainTable; - t_float *innerTweak; - + t_float * gainTable; + t_float *innerTweak; + } t_spectralgate; void spectralgate_tilde_set(t_spectralgate *x, t_symbol *s) { t_garray *a; int old_array_points; int i; - + old_array_points = x->x_array_points; - + if(!(a = (t_garray *)pd_findbyclass(s, garray_class))) { pd_error(x, "%s: no such array", s->s_name); @@ -123,7 +123,7 @@ void spectralgate_tilde_set(t_spectralgate *x, t_symbol *s) { pd_error(x, "%s: bad template for spectralgate", s->s_name); x->gainTweak = 0; } - else + else { x->x_arrayname = s; garray_resize((t_garray *)pd_findbyclass(x->x_arrayname,garray_class), 513.0); @@ -132,25 +132,25 @@ void spectralgate_tilde_set(t_spectralgate *x, t_symbol *s) { garray_usedindsp(a); for(i = 0; i <= x->halfSizeFFT; i++) x->innerTweak[i] = x->gainTweak[i].w_float = -48.0f; - } -} + } +} -void spectralgate_tilde_type(t_spectralgate *x, t_float value) +void spectralgate_tilde_type(t_spectralgate *x, t_float value) { x->typeValue = value; - + if(x->typeValue < 0.5f) x->type = kGate; else x->type = kDuck; } -void spectralgate_tilde_learn (t_spectralgate *x, t_float value) +void spectralgate_tilde_learn (t_spectralgate *x, t_float value) { int i; float threshPeak; - + x->learnValue = value; // start threshold learning if(x->learnValue > 0.5f && x->learning == FALSE) @@ -192,7 +192,7 @@ void spectralgate_tilde_reset(t_spectralgate *x, t_float value) { int i; x->resetValue = value; - for(i = 0; i <= x->halfSizeFFT; i++) + for(i = 0; i <= x->halfSizeFFT; i++) { x->innerTweak[i] = 0.0f; x->threshTable[i] = 1.0f; @@ -206,7 +206,7 @@ void spectralgate_tilde_reset(t_spectralgate *x, t_float value) void spectralgate_tilde_peaktrack(t_spectralgate *x, t_float value) { x->peakTrackValue = value; - + if(x->peakTrackValue < 0.5f) x->peakTrack = FALSE; else @@ -215,26 +215,26 @@ void spectralgate_tilde_peaktrack(t_spectralgate *x, t_float value) { void spectralgate_tilde_threshold(t_spectralgate *x, t_float value) { - + if(value>0.0 || value<-96.0) { - error("threshold value must be >= -96 and <= 0."); + pd_error(x, "threshold value must be >= -96 and <= 0."); return; } - + x->thresholdValue = value; x->threshold = powf(10.f, x->thresholdValue * 0.05f); x->thresholdSquare = x->threshold * x->threshold; } void spectralgate_tilde_attack(t_spectralgate *x, t_float value) { - + if(value <0.0) { - error("attack above 0 seconds"); + pd_error(x, "attack above 0 seconds"); return; } - else + else x->attack = value; if(x->attack == 0.0f) x->attackFactor = 1.0f/0.001f; @@ -243,15 +243,15 @@ void spectralgate_tilde_attack(t_spectralgate *x, t_float value) { x->attackFactor *= x->attackFactor; } -void spectralgate_tilde_release(t_spectralgate *x, t_float value) { +void spectralgate_tilde_release(t_spectralgate *x, t_float value) { if(value<0.0) { - error("release above 0 seconds"); + pd_error(x, "release above 0 seconds"); return; } - + else - x->release = value; + x->release = value; if(x->release == 0.0f) x->releaseFactor = 0.001f; else @@ -261,70 +261,70 @@ void spectralgate_tilde_release(t_spectralgate *x, t_float value) { void spectralgate_tilde_gain(t_spectralgate *x, t_float value) { - + if ((value <= 60) && (value >= -60)) { x->gateGain = powf(10.f, value * 0.05f); - if(x->gateGain >= 1.0f) + if(x->gateGain >= 1.0f) { x->highGain = x->gateGain; x->lowGain = 1.0f; } - else + else { x->highGain = 1.0f; x->lowGain = x->gateGain; } } else - error("gain between -60 and 60 db"); + pd_error(x, "gain between -60 and 60 db"); } -void spectralgate_tilde_makeupgain(t_spectralgate *x, t_float value) +void spectralgate_tilde_makeupgain(t_spectralgate *x, t_float value) { - - if ((value <= 24) && (value >= -24)) + + if ((value <= 24) && (value >= -24)) x->makeupGain = powf(10.f, value * 0.05f); else - error("makeupgain between -24 and 24 db"); + pd_error(x, "makeupgain between -24 and 24 db"); } -void spectralgate_tilde_tilt(t_spectralgate *x, t_float value) +void spectralgate_tilde_tilt(t_spectralgate *x, t_float value) { int i; float tiltBasis; - - if ((value <= 6) && (value >= -6)) - { - x->tilt = value; + + if ((value <= 6) && (value >= -6)) + { + x->tilt = value; tiltBasis = log10f((float)x->halfSizeFFT) * 20.0f * 0.5f; - + for(i=0; i <= x->halfSizeFFT; i++) x->tiltTable[i] = powf(10.0f, ((log10f((float)i+1) * 20.0f) - tiltBasis) * (x->tilt/tiltBasis)); - - } + + } else - error("tilt between -6 and 6 db/oct."); - + pd_error(x, "tilt between -6 and 6 db/oct."); + } void spectralgate_tilde_processSpect(t_spectralgate *x) { long i; - + float *triggerSpectra; float *localThresh; - + triggerSpectra = x->inWindowed; localThresh = x->threshTable; - - + + // if peak detection is on, the threshold is based on the peak value plus the threshold value // the range of threshold values changes in the GUI from 0 to -96 (no peak) to +/- 48 (peak), // so we can just combine the threshold with the peak - + // first - get the levels for all bands and identify the peaks // left channel - + float peakSquared = x->squareLevel[0] = triggerSpectra[0] * triggerSpectra[0]; x->squareLevel[x->halfSizeFFT] = triggerSpectra[x->halfSizeFFT] * triggerSpectra[x->halfSizeFFT]; if(x->squareLevel[x->halfSizeFFT] > peakSquared) @@ -335,14 +335,14 @@ void spectralgate_tilde_processSpect(t_spectralgate *x) if(x->squareLevel[i] > peakSquared) peakSquared = x->squareLevel[i]; } - + if(x->learning == TRUE) { for(i = 0; i < x->halfSizeFFT; i++) { if(x->squareLevel[i] > x->threshLearn[i]) x->threshLearn[i] = x->squareLevel[i]; - + } x->learnFrames++; if(x->learnFrames > 40) @@ -352,8 +352,8 @@ void spectralgate_tilde_processSpect(t_spectralgate *x) { peakSquared = peakSquared = 1.0f; } - - // now we reset the gain table, multiplying by the attackFactor or releaseFactor depending on whether + + // now we reset the gain table, multiplying by the attackFactor or releaseFactor depending on whether // above or below the threshold // left channel for(i = 0; i <= x->halfSizeFFT; i++) @@ -368,8 +368,8 @@ void spectralgate_tilde_processSpect(t_spectralgate *x) else if(x->gainTable[i] < x->lowGain) x->gainTable[i] = x->lowGain; } - - + + // c - gain the spectra x->outShift[0] = x->inWindowed[0]* x->gainTable[0]; // DC Component x->outShift[x->halfSizeFFT] = x->inWindowed[x->halfSizeFFT] * x->gainTable[x->halfSizeFFT]; // Nyquist Frequency @@ -378,7 +378,7 @@ void spectralgate_tilde_processSpect(t_spectralgate *x) x->outShift[i] = x->inWindowed[i] * x->gainTable[i]; x->outShift[x->sizeFFT - i] = x->inWindowed[x->sizeFFT - i] * x->gainTable[i]; } - + } void spectralgate_tilde_block(t_spectralgate *x) { @@ -386,7 +386,7 @@ void spectralgate_tilde_block(t_spectralgate *x) { // long j; long maskFFT = x->sizeFFT - 1; float tweakSum; - + if(x->gainTweak != 0) { tweakSum = 0.0f; @@ -401,31 +401,31 @@ void spectralgate_tilde_block(t_spectralgate *x) { } } } - + // shift data in the outBuffer toward the beginning of the buffer memcpy(x->outBuffer, x->outBuffer+x->blockSize, (x->sizeFFT - x->blockSize) * sizeof(float)); // zero out the end of the outBuffer memset(x->outBuffer+(x->sizeFFT - x->blockSize), 0, x->blockSize * sizeof(float)); - + // shift data in the inShift buffer toward the beginning of the buffer memcpy(x->inShift, x->inShift+x->blockSize, (x->sizeFFT - x->blockSize) * sizeof(float)); // put new samples in the end of the buffer memcpy(x->inShift + (x->sizeFFT - x->blockSize), x->inBuffer, x->blockSize * sizeof(float)); - + //window our input samples in preparation for FFT for(i = 0; i < x->sizeFFT; i++) { *(x->inWindowed + x->inputTime) = *(x->inShift + i) * *(x->analysisWindow + i); ++(x->inputTime); x->inputTime = x->inputTime & maskFFT; } - + mayer_realfft(x->sizeFFT, x->inWindowed); - - + + spectralgate_tilde_processSpect(x); - + mayer_realifft(x->sizeFFT, x->outShift); - + // now copy the output into the output buffer, multiplying by the window for(i = 0; i < x->sizeFFT; i++) { *(x->outBuffer + i) += *(x->outShift + x->outputTime) * *(x->synthesisWindow + i); @@ -438,19 +438,19 @@ void spectralgate_tilde_block(t_spectralgate *x) { t_int *spectralgate_perform(t_int *w) { - + t_spectralgate *x = (t_spectralgate *)(w[1]); t_float *in = (t_float *)(w[2]); t_float *out = (t_float *)(w[3]); int n = (int)(w[4]); - + // i like counting from zero, so i use sample to count the offset from // the start of the in and out blocks int i; // int j; // long frames; long framesLeft, processframes; - + framesLeft = n; @@ -462,9 +462,9 @@ t_int *spectralgate_perform(t_int *w) { // flush out previous output, copy in new input... // x->bufferPosition is used as a way to keep track of position in both // x->inBuffer and x->outBuffer - + memcpy(x->inBuffer+(x->bufferPosition), in, processframes * sizeof(float)); - + for (i=0; ioutBuffer[i+x->bufferPosition] * x->makeupGain; if(out[i] > 1000.0f) @@ -472,25 +472,25 @@ t_int *spectralgate_perform(t_int *w) { else if(out[i] < -1000.0f) out[i] = -1000.0f; } - // increment in and out pointers + // increment in and out pointers out += processframes; in += processframes; // increment bufferPostion, if the bufferPosition hits the blockSize (1/4 of FFT size) // perform another FFT. - + x->bufferPosition += processframes; if (x->bufferPosition >= x->blockSize){ - + x->bufferPosition = 0; spectralgate_tilde_block(x); } // decrement framesLeft by the number of frames (samples) processed framesLeft -= processframes; } - + return (w + 5); -} +} @@ -500,36 +500,36 @@ void spectralgate_tilde_initHammingWindows ( t_spectralgate *x ) { N = x->sizeFFT; for (k = 0; k < x->sizeFFT; k++ ) x->analysisWindow[k] = x->synthesisWindow[k] = (float) (.54f - (.46f * cosf(x->twoPi * k / (x->sizeFFT - 1)) ) ); - + } void spectralgate_tilde_scaleWindows (t_spectralgate *x) { long i; float a, b, sum, analFactor, synthFactor; - + a = 0.54f; b = 0.46f; sum = 0.0f; for (i = 0; i < x->sizeFFT; i++) sum += x->analysisWindow[i]; - + synthFactor = analFactor = 2.0f/sum; - + for (i = 0; i < x->sizeFFT; i++) { x->analysisWindow[i] *= analFactor; x->synthesisWindow[i] *= synthFactor; } - + sum = 0.0; for (i = 0; i < x->sizeFFT; i += x->blockSize) sum += x->synthesisWindow[i] * x->synthesisWindow[i]; - + sum = 0.5f/(sum * x->sizeFFT); - + for (i = 0; i < x->sizeFFT; i++) x->synthesisWindow[i] *= sum; -} +} @@ -571,17 +571,17 @@ void *spectralgate_new(t_symbol *table1) { x->outBuffer = (float *) malloc(sizeof(float) * x->sizeFFT); x->synthesisWindow = (float *) malloc(sizeof(float) * x->sizeFFT); x->analysisWindow = (float *) malloc(sizeof(float) * x->sizeFFT); - + // third - zero out all the memory for(i = 0; isizeFFT; i++) x->inBuffer[i] = x->outBuffer[i] = x->inShift[i] = x->outShift[i] = 0.0; // spectralcompand specific stuff x->gainTable = (float *) malloc(sizeof(float) * x->sizeFFT); - x->squareLevel = (float *) malloc(sizeof(float) * x->sizeFFT); + x->squareLevel = (float *) malloc(sizeof(float) * x->sizeFFT); x->tiltTable = (float *) malloc(sizeof(float) * x->sizeFFT); x->threshLearn = (float *) malloc(sizeof(float) * x->sizeFFT); - + for(i = 0; i < x->sizeFFT; i++) { x->threshLearn[i] = 0.0f; @@ -597,15 +597,15 @@ void *spectralgate_new(t_symbol *table1) { x->innerTweak[i] = 0.0f; x->threshTable[i] = 1.0f; } - + x->learnValue = 0.0f; x->learning = FALSE; x->learnFrames = 0; - - spectralgate_tilde_initHammingWindows( x ); // + + spectralgate_tilde_initHammingWindows( x ); // spectralgate_tilde_scaleWindows(x); // these we keep - + spectralgate_tilde_peaktrack(x, 0.0); spectralgate_tilde_threshold(x, -6.0); spectralgate_tilde_attack(x, 1.0); @@ -613,13 +613,13 @@ void *spectralgate_new(t_symbol *table1) { spectralgate_tilde_gain(x, 0.0); spectralgate_tilde_makeupgain(x, 0.0); spectralgate_tilde_tilt(x, 0.0); - - if(table1) { - x->x_array_points = 0; - spectralgate_tilde_set(x,table1); + + if(table1) { + x->x_array_points = 0; + spectralgate_tilde_set(x,table1); } - - + + return (x); } @@ -632,37 +632,37 @@ void spectralgate_free(t_spectralgate *x) { if(x->tiltTable) free(x->tiltTable); if(x->analysisWindow) free(x->analysisWindow); if(x->synthesisWindow) free(x->synthesisWindow); - if(x->threshLearn) free(x->threshLearn); + if(x->threshLearn) free(x->threshLearn); if(x->squareLevel) free(x->squareLevel) ; if(x->gainTable) free(x->gainTable); if(x->innerTweak) free(x->innerTweak); if(x->threshTable) free(x->threshTable); - + } void setup_0x2bspectralgate_tilde(void) { - spectralgate_class = class_new(gensym("+spectralgate~"), - (t_newmethod)spectralgate_new, + spectralgate_class = class_new(gensym("+spectralgate~"), + (t_newmethod)spectralgate_new, (t_method)spectralgate_free, - sizeof(t_spectralgate), - CLASS_DEFAULT, + sizeof(t_spectralgate), + CLASS_DEFAULT, A_DEFSYMBOL, A_DEFSYMBOL, 0); /* this is magic to declare that the leftmost, "main" inlet * takes signals; other signal inlets are done differently... */ - - /* also installs delay_time as the leftmost inlet float */ - + + /* also installs delay_time as the leftmost inlet float */ + CLASS_MAINSIGNALIN(spectralgate_class, t_spectralgate, makeupGain); /* here we tell Pd about the "dsp" method, which is called back when DSP is turned on. */ - - class_addmethod(spectralgate_class, (t_method) spectralgate_dsp, - gensym("dsp"), (t_atomtype)0); - - - + + class_addmethod(spectralgate_class, (t_method) spectralgate_dsp, + gensym("dsp"), (t_atomtype)0); + + + class_addmethod(spectralgate_class, (t_method) spectralgate_tilde_set, gensym("set"), A_SYMBOL, 0); class_addmethod(spectralgate_class, (t_method) spectralgate_tilde_type, gensym("type"), A_DEFFLOAT, 0); @@ -675,5 +675,4 @@ void setup_0x2bspectralgate_tilde(void) { class_addmethod(spectralgate_class, (t_method) spectralgate_tilde_gain, gensym("gain"), A_DEFFLOAT, 0); class_addmethod(spectralgate_class, (t_method) spectralgate_tilde_makeupgain, gensym("makeupgain"), A_DEFFLOAT, 0); class_addmethod(spectralgate_class, (t_method) spectralgate_tilde_tilt, gensym("tilt"), A_DEFFLOAT, 0); -} - +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..e1af94d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,157 @@ +name: Build CI + +on: + push: + pull_request: + branches: [ develop ] + +jobs: + +# =============================================================== +# =============================================================== +# =============================================================== + Linux-Build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install PureData + run: sudo apt-get install puredata -y + + - name: Downloads pd-Sources + run: | + PD_URL=$(curl -L -s https://api.github.com/repos/pure-data/pure-data/tags | grep zipball_url | grep -v latest | grep -v pd-0.54 | grep -v tagtest | head -n 1 | cut -d '"' -f 4) + curl -L -o pure-data.zip $PD_URL + unzip pure-data.zip + rm pure-data.zip + mv pure-data-* pure-data + + - name: Build pd-SoundHack + run: | + make install PDINCLUDEDIR=./pure-data/src PDLIBDIR=./pd-SoundHack + + - name: Upload Zip + uses: actions/upload-artifact@v4 + with: + name: SoundHack-Linux + path: ./pd-SoundHack/* + +# # # # =============================================================== +# # # # =============================================================== +# # # # =============================================================== + + Windows-Build: + runs-on: windows-latest + timeout-minutes: 25 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - if: runner.os == 'Windows' + name: "Install mingw deps" + uses: msys2/setup-msys2@v2 + with: + install: make mingw-w64-x86_64-gcc mingw64/mingw-w64-x86_64-ntldd-git mingw-w64-x86_64-fluidsynth mingw64/mingw-w64-x86_64-cmake unzip curl + update: false + + - if: runner.os == 'Windows' + name: Get Pd + shell: msys2 {0} + run: | + curl -L -o pure-data.zip http://msp.ucsd.edu/Software/pd-0.54-0.msw.zip + unzip pure-data.zip + rm pure-data.zip + rename pd-0.54-0 pure-data pd-0.54-0 + + - if: runner.os == 'Windows' + name: Build pd-else + shell: msys2 {0} + run: | + make install PDDIR=./pure-data PDLIBDIR=./pd-SoundHack + + - name: Upload Zip + uses: actions/upload-artifact@v4 + with: + name: SoundHack-Windows + path: ./pd-SoundHack/* + +# # =============================================================== +# # =============================================================== +# # =============================================================== + Mac-Intel: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: set Enviroment + run: | + brew cleanup --prune=all + brew install --cask pd + + - name: Build pd-SoundHack + run: | + make install PDLIBDIR=./pd-SoundHack + + - name: Upload Zip + uses: actions/upload-artifact@v4 + with: + name: SoundHack-macOS-intel + path: ./pd-SoundHack/* + +# =============================================================== +# =============================================================== +# =============================================================== + Mac-ARM: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: set Enviroment + run: | + brew cleanup --prune=all + brew install --cask pd + + - name: Build pd-SoundHack + run: | + make install PDLIBDIR=./pd-SoundHack arch=arm64 + + - name: Upload Zip + uses: actions/upload-artifact@v4 + with: + name: SoundHack-macoOS-arm + path: ./pd-SoundHack/* + +# =============================================================== +# =============================================================== +# =============================================================== + Mac-Universal: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: set Enviroment + run: | + brew cleanup --prune=all + brew install --cask pd + + - name: Build pd-SoundHack + run: | + make install PDLIBDIR=./pd-SoundHack arch="x86_64 arm64" + + - name: Upload Zip + uses: actions/upload-artifact@v4 + with: + name: SoundHack-macoOS-universal + path: ./pd-SoundHack/* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e5475a3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dep/pd-lib-builder"] + path = dep/pd-lib-builder + url = https://github.com/pure-data/pd-lib-builder.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..913e4ab --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +# Makefile for SoundHack + +lib.name = SoundHack + +class.sources = +binaural~.c +bubbler~.c +chebyshev~.c +compand~.c +decimate~.c +delay~.c \ + +matrix~.c +morphfilter~.c +pitchdelay~.c +spectralcompand~.c +spectralgate~.c + +datafiles = +binaural~-help.pd +bubbler~-help.pd +chebyshev~-help.pd +compand~-help.pd \ + +decimate~-help.pd +delay~-help.pd +matrix~-help.pd +morphfilter-help.pd +pitchdelay~-help.pd \ + +spectralcompand-help.pd +spectralgate-help.pd LICENSE.txt + +PDLIBBUILDER_DIR=dep/pd-lib-builder +include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder diff --git a/dep/pd-lib-builder b/dep/pd-lib-builder new file mode 160000 index 0000000..7752526 --- /dev/null +++ b/dep/pd-lib-builder @@ -0,0 +1 @@ +Subproject commit 77525265694bac50ed94c5ef62ebbae680c72ab0 diff --git a/makefile b/makefile deleted file mode 100644 index bdb1da3..0000000 --- a/makefile +++ /dev/null @@ -1,109 +0,0 @@ -SOURCES = +binaural~.c +bubbler~.c +chebyshev~.c +compand~.c +decimate~.c +delay~.c +matrix~.c +morphfilter~.c +pitchdelay~.c +spectralcompand~.c +spectralgate~.c - -LIBRARY_NAME := $(shell basename `pwd`) - -# ****SUPPLY THE LOCATION OF PD SOURCE**** -pd_src = /Applications/Pd-0.47-1-64bit.app/Contents/Resources/ - -objectsdir = $(pd_src)/extra - -CFLAGS = -DPD -I$(pd_src)/src -Wall -W -g -LDFLAGS = -LIBS = - -UNAME := $(shell uname -s) -ifeq ($(UNAME),Darwin) - SOURCES += - EXTENSION = pd_darwin - OS = macosx - OPT_CFLAGS = -O3 -ffast-math - FAT_FLAGS = -arch i386 -arch x86_64 -mmacosx-version-min=10.7 - CFLAGS += -fPIC $(FAT_FLAGS) - LDFLAGS += -bundle -undefined dynamic_lookup $(FAT_FLAGS) - LIBS += -lc - STRIP = strip -x - endif -ifeq ($(UNAME),Linux) - EXTENSION = pd_linux - OS = linux - OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer - CFLAGS += -fPIC - LDFLAGS += -Wl,--export-dynamic -shared -fPIC - LIBS += -lc - STRIP = strip --strip-unneeded -R .note -R .comment -endif -ifeq (MINGW,$(findstring MINGW,$(UNAME))) - SOURCES += - EXTENSION = dll - OS = windows - OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer -march=i686 -mtune=pentium4 - WINDOWS_HACKS = -D'O_NONBLOCK=1' - CFLAGS += -mms-bitfields $(WINDOWS_HACKS) - LDFLAGS += -s -shared -Wl,--enable-auto-import - LIBS += -L$(pd_src)/bin -L$(pd_src)/obj -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 - STRIP = strip --strip-unneeded -R .note -R .comment -endif - -CFLAGS += $(OPT_CFLAGS) - - -.PHONY = install libdir_install single_install install-doc install-exec clean dist etags - -all: $(SOURCES:.c=.$(EXTENSION)) - -%.o: %.c - $(CC) $(CFLAGS) -o "$*.o" -c "$*.c" - -%.$(EXTENSION): %.o - $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS) - chmod a-x "$*.$(EXTENSION)" - $(STRIP) $*.$(EXTENSION) - rm -f -- $*.o - -# this links everything into a single binary file -$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o - $(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS) - chmod a-x $(LIBRARY_NAME).$(EXTENSION) - $(STRIP) $(LIBRARY_NAME).$(EXTENSION) - rm -f -- $*.o - - -install: libdir_install - -# The meta and help files are explicitly installed to make sure they are -# actually there. Those files are not optional, then need to be there. -libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-exec - install -d $(objectsdir)/$(LIBRARY_NAME) - install -m644 -p $(LIBRARY_NAME)-meta.pd $(objectsdir)/$(LIBRARY_NAME) - install -m644 -p $(SOURCES:.c=.$(EXTENSION)) $(objectsdir)/$(LIBRARY_NAME) - -# install library linked as single binary -single_install: $(LIBRARY_NAME) install-doc install-exec - install -d $(objectsdir)/$(LIBRARY_NAME) - install -m644 -p $(LIBRARY_NAME).$(EXTENSION) $(objectsdir)/$(LIBRARY_NAME) - -install-doc: - install -d $(objectsdir)/$(LIBRARY_NAME) -# install -m644 -p $(SOURCES:.c=-help.pd) $(objectsdir)/$(LIBRARY_NAME) - install -m644 -p $(wildcard *.pd) $(objectsdir)/$(LIBRARY_NAME) - install -m644 -p README $(objectsdir)/$(LIBRARY_NAME)/README.txt - install -m644 -p VERSION $(objectsdir)/$(LIBRARY_NAME)/VERSION - install -m644 -p CHANGES $(objectsdir)/$(LIBRARY_NAME)/CHANGES.txt - -install-exec: - install -d $(objectsdir)/$(LIBRARY_NAME) - install -m644 -p $(wildcard *.pd) $(objectsdir)/$(LIBRARY_NAME) - - -clean: - -rm -f -- $(SOURCES:.c=.o) - -rm -f -- $(SOURCES:.c=.$(EXTENSION)) - -rm -f -- $(LIBRARY_NAME).$(EXTENSION) - - -dist: - cd .. && tar --exclude=.svn -cjpf $(LIBRARY_NAME)-$(OS).tar.bz2 $(LIBRARY_NAME) - - -etags: - etags *.[ch] ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h