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
239 239
240 float fidelityThreshold;240 float fidelityThreshold;
241 241
242 float history;
243 float alpha;
244 float tolerance;
245
242 } _tPeriodDetection;246 } _tPeriodDetection;
243 247
244 typedef _tPeriodDetection* tPeriodDetection;248 typedef _tPeriodDetection* tPeriodDetection;
@@ -253,6 +257,8 @@ extern "C" { · 8 unmodified lines
253 void tPeriodDetection_setHopSize (tPeriodDetection* const, int hs);257 void tPeriodDetection_setHopSize (tPeriodDetection* const, int hs);
254 void tPeriodDetection_setWindowSize (tPeriodDetection* const, int ws);258 void tPeriodDetection_setWindowSize (tPeriodDetection* const, int ws);
255 void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);259 void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);
260 void tPeriodDetection_setAlpha (tPeriodDetection* const, float alpha);
261 void tPeriodDetection_setTolerance (tPeriodDetection* const, float tolerance);
256 262
257 //==============================================================================263 //==============================================================================
258 264
LEAF/Inc/leaf-effects.h+2−0
@@ -264,6 +264,8 @@ extern "C" { · 263 unmodified lines
264 void tAutotune_setHopSize (tAutotune* const, int hs);264 void tAutotune_setHopSize (tAutotune* const, int hs);
265 void tAutotune_setWindowSize (tAutotune* const, int ws);265 void tAutotune_setWindowSize (tAutotune* const, int ws);
266 void tAutotune_setFidelityThreshold (tAutotune* const, float threshold);266 void tAutotune_setFidelityThreshold (tAutotune* const, float threshold);
267 void tAutotune_setAlpha (tAutotune* const, float alpha);
268 void tAutotune_setTolerance (tAutotune* const, float tolerance);
267 float tAutotune_getInputPeriod (tAutotune* const);269 float tAutotune_getInputPeriod (tAutotune* const);
268 float tAutotune_getInputFreq (tAutotune* const);270 float tAutotune_getInputFreq (tAutotune* const);
269 271
LEAF/Src/leaf-analysis.c+33−8
@@ -1,10 +1,10 @@
1/*==============================================================================1/*==============================================================================
2 2
3 leaf-analysis.c3 leaf-analysis.c
4 Created: 30 Nov 2018 11:56:49am4 Created: 30 Nov 2018 11:56:49am
5 Author: airship5 Author: airship
6 6
7==============================================================================*/7 ==============================================================================*/
8 8
9#if _WIN32 || _WIN649#if _WIN32 || _WIN64
10 10
@@ -504,7 +504,7 @@ void tSNAC_initToPool (tSNAC* const snac, int overlaparg, tMempool* const · 493 unmodified lines
504 s->fidelity = 0.;504 s->fidelity = 0.;
505 s->minrms = DEFMINRMS;505 s->minrms = DEFMINRMS;
506 s->framesize = SNAC_FRAME_SIZE;506 s->framesize = SNAC_FRAME_SIZE;
507 507
508 s->inputbuf = (float*) mpool_calloc(sizeof(float) * SNAC_FRAME_SIZE, m);508 s->inputbuf = (float*) mpool_calloc(sizeof(float) * SNAC_FRAME_SIZE, m);
509 s->processbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE * 2), m);509 s->processbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE * 2), m);
510 s->spectrumbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE / 2), m);510 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
873 p->timeConstant = DEFTIMECONSTANT;873 p->timeConstant = DEFTIMECONSTANT;
874 p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);874 p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
875 p->fidelityThreshold = 0.95;875 p->fidelityThreshold = 0.95;
876
877 p->history = 0.0f;
878 p->alpha = 1.0f;
879 p->tolerance = 1.0f;
876}880}
877 881
878void tPeriodDetection_freeFromPool (tPeriodDetection* const pd, tMempool* const mp)882void tPeriodDetection_freeFromPool (tPeriodDetection* const pd, tMempool* const mp)
@@ -910,7 +914,15 @@ float tPeriodDetection_tick (tPeriodDetection* pd, float sample) · 31 unmodified lines
910 tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);914 tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);
911 float fidelity = tSNAC_getFidelity(&p->snac);915 float fidelity = tSNAC_getFidelity(&p->snac);
912 // Fidelity threshold recommended by Katja Vetters is 0.95 for most instruments/voices http://www.katjaas.nl/helmholtz/helmholtz.html916 // 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 }
914 926
915 p->curBlock++;927 p->curBlock++;
916 if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;928 if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;
@@ -944,3 +956,16 @@ void tPeriodDetection_setFidelityThreshold(tPeriodDetection* pd, float threshold · 27 unmodified lines
944 _tPeriodDetection* p = *pd;956 _tPeriodDetection* p = *pd;
945 p->fidelityThreshold = threshold;957 p->fidelityThreshold = threshold;
946}958}
959
960void tPeriodDetection_setAlpha (tPeriodDetection* pd, float alpha)
961{
962 _tPeriodDetection* p = *pd;
963 p->alpha = LEAF_clip(0.0f, alpha, 1.0f);
964}
965
966void 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
254 v->pos = p0;254 v->pos = p0;
255 v->FX = fx;255 v->FX = fx;
256 256
257 257
258 return o;258 return o;
259}259}
260 260
@@ -517,12 +517,12 @@ void tSOLAD_free(tSOLAD* const wp) · 256 unmodified lines
517void tSOLAD_initToPool (tSOLAD* const wp, tMempool* const mp)517void tSOLAD_initToPool (tSOLAD* const wp, tMempool* const mp)
518{518{
519 _tMempool* m = *mp;519 _tMempool* m = *mp;
520 520
521 _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m);521 _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m);
522 522
523 w->pitchfactor = 1.;523 w->pitchfactor = 1.;
524 w->delaybuf = (float*) mpool_calloc(sizeof(float) * (LOOPSIZE+16), m);524 w->delaybuf = (float*) mpool_calloc(sizeof(float) * (LOOPSIZE+16), m);
525 525
526 solad_init(w);526 solad_init(w);
527}527}
528 528
@@ -900,9 +900,9 @@ void tPitchShift_free(tPitchShift* const psr) · 371 unmodified lines
900void tPitchShift_initToPool (tPitchShift* const psr, tPeriodDetection* const pd, float* out, int bufSize, tMempool* const mp)900void tPitchShift_initToPool (tPitchShift* const psr, tPeriodDetection* const pd, float* out, int bufSize, tMempool* const mp)
901{901{
902 _tMempool* m = *mp;902 _tMempool* m = *mp;
903 903
904 _tPitchShift* ps = *psr = (_tPitchShift*) mpool_calloc(sizeof(_tPitchShift), m);904 _tPitchShift* ps = *psr = (_tPitchShift*) mpool_calloc(sizeof(_tPitchShift), m);
905 905
906 _tPeriodDetection* p = *pd;906 _tPeriodDetection* p = *pd;
907 907
908 ps->p = pd;908 ps->p = pd;
@@ -1078,7 +1078,7 @@ void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, · 169 unmodified lines
1078 tRetune_setTimeConstant(rt, DEFTIMECONSTANT);1078 tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
1079 1079
1080 r->inputPeriod = 0.0f;1080 r->inputPeriod = 0.0f;
1081 1081
1082 r->ps = (tPitchShift*) mpool_calloc(sizeof(tPitchShift) * r->numVoices, m);1082 r->ps = (tPitchShift*) mpool_calloc(sizeof(tPitchShift) * r->numVoices, m);
1083 r->pitchFactor = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);1083 r->pitchFactor = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
1084 r->tickOutput = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);1084 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
1088 }1088 }
1089 1089
1090 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);1090 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1091 1091
1092 for (int i = 0; i < r->numVoices; ++i)1092 for (int i = 0; i < r->numVoices; ++i)
1093 {1093 {
1094 tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);1094 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
1259 }1259 }
1260 1260
1261 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);1261 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1262 1262
1263 for (int i = 0; i < r->numVoices; ++i)1263 for (int i = 0; i < r->numVoices; ++i)
1264 {1264 {
1265 tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);1265 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
1293 1293
1294 float tempPeriod = tPeriodDetection_tick(&r->pd, sample);1294 float tempPeriod = tPeriodDetection_tick(&r->pd, sample);
1295 if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS1295 if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
1296 {1296 {
1297 r->inputPeriod = tempPeriod;1297 r->inputPeriod = tempPeriod;
1298 }1298 }
1299 1299
1300 for (int v = 0; v < r->numVoices; ++v)1300 for (int v = 0; v < r->numVoices; ++v)
1301 {1301 {
1302 r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);1302 r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
1303 }1303 }
1304 1304
1305 return r->tickOutput;1305 return r->tickOutput;
1306}1306}
1307 1307
@@ -1376,10 +1376,22 @@ void tAutotune_setWindowSize(tAutotune* const rt, int ws) · 68 unmodified lines
1376void tAutotune_setFidelityThreshold(tAutotune* const rt, float threshold)1376void tAutotune_setFidelityThreshold(tAutotune* const rt, float threshold)
1377{1377{
1378 _tAutotune* r = *rt;1378 _tAutotune* r = *rt;
1379 1379
1380 tPeriodDetection_setFidelityThreshold(&r->pd, threshold);1380 tPeriodDetection_setFidelityThreshold(&r->pd, threshold);
1381}1381}
1382 1382
1383void tAutotune_setAlpha (tAutotune* rt, float alpha)
1384{
1385 _tAutotune* r = *rt;
1386 tPeriodDetection_setAlpha(&r->pd, alpha);
1387}
1388
1389void tAutotune_setTolerance (tAutotune* rt, float tolerance)
1390{
1391 _tAutotune* r = *rt;
1392 tPeriodDetection_setTolerance(&r->pd, tolerance);
1393}
1394
1383float tAutotune_getInputPeriod(tAutotune* const rt)1395float tAutotune_getInputPeriod(tAutotune* const rt)
1384{1396{
1385 _tAutotune* r = *rt;1397 _tAutotune* r = *rt;
@@ -1413,7 +1425,7 @@ void tFormantShifter_init(tFormantShifter* const fsr, int order) · 27 unmodified lines
1413 fs->fsmooth = (float*) leaf_calloc(sizeof(float) * fs->ford);1425 fs->fsmooth = (float*) leaf_calloc(sizeof(float) * fs->ford);
1414 fs->ftvec = (float*) leaf_calloc(sizeof(float) * fs->ford);1426 fs->ftvec = (float*) leaf_calloc(sizeof(float) * fs->ford);
1415 fs->fbuff = (float*) leaf_calloc(sizeof(float*) * fs->ford);1427 fs->fbuff = (float*) leaf_calloc(sizeof(float*) * fs->ford);
1416 1428
1417 fs->falph = powf(0.001f, 40.0f * leaf.invSampleRate);1429 fs->falph = powf(0.001f, 40.0f * leaf.invSampleRate);
1418 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);1430 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
1419 fs->fhp = 0.0f;1431 fs->fhp = 0.0f;
@@ -1423,11 +1435,11 @@ void tFormantShifter_init(tFormantShifter* const fsr, int order) · 3 unmodified lines
1423 fs->fmutealph = powf(0.001f, 0.5f * leaf.invSampleRate);1435 fs->fmutealph = powf(0.001f, 0.5f * leaf.invSampleRate);
1424 fs->cbi = 0;1436 fs->cbi = 0;
1425 fs->intensity = 1.0f;1437 fs->intensity = 1.0f;
1426 fs->invIntensity = 1.0f;1438 fs->invIntensity = 1.0f;
1427 tHighpass_init(&fs->hp, 10.0f);1439 tHighpass_init(&fs->hp, 10.0f);
1428 tHighpass_init(&fs->hp2, 10.0f);1440 tHighpass_init(&fs->hp2, 10.0f);
1429 tFeedbackLeveler_init(&fs->fbl1, 0.99f, 0.005f, 0.125f, 0);1441 tFeedbackLeveler_init(&fs->fbl1, 0.99f, 0.005f, 0.125f, 0);
1430 tFeedbackLeveler_init(&fs->fbl2, 0.99f, 0.005f, 0.125f, 0);1442 tFeedbackLeveler_init(&fs->fbl2, 0.99f, 0.005f, 0.125f, 0);
1431}1443}
1432 1444
1433void tFormantShifter_free(tFormantShifter* const fsr)1445void tFormantShifter_free(tFormantShifter* const fsr)
@@ -1445,8 +1457,8 @@ void tFormantShifter_free(tFormantShifter* const fsr) · 11 unmodified lines
1445 leaf_free(fs->fbuff);1457 leaf_free(fs->fbuff);
1446 tHighpass_free(&fs->hp);1458 tHighpass_free(&fs->hp);
1447 tHighpass_free(&fs->hp2);1459 tHighpass_free(&fs->hp2);
1448 tFeedbackLeveler_free(&fs->fbl1);1460 tFeedbackLeveler_free(&fs->fbl1);
1449 tFeedbackLeveler_free(&fs->fbl2);1461 tFeedbackLeveler_free(&fs->fbl2);
1450 leaf_free(fs);1462 leaf_free(fs);
1451}1463}
1452 1464
@@ -1466,7 +1478,7 @@ void tFormantShifter_initToPool (tFormantShifter* const fsr, int order, · 13 unmodified lines
1466 fs->ftvec = (float*) mpool_calloc(sizeof(float) * fs->ford, m);1478 fs->ftvec = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1467 1479
1468 fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);1480 fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);
1469 1481
1470 1482
1471 fs->falph = powf(0.001f, 10.0f * leaf.invSampleRate);1483 fs->falph = powf(0.001f, 10.0f * leaf.invSampleRate);
1472 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);1484 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
1516 in = tFeedbackLeveler_tick(&fs->fbl1, in);1528 in = tFeedbackLeveler_tick(&fs->fbl1, in);
1517 in = tHighpass_tick(&fs->hp, in * fs->intensity);1529 in = tHighpass_tick(&fs->hp, in * fs->intensity);
1518 1530
1519 1531
1520 float fa, fb, fc, foma, falph, ford, flamb, tf, fk;1532 float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
1521 1533
1522 ford = fs->ford;1534 ford = fs->ford;
1523 falph = fs->falph;1535 falph = fs->falph;
1524 foma = (1.0f - falph);1536 foma = (1.0f - falph);
@@ -1544,7 +1556,7 @@ float tFormantShifter_remove(tFormantShifter* const fsr, float in) · 19 unmodified lines
1544 fb = fc - tf*fa;1556 fb = fc - tf*fa;
1545 fa = fa - tf*fc;1557 fa = fa - tf*fc;
1546 }1558 }
1547 1559
1548 //return fa * 0.1f;1560 //return fa * 0.1f;
1549 return fa;1561 return fa;
1550}1562}
@@ -1555,7 +1567,7 @@ float tFormantShifter_add(tFormantShifter* const fsr, float in) · 4 unmodified lines
1555 1567
1556 float fa, fb, fc, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;1568 float fa, fb, fc, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
1557 ford = fs->ford;1569 ford = fs->ford;
1558 1570
1559 flpa = fs->flpa;1571 flpa = fs->flpa;
1560 flamb = fs->flamb;1572 flamb = fs->flamb;
1561 tf = fs->shiftFactor * (1.0f+flamb)/(1.0f-flamb);1573 tf = fs->shiftFactor * (1.0f+flamb)/(1.0f-flamb);
@@ -1642,7 +1654,7 @@ float tFormantShifter_add(tFormantShifter* const fsr, float in) · 80 unmodified lines
1642 // ...and we're done messing with formants1654 // ...and we're done messing with formants
1643 //tf = tFeedbackLeveler_tick(&fs->fbl2, tf);1655 //tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
1644 tf = tHighpass_tick(&fs->hp2, tanhf(tf));1656 tf = tHighpass_tick(&fs->hp2, tanhf(tf));
1645 1657
1646 return tf * fs->invIntensity;1658 return tf * fs->invIntensity;
1647}1659}
1648 1660
@@ -1656,21 +1668,21 @@ void tFormantShifter_setShiftFactor(tFormantShifter* const fsr, float shiftFacto · 7 unmodified lines
1656void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)1668void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)
1657{1669{
1658 _tFormantShifter* fs = *fsr;1670 _tFormantShifter* fs = *fsr;
1659 1671
1660 1672
1661 1673
1662 fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);1674 fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);
1663 1675
1664 // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);1676 // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
1665 //tFeedbackLeveler_setTargetLevel(&fs->fbl2, fs->intensity);1677 //tFeedbackLeveler_setTargetLevel(&fs->fbl2, fs->intensity);
1666 //make sure you don't divide by zero, doofies1678 //make sure you don't divide by zero, doofies
1667 if (fs->intensity != 0.0f)1679 if (fs->intensity != 0.0f)
1668 {1680 {
1669 fs->invIntensity = 1.0f/fs->intensity;1681 fs->invIntensity = 1.0f/fs->intensity;
1670 }1682 }
1671 else1683 else
1672 {1684 {
1673 fs->invIntensity = 1.0f;1685 fs->invIntensity = 1.0f;
1674 }1686 }
1675 1687
1676}1688}
LEAF/Src/leaf-math.c+11−5
@@ -262,11 +262,17 @@ float LEAF_softClip(float val, float thresh) · 261 unmodified lines
262 262
263float LEAF_clip(float min, float val, float max)263float LEAF_clip(float min, float val, float max)
264{264{
265 265 int tempmin = min;
266 if (val < min) {266 int tempmax = max;
267 return min;267 if (min > max)
268 } else if (val > max) {268 {
269 return max;269 tempmin = max;
270 tempmax = min;
271 }
272 if (val < tempmin) {
273 return tempmin;
274 } else if (val > tempmax) {
275 return tempmax;
270 } else {276 } else {
271 return val;277 return val;
272 }278 }

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