rename languages as they should be
[ardour2.git] / libs / soundtouch / RateTransposer.cpp
blob3000e37e4a9fb18843f57028cb76a7df6cfe364a
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 @ iki.fi
9 /// SoundTouch WWW: http://www.iki.fi/oparviai/soundtouch
10 ///
11 ////////////////////////////////////////////////////////////////////////////////
13 // Last changed : $Date$
14 // File revision : $Revision$
16 // $Id$
18 ////////////////////////////////////////////////////////////////////////////////
20 // License :
22 // SoundTouch audio processing library
23 // Copyright (c) Olli Parviainen
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.
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.
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
39 ////////////////////////////////////////////////////////////////////////////////
41 #include <memory.h>
42 #include <cassert>
43 #include <cstdlib>
44 #include <cstdio>
45 #include <climits>
46 #include "RateTransposer.h"
47 #include "AAFilter.h"
49 using namespace soundtouch;
52 /// A linear samplerate transposer class that uses integer arithmetics.
53 /// for the transposing.
54 class RateTransposerInteger : public RateTransposer
56 protected:
57 int iSlopeCount;
58 uint uRate;
59 SAMPLETYPE sPrevSampleL, sPrevSampleR;
61 virtual void resetRegisters();
63 virtual uint transposeStereo(SAMPLETYPE *dest,
64 const SAMPLETYPE *src,
65 uint numSamples);
66 virtual uint transposeMono(SAMPLETYPE *dest,
67 const SAMPLETYPE *src,
68 uint numSamples);
70 public:
71 RateTransposerInteger();
72 virtual ~RateTransposerInteger();
74 /// Sets new target rate. Normal rate = 1.0, smaller values represent slower
75 /// rate, larger faster rates.
76 virtual void setRate(float newRate);
81 /// A linear samplerate transposer class that uses floating point arithmetics
82 /// for the transposing.
83 class RateTransposerFloat : public RateTransposer
85 protected:
86 float fSlopeCount;
87 float fRateStep;
88 SAMPLETYPE sPrevSampleL, sPrevSampleR;
90 virtual void resetRegisters();
92 virtual uint transposeStereo(SAMPLETYPE *dest,
93 const SAMPLETYPE *src,
94 uint numSamples);
95 virtual uint transposeMono(SAMPLETYPE *dest,
96 const SAMPLETYPE *src,
97 uint numSamples);
99 public:
100 RateTransposerFloat();
101 virtual ~RateTransposerFloat();
106 #ifndef min
107 #define min(a,b) ((a > b) ? b : a)
108 #define max(a,b) ((a < b) ? b : a)
109 #endif
111 RateTransposer *RateTransposer::newInstance()
113 #ifdef INTEGER_SAMPLES
114 return ::new RateTransposerInteger;
115 #else
116 return ::new RateTransposerFloat;
117 #endif
121 // Constructor
122 RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
124 uChannels = 2;
125 bUseAAFilter = TRUE;
127 // Instantiates the anti-alias filter with default tap length
128 // of 32
129 pAAFilter = new AAFilter(32);
134 RateTransposer::~RateTransposer()
136 delete pAAFilter;
141 /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
142 void RateTransposer::enableAAFilter(const BOOL newMode)
144 bUseAAFilter = newMode;
148 /// Returns nonzero if anti-alias filter is enabled.
149 BOOL RateTransposer::isAAFilterEnabled() const
151 return bUseAAFilter;
155 AAFilter *RateTransposer::getAAFilter() const
157 return pAAFilter;
162 // Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
163 // uRate, larger faster uRates.
164 void RateTransposer::setRate(float newRate)
166 float fCutoff;
168 fRate = newRate;
170 // design a new anti-alias filter
171 if (newRate > 1.0f)
173 fCutoff = 0.5f / newRate;
175 else
177 fCutoff = 0.5f * newRate;
179 pAAFilter->setCutoffFreq(fCutoff);
183 // Outputs as many samples of the 'outputBuffer' as possible, and if there's
184 // any room left, outputs also as many of the incoming samples as possible.
185 // The goal is to drive the outputBuffer empty.
187 // It's allowed for 'output' and 'input' parameters to point to the same
188 // memory position.
189 void RateTransposer::flushStoreBuffer()
191 if (storeBuffer.isEmpty()) return;
193 outputBuffer.moveSamples(storeBuffer);
197 // Adds 'numSamples' pcs of samples from the 'samples' memory position into
198 // the input of the object.
199 void RateTransposer::putSamples(const SAMPLETYPE *samples, uint numSamples)
201 processSamples(samples, numSamples);
206 // Transposes up the sample rate, causing the observed playback 'rate' of the
207 // sound to decrease
208 void RateTransposer::upsample(const SAMPLETYPE *src, uint numSamples)
210 int count, sizeTemp, num;
212 // If the parameter 'uRate' value is smaller than 'SCALE', first transpose
213 // the samples and then apply the anti-alias filter to remove aliasing.
215 // First check that there's enough room in 'storeBuffer'
216 // (+16 is to reserve some slack in the destination buffer)
217 sizeTemp = (int)((float)numSamples / fRate + 16.0f);
219 // Transpose the samples, store the result into the end of "storeBuffer"
220 count = transpose(storeBuffer.ptrEnd(sizeTemp), src, numSamples);
221 storeBuffer.putSamples(count);
223 // Apply the anti-alias filter to samples in "store output", output the
224 // result to "dest"
225 num = storeBuffer.numSamples();
226 count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
227 storeBuffer.ptrBegin(), num, uChannels);
228 outputBuffer.putSamples(count);
230 // Remove the processed samples from "storeBuffer"
231 storeBuffer.receiveSamples(count);
235 // Transposes down the sample rate, causing the observed playback 'rate' of the
236 // sound to increase
237 void RateTransposer::downsample(const SAMPLETYPE *src, uint numSamples)
239 int count, sizeTemp;
241 // If the parameter 'uRate' value is larger than 'SCALE', first apply the
242 // anti-alias filter to remove high frequencies (prevent them from folding
243 // over the lover frequencies), then transpose. */
245 // Add the new samples to the end of the storeBuffer */
246 storeBuffer.putSamples(src, numSamples);
248 // Anti-alias filter the samples to prevent folding and output the filtered
249 // data to tempBuffer. Note : because of the FIR filter length, the
250 // filtering routine takes in 'filter_length' more samples than it outputs.
251 assert(tempBuffer.isEmpty());
252 sizeTemp = storeBuffer.numSamples();
254 count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
255 storeBuffer.ptrBegin(), sizeTemp, uChannels);
257 // Remove the filtered samples from 'storeBuffer'
258 storeBuffer.receiveSamples(count);
260 // Transpose the samples (+16 is to reserve some slack in the destination buffer)
261 sizeTemp = (int)((float)numSamples / fRate + 16.0f);
262 count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
263 outputBuffer.putSamples(count);
267 // Transposes sample rate by applying anti-alias filter to prevent folding.
268 // Returns amount of samples returned in the "dest" buffer.
269 // The maximum amount of samples that can be returned at a time is set by
270 // the 'set_returnBuffer_size' function.
271 void RateTransposer::processSamples(const SAMPLETYPE *src, uint numSamples)
273 uint count;
274 uint sizeReq;
276 if (numSamples == 0) return;
277 assert(pAAFilter);
279 // If anti-alias filter is turned off, simply transpose without applying
280 // the filter
281 if (bUseAAFilter == FALSE)
283 sizeReq = (int)((float)numSamples / fRate + 1.0f);
284 count = transpose(outputBuffer.ptrEnd(sizeReq), src, numSamples);
285 outputBuffer.putSamples(count);
286 return;
289 // Transpose with anti-alias filter
290 if (fRate < 1.0f)
292 upsample(src, numSamples);
294 else
296 downsample(src, numSamples);
301 // Transposes the sample rate of the given samples using linear interpolation.
302 // Returns the number of samples returned in the "dest" buffer
303 inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
305 if (uChannels == 2)
307 return transposeStereo(dest, src, numSamples);
309 else
311 return transposeMono(dest, src, numSamples);
316 // Sets the number of channels, 1 = mono, 2 = stereo
317 void RateTransposer::setChannels(const uint numchannels)
319 if (uChannels == numchannels) return;
321 assert(numchannels == 1 || numchannels == 2);
322 uChannels = numchannels;
324 storeBuffer.setChannels(uChannels);
325 tempBuffer.setChannels(uChannels);
326 outputBuffer.setChannels(uChannels);
328 // Inits the linear interpolation registers
329 resetRegisters();
333 // Clears all the samples in the object
334 void RateTransposer::clear()
336 outputBuffer.clear();
337 storeBuffer.clear();
341 // Returns nonzero if there aren't any samples available for outputting.
342 int RateTransposer::isEmpty() const
344 int res;
346 res = FIFOProcessor::isEmpty();
347 if (res == 0) return 0;
348 return storeBuffer.isEmpty();
352 //////////////////////////////////////////////////////////////////////////////
354 // RateTransposerInteger - integer arithmetic implementation
357 /// fixed-point interpolation routine precision
358 #define SCALE 65536
360 // Constructor
361 RateTransposerInteger::RateTransposerInteger() : RateTransposer()
363 // call these here as these are virtual functions; calling these
364 // from the base class constructor wouldn't execute the overloaded
365 // versions (<master yoda>peculiar C++ can be</my>).
366 resetRegisters();
367 setRate(1.0f);
371 RateTransposerInteger::~RateTransposerInteger()
376 void RateTransposerInteger::resetRegisters()
378 iSlopeCount = 0;
379 sPrevSampleL =
380 sPrevSampleR = 0;
385 // Transposes the sample rate of the given samples using linear interpolation.
386 // 'Mono' version of the routine. Returns the number of samples returned in
387 // the "dest" buffer
388 uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
390 unsigned int i, used;
391 LONG_SAMPLETYPE temp, vol1;
393 used = 0;
394 i = 0;
396 // Process the last sample saved from the previous call first...
397 while (iSlopeCount <= SCALE)
399 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
400 temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
401 dest[i] = (SAMPLETYPE)(temp / SCALE);
402 i++;
403 iSlopeCount += uRate;
405 // now always (iSlopeCount > SCALE)
406 iSlopeCount -= SCALE;
408 while (1)
410 while (iSlopeCount > SCALE)
412 iSlopeCount -= SCALE;
413 used ++;
414 if (used >= numSamples - 1) goto end;
416 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
417 temp = src[used] * vol1 + iSlopeCount * src[used + 1];
418 dest[i] = (SAMPLETYPE)(temp / SCALE);
420 i++;
421 iSlopeCount += uRate;
423 end:
424 // Store the last sample for the next round
425 sPrevSampleL = src[numSamples - 1];
427 return i;
431 // Transposes the sample rate of the given samples using linear interpolation.
432 // 'Mono' version of the routine. Returns the number of samples returned in
433 // the "dest" buffer
434 uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
436 unsigned int srcPos, i, used;
437 LONG_SAMPLETYPE temp, vol1;
439 if (numSamples == 0) return 0; // no samples, no work
441 used = 0;
442 i = 0;
444 // Process the last sample saved from the sPrevSampleLious call first...
445 while (iSlopeCount <= SCALE)
447 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
448 temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
449 dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
450 temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
451 dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
452 i++;
453 iSlopeCount += uRate;
455 // now always (iSlopeCount > SCALE)
456 iSlopeCount -= SCALE;
458 while (1)
460 while (iSlopeCount > SCALE)
462 iSlopeCount -= SCALE;
463 used ++;
464 if (used >= numSamples - 1) goto end;
466 srcPos = 2 * used;
467 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
468 temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
469 dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
470 temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
471 dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
473 i++;
474 iSlopeCount += uRate;
476 end:
477 // Store the last sample for the next round
478 sPrevSampleL = src[2 * numSamples - 2];
479 sPrevSampleR = src[2 * numSamples - 1];
481 return i;
485 // Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
486 // uRate, larger faster uRates.
487 void RateTransposerInteger::setRate(float newRate)
489 uRate = (int)(newRate * SCALE + 0.5f);
490 RateTransposer::setRate(newRate);
494 //////////////////////////////////////////////////////////////////////////////
496 // RateTransposerFloat - floating point arithmetic implementation
498 //////////////////////////////////////////////////////////////////////////////
500 // Constructor
501 RateTransposerFloat::RateTransposerFloat() : RateTransposer()
503 // call these here as these are virtual functions; calling these
504 // from the base class constructor wouldn't execute the overloaded
505 // versions (<master yoda>peculiar C++ can be</my>).
506 resetRegisters();
507 setRate(1.0f);
511 RateTransposerFloat::~RateTransposerFloat()
516 void RateTransposerFloat::resetRegisters()
518 fSlopeCount = 0;
519 sPrevSampleL =
520 sPrevSampleR = 0;
525 // Transposes the sample rate of the given samples using linear interpolation.
526 // 'Mono' version of the routine. Returns the number of samples returned in
527 // the "dest" buffer
528 uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
530 unsigned int i, used;
532 used = 0;
533 i = 0;
535 // Process the last sample saved from the previous call first...
536 while (fSlopeCount <= 1.0f)
538 dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
539 i++;
540 fSlopeCount += fRate;
542 fSlopeCount -= 1.0f;
544 while (1)
546 while (fSlopeCount > 1.0f)
548 fSlopeCount -= 1.0f;
549 used ++;
550 if (used >= numSamples - 1) goto end;
552 dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
553 i++;
554 fSlopeCount += fRate;
556 end:
557 // Store the last sample for the next round
558 sPrevSampleL = src[numSamples - 1];
560 return i;
564 // Transposes the sample rate of the given samples using linear interpolation.
565 // 'Mono' version of the routine. Returns the number of samples returned in
566 // the "dest" buffer
567 uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
569 unsigned int srcPos, i, used;
571 if (numSamples == 0) return 0; // no samples, no work
573 used = 0;
574 i = 0;
576 // Process the last sample saved from the sPrevSampleLious call first...
577 while (fSlopeCount <= 1.0f)
579 dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
580 dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
581 i++;
582 fSlopeCount += fRate;
584 // now always (iSlopeCount > 1.0f)
585 fSlopeCount -= 1.0f;
587 while (1)
589 while (fSlopeCount > 1.0f)
591 fSlopeCount -= 1.0f;
592 used ++;
593 if (used >= numSamples - 1) goto end;
595 srcPos = 2 * used;
597 dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
598 + fSlopeCount * src[srcPos + 2]);
599 dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
600 + fSlopeCount * src[srcPos + 3]);
602 i++;
603 fSlopeCount += fRate;
605 end:
606 // Store the last sample for the next round
607 sPrevSampleL = src[2 * numSamples - 2];
608 sPrevSampleR = src[2 * numSamples - 1];
610 return i;