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
86 86
87// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~87// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
88 88
89/* tSOLAD : pitch shifting algorithm that underlies tPitchShifter etc */89/* tSOLAD : pitch shifting algorithm that underlies tRetune etc */
90#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two90#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
91#define LOOPMASK (LOOPSIZE - 1)91#define LOOPMASK (LOOPSIZE - 1)
92#define PITCHFACTORDEFAULT 1.0f92#define PITCHFACTORDEFAULT 1.0f
@@ -111,99 +111,122 @@ typedef struct _tSOLAD · 18 unmodified lines
111 111
112void tSOLAD_init (tSOLAD* const);112void tSOLAD_init (tSOLAD* const);
113void tSOLAD_free (tSOLAD* const);113void tSOLAD_free (tSOLAD* const);
114
115// send one block of input samples, receive one block of output samples114// send one block of input samples, receive one block of output samples
116void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize);115void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize);
117
118// set periodicity analysis data116// set periodicity analysis data
119void tSOLAD_setPeriod (tSOLAD *w, float period);117void tSOLAD_setPeriod (tSOLAD *w, float period);
120
121// set pitch factor between 0.25 and 4118// set pitch factor between 0.25 and 4
122void tSOLAD_setPitchFactor (tSOLAD *w, float pitchfactor);119void tSOLAD_setPitchFactor (tSOLAD *w, float pitchfactor);
123
124// force readpointer lag120// force readpointer lag
125void tSOLAD_setReadLag (tSOLAD *w, float readlag);121void tSOLAD_setReadLag (tSOLAD *w, float readlag);
126
127// reset state variables122// reset state variables
128void tSOLAD_resetState (tSOLAD *w);123void tSOLAD_resetState (tSOLAD *w);
129 124
130// Pitch shifter125// Pitch shift
131typedef struct _tPitchShifter126typedef struct _tPitchShift
132{127{
133 tEnvPD env;
134 tSNAC snac;
135 tSOLAD sola;128 tSOLAD sola;
136 tHighpass hp;129 tHighpass hp;
130 tPeriodDetection* p;
137 131
138 float* inBuffer;
139 float* outBuffer;132 float* outBuffer;
140 int frameSize;133 int frameSize;
141 int bufSize;134 int bufSize;
135
142 int framesPerBuffer;136 int framesPerBuffer;
143 int curBlock;137 int curBlock;
144 int lastBlock;138 int lastBlock;
145 int index;139 int index;
146 140
141 float pitchFactor;
142 float timeConstant;
143 float radius;
144} tPitchShift;
145
146void tPitchShift_init (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize);
147void tPitchShift_free (tPitchShift* const);
148float tPitchShift_shift (tPitchShift* const);
149float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
150float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
151void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
152
153// Retune
154typedef 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
147 uint16_t hopSize;165 uint16_t hopSize;
148 uint16_t windowSize;166 uint16_t windowSize;
149 uint8_t fba;167 uint8_t fba;
150 168
151 float pitchFactor;169 float* pitchFactor;
152 float timeConstant;170 float timeConstant;
153 float radius;171 float radius;
154 float max;172
155 float lastmax;173 float inputPeriod;
156 float deltamax;174
157 175 int numVoices;
158} tPitchShifter;176} tRetune;
159 177
160void tPitchShifter_init (tPitchShifter* const, float* in, float* out, int bufSize, int frameSize);178void tRetune_init (tRetune* const, int numVoices, int bufSize, int frameSize);
161void tPitchShifter_free (tPitchShifter* const);179void tRetune_free (tRetune* const);
162 180
163float tPitchShifter_tick (tPitchShifter* const, float sample);181float* tRetune_tick (tRetune* const, float sample);
164float tPitchShifterToFreq_tick (tPitchShifter* const, float sample, float freq);182void tRetune_setNumVoices (tRetune* const, int numVoices);
165float tPitchShifterToFunc_tick (tPitchShifter* const, float sample, float (*fun)(float));183void tRetune_setPitchFactors (tRetune* const, float pf);
166void tPitchShifter_ioSamples_toFreq (tPitchShifter* const, float* in, float* out, int size, float toFreq);184void tRetune_setPitchFactor (tRetune* const, float pf, int voice);
167void tPitchShifter_ioSamples_toPeriod(tPitchShifter* const, float* in, float* out, int size, float toPeriod);185void tRetune_setTimeConstant (tRetune* const, float tc);
168void tPitchShifter_ioSamples_toFunc (tPitchShifter* const, float* in, float* out, int size, float (*fun)(float));186void tRetune_setHopSize (tRetune* const, int hs);
169void tPitchShifter_setPitchFactor (tPitchShifter* const, float pf);187void tRetune_setWindowSize (tRetune* const, int ws);
170void tPitchShifter_setTimeConstant (tPitchShifter* const, float tc);188float tRetune_getInputPeriod (tRetune* const);
171void tPitchShifter_setHopSize (tPitchShifter* const, int hs);189float tRetune_getInputFreq (tRetune* const);
172void tPitchShifter_setWindowSize (tPitchShifter* const, int ws);190
173float tPitchShifter_getPeriod (tPitchShifter* const);191// Autotune
174 192typedef struct _tAutotune
175//==============================================================================
176
177// Pitch shift
178typedef struct _tPitchShift
179{193{
180 tSOLAD sola;194 tPeriodDetection pd;
181 tHighpass hp;195 tPitchShift* ps;
182 tPeriodDetection* p;
183 196
184 float* outBuffer;197 float* inBuffer;
198 float** outBuffers;
199 float* tickOutput;
185 int frameSize;200 int frameSize;
186 int bufSize;201 int bufSize;
187 202
188 int framesPerBuffer;203 uint16_t hopSize;
189 int curBlock;204 uint16_t windowSize;
190 int lastBlock;205 uint8_t fba;
191 int index;
192 206
193 float pitchFactor;207 float* freq;
194 float timeConstant;208 float timeConstant;
195 float radius;209 float radius;
196} tPitchShift;210
211 float inputPeriod;
212
213 int numVoices;
214} tAutotune;
197 215
198void tPitchShift_init (tPitchShift* const,tPeriodDetection* const, float* out, int bufSize);216void tAutotune_init (tAutotune* const, int numVoices, int bufSize, int frameSize);
199void tPitchShift_free (tPitchShift* const);217void tAutotune_free (tAutotune* const);
200 218
201float tPitchShift_shift (tPitchShift* const);219float* tAutotune_tick (tAutotune* const, float sample);
202float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));220void tAutotune_setNumVoices (tAutotune* const, int numVoices);
203float tPitchShift_shiftToFreq (tPitchShift* const, float freq);221void tAutotune_setFreq (tAutotune* const, float f, int voice);
204void tPitchShift_setPitchFactor (tPitchShift* const, float pf);222void tAutotune_setTimeConstant (tAutotune* const, float tc);
223void tAutotune_setHopSize (tAutotune* const, int hs);
224void tAutotune_setWindowSize (tAutotune* const, int ws);
225float tAutotune_getInputPeriod (tAutotune* const);
226float tAutotune_getInputFreq (tAutotune* const);
205 227
206//==============================================================================228//==============================================================================
229
207 230
208#define FORD 7231#define FORD 7
209#define FORMANT_BUFFER_SIZE 2048232#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
402}402}
403 403
404//============================================================================================================404//============================================================================================================
405// PITCHSHIFTER405// RETUNE
406//============================================================================================================406//============================================================================================================
407static int pitchshifter_attackdetect(tPitchShifter* ps);
408 407
409void tPitchShifter_init(tPitchShifter* const ps, float* in, float* out, int bufSize, int frameSize)408void tRetune_init(tRetune* const r, int numVoices, int bufSize, int frameSize)
410{409{
411 ps->inBuffer = in;410 r->bufSize = bufSize;
412 ps->outBuffer = out;411 r->frameSize = frameSize;
413 ps->bufSize = bufSize;412 r->numVoices = numVoices;
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;
423 413
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);
425 416
426 tSNAC_init(&ps->snac, DEFOVERLAP);417 r->hopSize = DEFHOPSIZE;
427 418 r->windowSize = DEFWINDOWSIZE;
428 tSOLAD_init(&ps->sola);419 r->fba = FBA;
420 tRetune_setTimeConstant(r, DEFTIMECONSTANT);
429 421
430 tHighpass_init(&ps->hp, HPFREQ);422 tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
431 423
432 tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);424 r->inputPeriod = 0.0f;
433 425
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 }
435}432}
436 433
437void tPitchShifter_free(tPitchShifter* const ps)434void tRetune_free(tRetune* const r)
438{435{
439 tEnvPD_free(&ps->env);436 tPeriodDetection_free(&r->pd);
440 tSNAC_free(&ps->snac);437 for (int i = 0; i < r->numVoices; ++i)
441 tSOLAD_free(&ps->sola);438 {
442 tHighpass_free(&ps->hp);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);
443}445}
444 446
445float tPitchShifter_tick(tPitchShifter* ps, float sample)447float* tRetune_tick(tRetune* const r, float sample)
446{448{
447 float period, out;449 r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
448 int i, iLast;
449
450 i = (ps->curBlock*ps->frameSize);
451 iLast = (ps->lastBlock*ps->frameSize)+ps->index;
452 450
453 out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);451 for (int v = 0; v < r->numVoices; ++v)
454 ps->inBuffer[i+ps->index] = sample;
455
456 ps->index++;
457 if (ps->index >= ps->frameSize)
458 {452 {
459 ps->index = 0;453 r->tickOutput[v] = tPitchShift_shift(&r->ps[v]);
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
484 }454 }
485 455
486 return out;456 return r->tickOutput;
487}457}
488 458
489float tPitchShifterToFreq_tick(tPitchShifter* ps, float sample, float freq)459void tRetune_setNumVoices(tRetune* const r, int numVoices)
490{460{
491 float period, out;461 for (int i = 0; i < r->numVoices; ++i)
492 int i, iLast;462 {
493 463 tPitchShift_free(&r->ps[i]);
494 i = (ps->curBlock*ps->frameSize);464 leaf_free(r->outBuffers[i]);
495 iLast = (ps->lastBlock*ps->frameSize)+ps->index;465 }
466 leaf_free(r->ps);
467 leaf_free(r->outBuffers);
496 468
497 out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);469 r->numVoices = numVoices;
498 ps->inBuffer[i+ps->index] = sample;
499 470
500 ps->index++;471 r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
501 if (ps->index >= ps->frameSize)472 r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
473 for (int i = 0; i < r->numVoices; ++i)
502 {474 {
503 ps->index = 0;475 r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
504 476 tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
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;
526 }477 }
527 478
528 return out;479
529}480}
530 481
531float tPitchShifterToFunc_tick(tPitchShifter* ps, float sample, float (*fun)(float))482void tRetune_setPitchFactors(tRetune* const r, float pf)
532{483{
533 float period, out;484 for (int i = 0; i < r->numVoices; ++i)
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)
544 {485 {
545 ps->index = 0;486 r->pitchFactor[i] = pf;
546 487 tPitchShift_setPitchFactor(&r->ps[i], r->pitchFactor[i]);
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;
568 }488 }
569
570 return out;
571}489}
572 490
573void tPitchShifter_ioSamples(tPitchShifter* ps, float* in, float* out, int size)491void tRetune_setPitchFactor(tRetune* const r, float pf, int voice)
574{492{
575 float period;493 r->pitchFactor[voice] = pf;
576 494 tPitchShift_setPitchFactor(&r->ps[voice], r->pitchFactor[voice]);
577 tEnvPD_processBlock(&ps->env, in);495}
578 496
579 if(pitchshifter_attackdetect(ps) == 1)497void tRetune_setTimeConstant(tRetune* const r, float tc)
580 {498{
581 ps->fba = 5;499 r->timeConstant = tc;
582 tSOLAD_setReadLag(&ps->sola, ps->windowSize);500 r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
583 }501}
502
503void tRetune_setHopSize(tRetune* const r, int hs)
504{
505 r->hopSize = hs;
506 tPeriodDetection_setHopSize(&r->pd, r->hopSize);
507}
508
509void tRetune_setWindowSize(tRetune* const r, int ws)
510{
511 r->windowSize = ws;
512 tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
513}
514
515float tRetune_getInputPeriod(tRetune* const r)
516{
517 return r->inputPeriod;
518}
519
520float tRetune_getInputFreq(tRetune* const r)
521{
522 return 1.0f/r->inputPeriod;
523}
524
525//============================================================================================================
526// AUTOTUNE
527//============================================================================================================
528
529void tAutotune_init(tAutotune* const r, int numVoices, int bufSize, int frameSize)
530{
531 r->bufSize = bufSize;
532 r->frameSize = frameSize;
533 r->numVoices = numVoices;
584 534
585 tSNAC_ioSamples(&ps->snac, in, out, size);535 r->inBuffer = (float*) leaf_alloc(sizeof(float) * r->bufSize);
586 period = tSNAC_getPeriod(&ps->snac);536 r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
587 537
588 tSOLAD_setPeriod(&ps->sola, period);538 r->hopSize = DEFHOPSIZE;
539 r->windowSize = DEFWINDOWSIZE;
540 r->fba = FBA;
541 tAutotune_setTimeConstant(r, DEFTIMECONSTANT);
589 542
590 tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);543 tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
591 tSOLAD_ioSamples(&ps->sola, in, out, size);
592 544
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)
594 {547 {
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);
596 }550 }
551
552 r->inputPeriod = 0.0f;
597}553}
598 554
599void tPitchShifter_ioSamples_toFreq(tPitchShifter* ps, float* in, float* out, int size, float toFreq)555void tAutotune_free(tAutotune* const r)
600{556{
601 float period;557 tPeriodDetection_free(&r->pd);
602 558 for (int i = 0; i < r->numVoices; ++i)
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)
620 {559 {
621 out[cc] = tHighpass_tick(&ps->hp, out[cc]);560 tPitchShift_free(&r->ps[i]);
561 leaf_free(r->outBuffers[i]);
622 }562 }
563 leaf_free(r->ps);
564 leaf_free(r->inBuffer);
565 leaf_free(r->outBuffers);
623}566}
624 567
625void tPitchShifter_ioSamples_toPeriod(tPitchShifter* ps, float* in, float* out, int size, float toPeriod)568float* tAutotune_tick(tAutotune* const r, float sample)
626{569{
627 float period;570 r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
628 571
629 tEnvPD_processBlock(&ps->env, in);572 for (int v = 0; v < r->numVoices; ++v)
630
631 if(pitchshifter_attackdetect(ps) == 1)
632 {573 {
633 ps->fba = 5;574 r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
634 tSOLAD_setReadLag(&ps->sola, ps->windowSize);
635 }575 }
636 576
637 tSNAC_ioSamples(&ps->snac, in, out, size);577 return r->tickOutput;
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 }
649}578}
650 579
651void tPitchShifter_ioSamples_toFunc(tPitchShifter* ps, float* in, float* out, int size, float (*fun)(float))580void tAutotune_setNumVoices(tAutotune* const r, int numVoices)
652{581{
653 float period;582 for (int i = 0; i < r->numVoices; ++i)
654
655 tEnvPD_processBlock(&ps->env, in);
656
657 if(pitchshifter_attackdetect(ps) == 1)
658 {583 {
659 ps->fba = 5;584 tPitchShift_free(&r->ps[i]);
660 tSOLAD_setReadLag(&ps->sola, ps->windowSize);585 leaf_free(r->outBuffers[i]);
661 }586 }
587 leaf_free(r->ps);
588 leaf_free(r->outBuffers);
662 589
663 tSNAC_ioSamples(&ps->snac, in, out, size);590 r->numVoices = numVoices;
664 period = tSNAC_getPeriod(&ps->snac);
665 591
666 tSOLAD_setPeriod(&ps->sola, period);592 r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
667 ps->pitchFactor = period/fun(period);593 r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
668 tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);594 for (int i = 0; i < r->numVoices; ++i)
669 tSOLAD_ioSamples(&ps->sola, in, out, size);
670
671 for (int cc = 0; cc < size; ++cc)
672 {595 {
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);
674 }598 }
599
600
675}601}
676 602
677void tPitchShifter_setPitchFactor(tPitchShifter* ps, float pf)603void tAutotune_setFreq(tAutotune* const r, float f, int voice)
678{604{
679 ps->pitchFactor = pf;605 for (int i = 0; i < r->numVoices; ++i)
606 {
607 r->freq[i] = f;
608 }
680}609}
681 610
682void tPitchShifter_setTimeConstant(tPitchShifter* ps, float tc)611void tAutotune_setTimeConstant(tAutotune* const r, float tc)
683{612{
684 ps->timeConstant = tc;613 r->timeConstant = tc;
685 ps->radius = expf(-1000.0f * ps->hopSize * leaf.invSampleRate / ps->timeConstant);614 r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
686}615}
687 616
688void tPitchShifter_setHopSize(tPitchShifter* ps, int hs)617void tAutotune_setHopSize(tAutotune* const r, int hs)
689{618{
690 ps->hopSize = hs;619 r->hopSize = hs;
620 tPeriodDetection_setHopSize(&r->pd, r->hopSize);
691}621}
692 622
693void tPitchShifter_setWindowSize(tPitchShifter* ps, int ws)623void tAutotune_setWindowSize(tAutotune* const r, int ws)
694{624{
695 ps->windowSize = ws;625 r->windowSize = ws;
626 tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
696}627}
697 628
698float tPitchShifter_getPeriod(tPitchShifter* ps)629float tAutotune_getInputPeriod(tAutotune* const r)
699{630{
700 return tSNAC_getPeriod(&ps->snac);631 return r->inputPeriod;
701}632}
702 633
703static int pitchshifter_attackdetect(tPitchShifter* ps)634float tAutotune_getInputFreq(tAutotune* const r)
704{635{
705 float envout;636 return 1.0f/r->inputPeriod;
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;
727}637}
728 638
729
730//============================================================================================================639//============================================================================================================
731// PITCHSHIFT640// PITCHSHIFT
732//============================================================================================================641//============================================================================================================
@@ -735,7 +644,7 @@ static int pitchshift_attackdetect(tPitchShift* ps) · 2 unmodified lines
735{644{
736 float envout;645 float envout;
737 646
738 envout = tEnvPD_tick(&ps->p->env);647 envout = tEnv_tick(&ps->p->env);
739 648
740 if (envout >= 1.0f)649 if (envout >= 1.0f)
741 {650 {
@@ -757,7 +666,7 @@ static int pitchshift_attackdetect(tPitchShift* ps) · 15 unmodified lines
757 return (ps->p->fba == 0 && (ps->p->max > 60 && ps->p->deltamax > 6)) ? 1 : 0;666 return (ps->p->fba == 0 && (ps->p->max > 60 && ps->p->deltamax > 6)) ? 1 : 0;
758}667}
759 668
760void tPitchShift_init (tPitchShift* const ps,tPeriodDetection* p, float* out, int bufSize)669void tPitchShift_init (tPitchShift* const ps, tPeriodDetection* p, float* out, int bufSize)
761{670{
762 ps->p = p;671 ps->p = p;
763 672

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