1
////////////////////////////////////////////////////////////////////////////////
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)
7
/// Author : Copyright (c) Olli Parviainen
8
/// Author e-mail : oparviai 'at' iki.fi
9
/// SoundTouch WWW: http://www.surina.net/soundtouch
11
////////////////////////////////////////////////////////////////////////////////
13
// Last changed : $Date: 2006/09/18 22:29:22 $
14
// File revision : $Revision: 1.5 $
16
// $Id: RateTransposer.cpp,v 1.5 2006/09/18 22:29:22 martynshaw Exp $
18
////////////////////////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////////////////////////
46
#include "RateTransposer.h"
49
using namespace soundtouch;
52
/// A linear samplerate transposer class that uses integer arithmetics.
53
/// for the transposing.
54
class RateTransposerInteger : public RateTransposer
59
SAMPLETYPE sPrevSampleL, sPrevSampleR;
61
virtual void resetRegisters();
63
virtual uint transposeStereo(SAMPLETYPE *dest,
64
const SAMPLETYPE *src,
66
virtual uint transposeMono(SAMPLETYPE *dest,
67
const SAMPLETYPE *src,
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
88
SAMPLETYPE sPrevSampleL, sPrevSampleR;
90
virtual void resetRegisters();
92
virtual uint transposeStereo(SAMPLETYPE *dest,
93
const SAMPLETYPE *src,
95
virtual uint transposeMono(SAMPLETYPE *dest,
96
const SAMPLETYPE *src,
100
RateTransposerFloat();
101
virtual ~RateTransposerFloat();
107
#define min(a,b) ((a > b) ? b : a)
108
#define max(a,b) ((a < b) ? b : a)
112
// Operator 'new' is overloaded so that it automatically creates a suitable instance
113
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
114
void * RateTransposer::operator new(size_t s)
116
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
122
RateTransposer *RateTransposer::newInstance()
124
#ifdef INTEGER_SAMPLES
125
return ::new RateTransposerInteger;
127
return ::new RateTransposerFloat;
133
RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
138
// Instantiates the anti-alias filter with default tap length
140
pAAFilter = new AAFilter(32);
145
RateTransposer::~RateTransposer()
152
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
153
void RateTransposer::enableAAFilter(const BOOL newMode)
155
bUseAAFilter = newMode;
159
/// Returns nonzero if anti-alias filter is enabled.
160
BOOL RateTransposer::isAAFilterEnabled() const
166
AAFilter *RateTransposer::getAAFilter() const
173
// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
174
// uRate, larger faster uRates.
175
void RateTransposer::setRate(float newRate)
181
// design a new anti-alias filter
184
fCutoff = 0.5f / newRate;
188
fCutoff = 0.5f * newRate;
190
pAAFilter->setCutoffFreq(fCutoff);
194
// Outputs as many samples of the 'outputBuffer' as possible, and if there's
195
// any room left, outputs also as many of the incoming samples as possible.
196
// The goal is to drive the outputBuffer empty.
198
// It's allowed for 'output' and 'input' parameters to point to the same
200
void RateTransposer::flushStoreBuffer()
202
if (storeBuffer.isEmpty()) return;
204
outputBuffer.moveSamples(storeBuffer);
208
// Adds 'numSamples' pcs of samples from the 'samples' memory position into
209
// the input of the object.
210
void RateTransposer::putSamples(const SAMPLETYPE *samples, uint numSamples)
212
processSamples(samples, numSamples);
217
// Transposes up the sample rate, causing the observed playback 'rate' of the
219
void RateTransposer::upsample(const SAMPLETYPE *src, uint numSamples)
221
int count, sizeTemp, num;
223
// If the parameter 'uRate' value is smaller than 'SCALE', first transpose
224
// the samples and then apply the anti-alias filter to remove aliasing.
226
// First check that there's enough room in 'storeBuffer'
227
// (+16 is to reserve some slack in the destination buffer)
228
sizeTemp = (int)((float)numSamples / fRate + 16.0f);
230
// Transpose the samples, store the result into the end of "storeBuffer"
231
count = transpose(storeBuffer.ptrEnd(sizeTemp), src, numSamples);
232
storeBuffer.putSamples(count);
234
// Apply the anti-alias filter to samples in "store output", output the
236
num = storeBuffer.numSamples();
237
count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
238
storeBuffer.ptrBegin(), num, uChannels);
239
outputBuffer.putSamples(count);
241
// Remove the processed samples from "storeBuffer"
242
storeBuffer.receiveSamples(count);
246
// Transposes down the sample rate, causing the observed playback 'rate' of the
248
void RateTransposer::downsample(const SAMPLETYPE *src, uint numSamples)
252
// If the parameter 'uRate' value is larger than 'SCALE', first apply the
253
// anti-alias filter to remove high frequencies (prevent them from folding
254
// over the lover frequencies), then transpose. */
256
// Add the new samples to the end of the storeBuffer */
257
storeBuffer.putSamples(src, numSamples);
259
// Anti-alias filter the samples to prevent folding and output the filtered
260
// data to tempBuffer. Note : because of the FIR filter length, the
261
// filtering routine takes in 'filter_length' more samples than it outputs.
262
assert(tempBuffer.isEmpty());
263
sizeTemp = storeBuffer.numSamples();
265
count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
266
storeBuffer.ptrBegin(), sizeTemp, uChannels);
268
// Remove the filtered samples from 'storeBuffer'
269
storeBuffer.receiveSamples(count);
271
// Transpose the samples (+16 is to reserve some slack in the destination buffer)
272
sizeTemp = (int)((float)numSamples / fRate + 16.0f);
273
count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
274
outputBuffer.putSamples(count);
278
// Transposes sample rate by applying anti-alias filter to prevent folding.
279
// Returns amount of samples returned in the "dest" buffer.
280
// The maximum amount of samples that can be returned at a time is set by
281
// the 'set_returnBuffer_size' function.
282
void RateTransposer::processSamples(const SAMPLETYPE *src, uint numSamples)
287
if (numSamples == 0) return;
290
// If anti-alias filter is turned off, simply transpose without applying
292
if (bUseAAFilter == FALSE)
294
sizeReq = (int)((float)numSamples / fRate + 1.0f);
295
count = transpose(outputBuffer.ptrEnd(sizeReq), src, numSamples);
296
outputBuffer.putSamples(count);
300
// Transpose with anti-alias filter
303
upsample(src, numSamples);
307
downsample(src, numSamples);
312
// Transposes the sample rate of the given samples using linear interpolation.
313
// Returns the number of samples returned in the "dest" buffer
314
inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
318
return transposeStereo(dest, src, numSamples);
322
return transposeMono(dest, src, numSamples);
327
// Sets the number of channels, 1 = mono, 2 = stereo
328
void RateTransposer::setChannels(const uint numchannels)
330
if (uChannels == numchannels) return;
332
assert(numchannels == 1 || numchannels == 2);
333
uChannels = numchannels;
335
storeBuffer.setChannels(uChannels);
336
tempBuffer.setChannels(uChannels);
337
outputBuffer.setChannels(uChannels);
339
// Inits the linear interpolation registers
344
// Clears all the samples in the object
345
void RateTransposer::clear()
347
outputBuffer.clear();
352
// Returns nonzero if there aren't any samples available for outputting.
353
uint RateTransposer::isEmpty()
357
res = FIFOProcessor::isEmpty();
358
if (res == 0) return 0;
359
return storeBuffer.isEmpty();
363
//////////////////////////////////////////////////////////////////////////////
365
// RateTransposerInteger - integer arithmetic implementation
368
/// fixed-point interpolation routine precision
372
RateTransposerInteger::RateTransposerInteger() : RateTransposer()
374
// call these here as these are virtual functions; calling these
375
// from the base class constructor wouldn't execute the overloaded
376
// versions (<master yoda>peculiar C++ can be</my>).
382
RateTransposerInteger::~RateTransposerInteger()
387
void RateTransposerInteger::resetRegisters()
396
// Transposes the sample rate of the given samples using linear interpolation.
397
// 'Mono' version of the routine. Returns the number of samples returned in
399
uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
401
unsigned int i, used;
402
LONG_SAMPLETYPE temp, vol1;
407
// Process the last sample saved from the previous call first...
408
while (iSlopeCount <= SCALE)
410
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
411
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
412
dest[i] = (SAMPLETYPE)(temp / SCALE);
414
iSlopeCount += uRate;
416
// now always (iSlopeCount > SCALE)
417
iSlopeCount -= SCALE;
421
while (iSlopeCount > SCALE)
423
iSlopeCount -= SCALE;
425
if (used >= numSamples - 1) goto end;
427
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
428
temp = src[used] * vol1 + iSlopeCount * src[used + 1];
429
dest[i] = (SAMPLETYPE)(temp / SCALE);
432
iSlopeCount += uRate;
435
// Store the last sample for the next round
436
sPrevSampleL = src[numSamples - 1];
442
// Transposes the sample rate of the given samples using linear interpolation.
443
// 'Stereo' version of the routine. Returns the number of samples returned in
445
uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
447
unsigned int srcPos, i, used;
448
LONG_SAMPLETYPE temp, vol1;
450
if (numSamples == 0) return 0; // no samples, no work
455
// Process the last sample saved from the sPrevSampleLious call first...
456
while (iSlopeCount <= SCALE)
458
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
459
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
460
dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
461
temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
462
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
464
iSlopeCount += uRate;
466
// now always (iSlopeCount > SCALE)
467
iSlopeCount -= SCALE;
471
while (iSlopeCount > SCALE)
473
iSlopeCount -= SCALE;
475
if (used >= numSamples - 1) goto end;
478
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
479
temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
480
dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
481
temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
482
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
485
iSlopeCount += uRate;
488
// Store the last sample for the next round
489
sPrevSampleL = src[2 * numSamples - 2];
490
sPrevSampleR = src[2 * numSamples - 1];
496
// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
497
// uRate, larger faster uRates.
498
void RateTransposerInteger::setRate(float newRate)
500
uRate = (int)(newRate * SCALE + 0.5f);
501
RateTransposer::setRate(newRate);
505
//////////////////////////////////////////////////////////////////////////////
507
// RateTransposerFloat - floating point arithmetic implementation
509
//////////////////////////////////////////////////////////////////////////////
512
RateTransposerFloat::RateTransposerFloat() : RateTransposer()
514
// call these here as these are virtual functions; calling these
515
// from the base class constructor wouldn't execute the overloaded
516
// versions (<master yoda>peculiar C++ can be</my>).
522
RateTransposerFloat::~RateTransposerFloat()
527
void RateTransposerFloat::resetRegisters()
536
// Transposes the sample rate of the given samples using linear interpolation.
537
// 'Mono' version of the routine. Returns the number of samples returned in
539
uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
541
unsigned int i, used;
546
// Process the last sample saved from the previous call first...
547
while (fSlopeCount <= 1.0f)
549
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
551
fSlopeCount += fRate;
555
if (numSamples == 1) goto end;
559
while (fSlopeCount > 1.0f)
563
if (used >= numSamples - 1) goto end;
565
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
567
fSlopeCount += fRate;
570
// Store the last sample for the next round
571
sPrevSampleL = src[numSamples - 1];
577
// Transposes the sample rate of the given samples using linear interpolation.
578
// 'Mono' version of the routine. Returns the number of samples returned in
580
uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
582
unsigned int srcPos, i, used;
584
if (numSamples == 0) return 0; // no samples, no work
589
// Process the last sample saved from the sPrevSampleLious call first...
590
while (fSlopeCount <= 1.0f)
592
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
593
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
595
fSlopeCount += fRate;
597
// now always (iSlopeCount > 1.0f)
600
if (numSamples == 1) goto end;
604
while (fSlopeCount > 1.0f)
608
if (used >= numSamples - 1) goto end;
612
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
613
+ fSlopeCount * src[srcPos + 2]);
614
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
615
+ fSlopeCount * src[srcPos + 3]);
618
fSlopeCount += fRate;
621
// Store the last sample for the next round
622
sPrevSampleL = src[2 * numSamples - 2];
623
sPrevSampleR = src[2 * numSamples - 1];