History

replace pitchshifter with retune and autotune

Matthew Wang committed 7 years ago

Commit dd56c541 parent 7803edf3 files · +231 −299Browse files

Unified · Split

3 files
  1. LEAF/Inc/.DS_Store +0 −0
  2. LEAF/Inc/leaf-effects.h +76 −53
  3. LEAF/Src/leaf-effects.c +156 −247
LEAF/Inc/.DS_Store+0−0

Binary file not shown.

LEAF/Inc/leaf-effects.h+76−53
@@ -86,7 +86,7 @@ void tVocoder_suspend (tVocoder* const); · 85 unmodified lines
8686
8787 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
8888
89−/* tSOLAD : pitch shifting algorithm that underlies tPitchShifter etc */
89+/* tSOLAD : pitch shifting algorithm that underlies tRetune etc */
9090 #define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
9191 #define LOOPMASK (LOOPSIZE - 1)
9292 #define PITCHFACTORDEFAULT 1.0f
@@ -111,99 +111,122 @@ typedef struct _tSOLAD · 18 unmodified lines
111111
112112 void tSOLAD_init (tSOLAD* const);
113113 void tSOLAD_free (tSOLAD* const);
114−
115114 // send one block of input samples, receive one block of output samples
116115 void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize);
117−
118116 // set periodicity analysis data
119117 void tSOLAD_setPeriod (tSOLAD *w, float period);
120−
121118 // set pitch factor between 0.25 and 4
122119 void tSOLAD_setPitchFactor (tSOLAD *w, float pitchfactor);
123−
124120 // force readpointer lag
125121 void tSOLAD_setReadLag (tSOLAD *w, float readlag);
126−
127122 // reset state variables
128123 void tSOLAD_resetState (tSOLAD *w);
129124
130−// Pitch shifter
131−typedef struct _tPitchShifter
125+// Pitch shift
126+typedef struct _tPitchShift
132127 {
133− tEnvPD env;
134− tSNAC snac;
135128 tSOLAD sola;
136129 tHighpass hp;
130+ tPeriodDetection* p;
137131
138− float* inBuffer;
139132 float* outBuffer;
140133 int frameSize;
141134 int bufSize;
135+
142136 int framesPerBuffer;
143137 int curBlock;
144138 int lastBlock;
145139 int index;
146140
141+ float pitchFactor;
142+ float timeConstant;
143+ float radius;
144+} tPitchShift;
145+
146+void tPitchShift_init (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize);
147+void tPitchShift_free (tPitchShift* const);
148+float tPitchShift_shift (tPitchShift* const);
149+float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
150+float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
151+void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
152+
153+// Retune
154+typedef struct _tRetune
155+{
156+ tPeriodDetection pd;
157+ tPitchShift* ps;
158+
159+ float* inBuffer;
160+ float** outBuffers;
161+ float* tickOutput;
162+ int frameSize;
163+ int bufSize;
164+
147165 uint16_t hopSize;
148166 uint16_t windowSize;
149167 uint8_t fba;
150168
151− float pitchFactor;
169+ float* pitchFactor;
152170 float timeConstant;
153171 float radius;
154− float max;
155− float lastmax;
156− float deltamax;
157−
158−} tPitchShifter;
159−
160−void tPitchShifter_init (tPitchShifter* const, float* in, float* out, int bufSize, int frameSize);
161−void tPitchShifter_free (tPitchShifter* const);
162−
163−float tPitchShifter_tick (tPitchShifter* const, float sample);
164−float tPitchShifterToFreq_tick (tPitchShifter* const, float sample, float freq);
165−float tPitchShifterToFunc_tick (tPitchShifter* const, float sample, float (*fun)(float));
166−void tPitchShifter_ioSamples_toFreq (tPitchShifter* const, float* in, float* out, int size, float toFreq);
167−void tPitchShifter_ioSamples_toPeriod(tPitchShifter* const, float* in, float* out, int size, float toPeriod);
168−void tPitchShifter_ioSamples_toFunc (tPitchShifter* const, float* in, float* out, int size, float (*fun)(float));
169−void tPitchShifter_setPitchFactor (tPitchShifter* const, float pf);
170−void tPitchShifter_setTimeConstant (tPitchShifter* const, float tc);
171−void tPitchShifter_setHopSize (tPitchShifter* const, int hs);
172−void tPitchShifter_setWindowSize (tPitchShifter* const, int ws);
173−float tPitchShifter_getPeriod (tPitchShifter* const);
174−
175−//==============================================================================
176−
177−// Pitch shift
178−typedef struct _tPitchShift
172+
173+ float inputPeriod;
174+
175+ int numVoices;
176+} tRetune;
177+
178+void tRetune_init (tRetune* const, int numVoices, int bufSize, int frameSize);
179+void tRetune_free (tRetune* const);
180+
181+float* tRetune_tick (tRetune* const, float sample);
182+void tRetune_setNumVoices (tRetune* const, int numVoices);
183+void tRetune_setPitchFactors (tRetune* const, float pf);
184+void tRetune_setPitchFactor (tRetune* const, float pf, int voice);
185+void tRetune_setTimeConstant (tRetune* const, float tc);
186+void tRetune_setHopSize (tRetune* const, int hs);
187+void tRetune_setWindowSize (tRetune* const, int ws);
188+float tRetune_getInputPeriod (tRetune* const);
189+float tRetune_getInputFreq (tRetune* const);
190+
191+// Autotune
192+typedef struct _tAutotune
179193 {
180− tSOLAD sola;
181− tHighpass hp;
182− tPeriodDetection* p;
194+ tPeriodDetection pd;
195+ tPitchShift* ps;
183196
184− float* outBuffer;
197+ float* inBuffer;
198+ float** outBuffers;
199+ float* tickOutput;
185200 int frameSize;
186201 int bufSize;
187202
188− int framesPerBuffer;
189− int curBlock;
190− int lastBlock;
191− int index;
203+ uint16_t hopSize;
204+ uint16_t windowSize;
205+ uint8_t fba;
192206
193− float pitchFactor;
207+ float* freq;
194208 float timeConstant;
195209 float radius;
196−} tPitchShift;
210+
211+ float inputPeriod;
212+
213+ int numVoices;
214+} tAutotune;
197215
198−void tPitchShift_init (tPitchShift* const,tPeriodDetection* const, float* out, int bufSize);
199−void tPitchShift_free (tPitchShift* const);
216+void tAutotune_init (tAutotune* const, int numVoices, int bufSize, int frameSize);
217+void tAutotune_free (tAutotune* const);
200218
201−float tPitchShift_shift (tPitchShift* const);
202−float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
203−float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
204−void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
219+float* tAutotune_tick (tAutotune* const, float sample);
220+void tAutotune_setNumVoices (tAutotune* const, int numVoices);
221+void tAutotune_setFreq (tAutotune* const, float f, int voice);
222+void tAutotune_setTimeConstant (tAutotune* const, float tc);
223+void tAutotune_setHopSize (tAutotune* const, int hs);
224+void tAutotune_setWindowSize (tAutotune* const, int ws);
225+float tAutotune_getInputPeriod (tAutotune* const);
226+float tAutotune_getInputFreq (tAutotune* const);
205227
206228 //==============================================================================
229+
207230
208231 #define FORD 7
209232 #define FORMANT_BUFFER_SIZE 2048
LEAF/Src/leaf-effects.c+156−247
@@ -402,331 +402,240 @@ void tVocoder_suspend (tVocoder* const v) · 401 unmodified lines
402402 }
403403
404404 //============================================================================================================
405−// PITCHSHIFTER
405+// RETUNE
406406 //============================================================================================================
407−static int pitchshifter_attackdetect(tPitchShifter* ps);
408407
409−void tPitchShifter_init(tPitchShifter* const ps, float* in, float* out, int bufSize, int frameSize)
408+void tRetune_init(tRetune* const r, int numVoices, int bufSize, int frameSize)
410409 {
411− ps->inBuffer = in;
412− ps->outBuffer = out;
413− ps->bufSize = bufSize;
414− ps->frameSize = frameSize;
415− ps->framesPerBuffer = ps->bufSize / ps->frameSize;
416− ps->curBlock = 1;
417− ps->lastBlock = 0;
418− ps->index = 0;
419−
420− ps->hopSize = DEFHOPSIZE;
421− ps->windowSize = DEFWINDOWSIZE;
422− ps->fba = FBA;
410+ r->bufSize = bufSize;
411+ r->frameSize = frameSize;
412+ r->numVoices = numVoices;
423413
424− tEnvPD_init(&ps->env, ps->windowSize, ps->hopSize, ps->frameSize);
414+ r->inBuffer = (float*) leaf_alloc(sizeof(float) * r->bufSize);
415+ r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
425416
426− tSNAC_init(&ps->snac, DEFOVERLAP);
427−
428− tSOLAD_init(&ps->sola);
417+ r->hopSize = DEFHOPSIZE;
418+ r->windowSize = DEFWINDOWSIZE;
419+ r->fba = FBA;
420+ tRetune_setTimeConstant(r, DEFTIMECONSTANT);
429421
430− tHighpass_init(&ps->hp, HPFREQ);
422+ tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
431423
432− tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
424+ r->inputPeriod = 0.0f;
433425
434− tPitchShifter_setTimeConstant(ps, DEFTIMECONSTANT);
426+ r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
427+ for (int i = 0; i < r->numVoices; ++i)
428+ {
429+ r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
430+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
431+ }
435432 }
436433
437−void tPitchShifter_free(tPitchShifter* const ps)
434+void tRetune_free(tRetune* const r)
438435 {
439− tEnvPD_free(&ps->env);
440− tSNAC_free(&ps->snac);
441− tSOLAD_free(&ps->sola);
442− tHighpass_free(&ps->hp);
436+ tPeriodDetection_free(&r->pd);
437+ for (int i = 0; i < r->numVoices; ++i)
438+ {
439+ tPitchShift_free(&r->ps[i]);
440+ leaf_free(r->outBuffers[i]);
441+ }
442+ leaf_free(r->ps);
443+ leaf_free(r->inBuffer);
444+ leaf_free(r->outBuffers);
443445 }
444446
445−float tPitchShifter_tick(tPitchShifter* ps, float sample)
447+float* tRetune_tick(tRetune* const r, float sample)
446448 {
447− float period, out;
448− int i, iLast;
449−
450− i = (ps->curBlock*ps->frameSize);
451− iLast = (ps->lastBlock*ps->frameSize)+ps->index;
449+ r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
452450
453− out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
454− ps->inBuffer[i+ps->index] = sample;
455−
456− ps->index++;
457− if (ps->index >= ps->frameSize)
451+ for (int v = 0; v < r->numVoices; ++v)
458452 {
459− ps->index = 0;
460−
461− tEnvPD_processBlock(&ps->env, &(ps->inBuffer[i]));
462−
463− if(pitchshifter_attackdetect(ps) == 1)
464− {
465− ps->fba = 5;
466− tSOLAD_setReadLag(&ps->sola, ps->windowSize);
467− }
468−
469− tSNAC_ioSamples(&ps->snac, &(ps->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
470− period = tSNAC_getPeriod(&ps->snac);
471−
472− ps->curBlock++;
473− if (ps->curBlock >= ps->framesPerBuffer) ps->curBlock = 0;
474− ps->lastBlock++;
475− if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
476−
477− //separate here
478−
479− tSOLAD_setPeriod(&ps->sola, period);
480−
481− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
482− tSOLAD_ioSamples(&ps->sola, &(ps->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
483−
453+ r->tickOutput[v] = tPitchShift_shift(&r->ps[v]);
484454 }
485−
486− return out;
455+
456+ return r->tickOutput;
487457 }
488458
489−float tPitchShifterToFreq_tick(tPitchShifter* ps, float sample, float freq)
459+void tRetune_setNumVoices(tRetune* const r, int numVoices)
490460 {
491− float period, out;
492− int i, iLast;
493−
494− i = (ps->curBlock*ps->frameSize);
495− iLast = (ps->lastBlock*ps->frameSize)+ps->index;
461+ for (int i = 0; i < r->numVoices; ++i)
462+ {
463+ tPitchShift_free(&r->ps[i]);
464+ leaf_free(r->outBuffers[i]);
465+ }
466+ leaf_free(r->ps);
467+ leaf_free(r->outBuffers);
496468
497− out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
498− ps->inBuffer[i+ps->index] = sample;
469+ r->numVoices = numVoices;
499470
500− ps->index++;
501− if (ps->index >= ps->frameSize)
471+ r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
472+ r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
473+ for (int i = 0; i < r->numVoices; ++i)
502474 {
503− ps->index = 0;
504−
505− tEnvPD_processBlock(&ps->env, &(ps->inBuffer[i]));
506−
507− if(pitchshifter_attackdetect(ps) == 1)
508− {
509− ps->fba = 5;
510− tSOLAD_setReadLag(&ps->sola, ps->windowSize);
511− }
512−
513− tSNAC_ioSamples(&ps->snac, &(ps->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
514− period = tSNAC_getPeriod(&ps->snac);
515−
516− tSOLAD_setPeriod(&ps->sola, period);
517−
518− ps->pitchFactor = period*freq*leaf.invSampleRate;
519− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
520− tSOLAD_ioSamples(&ps->sola, &(ps->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
521−
522− ps->curBlock++;
523− if (ps->curBlock >= ps->framesPerBuffer) ps->curBlock = 0;
524− ps->lastBlock++;
525− if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
475+ r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
476+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
526477 }
527478
528− return out;
479+
529480 }
530481
531−float tPitchShifterToFunc_tick(tPitchShifter* ps, float sample, float (*fun)(float))
482+void tRetune_setPitchFactors(tRetune* const r, float pf)
532483 {
533− float period, out;
534− int i, iLast;
535−
536− i = (ps->curBlock*ps->frameSize);
537− iLast = (ps->lastBlock*ps->frameSize)+ps->index;
538−
539− out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
540− ps->inBuffer[i+ps->index] = sample;
541−
542− ps->index++;
543− if (ps->index >= ps->frameSize)
484+ for (int i = 0; i < r->numVoices; ++i)
544485 {
545− ps->index = 0;
546−
547− tEnvPD_processBlock(&ps->env, &(ps->inBuffer[i]));
548−
549− if(pitchshifter_attackdetect(ps) == 1)
550− {
551− ps->fba = 5;
552− tSOLAD_setReadLag(&ps->sola, ps->windowSize);
553− }
554−
555− tSNAC_ioSamples(&ps->snac, (&ps->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
556− period = tSNAC_getPeriod(&ps->snac);
557−
558− tSOLAD_setPeriod(&ps->sola, period);
559−
560− ps->pitchFactor = period/fun(period);
561− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
562− tSOLAD_ioSamples(&ps->sola, &(ps->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
563−
564− ps->curBlock++;
565− if (ps->curBlock >= ps->framesPerBuffer) ps->curBlock = 0;
566− ps->lastBlock++;
567− if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
486+ r->pitchFactor[i] = pf;
487+ tPitchShift_setPitchFactor(&r->ps[i], r->pitchFactor[i]);
568488 }
569−
570− return out;
571489 }
572490
573−void tPitchShifter_ioSamples(tPitchShifter* ps, float* in, float* out, int size)
491+void tRetune_setPitchFactor(tRetune* const r, float pf, int voice)
574492 {
575− float period;
576−
577− tEnvPD_processBlock(&ps->env, in);
578−
579− if(pitchshifter_attackdetect(ps) == 1)
580− {
581− ps->fba = 5;
582− tSOLAD_setReadLag(&ps->sola, ps->windowSize);
583− }
493+ r->pitchFactor[voice] = pf;
494+ tPitchShift_setPitchFactor(&r->ps[voice], r->pitchFactor[voice]);
495+}
496+
497+void tRetune_setTimeConstant(tRetune* const r, float tc)
498+{
499+ r->timeConstant = tc;
500+ r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
501+}
502+
503+void tRetune_setHopSize(tRetune* const r, int hs)
504+{
505+ r->hopSize = hs;
506+ tPeriodDetection_setHopSize(&r->pd, r->hopSize);
507+}
508+
509+void tRetune_setWindowSize(tRetune* const r, int ws)
510+{
511+ r->windowSize = ws;
512+ tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
513+}
514+
515+float tRetune_getInputPeriod(tRetune* const r)
516+{
517+ return r->inputPeriod;
518+}
519+
520+float tRetune_getInputFreq(tRetune* const r)
521+{
522+ return 1.0f/r->inputPeriod;
523+}
524+
525+//============================================================================================================
526+// AUTOTUNE
527+//============================================================================================================
528+
529+void tAutotune_init(tAutotune* const r, int numVoices, int bufSize, int frameSize)
530+{
531+ r->bufSize = bufSize;
532+ r->frameSize = frameSize;
533+ r->numVoices = numVoices;
584534
585− tSNAC_ioSamples(&ps->snac, in, out, size);
586− period = tSNAC_getPeriod(&ps->snac);
535+ r->inBuffer = (float*) leaf_alloc(sizeof(float) * r->bufSize);
536+ r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
587537
588− tSOLAD_setPeriod(&ps->sola, period);
538+ r->hopSize = DEFHOPSIZE;
539+ r->windowSize = DEFWINDOWSIZE;
540+ r->fba = FBA;
541+ tAutotune_setTimeConstant(r, DEFTIMECONSTANT);
589542
590− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
591− tSOLAD_ioSamples(&ps->sola, in, out, size);
543+ tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
592544
593− for (int cc = 0; cc < size; ++cc)
545+ r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
546+ for (int i = 0; i < r->numVoices; ++i)
594547 {
595− out[cc] = tHighpass_tick(&ps->hp, out[cc]);
548+ r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
549+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
596550 }
551+
552+ r->inputPeriod = 0.0f;
597553 }
598554
599−void tPitchShifter_ioSamples_toFreq(tPitchShifter* ps, float* in, float* out, int size, float toFreq)
555+void tAutotune_free(tAutotune* const r)
600556 {
601− float period;
602−
603− tEnvPD_processBlock(&ps->env, in);
604−
605− if(pitchshifter_attackdetect(ps) == 1)
606− {
607− ps->fba = 5;
608− tSOLAD_setReadLag(&ps->sola, ps->windowSize);
609− }
610−
611− tSNAC_ioSamples(&ps->snac, in, out, size);
612− period = tSNAC_getPeriod(&ps->snac);
613−
614− tSOLAD_setPeriod(&ps->sola, period);
615− ps->pitchFactor = period*toFreq;
616− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
617− tSOLAD_ioSamples(&ps->sola, in, out, size);
618−
619− for (int cc = 0; cc < size; ++cc)
557+ tPeriodDetection_free(&r->pd);
558+ for (int i = 0; i < r->numVoices; ++i)
620559 {
621− out[cc] = tHighpass_tick(&ps->hp, out[cc]);
560+ tPitchShift_free(&r->ps[i]);
561+ leaf_free(r->outBuffers[i]);
622562 }
563+ leaf_free(r->ps);
564+ leaf_free(r->inBuffer);
565+ leaf_free(r->outBuffers);
623566 }
624567
625−void tPitchShifter_ioSamples_toPeriod(tPitchShifter* ps, float* in, float* out, int size, float toPeriod)
568+float* tAutotune_tick(tAutotune* const r, float sample)
626569 {
627− float period;
570+ r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
628571
629− tEnvPD_processBlock(&ps->env, in);
630−
631− if(pitchshifter_attackdetect(ps) == 1)
572+ for (int v = 0; v < r->numVoices; ++v)
632573 {
633− ps->fba = 5;
634− tSOLAD_setReadLag(&ps->sola, ps->windowSize);
574+ r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
635575 }
636576
637− tSNAC_ioSamples(&ps->snac, in, out, size);
638− period = tSNAC_getPeriod(&ps->snac);
639−
640− tSOLAD_setPeriod(&ps->sola, period);
641− ps->pitchFactor = period/toPeriod;
642− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
643− tSOLAD_ioSamples(&ps->sola, in, out, size);
644−
645− for (int cc = 0; cc < size; ++cc)
646− {
647− out[cc] = tHighpass_tick(&ps->hp, out[cc]);
648− }
577+ return r->tickOutput;
649578 }
650579
651−void tPitchShifter_ioSamples_toFunc(tPitchShifter* ps, float* in, float* out, int size, float (*fun)(float))
580+void tAutotune_setNumVoices(tAutotune* const r, int numVoices)
652581 {
653− float period;
654−
655− tEnvPD_processBlock(&ps->env, in);
656−
657− if(pitchshifter_attackdetect(ps) == 1)
582+ for (int i = 0; i < r->numVoices; ++i)
658583 {
659− ps->fba = 5;
660− tSOLAD_setReadLag(&ps->sola, ps->windowSize);
584+ tPitchShift_free(&r->ps[i]);
585+ leaf_free(r->outBuffers[i]);
661586 }
587+ leaf_free(r->ps);
588+ leaf_free(r->outBuffers);
662589
663− tSNAC_ioSamples(&ps->snac, in, out, size);
664− period = tSNAC_getPeriod(&ps->snac);
590+ r->numVoices = numVoices;
665591
666− tSOLAD_setPeriod(&ps->sola, period);
667− ps->pitchFactor = period/fun(period);
668− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
669− tSOLAD_ioSamples(&ps->sola, in, out, size);
670−
671− for (int cc = 0; cc < size; ++cc)
592+ r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
593+ r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
594+ for (int i = 0; i < r->numVoices; ++i)
672595 {
673− out[cc] = tHighpass_tick(&ps->hp, out[cc]);
596+ r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
597+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
674598 }
599+
600+
675601 }
676602
677−void tPitchShifter_setPitchFactor(tPitchShifter* ps, float pf)
603+void tAutotune_setFreq(tAutotune* const r, float f, int voice)
678604 {
679− ps->pitchFactor = pf;
605+ for (int i = 0; i < r->numVoices; ++i)
606+ {
607+ r->freq[i] = f;
608+ }
680609 }
681610
682−void tPitchShifter_setTimeConstant(tPitchShifter* ps, float tc)
611+void tAutotune_setTimeConstant(tAutotune* const r, float tc)
683612 {
684− ps->timeConstant = tc;
685− ps->radius = expf(-1000.0f * ps->hopSize * leaf.invSampleRate / ps->timeConstant);
613+ r->timeConstant = tc;
614+ r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
686615 }
687616
688−void tPitchShifter_setHopSize(tPitchShifter* ps, int hs)
617+void tAutotune_setHopSize(tAutotune* const r, int hs)
689618 {
690− ps->hopSize = hs;
619+ r->hopSize = hs;
620+ tPeriodDetection_setHopSize(&r->pd, r->hopSize);
691621 }
692622
693−void tPitchShifter_setWindowSize(tPitchShifter* ps, int ws)
623+void tAutotune_setWindowSize(tAutotune* const r, int ws)
694624 {
695− ps->windowSize = ws;
625+ r->windowSize = ws;
626+ tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
696627 }
697628
698−float tPitchShifter_getPeriod(tPitchShifter* ps)
629+float tAutotune_getInputPeriod(tAutotune* const r)
699630 {
700− return tSNAC_getPeriod(&ps->snac);
631+ return r->inputPeriod;
701632 }
702633
703−static int pitchshifter_attackdetect(tPitchShifter* ps)
634+float tAutotune_getInputFreq(tAutotune* const r)
704635 {
705− float envout;
706−
707− envout = tEnvPD_tick(&ps->env);
708−
709− if (envout >= 1.0f)
710− {
711− ps->lastmax = ps->max;
712− if (envout > ps->max)
713− {
714− ps->max = envout;
715− }
716− else
717− {
718− ps->deltamax = envout - ps->max;
719− ps->max = ps->max * ps->radius;
720− }
721− ps->deltamax = ps->max - ps->lastmax;
722− }
723−
724− ps->fba = ps->fba ? (ps->fba - 1) : 0;
725−
726− return (ps->fba == 0 && (ps->max > 60 && ps->deltamax > 6)) ? 1 : 0;
636+ return 1.0f/r->inputPeriod;
727637 }
728638
729−
730639 //============================================================================================================
731640 // PITCHSHIFT
732641 //============================================================================================================
@@ -735,7 +644,7 @@ static int pitchshift_attackdetect(tPitchShift* ps) · 2 unmodified lines
735644 {
736645 float envout;
737646
738− envout = tEnvPD_tick(&ps->p->env);
647+ envout = tEnv_tick(&ps->p->env);
739648
740649 if (envout >= 1.0f)
741650 {
@@ -757,7 +666,7 @@ static int pitchshift_attackdetect(tPitchShift* ps) · 15 unmodified lines
757666 return (ps->p->fba == 0 && (ps->p->max > 60 && ps->p->deltamax > 6)) ? 1 : 0;
758667 }
759668
760−void tPitchShift_init (tPitchShift* const ps,tPeriodDetection* p, float* out, int bufSize)
669+void tPitchShift_init (tPitchShift* const ps, tPeriodDetection* p, float* out, int bufSize)
761670 {
762671 ps->p = p;
763672

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t