History

trying some period detection hysteresis options

Matthew Wang committed 6 years ago

Commit 8f147941 parent c3197de5 files · +104 −53Browse files

Unified · Split

5 files
  1. LEAF/Inc/leaf-analysis.h +6 −0
  2. LEAF/Inc/leaf-effects.h +2 −0
  3. LEAF/Src/leaf-analysis.c +33 −8
  4. LEAF/Src/leaf-effects.c +52 −40
  5. LEAF/Src/leaf-math.c +11 −5
LEAF/Inc/leaf-analysis.h+6−0
@@ -239,6 +239,10 @@ extern "C" { · 238 unmodified lines
239239
240240 float fidelityThreshold;
241241
242+ float history;
243+ float alpha;
244+ float tolerance;
245+
242246 } _tPeriodDetection;
243247
244248 typedef _tPeriodDetection* tPeriodDetection;
@@ -253,6 +257,8 @@ extern "C" { · 8 unmodified lines
253257 void tPeriodDetection_setHopSize (tPeriodDetection* const, int hs);
254258 void tPeriodDetection_setWindowSize (tPeriodDetection* const, int ws);
255259 void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);
260+ void tPeriodDetection_setAlpha (tPeriodDetection* const, float alpha);
261+ void tPeriodDetection_setTolerance (tPeriodDetection* const, float tolerance);
256262
257263 //==============================================================================
258264
LEAF/Inc/leaf-effects.h+2−0
@@ -264,6 +264,8 @@ extern "C" { · 263 unmodified lines
264264 void tAutotune_setHopSize (tAutotune* const, int hs);
265265 void tAutotune_setWindowSize (tAutotune* const, int ws);
266266 void tAutotune_setFidelityThreshold (tAutotune* const, float threshold);
267+ void tAutotune_setAlpha (tAutotune* const, float alpha);
268+ void tAutotune_setTolerance (tAutotune* const, float tolerance);
267269 float tAutotune_getInputPeriod (tAutotune* const);
268270 float tAutotune_getInputFreq (tAutotune* const);
269271
LEAF/Src/leaf-analysis.c+33−8
@@ -1,10 +1,10 @@
11 /*==============================================================================
2−
3− leaf-analysis.c
4− Created: 30 Nov 2018 11:56:49am
5− Author: airship
6−
7−==============================================================================*/
2+
3+ leaf-analysis.c
4+ Created: 30 Nov 2018 11:56:49am
5+ Author: airship
6+
7+ ==============================================================================*/
88
99 #if _WIN32 || _WIN64
1010
@@ -504,7 +504,7 @@ void tSNAC_initToPool (tSNAC* const snac, int overlaparg, tMempool* const · 493 unmodified lines
504504 s->fidelity = 0.;
505505 s->minrms = DEFMINRMS;
506506 s->framesize = SNAC_FRAME_SIZE;
507−
507+
508508 s->inputbuf = (float*) mpool_calloc(sizeof(float) * SNAC_FRAME_SIZE, m);
509509 s->processbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE * 2), m);
510510 s->spectrumbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE / 2), m);
@@ -873,6 +873,10 @@ void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, flo · 362 unmodified lines
873873 p->timeConstant = DEFTIMECONSTANT;
874874 p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
875875 p->fidelityThreshold = 0.95;
876+
877+ p->history = 0.0f;
878+ p->alpha = 1.0f;
879+ p->tolerance = 1.0f;
876880 }
877881
878882 void tPeriodDetection_freeFromPool (tPeriodDetection* const pd, tMempool* const mp)
@@ -910,7 +914,15 @@ float tPeriodDetection_tick (tPeriodDetection* pd, float sample) · 31 unmodified lines
910914 tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);
911915 float fidelity = tSNAC_getFidelity(&p->snac);
912916 // Fidelity threshold recommended by Katja Vetters is 0.95 for most instruments/voices http://www.katjaas.nl/helmholtz/helmholtz.html
913− if (fidelity > p->fidelityThreshold) p->period = tSNAC_getPeriod(&p->snac);
917+ if (fidelity > p->fidelityThreshold)
918+ {
919+ float detected = tSNAC_getPeriod(&p->snac);
920+ p->history = detected * p->alpha + (p->history * (1 - p->alpha));
921+ float delta = 0.0f;
922+ if (detected > p->history) delta = (detected / p->history) - 1.0f;
923+ else delta = (p->history / detected) - 1.0f;
924+ if (delta < p->tolerance) p->period = detected;
925+ }
914926
915927 p->curBlock++;
916928 if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;
@@ -944,3 +956,16 @@ void tPeriodDetection_setFidelityThreshold(tPeriodDetection* pd, float threshold · 27 unmodified lines
944956 _tPeriodDetection* p = *pd;
945957 p->fidelityThreshold = threshold;
946958 }
959+
960+void tPeriodDetection_setAlpha (tPeriodDetection* pd, float alpha)
961+{
962+ _tPeriodDetection* p = *pd;
963+ p->alpha = LEAF_clip(0.0f, alpha, 1.0f);
964+}
965+
966+void tPeriodDetection_setTolerance (tPeriodDetection* pd, float tolerance)
967+{
968+ _tPeriodDetection* p = *pd;
969+ if (tolerance < 0.0f) p->tolerance = 0.0f;
970+ else p->tolerance = tolerance;
971+}
LEAF/Src/leaf-effects.c+52−40
@@ -254,7 +254,7 @@ float tTalkbox_tick(tTalkbox* const voc, float synth, float voice) · 253 unmodified lines
254254 v->pos = p0;
255255 v->FX = fx;
256256
257−
257+
258258 return o;
259259 }
260260
@@ -517,12 +517,12 @@ void tSOLAD_free(tSOLAD* const wp) · 256 unmodified lines
517517 void tSOLAD_initToPool (tSOLAD* const wp, tMempool* const mp)
518518 {
519519 _tMempool* m = *mp;
520−
520+
521521 _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m);
522522
523523 w->pitchfactor = 1.;
524524 w->delaybuf = (float*) mpool_calloc(sizeof(float) * (LOOPSIZE+16), m);
525−
525+
526526 solad_init(w);
527527 }
528528
@@ -900,9 +900,9 @@ void tPitchShift_free(tPitchShift* const psr) · 371 unmodified lines
900900 void tPitchShift_initToPool (tPitchShift* const psr, tPeriodDetection* const pd, float* out, int bufSize, tMempool* const mp)
901901 {
902902 _tMempool* m = *mp;
903−
903+
904904 _tPitchShift* ps = *psr = (_tPitchShift*) mpool_calloc(sizeof(_tPitchShift), m);
905−
905+
906906 _tPeriodDetection* p = *pd;
907907
908908 ps->p = pd;
@@ -1078,7 +1078,7 @@ void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, · 169 unmodified lines
10781078 tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
10791079
10801080 r->inputPeriod = 0.0f;
1081−
1081+
10821082 r->ps = (tPitchShift*) mpool_calloc(sizeof(tPitchShift) * r->numVoices, m);
10831083 r->pitchFactor = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
10841084 r->tickOutput = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
@@ -1088,7 +1088,7 @@ void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, · 3 unmodified lines
10881088 }
10891089
10901090 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1091−
1091+
10921092 for (int i = 0; i < r->numVoices; ++i)
10931093 {
10941094 tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);
@@ -1259,7 +1259,7 @@ void tAutotune_initToPool (tAutotune* const rt, int numVoices, int buf · 164 unmodified lines
12591259 }
12601260
12611261 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1262−
1262+
12631263 for (int i = 0; i < r->numVoices; ++i)
12641264 {
12651265 tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);
@@ -1293,15 +1293,15 @@ float* tAutotune_tick(tAutotune* const rt, float sample) · 27 unmodified lines
12931293
12941294 float tempPeriod = tPeriodDetection_tick(&r->pd, sample);
12951295 if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
1296− {
1297− r->inputPeriod = tempPeriod;
1298− }
1299−
1300− for (int v = 0; v < r->numVoices; ++v)
1301− {
1302− r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
1303− }
1304−
1296+ {
1297+ r->inputPeriod = tempPeriod;
1298+ }
1299+
1300+ for (int v = 0; v < r->numVoices; ++v)
1301+ {
1302+ r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
1303+ }
1304+
13051305 return r->tickOutput;
13061306 }
13071307
@@ -1376,10 +1376,22 @@ void tAutotune_setWindowSize(tAutotune* const rt, int ws) · 68 unmodified lines
13761376 void tAutotune_setFidelityThreshold(tAutotune* const rt, float threshold)
13771377 {
13781378 _tAutotune* r = *rt;
1379−
1379+
13801380 tPeriodDetection_setFidelityThreshold(&r->pd, threshold);
13811381 }
13821382
1383+void tAutotune_setAlpha (tAutotune* rt, float alpha)
1384+{
1385+ _tAutotune* r = *rt;
1386+ tPeriodDetection_setAlpha(&r->pd, alpha);
1387+}
1388+
1389+void tAutotune_setTolerance (tAutotune* rt, float tolerance)
1390+{
1391+ _tAutotune* r = *rt;
1392+ tPeriodDetection_setTolerance(&r->pd, tolerance);
1393+}
1394+
13831395 float tAutotune_getInputPeriod(tAutotune* const rt)
13841396 {
13851397 _tAutotune* r = *rt;
@@ -1413,7 +1425,7 @@ void tFormantShifter_init(tFormantShifter* const fsr, int order) · 27 unmodified lines
14131425 fs->fsmooth = (float*) leaf_calloc(sizeof(float) * fs->ford);
14141426 fs->ftvec = (float*) leaf_calloc(sizeof(float) * fs->ford);
14151427 fs->fbuff = (float*) leaf_calloc(sizeof(float*) * fs->ford);
1416−
1428+
14171429 fs->falph = powf(0.001f, 40.0f * leaf.invSampleRate);
14181430 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
14191431 fs->fhp = 0.0f;
@@ -1423,11 +1435,11 @@ void tFormantShifter_init(tFormantShifter* const fsr, int order) · 3 unmodified lines
14231435 fs->fmutealph = powf(0.001f, 0.5f * leaf.invSampleRate);
14241436 fs->cbi = 0;
14251437 fs->intensity = 1.0f;
1426− fs->invIntensity = 1.0f;
1427− tHighpass_init(&fs->hp, 10.0f);
1428− tHighpass_init(&fs->hp2, 10.0f);
1429− tFeedbackLeveler_init(&fs->fbl1, 0.99f, 0.005f, 0.125f, 0);
1430− tFeedbackLeveler_init(&fs->fbl2, 0.99f, 0.005f, 0.125f, 0);
1438+ fs->invIntensity = 1.0f;
1439+ tHighpass_init(&fs->hp, 10.0f);
1440+ tHighpass_init(&fs->hp2, 10.0f);
1441+ tFeedbackLeveler_init(&fs->fbl1, 0.99f, 0.005f, 0.125f, 0);
1442+ tFeedbackLeveler_init(&fs->fbl2, 0.99f, 0.005f, 0.125f, 0);
14311443 }
14321444
14331445 void tFormantShifter_free(tFormantShifter* const fsr)
@@ -1445,8 +1457,8 @@ void tFormantShifter_free(tFormantShifter* const fsr) · 11 unmodified lines
14451457 leaf_free(fs->fbuff);
14461458 tHighpass_free(&fs->hp);
14471459 tHighpass_free(&fs->hp2);
1448− tFeedbackLeveler_free(&fs->fbl1);
1449− tFeedbackLeveler_free(&fs->fbl2);
1460+ tFeedbackLeveler_free(&fs->fbl1);
1461+ tFeedbackLeveler_free(&fs->fbl2);
14501462 leaf_free(fs);
14511463 }
14521464
@@ -1466,7 +1478,7 @@ void tFormantShifter_initToPool (tFormantShifter* const fsr, int order, · 13 unmodified lines
14661478 fs->ftvec = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
14671479
14681480 fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);
1469−
1481+
14701482
14711483 fs->falph = powf(0.001f, 10.0f * leaf.invSampleRate);
14721484 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
@@ -1516,9 +1528,9 @@ float tFormantShifter_remove(tFormantShifter* const fsr, float in) · 43 unmodified lines
15161528 in = tFeedbackLeveler_tick(&fs->fbl1, in);
15171529 in = tHighpass_tick(&fs->hp, in * fs->intensity);
15181530
1519−
1531+
15201532 float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
1521−
1533+
15221534 ford = fs->ford;
15231535 falph = fs->falph;
15241536 foma = (1.0f - falph);
@@ -1544,7 +1556,7 @@ float tFormantShifter_remove(tFormantShifter* const fsr, float in) · 19 unmodified lines
15441556 fb = fc - tf*fa;
15451557 fa = fa - tf*fc;
15461558 }
1547−
1559+
15481560 //return fa * 0.1f;
15491561 return fa;
15501562 }
@@ -1555,7 +1567,7 @@ float tFormantShifter_add(tFormantShifter* const fsr, float in) · 4 unmodified lines
15551567
15561568 float fa, fb, fc, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
15571569 ford = fs->ford;
1558−
1570+
15591571 flpa = fs->flpa;
15601572 flamb = fs->flamb;
15611573 tf = fs->shiftFactor * (1.0f+flamb)/(1.0f-flamb);
@@ -1642,7 +1654,7 @@ float tFormantShifter_add(tFormantShifter* const fsr, float in) · 80 unmodified lines
16421654 // ...and we're done messing with formants
16431655 //tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
16441656 tf = tHighpass_tick(&fs->hp2, tanhf(tf));
1645−
1657+
16461658 return tf * fs->invIntensity;
16471659 }
16481660
@@ -1656,21 +1668,21 @@ void tFormantShifter_setShiftFactor(tFormantShifter* const fsr, float shiftFacto · 7 unmodified lines
16561668 void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)
16571669 {
16581670 _tFormantShifter* fs = *fsr;
1659−
1660−
1661−
1671+
1672+
1673+
16621674 fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);
1663−
1664− // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
1675+
1676+ // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
16651677 //tFeedbackLeveler_setTargetLevel(&fs->fbl2, fs->intensity);
16661678 //make sure you don't divide by zero, doofies
16671679 if (fs->intensity != 0.0f)
16681680 {
1669− fs->invIntensity = 1.0f/fs->intensity;
1681+ fs->invIntensity = 1.0f/fs->intensity;
16701682 }
16711683 else
16721684 {
1673− fs->invIntensity = 1.0f;
1685+ fs->invIntensity = 1.0f;
16741686 }
1675−
1687+
16761688 }
LEAF/Src/leaf-math.c+11−5
@@ -262,11 +262,17 @@ float LEAF_softClip(float val, float thresh) · 261 unmodified lines
262262
263263 float LEAF_clip(float min, float val, float max)
264264 {
265−
266− if (val < min) {
267− return min;
268− } else if (val > max) {
269− return max;
265+ int tempmin = min;
266+ int tempmax = max;
267+ if (min > max)
268+ {
269+ tempmin = max;
270+ tempmax = min;
271+ }
272+ if (val < tempmin) {
273+ return tempmin;
274+ } else if (val > tempmax) {
275+ return tempmax;
270276 } else {
271277 return val;
272278 }

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