| @@ -1019,19 +1019,20 @@ static void pitchup(_tSOLAD *w, float *out); · 1018 unmodified lines |
| 1019 | /******************************************************************************/ | 1019 | /******************************************************************************/ |
| 1020 | | 1020 | |
| 1021 | // init | 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 | _tMempool* m = *mp; | 1029 | _tMempool* m = *mp; |
| 1030 | _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m); | 1030 | _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m); |
| 1031 | w->mempool = m; | 1031 | w->mempool = m; |
| 1032 | | 1032 | |
| | 1033 | w->loopSize = loopSize; |
| 1033 | w->pitchfactor = 1.; | 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 | w->timeindex = 0; | 1037 | w->timeindex = 0; |
| 1037 | w->xfadevalue = -1; | 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 | float sample = tHighpass_tick(&w->hp, in[0]); | 1067 | float sample = tHighpass_tick(&w->hp, in[0]); |
| 1067 | w->delaybuf[0] = sample; | 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 | n--; | 1070 | n--; |
| 1070 | i++; | 1071 | i++; |
| 1071 | in++; | 1072 | in++; |
| @@ -1082,7 +1083,7 @@ void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize) · 10 unmodified lines |
| 1082 | else pitchdown(w, out); | 1083 | else pitchdown(w, out); |
| 1083 | | 1084 | |
| 1084 | w->timeindex += blocksize; | 1085 | w->timeindex += blocksize; |
| 1085 | w->timeindex &= LOOPMASK; | 1086 | w->timeindex &= (w->loopSize - 1); |
| 1086 | } | 1087 | } |
| 1087 | | 1088 | |
| 1088 | // set periodicity analysis data | 1089 | // set periodicity analysis data |
| @@ -1090,7 +1091,8 @@ void tSOLAD_setPeriod(tSOLAD* const wp, float period) · 1 unmodified line |
| 1090 | { | 1091 | { |
| 1091 | _tSOLAD* w = *wp; | 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 | if(period > MINPERIOD) w->period = period; // ignore period when too small | 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 | _tSOLAD* w = *wp; | 1129 | _tSOLAD* w = *wp; |
| 1128 | | 1130 | |
| 1129 | int n = LOOPSIZE; | 1131 | int n = w->loopSize; |
| 1130 | float *buf = w->delaybuf; | 1132 | float *buf = w->delaybuf; |
| 1131 | | 1133 | |
| 1132 | while(n--) *buf++ = 0; | 1134 | while(n--) *buf++ = 0; |
| @@ -1173,7 +1175,7 @@ void tSOLAD_resetState(tSOLAD* const wp) · 40 unmodified lines |
| 1173 | static void pitchdown(_tSOLAD* const w, float *out) | 1175 | static void pitchdown(_tSOLAD* const w, float *out) |
| 1174 | { | 1176 | { |
| 1175 | int n = w->blocksize; | 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 | float pitchfactor = w->pitchfactor; | 1179 | float pitchfactor = w->pitchfactor; |
| 1178 | float period = w->period; | 1180 | float period = w->period; |
| 1179 | float readlag = w->readlag; | 1181 | float readlag = w->readlag; |
| @@ -1291,7 +1293,7 @@ static void pitchdown(_tSOLAD* const w, float *out) · 111 unmodified lines |
| 1291 | static void pitchup(_tSOLAD* const w, float *out) | 1293 | static void pitchup(_tSOLAD* const w, float *out) |
| 1292 | { | 1294 | { |
| 1293 | int n = w->blocksize; | 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 | float pitchfactor = w->pitchfactor; | 1297 | float pitchfactor = w->pitchfactor; |
| 1296 | float period = w->period; | 1298 | float period = w->period; |
| 1297 | float readlag = w->readlag; | 1299 | float readlag = w->readlag; |
| @@ -1359,7 +1361,7 @@ static inline float read_sample(_tSOLAD* const w, float floatindex) · 61 unmodified lines |
| 1359 | int index = (int)floatindex; | 1361 | int index = (int)floatindex; |
| 1360 | float fraction = floatindex - (float)index; | 1362 | float fraction = floatindex - (float)index; |
| 1361 | float *buf = w->delaybuf; | 1363 | float *buf = w->delaybuf; |
| 1362 | index &= LOOPMASK; | 1364 | index &= (w->loopSize - 1); |
| 1363 | | 1365 | |
| 1364 | return (buf[index] + (fraction * (buf[index+1] - buf[index]))); | 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 | // PITCHSHIFT | 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 | _tMempool* m = *mp; | 1380 | _tMempool* m = *mp; |
| 1379 | _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m); | 1381 | _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m); |
| 1380 | ps->mempool = m; | 1382 | ps->mempool = m; |
| 1381 | | 1383 | |
| 1382 | ps->pd = *dpd; | 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 | tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO); | 1389 | tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO); |
| 1386 | } | 1390 | } |
| 1387 | | 1391 | |
| @@ -1393,29 +1397,31 @@ void tPitchShift_free (tPitchShift* const psr) · 5 unmodified lines |
| 1393 | mpool_free((char*)ps, ps->mempool); | 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 | _tPitchShift* ps = *psr; | 1402 | _tPitchShift* ps = *psr; |
| 1399 | LEAF* leaf = ps->mempool->leaf; | 1403 | LEAF* leaf = ps->mempool->leaf; |
| 1400 | | 1404 | |
| 1401 | float detected = tDualPitchDetector_getFrequency(&ps->pd); | 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 | float period = leaf->sampleRate / detected; | 1409 | float period = leaf->sampleRate / detected; |
| 1405 | tSOLAD_setPeriod(&ps->sola, period); | 1410 | tSOLAD_setPeriod(&ps->sola, period); |
| 1406 | tSOLAD_setPitchFactor(&ps->sola, factor); | 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 | _tPitchShift* ps = *psr; | 1419 | _tPitchShift* ps = *psr; |
| 1415 | LEAF* leaf = ps->mempool->leaf; | 1420 | LEAF* leaf = ps->mempool->leaf; |
| 1416 | | 1421 | |
| 1417 | float detected = tDualPitchDetector_getFrequency(&ps->pd); | 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 | float period = 1.0f / detected; | 1426 | float period = 1.0f / detected; |
| 1421 | float factor = freq * period; | 1427 | float factor = freq * period; |
| @@ -1423,7 +1429,14 @@ void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, floa · 1 unmodified line |
| 1423 | tSOLAD_setPitchFactor(&ps->sola, factor); | 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 | for (int i = 0; i < r->numVoices; ++i) | 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 | r->shiftFunction = &tPitchShift_shiftBy; | 1478 | r->shiftFunction = &tPitchShift_shiftBy; |
| @@ -1495,7 +1508,7 @@ float tSimpleRetune_tick(tSimpleRetune* const rt, float sample) · 29 unmodified lines |
| 1495 | { | 1508 | { |
| 1496 | for (int i = 0; i < r->numVoices; ++i) | 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 | r->index = 0; | 1513 | r->index = 0; |
| 1501 | } | 1514 | } |
| @@ -1524,6 +1537,16 @@ void tSimpleRetune_setNumVoices(tSimpleRetune* const rt, int numVoices) · 22 unmodified lines |
| 1524 | tSimpleRetune_initToPool(rt, minInputFreq, maxInputFreq, numVoices, bufSize, &mempool); | 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 | void tSimpleRetune_tuneVoices(tSimpleRetune* const rt, float* t) | 1550 | void tSimpleRetune_tuneVoices(tSimpleRetune* const rt, float* t) |
| 1528 | { | 1551 | { |
| 1529 | _tSimpleRetune* r = *rt; | 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 | for (int i = 0; i < r->numVoices; ++i) | 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 | r->outBuffers[i] = (float*) mpool_calloc(sizeof(float) * r->bufSize, m); | 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 | for (int i = 0; i < r->numVoices; ++i) | 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 | r->index = 0; | 1651 | r->index = 0; |
| 1629 | } | 1652 | } |
| @@ -1639,6 +1662,16 @@ void tRetune_setMode (tRetune* const rt, int mode) · 9 unmodified lines |
| 1639 | else r->shiftFunction = &tPitchShift_shiftBy; | 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 | void tRetune_setNumVoices(tRetune* const rt, int numVoices) | 1675 | void tRetune_setNumVoices(tRetune* const rt, int numVoices) |
| 1643 | { | 1676 | { |
| 1644 | _tRetune* r = *rt; | 1677 | _tRetune* r = *rt; |