| @@ -1019,19 +1019,20 @@ static void pitchup(_tSOLAD *w, float *out); · 1018 unmodified lines |
| 1019 | 1019 | /******************************************************************************/ |
| 1020 | 1020 | |
| 1021 | 1021 | // init |
| 1022 | | −void tSOLAD_init (tSOLAD* const wp, LEAF* const leaf) |
| 1022 | +void tSOLAD_init (tSOLAD* const wp, int loopSize, LEAF* const leaf) |
| 1023 | 1023 | { |
| 1024 | | − tSOLAD_initToPool(wp, &leaf->mempool); |
| 1024 | + tSOLAD_initToPool(wp, loopSize, &leaf->mempool); |
| 1025 | 1025 | } |
| 1026 | 1026 | |
| 1027 | | −void tSOLAD_initToPool (tSOLAD* const wp, tMempool* const mp) |
| 1027 | +void tSOLAD_initToPool (tSOLAD* const wp, int loopSize, tMempool* const mp) |
| 1028 | 1028 | { |
| 1029 | 1029 | _tMempool* m = *mp; |
| 1030 | 1030 | _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m); |
| 1031 | 1031 | w->mempool = m; |
| 1032 | 1032 | |
| 1033 | + w->loopSize = loopSize; |
| 1033 | 1034 | w->pitchfactor = 1.; |
| 1034 | | − w->delaybuf = (float*) mpool_calloc(sizeof(float) * LOOPSIZE, m); |
| 1035 | + w->delaybuf = (float*) mpool_calloc(sizeof(float) * w->loopSize, m); |
| 1035 | 1036 | |
| 1036 | 1037 | w->timeindex = 0; |
| 1037 | 1038 | w->xfadevalue = -1; |
| @@ -1065,7 +1066,7 @@ void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize) · 27 unmodified lines |
| 1065 | 1066 | { |
| 1066 | 1067 | float sample = tHighpass_tick(&w->hp, in[0]); |
| 1067 | 1068 | 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 |
| 1069 | 1070 | n--; |
| 1070 | 1071 | i++; |
| 1071 | 1072 | in++; |
| @@ -1082,7 +1083,7 @@ void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize) · 10 unmodified lines |
| 1082 | 1083 | else pitchdown(w, out); |
| 1083 | 1084 | |
| 1084 | 1085 | w->timeindex += blocksize; |
| 1085 | | − w->timeindex &= LOOPMASK; |
| 1086 | + w->timeindex &= (w->loopSize - 1); |
| 1086 | 1087 | } |
| 1087 | 1088 | |
| 1088 | 1089 | // set periodicity analysis data |
| @@ -1090,7 +1091,8 @@ void tSOLAD_setPeriod(tSOLAD* const wp, float period) · 1 unmodified line |
| 1090 | 1091 | { |
| 1091 | 1092 | _tSOLAD* w = *wp; |
| 1092 | 1093 | |
| 1093 | | − if(period > MAXPERIOD) period = MAXPERIOD; |
| 1094 | + float maxPeriod = (float)((w->loopSize - w->blocksize) * 0.8f); |
| 1095 | + if(period > maxPeriod) period = maxPeriod; |
| 1094 | 1096 | if(period > MINPERIOD) w->period = period; // ignore period when too small |
| 1095 | 1097 | } |
| 1096 | 1098 | |
| @@ -1126,7 +1128,7 @@ void tSOLAD_resetState(tSOLAD* const wp) · 29 unmodified lines |
| 1126 | 1128 | { |
| 1127 | 1129 | _tSOLAD* w = *wp; |
| 1128 | 1130 | |
| 1129 | | − int n = LOOPSIZE; |
| 1131 | + int n = w->loopSize; |
| 1130 | 1132 | float *buf = w->delaybuf; |
| 1131 | 1133 | |
| 1132 | 1134 | while(n--) *buf++ = 0; |
| @@ -1173,7 +1175,7 @@ void tSOLAD_resetState(tSOLAD* const wp) · 40 unmodified lines |
| 1173 | 1175 | static void pitchdown(_tSOLAD* const w, float *out) |
| 1174 | 1176 | { |
| 1175 | 1177 | 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! |
| 1177 | 1179 | float pitchfactor = w->pitchfactor; |
| 1178 | 1180 | float period = w->period; |
| 1179 | 1181 | float readlag = w->readlag; |
| @@ -1291,7 +1293,7 @@ static void pitchdown(_tSOLAD* const w, float *out) · 111 unmodified lines |
| 1291 | 1293 | static void pitchup(_tSOLAD* const w, float *out) |
| 1292 | 1294 | { |
| 1293 | 1295 | 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 |
| 1295 | 1297 | float pitchfactor = w->pitchfactor; |
| 1296 | 1298 | float period = w->period; |
| 1297 | 1299 | float readlag = w->readlag; |
| @@ -1359,7 +1361,7 @@ static inline float read_sample(_tSOLAD* const w, float floatindex) · 61 unmodified lines |
| 1359 | 1361 | int index = (int)floatindex; |
| 1360 | 1362 | float fraction = floatindex - (float)index; |
| 1361 | 1363 | float *buf = w->delaybuf; |
| 1362 | | − index &= LOOPMASK; |
| 1364 | + index &= (w->loopSize - 1); |
| 1363 | 1365 | |
| 1364 | 1366 | return (buf[index] + (fraction * (buf[index+1] - buf[index]))); |
| 1365 | 1367 | } |
| @@ -1368,20 +1370,22 @@ static inline float read_sample(_tSOLAD* const w, float floatindex) · 2 unmodified lines |
| 1368 | 1370 | // PITCHSHIFT |
| 1369 | 1371 | //============================================================================================================ |
| 1370 | 1372 | |
| 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) |
| 1372 | 1374 | { |
| 1373 | | − tPitchShift_initToPool(psr, dpd, &leaf->mempool); |
| 1375 | + tPitchShift_initToPool(psr, dpd, bufSize, &leaf->mempool); |
| 1374 | 1376 | } |
| 1375 | 1377 | |
| 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) |
| 1377 | 1379 | { |
| 1378 | 1380 | _tMempool* m = *mp; |
| 1379 | 1381 | _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m); |
| 1380 | 1382 | ps->mempool = m; |
| 1381 | 1383 | |
| 1382 | 1384 | ps->pd = *dpd; |
| 1385 | + ps->bufSize = bufSize; |
| 1386 | + ps->pickiness = 0.95f; |
| 1383 | 1387 | |
| 1384 | | − tSOLAD_initToPool(&ps->sola, mp); |
| 1388 | + tSOLAD_initToPool(&ps->sola, pow(2.0, ceil(log2(ps->bufSize * 2.0))), mp); |
| 1385 | 1389 | tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO); |
| 1386 | 1390 | } |
| 1387 | 1391 | |
| @@ -1393,29 +1397,31 @@ void tPitchShift_free (tPitchShift* const psr) · 5 unmodified lines |
| 1393 | 1397 | mpool_free((char*)ps, ps->mempool); |
| 1394 | 1398 | } |
| 1395 | 1399 | |
| 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) |
| 1397 | 1401 | { |
| 1398 | 1402 | _tPitchShift* ps = *psr; |
| 1399 | 1403 | LEAF* leaf = ps->mempool->leaf; |
| 1400 | 1404 | |
| 1401 | 1405 | 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) |
| 1403 | 1408 | { |
| 1404 | 1409 | float period = leaf->sampleRate / detected; |
| 1405 | 1410 | tSOLAD_setPeriod(&ps->sola, period); |
| 1406 | 1411 | tSOLAD_setPitchFactor(&ps->sola, factor); |
| 1407 | 1412 | } |
| 1408 | 1413 | |
| 1409 | | − tSOLAD_ioSamples(&ps->sola, in, out, bufSize); |
| 1414 | + tSOLAD_ioSamples(&ps->sola, in, out, ps->bufSize); |
| 1410 | 1415 | } |
| 1411 | 1416 | |
| 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) |
| 1413 | 1418 | { |
| 1414 | 1419 | _tPitchShift* ps = *psr; |
| 1415 | 1420 | LEAF* leaf = ps->mempool->leaf; |
| 1416 | 1421 | |
| 1417 | 1422 | 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) |
| 1419 | 1425 | { |
| 1420 | 1426 | float period = 1.0f / detected; |
| 1421 | 1427 | float factor = freq * period; |
| @@ -1423,7 +1429,14 @@ void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, floa · 1 unmodified line |
| 1423 | 1429 | tSOLAD_setPitchFactor(&ps->sola, factor); |
| 1424 | 1430 | } |
| 1425 | 1431 | |
| 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; |
| 1427 | 1440 | } |
| 1428 | 1441 | |
| 1429 | 1442 | |
| @@ -1459,7 +1472,7 @@ void tSimpleRetune_initToPool (tSimpleRetune* const rt, int numVoices, float min · 29 unmodified lines |
| 1459 | 1472 | |
| 1460 | 1473 | for (int i = 0; i < r->numVoices; ++i) |
| 1461 | 1474 | { |
| 1462 | | − tPitchShift_initToPool(&r->ps[i], &r->dp, mp); |
| 1475 | + tPitchShift_initToPool(&r->ps[i], &r->dp, r->bufSize, mp); |
| 1463 | 1476 | } |
| 1464 | 1477 | |
| 1465 | 1478 | r->shiftFunction = &tPitchShift_shiftBy; |
| @@ -1495,7 +1508,7 @@ float tSimpleRetune_tick(tSimpleRetune* const rt, float sample) · 29 unmodified lines |
| 1495 | 1508 | { |
| 1496 | 1509 | for (int i = 0; i < r->numVoices; ++i) |
| 1497 | 1510 | { |
| 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); |
| 1499 | 1512 | } |
| 1500 | 1513 | r->index = 0; |
| 1501 | 1514 | } |
| @@ -1524,6 +1537,16 @@ void tSimpleRetune_setNumVoices(tSimpleRetune* const rt, int numVoices) · 22 unmodified lines |
| 1524 | 1537 | tSimpleRetune_initToPool(rt, minInputFreq, maxInputFreq, numVoices, bufSize, &mempool); |
| 1525 | 1538 | } |
| 1526 | 1539 | |
| 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 | + |
| 1527 | 1550 | void tSimpleRetune_tuneVoices(tSimpleRetune* const rt, float* t) |
| 1528 | 1551 | { |
| 1529 | 1552 | _tSimpleRetune* r = *rt; |
| @@ -1581,7 +1604,7 @@ void tRetune_initToPool (tRetune* const rt, int numVoices, float minInputFreq, f · 51 unmodified lines |
| 1581 | 1604 | |
| 1582 | 1605 | for (int i = 0; i < r->numVoices; ++i) |
| 1583 | 1606 | { |
| 1584 | | − tPitchShift_initToPool(&r->ps[i], &r->dp, mp); |
| 1607 | + tPitchShift_initToPool(&r->ps[i], &r->dp, r->bufSize, mp); |
| 1585 | 1608 | r->outBuffers[i] = (float*) mpool_calloc(sizeof(float) * r->bufSize, m); |
| 1586 | 1609 | } |
| 1587 | 1610 | |
| @@ -1623,7 +1646,7 @@ float* tRetune_tick(tRetune* const rt, float sample) · 35 unmodified lines |
| 1623 | 1646 | { |
| 1624 | 1647 | for (int i = 0; i < r->numVoices; ++i) |
| 1625 | 1648 | { |
| 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]); |
| 1627 | 1650 | } |
| 1628 | 1651 | r->index = 0; |
| 1629 | 1652 | } |
| @@ -1639,6 +1662,16 @@ void tRetune_setMode (tRetune* const rt, int mode) · 9 unmodified lines |
| 1639 | 1662 | else r->shiftFunction = &tPitchShift_shiftBy; |
| 1640 | 1663 | } |
| 1641 | 1664 | |
| 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 | + |
| 1642 | 1675 | void tRetune_setNumVoices(tRetune* const rt, int numVoices) |
| 1643 | 1676 | { |
| 1644 | 1677 | _tRetune* r = *rt; |