TDStretch.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. ////////////////////////////////////////////////////////////////////////////////
  2. ///
  3. /// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
  4. /// while maintaining the original pitch by using a time domain WSOLA-like
  5. /// method with several performance-increasing tweaks.
  6. ///
  7. /// Note : MMX optimized functions reside in a separate, platform-specific
  8. /// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
  9. ///
  10. /// Author : Copyright (c) Olli Parviainen
  11. /// Author e-mail : oparviai 'at' iki.fi
  12. /// SoundTouch WWW: http://www.surina.net/soundtouch
  13. ///
  14. ////////////////////////////////////////////////////////////////////////////////
  15. //
  16. // Last changed : $Date: 2013-06-14 17:34:33 +0000 (Fri, 14 Jun 2013) $
  17. // File revision : $Revision: 1.12 $
  18. //
  19. // $Id: TDStretch.cpp 172 2013-06-14 17:34:33Z oparviai $
  20. //
  21. ////////////////////////////////////////////////////////////////////////////////
  22. //
  23. // License :
  24. //
  25. // SoundTouch audio processing library
  26. // Copyright (c) Olli Parviainen
  27. //
  28. // This library is free software; you can redistribute it and/or
  29. // modify it under the terms of the GNU Lesser General Public
  30. // License as published by the Free Software Foundation; either
  31. // version 2.1 of the License, or (at your option) any later version.
  32. //
  33. // This library is distributed in the hope that it will be useful,
  34. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  36. // Lesser General Public License for more details.
  37. //
  38. // You should have received a copy of the GNU Lesser General Public
  39. // License along with this library; if not, write to the Free Software
  40. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  41. //
  42. ////////////////////////////////////////////////////////////////////////////////
  43. #include <string.h>
  44. #include <limits.h>
  45. #include <assert.h>
  46. #include <math.h>
  47. #include <float.h>
  48. #include "STTypes.h"
  49. #include "cpu_detect.h"
  50. #include "TDStretch.h"
  51. using namespace soundtouch;
  52. #define max(x, y) (((x) > (y)) ? (x) : (y))
  53. /*****************************************************************************
  54. *
  55. * Constant definitions
  56. *
  57. *****************************************************************************/
  58. // Table for the hierarchical mixing position seeking algorithm
  59. static const short _scanOffsets[5][24]={
  60. { 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806,
  61. 868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0},
  62. {-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0,
  63. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  64. { -20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0,
  65. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  66. { -4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0,
  67. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  68. { 121, 114, 97, 114, 98, 105, 108, 32, 104, 99, 117, 111,
  69. 116, 100, 110, 117, 111, 115, 0, 0, 0, 0, 0, 0}};
  70. /*****************************************************************************
  71. *
  72. * Implementation of the class 'TDStretch'
  73. *
  74. *****************************************************************************/
  75. TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
  76. {
  77. bQuickSeek = FALSE;
  78. channels = 2;
  79. pMidBuffer = NULL;
  80. pMidBufferUnaligned = NULL;
  81. overlapLength = 0;
  82. bAutoSeqSetting = TRUE;
  83. bAutoSeekSetting = TRUE;
  84. // outDebt = 0;
  85. skipFract = 0;
  86. tempo = 1.0f;
  87. setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
  88. setTempo(1.0f);
  89. clear();
  90. }
  91. TDStretch::~TDStretch()
  92. {
  93. delete[] pMidBufferUnaligned;
  94. }
  95. // Sets routine control parameters. These control are certain time constants
  96. // defining how the sound is stretched to the desired duration.
  97. //
  98. // 'sampleRate' = sample rate of the sound
  99. // 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms)
  100. // 'seekwindowMS' = seeking window length for scanning the best overlapping
  101. // position (default = 28 ms)
  102. // 'overlapMS' = overlapping length (default = 12 ms)
  103. void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
  104. int aSeekWindowMS, int aOverlapMS)
  105. {
  106. // accept only positive parameter values - if zero or negative, use old values instead
  107. if (aSampleRate > 0) this->sampleRate = aSampleRate;
  108. if (aOverlapMS > 0) this->overlapMs = aOverlapMS;
  109. if (aSequenceMS > 0)
  110. {
  111. this->sequenceMs = aSequenceMS;
  112. bAutoSeqSetting = FALSE;
  113. }
  114. else if (aSequenceMS == 0)
  115. {
  116. // if zero, use automatic setting
  117. bAutoSeqSetting = TRUE;
  118. }
  119. if (aSeekWindowMS > 0)
  120. {
  121. this->seekWindowMs = aSeekWindowMS;
  122. bAutoSeekSetting = FALSE;
  123. }
  124. else if (aSeekWindowMS == 0)
  125. {
  126. // if zero, use automatic setting
  127. bAutoSeekSetting = TRUE;
  128. }
  129. calcSeqParameters();
  130. calculateOverlapLength(overlapMs);
  131. // set tempo to recalculate 'sampleReq'
  132. setTempo(tempo);
  133. }
  134. /// Get routine control parameters, see setParameters() function.
  135. /// Any of the parameters to this function can be NULL, in such case corresponding parameter
  136. /// value isn't returned.
  137. void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const
  138. {
  139. if (pSampleRate)
  140. {
  141. *pSampleRate = sampleRate;
  142. }
  143. if (pSequenceMs)
  144. {
  145. *pSequenceMs = (bAutoSeqSetting) ? (USE_AUTO_SEQUENCE_LEN) : sequenceMs;
  146. }
  147. if (pSeekWindowMs)
  148. {
  149. *pSeekWindowMs = (bAutoSeekSetting) ? (USE_AUTO_SEEKWINDOW_LEN) : seekWindowMs;
  150. }
  151. if (pOverlapMs)
  152. {
  153. *pOverlapMs = overlapMs;
  154. }
  155. }
  156. // Overlaps samples in 'midBuffer' with the samples in 'pInput'
  157. void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
  158. {
  159. int i;
  160. SAMPLETYPE m1, m2;
  161. m1 = (SAMPLETYPE)0;
  162. m2 = (SAMPLETYPE)overlapLength;
  163. for (i = 0; i < overlapLength ; i ++)
  164. {
  165. pOutput[i] = (pInput[i] * m1 + pMidBuffer[i] * m2 ) / overlapLength;
  166. m1 += 1;
  167. m2 -= 1;
  168. }
  169. }
  170. void TDStretch::clearMidBuffer()
  171. {
  172. memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
  173. }
  174. void TDStretch::clearInput()
  175. {
  176. inputBuffer.clear();
  177. clearMidBuffer();
  178. }
  179. // Clears the sample buffers
  180. void TDStretch::clear()
  181. {
  182. outputBuffer.clear();
  183. clearInput();
  184. }
  185. // Enables/disables the quick position seeking algorithm. Zero to disable, nonzero
  186. // to enable
  187. void TDStretch::enableQuickSeek(BOOL enable)
  188. {
  189. bQuickSeek = enable;
  190. }
  191. // Returns nonzero if the quick seeking algorithm is enabled.
  192. BOOL TDStretch::isQuickSeekEnabled() const
  193. {
  194. return bQuickSeek;
  195. }
  196. // Seeks for the optimal overlap-mixing position.
  197. int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
  198. {
  199. if (bQuickSeek)
  200. {
  201. return seekBestOverlapPositionQuick(refPos);
  202. }
  203. else
  204. {
  205. return seekBestOverlapPositionFull(refPos);
  206. }
  207. }
  208. // Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position
  209. // of 'ovlPos'.
  210. inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
  211. {
  212. #ifndef USE_MULTICH_ALWAYS
  213. if (channels == 1)
  214. {
  215. // mono sound.
  216. overlapMono(pOutput, pInput + ovlPos);
  217. }
  218. else if (channels == 2)
  219. {
  220. // stereo sound
  221. overlapStereo(pOutput, pInput + 2 * ovlPos);
  222. }
  223. else
  224. #endif // USE_MULTICH_ALWAYS
  225. {
  226. assert(channels > 0);
  227. overlapMulti(pOutput, pInput + channels * ovlPos);
  228. }
  229. }
  230. // Seeks for the optimal overlap-mixing position. The 'stereo' version of the
  231. // routine
  232. //
  233. // The best position is determined as the position where the two overlapped
  234. // sample sequences are 'most alike', in terms of the highest cross-correlation
  235. // value over the overlapping period
  236. int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
  237. {
  238. int bestOffs;
  239. double bestCorr, corr;
  240. int i;
  241. bestCorr = FLT_MIN;
  242. bestOffs = 0;
  243. // Scans for the best correlation value by testing each possible position
  244. // over the permitted range.
  245. for (i = 0; i < seekLength; i ++)
  246. {
  247. // Calculates correlation value for the mixing position corresponding
  248. // to 'i'
  249. corr = calcCrossCorr(refPos + channels * i, pMidBuffer);
  250. // heuristic rule to slightly favour values close to mid of the range
  251. double tmp = (double)(2 * i - seekLength) / (double)seekLength;
  252. corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
  253. // Checks for the highest correlation value
  254. if (corr > bestCorr)
  255. {
  256. bestCorr = corr;
  257. bestOffs = i;
  258. }
  259. }
  260. // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
  261. clearCrossCorrState();
  262. return bestOffs;
  263. }
  264. // Seeks for the optimal overlap-mixing position. The 'stereo' version of the
  265. // routine
  266. //
  267. // The best position is determined as the position where the two overlapped
  268. // sample sequences are 'most alike', in terms of the highest cross-correlation
  269. // value over the overlapping period
  270. int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
  271. {
  272. int j;
  273. int bestOffs;
  274. double bestCorr, corr;
  275. int scanCount, corrOffset, tempOffset;
  276. bestCorr = FLT_MIN;
  277. bestOffs = _scanOffsets[0][0];
  278. corrOffset = 0;
  279. tempOffset = 0;
  280. // Scans for the best correlation value using four-pass hierarchical search.
  281. //
  282. // The look-up table 'scans' has hierarchical position adjusting steps.
  283. // In first pass the routine searhes for the highest correlation with
  284. // relatively coarse steps, then rescans the neighbourhood of the highest
  285. // correlation with better resolution and so on.
  286. for (scanCount = 0;scanCount < 4; scanCount ++)
  287. {
  288. j = 0;
  289. while (_scanOffsets[scanCount][j])
  290. {
  291. tempOffset = corrOffset + _scanOffsets[scanCount][j];
  292. if (tempOffset >= seekLength) break;
  293. // Calculates correlation value for the mixing position corresponding
  294. // to 'tempOffset'
  295. corr = (double)calcCrossCorr(refPos + channels * tempOffset, pMidBuffer);
  296. // heuristic rule to slightly favour values close to mid of the range
  297. double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
  298. corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
  299. // Checks for the highest correlation value
  300. if (corr > bestCorr)
  301. {
  302. bestCorr = corr;
  303. bestOffs = tempOffset;
  304. }
  305. j ++;
  306. }
  307. corrOffset = bestOffs;
  308. }
  309. // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
  310. clearCrossCorrState();
  311. return bestOffs;
  312. }
  313. /// clear cross correlation routine state if necessary
  314. void TDStretch::clearCrossCorrState()
  315. {
  316. // default implementation is empty.
  317. }
  318. /// Calculates processing sequence length according to tempo setting
  319. void TDStretch::calcSeqParameters()
  320. {
  321. // Adjust tempo param according to tempo, so that variating processing sequence length is used
  322. // at varius tempo settings, between the given low...top limits
  323. #define AUTOSEQ_TEMPO_LOW 0.5 // auto setting low tempo range (-50%)
  324. #define AUTOSEQ_TEMPO_TOP 2.0 // auto setting top tempo range (+100%)
  325. // sequence-ms setting values at above low & top tempo
  326. #define AUTOSEQ_AT_MIN 125.0
  327. #define AUTOSEQ_AT_MAX 50.0
  328. #define AUTOSEQ_K ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
  329. #define AUTOSEQ_C (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW))
  330. // seek-window-ms setting values at above low & top tempo
  331. #define AUTOSEEK_AT_MIN 25.0
  332. #define AUTOSEEK_AT_MAX 15.0
  333. #define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
  334. #define AUTOSEEK_C (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW))
  335. #define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)))
  336. double seq, seek;
  337. if (bAutoSeqSetting)
  338. {
  339. seq = AUTOSEQ_C + AUTOSEQ_K * tempo;
  340. seq = CHECK_LIMITS(seq, AUTOSEQ_AT_MAX, AUTOSEQ_AT_MIN);
  341. sequenceMs = (int)(seq + 0.5);
  342. }
  343. if (bAutoSeekSetting)
  344. {
  345. seek = AUTOSEEK_C + AUTOSEEK_K * tempo;
  346. seek = CHECK_LIMITS(seek, AUTOSEEK_AT_MAX, AUTOSEEK_AT_MIN);
  347. seekWindowMs = (int)(seek + 0.5);
  348. }
  349. // Update seek window lengths
  350. seekWindowLength = (sampleRate * sequenceMs) / 1000;
  351. if (seekWindowLength < 2 * overlapLength)
  352. {
  353. seekWindowLength = 2 * overlapLength;
  354. }
  355. seekLength = (sampleRate * seekWindowMs) / 1000;
  356. }
  357. // Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
  358. // tempo, larger faster tempo.
  359. void TDStretch::setTempo(float newTempo)
  360. {
  361. int intskip;
  362. tempo = newTempo;
  363. // Calculate new sequence duration
  364. calcSeqParameters();
  365. // Calculate ideal skip length (according to tempo value)
  366. nominalSkip = tempo * (seekWindowLength - overlapLength);
  367. intskip = (int)(nominalSkip + 0.5f);
  368. // Calculate how many samples are needed in the 'inputBuffer' to
  369. // process another batch of samples
  370. //sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength / 2;
  371. sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength;
  372. }
  373. // Sets the number of channels, 1 = mono, 2 = stereo
  374. void TDStretch::setChannels(int numChannels)
  375. {
  376. assert(numChannels > 0);
  377. if (channels == numChannels) return;
  378. // assert(numChannels == 1 || numChannels == 2);
  379. channels = numChannels;
  380. inputBuffer.setChannels(channels);
  381. outputBuffer.setChannels(channels);
  382. // re-init overlap/buffer
  383. overlapLength=0;
  384. setParameters(sampleRate);
  385. }
  386. // nominal tempo, no need for processing, just pass the samples through
  387. // to outputBuffer
  388. /*
  389. void TDStretch::processNominalTempo()
  390. {
  391. assert(tempo == 1.0f);
  392. if (bMidBufferDirty)
  393. {
  394. // If there are samples in pMidBuffer waiting for overlapping,
  395. // do a single sliding overlapping with them in order to prevent a
  396. // clicking distortion in the output sound
  397. if (inputBuffer.numSamples() < overlapLength)
  398. {
  399. // wait until we've got overlapLength input samples
  400. return;
  401. }
  402. // Mix the samples in the beginning of 'inputBuffer' with the
  403. // samples in 'midBuffer' using sliding overlapping
  404. overlap(outputBuffer.ptrEnd(overlapLength), inputBuffer.ptrBegin(), 0);
  405. outputBuffer.putSamples(overlapLength);
  406. inputBuffer.receiveSamples(overlapLength);
  407. clearMidBuffer();
  408. // now we've caught the nominal sample flow and may switch to
  409. // bypass mode
  410. }
  411. // Simply bypass samples from input to output
  412. outputBuffer.moveSamples(inputBuffer);
  413. }
  414. */
  415. // Processes as many processing frames of the samples 'inputBuffer', store
  416. // the result into 'outputBuffer'
  417. void TDStretch::processSamples()
  418. {
  419. int ovlSkip, offset;
  420. int temp;
  421. /* Removed this small optimization - can introduce a click to sound when tempo setting
  422. crosses the nominal value
  423. if (tempo == 1.0f)
  424. {
  425. // tempo not changed from the original, so bypass the processing
  426. processNominalTempo();
  427. return;
  428. }
  429. */
  430. // Process samples as long as there are enough samples in 'inputBuffer'
  431. // to form a processing frame.
  432. while ((int)inputBuffer.numSamples() >= sampleReq)
  433. {
  434. // If tempo differs from the normal ('SCALE'), scan for the best overlapping
  435. // position
  436. offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
  437. // Mix the samples in the 'inputBuffer' at position of 'offset' with the
  438. // samples in 'midBuffer' using sliding overlapping
  439. // ... first partially overlap with the end of the previous sequence
  440. // (that's in 'midBuffer')
  441. overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
  442. outputBuffer.putSamples((uint)overlapLength);
  443. // ... then copy sequence samples from 'inputBuffer' to output:
  444. // length of sequence
  445. temp = (seekWindowLength - 2 * overlapLength);
  446. // crosscheck that we don't have buffer overflow...
  447. if ((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2))
  448. {
  449. continue; // just in case, shouldn't really happen
  450. }
  451. outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp);
  452. // Copies the end of the current sequence from 'inputBuffer' to
  453. // 'midBuffer' for being mixed with the beginning of the next
  454. // processing sequence and so on
  455. assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples());
  456. memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength),
  457. channels * sizeof(SAMPLETYPE) * overlapLength);
  458. // Remove the processed samples from the input buffer. Update
  459. // the difference between integer & nominal skip step to 'skipFract'
  460. // in order to prevent the error from accumulating over time.
  461. skipFract += nominalSkip; // real skip size
  462. ovlSkip = (int)skipFract; // rounded to integer skip
  463. skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip
  464. inputBuffer.receiveSamples((uint)ovlSkip);
  465. }
  466. }
  467. // Adds 'numsamples' pcs of samples from the 'samples' memory position into
  468. // the input of the object.
  469. void TDStretch::putSamples(const SAMPLETYPE *samples, uint nSamples)
  470. {
  471. // Add the samples into the input buffer
  472. inputBuffer.putSamples(samples, nSamples);
  473. // Process the samples in input buffer
  474. processSamples();
  475. }
  476. /// Set new overlap length parameter & reallocate RefMidBuffer if necessary.
  477. void TDStretch::acceptNewOverlapLength(int newOverlapLength)
  478. {
  479. int prevOvl;
  480. assert(newOverlapLength >= 0);
  481. prevOvl = overlapLength;
  482. overlapLength = newOverlapLength;
  483. if (overlapLength > prevOvl)
  484. {
  485. delete[] pMidBufferUnaligned;
  486. pMidBufferUnaligned = new SAMPLETYPE[overlapLength * channels + 16 / sizeof(SAMPLETYPE)];
  487. // ensure that 'pMidBuffer' is aligned to 16 byte boundary for efficiency
  488. pMidBuffer = (SAMPLETYPE *)SOUNDTOUCH_ALIGN_POINTER_16(pMidBufferUnaligned);
  489. clearMidBuffer();
  490. }
  491. }
  492. // Operator 'new' is overloaded so that it automatically creates a suitable instance
  493. // depending on if we've a MMX/SSE/etc-capable CPU available or not.
  494. void * TDStretch::operator new(size_t s)
  495. {
  496. // Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
  497. ST_THROW_RT_ERROR("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
  498. return newInstance();
  499. }
  500. TDStretch * TDStretch::newInstance()
  501. {
  502. uint uExtensions;
  503. uExtensions = detectCPUextensions();
  504. // Check if MMX/SSE instruction set extensions supported by CPU
  505. #ifdef SOUNDTOUCH_ALLOW_MMX
  506. // MMX routines available only with integer sample types
  507. if (uExtensions & SUPPORT_MMX)
  508. {
  509. return ::new TDStretchMMX;
  510. }
  511. else
  512. #endif // SOUNDTOUCH_ALLOW_MMX
  513. #ifdef SOUNDTOUCH_ALLOW_SSE
  514. if (uExtensions & SUPPORT_SSE)
  515. {
  516. // SSE support
  517. return ::new TDStretchSSE;
  518. }
  519. else
  520. #endif // SOUNDTOUCH_ALLOW_SSE
  521. {
  522. // ISA optimizations not supported, use plain C version
  523. return ::new TDStretch;
  524. }
  525. }
  526. //////////////////////////////////////////////////////////////////////////////
  527. //
  528. // Integer arithmetics specific algorithm implementations.
  529. //
  530. //////////////////////////////////////////////////////////////////////////////
  531. #ifdef SOUNDTOUCH_INTEGER_SAMPLES
  532. // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
  533. // version of the routine.
  534. void TDStretch::overlapStereo(short *poutput, const short *input) const
  535. {
  536. int i;
  537. short temp;
  538. int cnt2;
  539. for (i = 0; i < overlapLength ; i ++)
  540. {
  541. temp = (short)(overlapLength - i);
  542. cnt2 = 2 * i;
  543. poutput[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp ) / overlapLength;
  544. poutput[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength;
  545. }
  546. }
  547. // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Multi'
  548. // version of the routine.
  549. void TDStretch::overlapMulti(SAMPLETYPE *poutput, const SAMPLETYPE *input) const
  550. {
  551. SAMPLETYPE m1=(SAMPLETYPE)0;
  552. SAMPLETYPE m2;
  553. int i=0;
  554. for (m2 = (SAMPLETYPE)overlapLength; m2; m2 --)
  555. {
  556. for (int c = 0; c < channels; c ++)
  557. {
  558. poutput[i] = (input[i] * m1 + pMidBuffer[i] * m2) / overlapLength;
  559. i++;
  560. }
  561. m1++;
  562. }
  563. }
  564. // Calculates the x having the closest 2^x value for the given value
  565. static int _getClosest2Power(double value)
  566. {
  567. return (int)(log(value) / log(2.0) + 0.5);
  568. }
  569. /// Calculates overlap period length in samples.
  570. /// Integer version rounds overlap length to closest power of 2
  571. /// for a divide scaling operation.
  572. void TDStretch::calculateOverlapLength(int aoverlapMs)
  573. {
  574. int newOvl;
  575. assert(aoverlapMs >= 0);
  576. // calculate overlap length so that it's power of 2 - thus it's easy to do
  577. // integer division by right-shifting. Term "-1" at end is to account for
  578. // the extra most significatnt bit left unused in result by signed multiplication
  579. overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1;
  580. if (overlapDividerBits > 9) overlapDividerBits = 9;
  581. if (overlapDividerBits < 3) overlapDividerBits = 3;
  582. newOvl = (int)pow(2.0, (int)overlapDividerBits + 1); // +1 => account for -1 above
  583. acceptNewOverlapLength(newOvl);
  584. // calculate sloping divider so that crosscorrelation operation won't
  585. // overflow 32-bit register. Max. sum of the crosscorrelation sum without
  586. // divider would be 2^30*(N^3-N)/3, where N = overlap length
  587. slopingDivider = (newOvl * newOvl - 1) / 3;
  588. }
  589. double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare) const
  590. {
  591. long corr;
  592. long norm;
  593. int i;
  594. corr = norm = 0;
  595. // Same routine for stereo and mono. For stereo, unroll loop for better
  596. // efficiency and gives slightly better resolution against rounding.
  597. // For mono it same routine, just unrolls loop by factor of 4
  598. for (i = 0; i < channels * overlapLength; i += 4)
  599. {
  600. corr += (mixingPos[i] * compare[i] +
  601. mixingPos[i + 1] * compare[i + 1] +
  602. mixingPos[i + 2] * compare[i + 2] +
  603. mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits;
  604. norm += (mixingPos[i] * mixingPos[i] +
  605. mixingPos[i + 1] * mixingPos[i + 1] +
  606. mixingPos[i + 2] * mixingPos[i + 2] +
  607. mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBits;
  608. }
  609. // Normalize result by dividing by sqrt(norm) - this step is easiest
  610. // done using floating point operation
  611. if (norm == 0) norm = 1; // to avoid div by zero
  612. return (double)corr / sqrt((double)norm);
  613. }
  614. #endif // SOUNDTOUCH_INTEGER_SAMPLES
  615. //////////////////////////////////////////////////////////////////////////////
  616. //
  617. // Floating point arithmetics specific algorithm implementations.
  618. //
  619. #ifdef SOUNDTOUCH_FLOAT_SAMPLES
  620. // Overlaps samples in 'midBuffer' with the samples in 'pInput'
  621. void TDStretch::overlapStereo(float *pOutput, const float *pInput) const
  622. {
  623. int i;
  624. float fScale;
  625. float f1;
  626. float f2;
  627. fScale = 1.0f / (float)overlapLength;
  628. f1 = 0;
  629. f2 = 1.0f;
  630. for (i = 0; i < 2 * (int)overlapLength ; i += 2)
  631. {
  632. pOutput[i + 0] = pInput[i + 0] * f1 + pMidBuffer[i + 0] * f2;
  633. pOutput[i + 1] = pInput[i + 1] * f1 + pMidBuffer[i + 1] * f2;
  634. f1 += fScale;
  635. f2 -= fScale;
  636. }
  637. }
  638. // Overlaps samples in 'midBuffer' with the samples in 'input'.
  639. void TDStretch::overlapMulti(float *pOutput, const float *pInput) const
  640. {
  641. int i;
  642. float fScale;
  643. float f1;
  644. float f2;
  645. fScale = 1.0f / (float)overlapLength;
  646. f1 = 0;
  647. f2 = 1.0f;
  648. i=0;
  649. for (int i2 = 0; i2 < overlapLength; i2 ++)
  650. {
  651. // note: Could optimize this slightly by taking into account that always channels > 2
  652. for (int c = 0; c < channels; c ++)
  653. {
  654. pOutput[i] = pInput[i] * f1 + pMidBuffer[i] * f2;
  655. i++;
  656. }
  657. f1 += fScale;
  658. f2 -= fScale;
  659. }
  660. }
  661. /// Calculates overlapInMsec period length in samples.
  662. void TDStretch::calculateOverlapLength(int overlapInMsec)
  663. {
  664. int newOvl;
  665. assert(overlapInMsec >= 0);
  666. newOvl = (sampleRate * overlapInMsec) / 1000;
  667. if (newOvl < 16) newOvl = 16;
  668. // must be divisible by 8
  669. newOvl -= newOvl % 8;
  670. acceptNewOverlapLength(newOvl);
  671. }
  672. double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare) const
  673. {
  674. double corr;
  675. double norm;
  676. int i;
  677. corr = norm = 0;
  678. // Same routine for stereo and mono. For Stereo, unroll by factor of 2.
  679. // For mono it's same routine yet unrollsd by factor of 4.
  680. for (i = 0; i < channels * overlapLength; i += 4)
  681. {
  682. corr += mixingPos[i] * compare[i] +
  683. mixingPos[i + 1] * compare[i + 1];
  684. norm += mixingPos[i] * mixingPos[i] +
  685. mixingPos[i + 1] * mixingPos[i + 1];
  686. // unroll the loop for better CPU efficiency:
  687. corr += mixingPos[i + 2] * compare[i + 2] +
  688. mixingPos[i + 3] * compare[i + 3];
  689. norm += mixingPos[i + 2] * mixingPos[i + 2] +
  690. mixingPos[i + 3] * mixingPos[i + 3];
  691. }
  692. if (norm < 1e-9) norm = 1.0; // to avoid div by zero
  693. return corr / sqrt(norm);
  694. }
  695. #endif // SOUNDTOUCH_FLOAT_SAMPLES