RateTransposer.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. ////////////////////////////////////////////////////////////////////////////////
  2. ///
  3. /// Sample rate transposer. Changes sample rate by using linear interpolation
  4. /// together with anti-alias filtering (first order interpolation with anti-
  5. /// alias filtering should be quite adequate for this application)
  6. ///
  7. /// Author : Copyright (c) Olli Parviainen
  8. /// Author e-mail : oparviai 'at' iki.fi
  9. /// SoundTouch WWW: http://www.surina.net/soundtouch
  10. ///
  11. ////////////////////////////////////////////////////////////////////////////////
  12. //
  13. // Last changed : $Date: 2011-09-02 21:56:11 +0300 (Fri, 02 Sep 2011) $
  14. // File revision : $Revision: 4 $
  15. //
  16. // $Id: RateTransposer.cpp 131 2011-09-02 18:56:11Z oparviai $
  17. //
  18. ////////////////////////////////////////////////////////////////////////////////
  19. //
  20. // License :
  21. //
  22. // SoundTouch audio processing library
  23. // Copyright (c) Olli Parviainen
  24. //
  25. // This library is free software; you can redistribute it and/or
  26. // modify it under the terms of the GNU Lesser General Public
  27. // License as published by the Free Software Foundation; either
  28. // version 2.1 of the License, or (at your option) any later version.
  29. //
  30. // This library is distributed in the hope that it will be useful,
  31. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  33. // Lesser General Public License for more details.
  34. //
  35. // You should have received a copy of the GNU Lesser General Public
  36. // License along with this library; if not, write to the Free Software
  37. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  38. //
  39. ////////////////////////////////////////////////////////////////////////////////
  40. #include <memory.h>
  41. #include <assert.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include "RateTransposer.h"
  45. #include "AAFilter.h"
  46. using namespace soundtouch;
  47. /// A linear samplerate transposer class that uses integer arithmetics.
  48. /// for the transposing.
  49. class RateTransposerInteger : public RateTransposer
  50. {
  51. protected:
  52. int iSlopeCount;
  53. int iRate;
  54. SAMPLETYPE sPrevSampleL, sPrevSampleR;
  55. virtual void resetRegisters();
  56. virtual uint transposeStereo(SAMPLETYPE *dest,
  57. const SAMPLETYPE *src,
  58. uint numSamples);
  59. virtual uint transposeMono(SAMPLETYPE *dest,
  60. const SAMPLETYPE *src,
  61. uint numSamples);
  62. public:
  63. RateTransposerInteger();
  64. virtual ~RateTransposerInteger();
  65. /// Sets new target rate. Normal rate = 1.0, smaller values represent slower
  66. /// rate, larger faster rates.
  67. virtual void setRate(float newRate);
  68. };
  69. /// A linear samplerate transposer class that uses floating point arithmetics
  70. /// for the transposing.
  71. class RateTransposerFloat : public RateTransposer
  72. {
  73. protected:
  74. float fSlopeCount;
  75. SAMPLETYPE sPrevSampleL, sPrevSampleR;
  76. virtual void resetRegisters();
  77. virtual uint transposeStereo(SAMPLETYPE *dest,
  78. const SAMPLETYPE *src,
  79. uint numSamples);
  80. virtual uint transposeMono(SAMPLETYPE *dest,
  81. const SAMPLETYPE *src,
  82. uint numSamples);
  83. public:
  84. RateTransposerFloat();
  85. virtual ~RateTransposerFloat();
  86. };
  87. // Operator 'new' is overloaded so that it automatically creates a suitable instance
  88. // depending on if we've a MMX/SSE/etc-capable CPU available or not.
  89. void * RateTransposer::operator new(size_t s)
  90. {
  91. ST_THROW_RT_ERROR("Error in RateTransoser::new: don't use \"new TDStretch\" directly, use \"newInstance\" to create a new instance instead!");
  92. return newInstance();
  93. }
  94. RateTransposer *RateTransposer::newInstance()
  95. {
  96. #ifdef SOUNDTOUCH_INTEGER_SAMPLES
  97. return ::new RateTransposerInteger;
  98. #else
  99. return ::new RateTransposerFloat;
  100. #endif
  101. }
  102. // Constructor
  103. RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
  104. {
  105. numChannels = 2;
  106. bUseAAFilter = TRUE;
  107. fRate = 0;
  108. // Instantiates the anti-alias filter with default tap length
  109. // of 32
  110. pAAFilter = new AAFilter(32);
  111. }
  112. RateTransposer::~RateTransposer()
  113. {
  114. delete pAAFilter;
  115. }
  116. /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
  117. void RateTransposer::enableAAFilter(SBOOL newMode)
  118. {
  119. bUseAAFilter = newMode;
  120. }
  121. /// Returns nonzero if anti-alias filter is enabled.
  122. SBOOL RateTransposer::isAAFilterEnabled() const
  123. {
  124. return bUseAAFilter;
  125. }
  126. AAFilter *RateTransposer::getAAFilter()
  127. {
  128. return pAAFilter;
  129. }
  130. // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
  131. // iRate, larger faster iRates.
  132. void RateTransposer::setRate(float newRate)
  133. {
  134. double fCutoff;
  135. fRate = newRate;
  136. // design a new anti-alias filter
  137. if (newRate > 1.0f)
  138. {
  139. fCutoff = 0.5f / newRate;
  140. }
  141. else
  142. {
  143. fCutoff = 0.5f * newRate;
  144. }
  145. pAAFilter->setCutoffFreq(fCutoff);
  146. }
  147. // Outputs as many samples of the 'outputBuffer' as possible, and if there's
  148. // any room left, outputs also as many of the incoming samples as possible.
  149. // The goal is to drive the outputBuffer empty.
  150. //
  151. // It's allowed for 'output' and 'input' parameters to point to the same
  152. // memory position.
  153. /*
  154. void RateTransposer::flushStoreBuffer()
  155. {
  156. if (storeBuffer.isEmpty()) return;
  157. outputBuffer.moveSamples(storeBuffer);
  158. }
  159. */
  160. // Adds 'nSamples' pcs of samples from the 'samples' memory position into
  161. // the input of the object.
  162. void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
  163. {
  164. processSamples(samples, nSamples);
  165. }
  166. // Transposes up the sample rate, causing the observed playback 'rate' of the
  167. // sound to decrease
  168. void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples)
  169. {
  170. uint count, sizeTemp, num;
  171. // If the parameter 'uRate' value is smaller than 'SCALE', first transpose
  172. // the samples and then apply the anti-alias filter to remove aliasing.
  173. // First check that there's enough room in 'storeBuffer'
  174. // (+16 is to reserve some slack in the destination buffer)
  175. sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
  176. // Transpose the samples, store the result into the end of "storeBuffer"
  177. count = transpose(storeBuffer.ptrEnd(sizeTemp), src, nSamples);
  178. storeBuffer.putSamples(count);
  179. // Apply the anti-alias filter to samples in "store output", output the
  180. // result to "dest"
  181. num = storeBuffer.numSamples();
  182. count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
  183. storeBuffer.ptrBegin(), num, (uint)numChannels);
  184. outputBuffer.putSamples(count);
  185. // Remove the processed samples from "storeBuffer"
  186. storeBuffer.receiveSamples(count);
  187. }
  188. // Transposes down the sample rate, causing the observed playback 'rate' of the
  189. // sound to increase
  190. void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
  191. {
  192. uint count, sizeTemp;
  193. // If the parameter 'uRate' value is larger than 'SCALE', first apply the
  194. // anti-alias filter to remove high frequencies (prevent them from folding
  195. // over the lover frequencies), then transpose.
  196. // Add the new samples to the end of the storeBuffer
  197. storeBuffer.putSamples(src, nSamples);
  198. // Anti-alias filter the samples to prevent folding and output the filtered
  199. // data to tempBuffer. Note : because of the FIR filter length, the
  200. // filtering routine takes in 'filter_length' more samples than it outputs.
  201. assert(tempBuffer.isEmpty());
  202. sizeTemp = storeBuffer.numSamples();
  203. count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
  204. storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
  205. if (count == 0) return;
  206. // Remove the filtered samples from 'storeBuffer'
  207. storeBuffer.receiveSamples(count);
  208. // Transpose the samples (+16 is to reserve some slack in the destination buffer)
  209. sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
  210. count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
  211. outputBuffer.putSamples(count);
  212. }
  213. // Transposes sample rate by applying anti-alias filter to prevent folding.
  214. // Returns amount of samples returned in the "dest" buffer.
  215. // The maximum amount of samples that can be returned at a time is set by
  216. // the 'set_returnBuffer_size' function.
  217. void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
  218. {
  219. uint count;
  220. uint sizeReq;
  221. if (nSamples == 0) return;
  222. assert(pAAFilter);
  223. // If anti-alias filter is turned off, simply transpose without applying
  224. // the filter
  225. if (bUseAAFilter == FALSE)
  226. {
  227. sizeReq = (uint)((float)nSamples / fRate + 1.0f);
  228. count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
  229. outputBuffer.putSamples(count);
  230. return;
  231. }
  232. // Transpose with anti-alias filter
  233. if (fRate < 1.0f)
  234. {
  235. upsample(src, nSamples);
  236. }
  237. else
  238. {
  239. downsample(src, nSamples);
  240. }
  241. }
  242. // Transposes the sample rate of the given samples using linear interpolation.
  243. // Returns the number of samples returned in the "dest" buffer
  244. inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
  245. {
  246. if (numChannels == 2)
  247. {
  248. return transposeStereo(dest, src, nSamples);
  249. }
  250. else
  251. {
  252. return transposeMono(dest, src, nSamples);
  253. }
  254. }
  255. // Sets the number of channels, 1 = mono, 2 = stereo
  256. void RateTransposer::setChannels(int nChannels)
  257. {
  258. assert(nChannels > 0);
  259. if (numChannels == nChannels) return;
  260. assert(nChannels == 1 || nChannels == 2);
  261. numChannels = nChannels;
  262. storeBuffer.setChannels(numChannels);
  263. tempBuffer.setChannels(numChannels);
  264. outputBuffer.setChannels(numChannels);
  265. // Inits the linear interpolation registers
  266. resetRegisters();
  267. }
  268. // Clears all the samples in the object
  269. void RateTransposer::clear()
  270. {
  271. outputBuffer.clear();
  272. storeBuffer.clear();
  273. }
  274. // Returns nonzero if there aren't any samples available for outputting.
  275. int RateTransposer::isEmpty() const
  276. {
  277. int res;
  278. res = FIFOProcessor::isEmpty();
  279. if (res == 0) return 0;
  280. return storeBuffer.isEmpty();
  281. }
  282. //////////////////////////////////////////////////////////////////////////////
  283. //
  284. // RateTransposerInteger - integer arithmetic implementation
  285. //
  286. /// fixed-point interpolation routine precision
  287. #define SCALE 65536
  288. // Constructor
  289. RateTransposerInteger::RateTransposerInteger() : RateTransposer()
  290. {
  291. // Notice: use local function calling syntax for sake of clarity,
  292. // to indicate the fact that C++ constructor can't call virtual functions.
  293. RateTransposerInteger::resetRegisters();
  294. RateTransposerInteger::setRate(1.0f);
  295. }
  296. RateTransposerInteger::~RateTransposerInteger()
  297. {
  298. }
  299. void RateTransposerInteger::resetRegisters()
  300. {
  301. iSlopeCount = 0;
  302. sPrevSampleL =
  303. sPrevSampleR = 0;
  304. }
  305. // Transposes the sample rate of the given samples using linear interpolation.
  306. // 'Mono' version of the routine. Returns the number of samples returned in
  307. // the "dest" buffer
  308. uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
  309. {
  310. unsigned int i, used;
  311. LONG_SAMPLETYPE temp, vol1;
  312. if (nSamples == 0) return 0; // no samples, no work
  313. used = 0;
  314. i = 0;
  315. // Process the last sample saved from the previous call first...
  316. while (iSlopeCount <= SCALE)
  317. {
  318. vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
  319. temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
  320. dest[i] = (SAMPLETYPE)(temp / SCALE);
  321. i++;
  322. iSlopeCount += iRate;
  323. }
  324. // now always (iSlopeCount > SCALE)
  325. iSlopeCount -= SCALE;
  326. while (1)
  327. {
  328. while (iSlopeCount > SCALE)
  329. {
  330. iSlopeCount -= SCALE;
  331. used ++;
  332. if (used >= nSamples - 1) goto end;
  333. }
  334. vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
  335. temp = src[used] * vol1 + iSlopeCount * src[used + 1];
  336. dest[i] = (SAMPLETYPE)(temp / SCALE);
  337. i++;
  338. iSlopeCount += iRate;
  339. }
  340. end:
  341. // Store the last sample for the next round
  342. sPrevSampleL = src[nSamples - 1];
  343. return i;
  344. }
  345. // Transposes the sample rate of the given samples using linear interpolation.
  346. // 'Stereo' version of the routine. Returns the number of samples returned in
  347. // the "dest" buffer
  348. uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
  349. {
  350. unsigned int srcPos, i, used;
  351. LONG_SAMPLETYPE temp, vol1;
  352. if (nSamples == 0) return 0; // no samples, no work
  353. used = 0;
  354. i = 0;
  355. // Process the last sample saved from the sPrevSampleLious call first...
  356. while (iSlopeCount <= SCALE)
  357. {
  358. vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
  359. temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
  360. dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
  361. temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
  362. dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
  363. i++;
  364. iSlopeCount += iRate;
  365. }
  366. // now always (iSlopeCount > SCALE)
  367. iSlopeCount -= SCALE;
  368. while (1)
  369. {
  370. while (iSlopeCount > SCALE)
  371. {
  372. iSlopeCount -= SCALE;
  373. used ++;
  374. if (used >= nSamples - 1) goto end;
  375. }
  376. srcPos = 2 * used;
  377. vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
  378. temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
  379. dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
  380. temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
  381. dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
  382. i++;
  383. iSlopeCount += iRate;
  384. }
  385. end:
  386. // Store the last sample for the next round
  387. sPrevSampleL = src[2 * nSamples - 2];
  388. sPrevSampleR = src[2 * nSamples - 1];
  389. return i;
  390. }
  391. // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
  392. // iRate, larger faster iRates.
  393. void RateTransposerInteger::setRate(float newRate)
  394. {
  395. iRate = (int)(newRate * SCALE + 0.5f);
  396. RateTransposer::setRate(newRate);
  397. }
  398. //////////////////////////////////////////////////////////////////////////////
  399. //
  400. // RateTransposerFloat - floating point arithmetic implementation
  401. //
  402. //////////////////////////////////////////////////////////////////////////////
  403. // Constructor
  404. RateTransposerFloat::RateTransposerFloat() : RateTransposer()
  405. {
  406. // Notice: use local function calling syntax for sake of clarity,
  407. // to indicate the fact that C++ constructor can't call virtual functions.
  408. RateTransposerFloat::resetRegisters();
  409. RateTransposerFloat::setRate(1.0f);
  410. }
  411. RateTransposerFloat::~RateTransposerFloat()
  412. {
  413. }
  414. void RateTransposerFloat::resetRegisters()
  415. {
  416. fSlopeCount = 0;
  417. sPrevSampleL =
  418. sPrevSampleR = 0;
  419. }
  420. // Transposes the sample rate of the given samples using linear interpolation.
  421. // 'Mono' version of the routine. Returns the number of samples returned in
  422. // the "dest" buffer
  423. uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
  424. {
  425. unsigned int i, used;
  426. used = 0;
  427. i = 0;
  428. // Process the last sample saved from the previous call first...
  429. while (fSlopeCount <= 1.0f)
  430. {
  431. dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
  432. i++;
  433. fSlopeCount += fRate;
  434. }
  435. fSlopeCount -= 1.0f;
  436. if (nSamples > 1)
  437. {
  438. while (1)
  439. {
  440. while (fSlopeCount > 1.0f)
  441. {
  442. fSlopeCount -= 1.0f;
  443. used ++;
  444. if (used >= nSamples - 1) goto end;
  445. }
  446. dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
  447. i++;
  448. fSlopeCount += fRate;
  449. }
  450. }
  451. end:
  452. // Store the last sample for the next round
  453. sPrevSampleL = src[nSamples - 1];
  454. return i;
  455. }
  456. // Transposes the sample rate of the given samples using linear interpolation.
  457. // 'Mono' version of the routine. Returns the number of samples returned in
  458. // the "dest" buffer
  459. uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
  460. {
  461. unsigned int srcPos, i, used;
  462. if (nSamples == 0) return 0; // no samples, no work
  463. used = 0;
  464. i = 0;
  465. // Process the last sample saved from the sPrevSampleLious call first...
  466. while (fSlopeCount <= 1.0f)
  467. {
  468. dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
  469. dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
  470. i++;
  471. fSlopeCount += fRate;
  472. }
  473. // now always (iSlopeCount > 1.0f)
  474. fSlopeCount -= 1.0f;
  475. if (nSamples > 1)
  476. {
  477. while (1)
  478. {
  479. while (fSlopeCount > 1.0f)
  480. {
  481. fSlopeCount -= 1.0f;
  482. used ++;
  483. if (used >= nSamples - 1) goto end;
  484. }
  485. srcPos = 2 * used;
  486. dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
  487. + fSlopeCount * src[srcPos + 2]);
  488. dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
  489. + fSlopeCount * src[srcPos + 3]);
  490. i++;
  491. fSlopeCount += fRate;
  492. }
  493. }
  494. end:
  495. // Store the last sample for the next round
  496. sPrevSampleL = src[2 * nSamples - 2];
  497. sPrevSampleR = src[2 * nSamples - 1];
  498. return i;
  499. }