History

trying out some ways to improve and optimize pitch detection

Matthew Wang committed 6 years ago

Commit f253eaf1 parent a8e41584 files · +118 −58Browse files

Unified · Split

4 files
  1. leaf/Inc/leaf-analysis.h +1 −0
  2. leaf/Inc/leaf-effects.h +18 −11
  3. leaf/Src/leaf-analysis.c +41 −22
  4. leaf/Src/leaf-effects.c +58 −25
leaf/Inc/leaf-analysis.h+1−0
@@ -909,6 +909,7 @@ extern "C" { · 908 unmodified lines
909909 float _mean;
910910 float _predicted_frequency;
911911 int _first;
912+ int sub;
912913
913914 } _tDualPitchDetector;
914915
leaf/Inc/leaf-effects.h+18−11
@@ -430,11 +430,11 @@ extern "C" { · 429 unmodified lines
430430
431431 @} */
432432
433−#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
434−#define LOOPMASK (LOOPSIZE - 1)
433+//#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
434+//#define LOOPMASK (LOOPSIZE - 1)
435435 #define PITCHFACTORDEFAULT 1.0f
436436 #define INITPERIOD 64.0f
437−#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
437+//#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
438438 #define MINPERIOD 8.0f
439439
440440 typedef struct _tSOLAD
@@ -444,6 +444,7 @@ extern "C" { · 3 unmodified lines
444444 tAttackDetection ad;
445445 tHighpass hp;
446446
447+ int loopSize;
447448 uint16_t timeindex; // current reference time, write index
448449 uint16_t blocksize; // signal input / output block size
449450 float pitchfactor; // pitch factor between 0.25 and 4
@@ -459,8 +460,8 @@ extern "C" { · 9 unmodified lines
459460
460461 typedef _tSOLAD* tSOLAD;
461462
462− void tSOLAD_init (tSOLAD* const, LEAF* const leaf);
463− void tSOLAD_initToPool (tSOLAD* const, tMempool* const);
463+ void tSOLAD_init (tSOLAD* const, int loopSize, LEAF* const leaf);
464+ void tSOLAD_initToPool (tSOLAD* const, int loopSize, tMempool* const);
464465 void tSOLAD_free (tSOLAD* const);
465466
466467 // send one block of input samples, receive one block of output samples
@@ -521,16 +522,20 @@ extern "C" { · 54 unmodified lines
521522 float* inBuffer;
522523 int bufSize;
523524 int index;
525+
526+ float pickiness;
524527 } _tPitchShift;
525528
526529 typedef _tPitchShift* tPitchShift;
527530
528− void tPitchShift_init (tPitchShift* const, tDualPitchDetector* const, LEAF* const leaf);
529− void tPitchShift_initToPool (tPitchShift* const, tDualPitchDetector* const, tMempool* const);
531+ void tPitchShift_init (tPitchShift* const, tDualPitchDetector* const, int bufSize, LEAF* const leaf);
532+ void tPitchShift_initToPool (tPitchShift* const, tDualPitchDetector* const, int bufSize, tMempool* const);
530533 void tPitchShift_free (tPitchShift* const);
531534
532− void tPitchShift_shiftBy (tPitchShift* const, float factor, float* in, float* out, int bufSize);
533− void tPitchShift_shiftTo (tPitchShift* const, float freq, float* in, float* out, int bufSize);
535+ void tPitchShift_shiftBy (tPitchShift* const, float factor, float* in, float* out);
536+ void tPitchShift_shiftTo (tPitchShift* const, float freq, float* in, float* out);
537+
538+ void tPitchShift_setPickiness (tPitchShift* const, float p);
534539
535540 /*!
536541 @defgroup tsimpleretune tSimpleRetune
@@ -582,7 +587,7 @@ extern "C" { · 45 unmodified lines
582587 int bufSize;
583588 int index;
584589
585− void (*shiftFunction)(tPitchShift* const, float, float*, float*, int);
590+ void (*shiftFunction)(tPitchShift* const, float, float*, float*);
586591
587592 float* shiftValues;
588593 int numVoices;
@@ -597,6 +602,7 @@ extern "C" { · 8 unmodified lines
597602 float tSimpleRetune_tick (tSimpleRetune* const, float sample);
598603 void tSimpleRetune_setMode (tSimpleRetune* const, int mode);
599604 void tSimpleRetune_setNumVoices (tSimpleRetune* const, int numVoices);
605+ void tSimpleRetune_setPickiness (tSimpleRetune* const, float p);
600606 void tSimpleRetune_tuneVoices (tSimpleRetune* const, float* t);
601607 void tSimpleRetune_tuneVoice (tSimpleRetune* const, int voice, float t);
602608 float tSimpleRetune_getInputFrequency (tSimpleRetune* const);
@@ -653,7 +659,7 @@ extern "C" { · 50 unmodified lines
653659
654660 float* output;
655661
656− void (*shiftFunction)(tPitchShift* const, float, float*, float*, int);
662+ void (*shiftFunction)(tPitchShift* const, float, float*, float*);
657663
658664 float* shiftValues;
659665 int numVoices;
@@ -668,6 +674,7 @@ extern "C" { · 8 unmodified lines
668674 float* tRetune_tick (tRetune* const, float sample);
669675 void tRetune_setMode (tRetune* const, int mode);
670676 void tRetune_setNumVoices (tRetune* const, int numVoices);
677+ void tRetune_setPickiness (tRetune* const, float p);
671678 void tRetune_tuneVoices (tRetune* const, float* t);
672679 void tRetune_tuneVoice (tRetune* const, int voice, float t);
673680 float tRetune_getInputFrequency (tRetune* const);
leaf/Src/leaf-analysis.c+41−22
@@ -1889,7 +1889,7 @@ void tPitchDetector_initToPool (tPitchDetector* const detector, float lowes · 1888 unmodified lines
18891889 _tPitchDetector* p = *detector = (_tPitchDetector*) mpool_alloc(sizeof(_tPitchDetector), m);
18901890 p->mempool = m;
18911891
1892− tPeriodDetector_initToPool(&p->_pd, lowestFreq, highestFreq, DEFAULT_HYSTERESIS, mempool);
1892+ tPeriodDetector_initToPool(&p->_pd, lowestFreq, highestFreq, -120.0f, mempool);
18931893 p->_current.frequency = 0.0f;
18941894 p->_current.periodicity = 0.0f;
18951895 p->_frames_after_shift = 0;
@@ -2119,13 +2119,14 @@ void tDualPitchDetector_initToPool (tDualPitchDetector* const detector, flo · 223 unmodified lines
21192119 _tDualPitchDetector* p = *detector = (_tDualPitchDetector*) mpool_alloc(sizeof(_tDualPitchDetector), m);
21202120 p->mempool = m;
21212121
2122− tPitchDetector_initToPool(&p->_pd1, lowestFreq, highestFreq, mempool);
2123− tPitchDetector_initToPool(&p->_pd2, lowestFreq, highestFreq, mempool);
2122+ tPitchDetector_initToPool(&p->_pd1, lowestFreq*2.0f, highestFreq*2.0f, mempool);
2123+ tPitchDetector_initToPool(&p->_pd2, lowestFreq*2.0f, highestFreq*2.0f, mempool);
21242124 p->_current.frequency = 0.0f;
21252125 p->_current.periodicity = 0.0f;
21262126 p->_mean = lowestFreq + ((highestFreq - lowestFreq) / 2.0f);
21272127 p->_predicted_frequency = 0.0f;
21282128 p->_first = 1;
2129+ p->sub = 0;
21292130 }
21302131
21312132 void tDualPitchDetector_free (tDualPitchDetector* const detector)
@@ -2142,34 +2143,52 @@ int tDualPitchDetector_tick (tDualPitchDetector* const detector, float sa · 10 unmodified lines
21422143 {
21432144 _tDualPitchDetector* p = *detector;
21442145
2145− int pd1_ready = tPitchDetector_tick(&p->_pd1, sample);
2146− int pd2_ready = tPitchDetector_tick(&p->_pd2, -sample);
2146+ int pd1_ready;
2147+ if (!(p->sub % 2))
2148+ {
2149+ pd1_ready = tPitchDetector_tick(&p->_pd2, sample);
2150+ p->sub = 0;
2151+ }
2152+ else
2153+ {
2154+ pd1_ready = tPitchDetector_tick(&p->_pd1, sample);
2155+ }
2156+ p->sub++;
21472157
2148− if (pd1_ready || pd2_ready)
2158+ if (pd1_ready)
21492159 {
21502160 int pd1_indeterminate = tPitchDetector_indeterminate(&p->_pd1);
21512161 int pd2_indeterminate = tPitchDetector_indeterminate(&p->_pd2);
2162+ int disagreement = 0;
21522163 if (!pd1_indeterminate && !pd2_indeterminate)
21532164 {
21542165 _pitch_info _i1 = p->_pd1->_current;
21552166 _pitch_info _i2 = p->_pd2->_current;
21562167
2157− float pd1_diff = fabsf(_i1.frequency - p->_mean);
2158− float pd2_diff = fabsf(_i2.frequency - p->_mean);
2159− _pitch_info i = (pd1_diff < pd2_diff) ? _i1 : _i2;
2168+ float pd1_diff = fabsf(_i1.frequency*0.5f - p->_mean);
2169+ float pd2_diff = fabsf(_i2.frequency*0.5f - p->_mean);
2170+ _pitch_info i1 = _i1;
2171+ i1.frequency = i1.frequency*0.5f;
2172+ _pitch_info i2 = _i2;
2173+ i2.frequency = i2.frequency*0.5f;
2174+
2175+ _pitch_info i = (pd1_diff < pd2_diff) ? i1 : i2;
2176+ disagreement = fabsf(pd1_diff - pd2_diff) > 2.0f;
21602177
2161− if (p->_first)
2162− {
2163− p->_current = i;
2164− p->_mean = p->_current.frequency;
2165− p->_first = 0;
2166− p->_predicted_frequency = 0.0f;
2167− }
2168− else
2169− {
2170− p->_current = i;
2171− p->_mean = (0.222222f * p->_current.frequency) + (0.777778f * p->_mean);
2172− p->_predicted_frequency = 0.0f;
2178+ if (!disagreement) {
2179+ if (p->_first)
2180+ {
2181+ p->_current = i;
2182+ p->_mean = p->_current.frequency;
2183+ p->_first = 0;
2184+ p->_predicted_frequency = 0.0f;
2185+ }
2186+ else
2187+ {
2188+ p->_current = i;
2189+ p->_mean = (0.2222222 * p->_current.frequency) + (0.7777778 * p->_mean);
2190+ p->_predicted_frequency = 0.0f;
2191+ }
21732192 }
21742193 }
21752194
@@ -2181,7 +2200,7 @@ int tDualPitchDetector_tick (tDualPitchDetector* const detector, float sa · 5 unmodified lines
21812200 }
21822201 }
21832202
2184− return pd1_ready || pd2_ready;
2203+ return pd1_ready;
21852204 }
21862205
21872206 float tDualPitchDetector_getFrequency (tDualPitchDetector* const detector)
leaf/Src/leaf-effects.c+58−25
@@ -1019,19 +1019,20 @@ static void pitchup(_tSOLAD *w, float *out); · 1018 unmodified lines
10191019 /******************************************************************************/
10201020
10211021 // init
1022−void tSOLAD_init (tSOLAD* const wp, LEAF* const leaf)
1022+void tSOLAD_init (tSOLAD* const wp, int loopSize, LEAF* const leaf)
10231023 {
1024− tSOLAD_initToPool(wp, &leaf->mempool);
1024+ tSOLAD_initToPool(wp, loopSize, &leaf->mempool);
10251025 }
10261026
1027−void tSOLAD_initToPool (tSOLAD* const wp, tMempool* const mp)
1027+void tSOLAD_initToPool (tSOLAD* const wp, int loopSize, tMempool* const mp)
10281028 {
10291029 _tMempool* m = *mp;
10301030 _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m);
10311031 w->mempool = m;
10321032
1033+ w->loopSize = loopSize;
10331034 w->pitchfactor = 1.;
1034− w->delaybuf = (float*) mpool_calloc(sizeof(float) * LOOPSIZE, m);
1035+ w->delaybuf = (float*) mpool_calloc(sizeof(float) * w->loopSize, m);
10351036
10361037 w->timeindex = 0;
10371038 w->xfadevalue = -1;
@@ -1065,7 +1066,7 @@ void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize) · 27 unmodified lines
10651066 {
10661067 float sample = tHighpass_tick(&w->hp, in[0]);
10671068 w->delaybuf[0] = sample;
1068− w->delaybuf[LOOPSIZE] = sample; // copy one sample for interpolation
1069+ w->delaybuf[w->loopSize] = sample; // copy one sample for interpolation
10691070 n--;
10701071 i++;
10711072 in++;
@@ -1082,7 +1083,7 @@ void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize) · 10 unmodified lines
10821083 else pitchdown(w, out);
10831084
10841085 w->timeindex += blocksize;
1085− w->timeindex &= LOOPMASK;
1086+ w->timeindex &= (w->loopSize - 1);
10861087 }
10871088
10881089 // set periodicity analysis data
@@ -1090,7 +1091,8 @@ void tSOLAD_setPeriod(tSOLAD* const wp, float period) · 1 unmodified line
10901091 {
10911092 _tSOLAD* w = *wp;
10921093
1093− if(period > MAXPERIOD) period = MAXPERIOD;
1094+ float maxPeriod = (float)((w->loopSize - w->blocksize) * 0.8f);
1095+ if(period > maxPeriod) period = maxPeriod;
10941096 if(period > MINPERIOD) w->period = period; // ignore period when too small
10951097 }
10961098
@@ -1126,7 +1128,7 @@ void tSOLAD_resetState(tSOLAD* const wp) · 29 unmodified lines
11261128 {
11271129 _tSOLAD* w = *wp;
11281130
1129− int n = LOOPSIZE;
1131+ int n = w->loopSize;
11301132 float *buf = w->delaybuf;
11311133
11321134 while(n--) *buf++ = 0;
@@ -1173,7 +1175,7 @@ void tSOLAD_resetState(tSOLAD* const wp) · 40 unmodified lines
11731175 static void pitchdown(_tSOLAD* const w, float *out)
11741176 {
11751177 int n = w->blocksize;
1176− float refindex = (float)(w->timeindex + LOOPSIZE); // no negative values!
1178+ float refindex = (float)(w->timeindex + w->loopSize); // no negative values!
11771179 float pitchfactor = w->pitchfactor;
11781180 float period = w->period;
11791181 float readlag = w->readlag;
@@ -1291,7 +1293,7 @@ static void pitchdown(_tSOLAD* const w, float *out) · 111 unmodified lines
12911293 static void pitchup(_tSOLAD* const w, float *out)
12921294 {
12931295 int n = w->blocksize;
1294− float refindex = (float)(w->timeindex + LOOPSIZE); // no negative values
1296+ float refindex = (float)(w->timeindex + w->loopSize); // no negative values
12951297 float pitchfactor = w->pitchfactor;
12961298 float period = w->period;
12971299 float readlag = w->readlag;
@@ -1359,7 +1361,7 @@ static inline float read_sample(_tSOLAD* const w, float floatindex) · 61 unmodified lines
13591361 int index = (int)floatindex;
13601362 float fraction = floatindex - (float)index;
13611363 float *buf = w->delaybuf;
1362− index &= LOOPMASK;
1364+ index &= (w->loopSize - 1);
13631365
13641366 return (buf[index] + (fraction * (buf[index+1] - buf[index])));
13651367 }
@@ -1368,20 +1370,22 @@ static inline float read_sample(_tSOLAD* const w, float floatindex) · 2 unmodified lines
13681370 // PITCHSHIFT
13691371 //============================================================================================================
13701372
1371−void tPitchShift_init (tPitchShift* const psr, tDualPitchDetector* const dpd, LEAF* const leaf)
1373+void tPitchShift_init (tPitchShift* const psr, tDualPitchDetector* const dpd, int bufSize, LEAF* const leaf)
13721374 {
1373− tPitchShift_initToPool(psr, dpd, &leaf->mempool);
1375+ tPitchShift_initToPool(psr, dpd, bufSize, &leaf->mempool);
13741376 }
13751377
1376−void tPitchShift_initToPool (tPitchShift* const psr, tDualPitchDetector* const dpd, tMempool* const mp)
1378+void tPitchShift_initToPool (tPitchShift* const psr, tDualPitchDetector* const dpd, int bufSize, tMempool* const mp)
13771379 {
13781380 _tMempool* m = *mp;
13791381 _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m);
13801382 ps->mempool = m;
13811383
13821384 ps->pd = *dpd;
1385+ ps->bufSize = bufSize;
1386+ ps->pickiness = 0.95f;
13831387
1384− tSOLAD_initToPool(&ps->sola, mp);
1388+ tSOLAD_initToPool(&ps->sola, pow(2.0, ceil(log2(ps->bufSize * 2.0))), mp);
13851389 tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
13861390 }
13871391
@@ -1393,29 +1397,31 @@ void tPitchShift_free (tPitchShift* const psr) · 5 unmodified lines
13931397 mpool_free((char*)ps, ps->mempool);
13941398 }
13951399
1396−void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float* out, int bufSize)
1400+void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float* out)
13971401 {
13981402 _tPitchShift* ps = *psr;
13991403 LEAF* leaf = ps->mempool->leaf;
14001404
14011405 float detected = tDualPitchDetector_getFrequency(&ps->pd);
1402− if (detected > 0.0f)
1406+ float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
1407+ if (detected > 0.0f && periodicity > ps->pickiness)
14031408 {
14041409 float period = leaf->sampleRate / detected;
14051410 tSOLAD_setPeriod(&ps->sola, period);
14061411 tSOLAD_setPitchFactor(&ps->sola, factor);
14071412 }
14081413
1409− tSOLAD_ioSamples(&ps->sola, in, out, bufSize);
1414+ tSOLAD_ioSamples(&ps->sola, in, out, ps->bufSize);
14101415 }
14111416
1412−void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, float* out, int bufSize)
1417+void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, float* out)
14131418 {
14141419 _tPitchShift* ps = *psr;
14151420 LEAF* leaf = ps->mempool->leaf;
14161421
14171422 float detected = tDualPitchDetector_getFrequency(&ps->pd);
1418− if (detected > 0.0f)
1423+ float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
1424+ if (detected > 0.0f && periodicity > ps->pickiness)
14191425 {
14201426 float period = 1.0f / detected;
14211427 float factor = freq * period;
@@ -1423,7 +1429,14 @@ void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, floa · 1 unmodified line
14231429 tSOLAD_setPitchFactor(&ps->sola, factor);
14241430 }
14251431
1426− tSOLAD_ioSamples(&ps->sola, in, out, bufSize);
1432+ tSOLAD_ioSamples(&ps->sola, in, out, ps->bufSize);
1433+}
1434+
1435+void tPitchShift_setPickiness (tPitchShift* const psr, float p)
1436+{
1437+ _tPitchShift* ps = *psr;
1438+
1439+ ps->pickiness = p;
14271440 }
14281441
14291442
@@ -1459,7 +1472,7 @@ void tSimpleRetune_initToPool (tSimpleRetune* const rt, int numVoices, float min · 29 unmodified lines
14591472
14601473 for (int i = 0; i < r->numVoices; ++i)
14611474 {
1462− tPitchShift_initToPool(&r->ps[i], &r->dp, mp);
1475+ tPitchShift_initToPool(&r->ps[i], &r->dp, r->bufSize, mp);
14631476 }
14641477
14651478 r->shiftFunction = &tPitchShift_shiftBy;
@@ -1495,7 +1508,7 @@ float tSimpleRetune_tick(tSimpleRetune* const rt, float sample) · 29 unmodified lines
14951508 {
14961509 for (int i = 0; i < r->numVoices; ++i)
14971510 {
1498− r->shiftFunction(&r->ps[i], r->shiftValues[i], r->inBuffer, r->outBuffer, r->bufSize);
1511+ r->shiftFunction(&r->ps[i], r->shiftValues[i], r->inBuffer, r->outBuffer);
14991512 }
15001513 r->index = 0;
15011514 }
@@ -1524,6 +1537,16 @@ void tSimpleRetune_setNumVoices(tSimpleRetune* const rt, int numVoices) · 22 unmodified lines
15241537 tSimpleRetune_initToPool(rt, minInputFreq, maxInputFreq, numVoices, bufSize, &mempool);
15251538 }
15261539
1540+void tSimpleRetune_setPickiness (tSimpleRetune* const rt, float p)
1541+{
1542+ _tSimpleRetune* r = *rt;
1543+
1544+ for (int i = 0; i < r->numVoices; ++i)
1545+ {
1546+ tPitchShift_setPickiness(&r->ps[i], p);
1547+ }
1548+}
1549+
15271550 void tSimpleRetune_tuneVoices(tSimpleRetune* const rt, float* t)
15281551 {
15291552 _tSimpleRetune* r = *rt;
@@ -1581,7 +1604,7 @@ void tRetune_initToPool (tRetune* const rt, int numVoices, float minInputFreq, f · 51 unmodified lines
15811604
15821605 for (int i = 0; i < r->numVoices; ++i)
15831606 {
1584− tPitchShift_initToPool(&r->ps[i], &r->dp, mp);
1607+ tPitchShift_initToPool(&r->ps[i], &r->dp, r->bufSize, mp);
15851608 r->outBuffers[i] = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
15861609 }
15871610
@@ -1623,7 +1646,7 @@ float* tRetune_tick(tRetune* const rt, float sample) · 35 unmodified lines
16231646 {
16241647 for (int i = 0; i < r->numVoices; ++i)
16251648 {
1626− r->shiftFunction(&r->ps[i], r->shiftValues[i], r->inBuffer, r->outBuffers[i], r->bufSize);
1649+ r->shiftFunction(&r->ps[i], r->shiftValues[i], r->inBuffer, r->outBuffers[i]);
16271650 }
16281651 r->index = 0;
16291652 }
@@ -1639,6 +1662,16 @@ void tRetune_setMode (tRetune* const rt, int mode) · 9 unmodified lines
16391662 else r->shiftFunction = &tPitchShift_shiftBy;
16401663 }
16411664
1665+void tRetune_setPickiness (tRetune* const rt, float p)
1666+{
1667+ _tRetune* r = *rt;
1668+
1669+ for (int i = 0; i < r->numVoices; ++i)
1670+ {
1671+ tPitchShift_setPickiness(&r->ps[i], p);
1672+ }
1673+}
1674+
16421675 void tRetune_setNumVoices(tRetune* const rt, int numVoices)
16431676 {
16441677 _tRetune* r = *rt;

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