Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,527 +0,0 @@
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 15:56:11 -0300 (sex, 02 set 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
-
41
-#include <stdexcept>
42
-#include "RateTransposer.h"
43
-
44
-using namespace soundtouch;
45
-
46
-/// A linear samplerate transposer class that uses integer arithmetics.
47
-/// for the transposing.
48
-class RateTransposerInteger : public RateTransposer
49
-{
50
-protected:
51
-	int iSlopeCount;
52
-	int iRate;
53
-	SAMPLETYPE sPrevSampleL, sPrevSampleR;
54
-
55
-	virtual void resetRegisters();
56
-
57
-	virtual uint32_t transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
58
-	virtual uint32_t transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
59
-
60
-public:
61
-	RateTransposerInteger();
62
-	virtual ~RateTransposerInteger();
63
-
64
-	/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
65
-	/// rate, larger faster rates.
66
-	virtual void setRate(float newRate);
67
-};
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
-
77
-	virtual void resetRegisters();
78
-
79
-	virtual uint32_t transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
80
-	virtual uint32_t transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
81
-
82
-public:
83
-	RateTransposerFloat();
84
-	virtual ~RateTransposerFloat();
85
-};
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)
90
-{
91
-	// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
92
-	//assert(false);
93
-	//return NULL;
94
-	throw std::runtime_error("Don't use 'new RateTransposer', use 'newInstance' member instead!");
95
-}
96
-
97
-RateTransposer *RateTransposer::newInstance()
98
-{
99
-#ifdef SOUNDTOUCH_INTEGER_SAMPLES
100
-	return ::new RateTransposerInteger;
101
-#else
102
-	return ::new RateTransposerFloat;
103
-#endif
104
-}
105
-
106
-// Constructor
107
-RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
108
-{
109
-	this->numChannels = 2;
110
-	this->bUseAAFilter = true;
111
-	this->fRate = 0;
112
-
113
-	// Instantiates the anti-alias filter with default tap length
114
-	// of 32
115
-	this->pAAFilter.reset(new AAFilter(32));
116
-}
117
-
118
-RateTransposer::~RateTransposer()
119
-{
120
-}
121
-
122
-/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
123
-void RateTransposer::enableAAFilter(bool newMode)
124
-{
125
-	this->bUseAAFilter = newMode;
126
-}
127
-
128
-/// Returns nonzero if anti-alias filter is enabled.
129
-bool RateTransposer::isAAFilterEnabled() const
130
-{
131
-	return this->bUseAAFilter;
132
-}
133
-
134
-AAFilter *RateTransposer::getAAFilter()
135
-{
136
-	return this->pAAFilter.get();
137
-}
138
-
139
-// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
140
-// iRate, larger faster iRates.
141
-void RateTransposer::setRate(float newRate)
142
-{
143
-	double fCutoff;
144
-
145
-	this->fRate = newRate;
146
-
147
-	// design a new anti-alias filter
148
-	if (newRate > 1.0f)
149
-		fCutoff = 0.5f / newRate;
150
-	else
151
-		fCutoff = 0.5f * newRate;
152
-    this->pAAFilter->setCutoffFreq(fCutoff);
153
-}
154
-
155
-// Adds 'nSamples' pcs of samples from the 'samples' memory position into
156
-// the input of the object.
157
-void RateTransposer::putSamples(const SAMPLETYPE *samples, uint32_t nSamples)
158
-{
159
-	this->processSamples(samples, nSamples);
160
-}
161
-
162
-// Transposes up the sample rate, causing the observed playback 'rate' of the
163
-// sound to decrease
164
-void RateTransposer::upsample(const SAMPLETYPE *src, uint32_t nSamples)
165
-{
166
-	// If the parameter 'uRate' value is smaller than 'SCALE', first transpose
167
-	// the samples and then apply the anti-alias filter to remove aliasing.
168
-
169
-	// First check that there's enough room in 'storeBuffer'
170
-	// (+16 is to reserve some slack in the destination buffer)
171
-	uint32_t sizeTemp = static_cast<uint32_t>(nSamples / this->fRate + 16.0f);
172
-
173
-	// Transpose the samples, store the result into the end of "storeBuffer"
174
-	uint32_t count = this->transpose(this->storeBuffer.ptrEnd(sizeTemp), src, nSamples);
175
-	this->storeBuffer.putSamples(count);
176
-
177
-	// Apply the anti-alias filter to samples in "store output", output the
178
-	// result to "dest"
179
-	uint32_t num = this->storeBuffer.numSamples();
180
-	count = this->pAAFilter->evaluate(this->outputBuffer.ptrEnd(num), this->storeBuffer.ptrBegin(), num, this->numChannels);
181
-	this->outputBuffer.putSamples(count);
182
-
183
-	// Remove the processed samples from "storeBuffer"
184
-	this->storeBuffer.receiveSamples(count);
185
-}
186
-
187
-// Transposes down the sample rate, causing the observed playback 'rate' of the
188
-// sound to increase
189
-void RateTransposer::downsample(const SAMPLETYPE *src, uint32_t nSamples)
190
-{
191
-	// If the parameter 'uRate' value is larger than 'SCALE', first apply the
192
-	// anti-alias filter to remove high frequencies (prevent them from folding
193
-	// over the lover frequencies), then transpose. */
194
-
195
-	// Add the new samples to the end of the storeBuffer */
196
-	this->storeBuffer.putSamples(src, nSamples);
197
-
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(this->tempBuffer.isEmpty());
202
-	uint32_t sizeTemp = this->storeBuffer.numSamples();
203
-
204
-	uint32_t count = this->pAAFilter->evaluate(this->tempBuffer.ptrEnd(sizeTemp), this->storeBuffer.ptrBegin(), sizeTemp, this->numChannels);
205
-
206
-	// Remove the filtered samples from 'storeBuffer'
207
-	this->storeBuffer.receiveSamples(count);
208
-
209
-	// Transpose the samples (+16 is to reserve some slack in the destination buffer)
210
-	sizeTemp = static_cast<uint32_t>(nSamples / this->fRate + 16.0f);
211
-	count = this->transpose(this->outputBuffer.ptrEnd(sizeTemp), this->tempBuffer.ptrBegin(), count);
212
-	this->outputBuffer.putSamples(count);
213
-}
214
-
215
-// Transposes sample rate by applying anti-alias filter to prevent folding.
216
-// Returns amount of samples returned in the "dest" buffer.
217
-// The maximum amount of samples that can be returned at a time is set by
218
-// the 'set_returnBuffer_size' function.
219
-void RateTransposer::processSamples(const SAMPLETYPE *src, uint32_t nSamples)
220
-{
221
-	if (!nSamples)
222
-		return;
223
-	assert(this->pAAFilter);
224
-
225
-	// If anti-alias filter is turned off, simply transpose without applying
226
-	// the filter
227
-	if (!bUseAAFilter)
228
-	{
229
-		uint32_t sizeReq = static_cast<uint32_t>(nSamples / this->fRate + 1.0f);
230
-		uint32_t count = this->transpose(this->outputBuffer.ptrEnd(sizeReq), src, nSamples);
231
-		this->outputBuffer.putSamples(count);
232
-		return;
233
-	}
234
-
235
-	// Transpose with anti-alias filter
236
-	if (this->fRate < 1.0f)
237
-		this->upsample(src, nSamples);
238
-	else
239
-		this->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
-uint32_t RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
245
-{
246
-	if (this->numChannels == 2)
247
-		return this->transposeStereo(dest, src, nSamples);
248
-	else
249
-		return this->transposeMono(dest, src, nSamples);
250
-}
251
-
252
-// Sets the number of channels, 1 = mono, 2 = stereo
253
-void RateTransposer::setChannels(int32_t nChannels)
254
-{
255
-	assert(nChannels > 0);
256
-	if (this->numChannels == nChannels)
257
-		return;
258
-
259
-	assert(nChannels == 1 || nChannels == 2);
260
-	this->numChannels = nChannels;
261
-
262
-	this->storeBuffer.setChannels(this->numChannels);
263
-	this->tempBuffer.setChannels(this->numChannels);
264
-	this->outputBuffer.setChannels(this->numChannels);
265
-
266
-	// Inits the linear interpolation registers
267
-	this->resetRegisters();
268
-}
269
-
270
-// Clears all the samples in the object
271
-void RateTransposer::clear()
272
-{
273
-	this->outputBuffer.clear();
274
-	this->storeBuffer.clear();
275
-}
276
-
277
-// Returns nonzero if there aren't any samples available for outputting.
278
-bool RateTransposer::isEmpty() const
279
-{
280
-	bool res = FIFOProcessor::isEmpty();
281
-	if (!res)
282
-		return false;
283
-	return this->storeBuffer.isEmpty();
284
-}
285
-
286
-//////////////////////////////////////////////////////////////////////////////
287
-//
288
-// RateTransposerInteger - integer arithmetic implementation
289
-//
290
-
291
-/// fixed-point interpolation routine precision
292
-static const int SCALE = 65536;
293
-
294
-// Constructor
295
-RateTransposerInteger::RateTransposerInteger() : RateTransposer()
296
-{
297
-	// Notice: use local function calling syntax for sake of clarity,
298
-	// to indicate the fact that C++ constructor can't call virtual functions.
299
-	RateTransposerInteger::resetRegisters();
300
-	RateTransposerInteger::setRate(1.0f);
301
-}
302
-
303
-RateTransposerInteger::~RateTransposerInteger()
304
-{
305
-}
306
-
307
-void RateTransposerInteger::resetRegisters()
308
-{
309
-	this->iSlopeCount = 0;
310
-	this->sPrevSampleL = this->sPrevSampleR = 0;
311
-}
312
-
313
-// Transposes the sample rate of the given samples using linear interpolation.
314
-// 'Mono' version of the routine. Returns the number of samples returned in
315
-// the "dest" buffer
316
-uint32_t RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
317
-{
318
-	if (!nSamples)
319
-		return 0; // no samples, no work
320
-
321
-	unsigned used = 0, i = 0;
322
-
323
-	// Process the last sample saved from the previous call first...
324
-	LONG_SAMPLETYPE temp, vol1;
325
-	while (this->iSlopeCount <= SCALE)
326
-	{
327
-		vol1 = SCALE - this->iSlopeCount;
328
-		temp = vol1 * this->sPrevSampleL + this->iSlopeCount * src[0];
329
-		dest[i] = static_cast<SAMPLETYPE>(temp / SCALE);
330
-		++i;
331
-		this->iSlopeCount += this->iRate;
332
-	}
333
-	// now always (iSlopeCount > SCALE)
334
-	this->iSlopeCount -= SCALE;
335
-
336
-	while (1)
337
-	{
338
-		while (this->iSlopeCount > SCALE)
339
-		{
340
-			this->iSlopeCount -= SCALE;
341
-			++used;
342
-			if (used >= nSamples - 1)
343
-				goto end;
344
-		}
345
-		vol1 = SCALE - this->iSlopeCount;
346
-		temp = src[used] * vol1 + this->iSlopeCount * src[used + 1];
347
-		dest[i] = static_cast<SAMPLETYPE>(temp / SCALE);
348
-		++i;
349
-		this->iSlopeCount += this->iRate;
350
-	}
351
-end:
352
-	// Store the last sample for the next round
353
-	this->sPrevSampleL = src[nSamples - 1];
354
-
355
-	return i;
356
-}
357
-
358
-// Transposes the sample rate of the given samples using linear interpolation.
359
-// 'Stereo' version of the routine. Returns the number of samples returned in
360
-// the "dest" buffer
361
-uint32_t RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
362
-{
363
-	if (!nSamples)
364
-		return 0; // no samples, no work
365
-
366
-	unsigned used = 0, i = 0;
367
-
368
-	// Process the last sample saved from the sPrevSampleLious call first...
369
-	LONG_SAMPLETYPE temp, vol1;
370
-	while (this->iSlopeCount <= SCALE)
371
-	{
372
-		vol1 = SCALE - this->iSlopeCount;
373
-		temp = vol1 * this->sPrevSampleL + this->iSlopeCount * src[0];
374
-		dest[2 * i] = static_cast<SAMPLETYPE>(temp / SCALE);
375
-		temp = vol1 * this->sPrevSampleR + this->iSlopeCount * src[1];
376
-		dest[2 * i + 1] = static_cast<SAMPLETYPE>(temp / SCALE);
377
-		++i;
378
-		this->iSlopeCount += this->iRate;
379
-	}
380
-	// now always (iSlopeCount > SCALE)
381
-	this->iSlopeCount -= SCALE;
382
-
383
-	while (1)
384
-	{
385
-		while (this->iSlopeCount > SCALE)
386
-		{
387
-			this->iSlopeCount -= SCALE;
388
-			++used;
389
-			if (used >= nSamples - 1)
390
-				goto end;
391
-		}
392
-		unsigned srcPos = 2 * used;
393
-		vol1 = SCALE - this->iSlopeCount;
394
-		temp = src[srcPos] * vol1 + this->iSlopeCount * src[srcPos + 2];
395
-		dest[2 * i] = static_cast<SAMPLETYPE>(temp / SCALE);
396
-		temp = src[srcPos + 1] * vol1 + this->iSlopeCount * src[srcPos + 3];
397
-		dest[2 * i + 1] = static_cast<SAMPLETYPE>(temp / SCALE);
398
-		++i;
399
-		this->iSlopeCount += this->iRate;
400
-	}
401
-end:
402
-	// Store the last sample for the next round
403
-	this->sPrevSampleL = src[2 * nSamples - 2];
404
-	this->sPrevSampleR = src[2 * nSamples - 1];
405
-
406
-	return i;
407
-}
408
-
409
-// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
410
-// iRate, larger faster iRates.
411
-void RateTransposerInteger::setRate(float newRate)
412
-{
413
-	this->iRate = static_cast<int>(newRate * SCALE + 0.5f);
414
-	RateTransposer::setRate(newRate);
415
-}
416
-
417
-//////////////////////////////////////////////////////////////////////////////
418
-//
419
-// RateTransposerFloat - floating point arithmetic implementation
420
-//
421
-//////////////////////////////////////////////////////////////////////////////
422
-
423
-// Constructor
424
-RateTransposerFloat::RateTransposerFloat() : RateTransposer()
425
-{
426
-	// Notice: use local function calling syntax for sake of clarity,
427
-	// to indicate the fact that C++ constructor can't call virtual functions.
428
-	RateTransposerFloat::resetRegisters();
429
-	RateTransposerFloat::setRate(1.0f);
430
-}
431
-
432
-RateTransposerFloat::~RateTransposerFloat()
433
-{
434
-}
435
-
436
-void RateTransposerFloat::resetRegisters()
437
-{
438
-	this->fSlopeCount = 0;
439
-	this->sPrevSampleL = this->sPrevSampleR = 0;
440
-}
441
-
442
-// Transposes the sample rate of the given samples using linear interpolation.
443
-// 'Mono' version of the routine. Returns the number of samples returned in
444
-// the "dest" buffer
445
-uint32_t RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
446
-{
447
-	unsigned used = 0, i = 0;
448
-
449
-	// Process the last sample saved from the previous call first...
450
-	while (this->fSlopeCount <= 1.0f)
451
-	{
452
-		dest[i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * this->sPrevSampleL + this->fSlopeCount * src[0]);
453
-		++i;
454
-		this->fSlopeCount += this->fRate;
455
-	}
456
-	this->fSlopeCount -= 1.0f;
457
-
458
-	if (nSamples > 1)
459
-	{
460
-		while (1)
461
-		{
462
-			while (this->fSlopeCount > 1.0f)
463
-			{
464
-				this->fSlopeCount -= 1.0f;
465
-				++used;
466
-				if (used >= nSamples - 1)
467
-					goto end;
468
-			}
469
-			dest[i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * src[used] + this->fSlopeCount * src[used + 1]);
470
-			++i;
471
-			this->fSlopeCount += this->fRate;
472
-		}
473
-	}
474
-end:
475
-	// Store the last sample for the next round
476
-	this->sPrevSampleL = src[nSamples - 1];
477
-
478
-	return i;
479
-}
480
-
481
-// Transposes the sample rate of the given samples using linear interpolation.
482
-// 'Mono' version of the routine. Returns the number of samples returned in
483
-// the "dest" buffer
484
-uint32_t RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
485
-{
486
-	if (!nSamples)
487
-		return 0; // no samples, no work
488
-
489
-	unsigned used = 0, i = 0;
490
-
491
-	// Process the last sample saved from the sPrevSampleLious call first...
492
-	while (this->fSlopeCount <= 1.0f)
493
-	{
494
-		dest[2 * i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * this->sPrevSampleL + this->fSlopeCount * src[0]);
495
-		dest[2 * i + 1] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * this->sPrevSampleR + this->fSlopeCount * src[1]);
496
-		++i;
497
-		this->fSlopeCount += this->fRate;
498
-	}
499
-	// now always (iSlopeCount > 1.0f)
500
-	this->fSlopeCount -= 1.0f;
501
-
502
-	if (nSamples > 1)
503
-	{
504
-		while (1)
505
-		{
506
-			while (this->fSlopeCount > 1.0f)
507
-			{
508
-				this->fSlopeCount -= 1.0f;
509
-				++used;
510
-				if (used >= nSamples - 1)
511
-					goto end;
512
-			}
513
-			unsigned srcPos = 2 * used;
514
-
515
-			dest[2 * i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * src[srcPos] + this->fSlopeCount * src[srcPos + 2]);
516
-			dest[2 * i + 1] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * src[srcPos + 1] + this->fSlopeCount * src[srcPos + 3]);
517
-			++i;
518
-			this->fSlopeCount += this->fRate;
519
-		}
520
-	}
521
-end:
522
-	// Store the last sample for the next round
523
-	this->sPrevSampleL = src[2 * nSamples - 2];
524
-	this->sPrevSampleR = src[2 * nSamples - 1];
525
-
526
-	return i;
527
-}
Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -40,7 +40,6 @@
40 40
 
41 41
 #include <stdexcept>
42 42
 #include "RateTransposer.h"
43
-#include "AAFilter.h"
44 43
 
45 44
 using namespace soundtouch;
46 45
 
... ...
@@ -137,7 +136,7 @@ AAFilter *RateTransposer::getAAFilter()
137 136
 	return this->pAAFilter.get();
138 137
 }
139 138
 
140
-// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
139
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
141 140
 // iRate, larger faster iRates.
142 141
 void RateTransposer::setRate(float newRate)
143 142
 {
... ...
@@ -192,7 +191,7 @@ void RateTransposer::downsample(const SAMPLETYPE *src, uint32_t nSamples)
192 191
 	// If the parameter 'uRate' value is larger than 'SCALE', first apply the
193 192
 	// anti-alias filter to remove high frequencies (prevent them from folding
194 193
 	// over the lover frequencies), then transpose. */
195
-	
194
+
196 195
 	// Add the new samples to the end of the storeBuffer */
197 196
 	this->storeBuffer.putSamples(src, nSamples);
198 197
 
... ...
@@ -407,7 +406,7 @@ end:
407 406
 	return i;
408 407
 }
409 408
 
410
-// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
409
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
411 410
 // iRate, larger faster iRates.
412 411
 void RateTransposerInteger::setRate(float newRate)
413 412
 {
Browse code

Added Lanczos interpolation to the NCSF plugin, and cleaned up a bit of the other code, as well as removing pstdint.h since it's no longer needed.

Naram Qashat authored on 2013/04/23 20:29:21
Showing 1 changed files
... ...
@@ -221,7 +221,7 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint32_t nSamples)
221 221
 {
222 222
 	if (!nSamples)
223 223
 		return;
224
-	assert(this->pAAFilter.get());
224
+	assert(this->pAAFilter);
225 225
 
226 226
 	// If anti-alias filter is turned off, simply transpose without applying
227 227
 	// the filter
Browse code

Removed a bunch of casts, they seem to be fine without them in most cases.

Naram Qashat authored on 2013/04/18 23:22:54
Showing 1 changed files
... ...
@@ -325,7 +325,7 @@ uint32_t RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE
325 325
 	LONG_SAMPLETYPE temp, vol1;
326 326
 	while (this->iSlopeCount <= SCALE)
327 327
 	{
328
-		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
328
+		vol1 = SCALE - this->iSlopeCount;
329 329
 		temp = vol1 * this->sPrevSampleL + this->iSlopeCount * src[0];
330 330
 		dest[i] = static_cast<SAMPLETYPE>(temp / SCALE);
331 331
 		++i;
... ...
@@ -343,7 +343,7 @@ uint32_t RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE
343 343
 			if (used >= nSamples - 1)
344 344
 				goto end;
345 345
 		}
346
-		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
346
+		vol1 = SCALE - this->iSlopeCount;
347 347
 		temp = src[used] * vol1 + this->iSlopeCount * src[used + 1];
348 348
 		dest[i] = static_cast<SAMPLETYPE>(temp / SCALE);
349 349
 		++i;
... ...
@@ -370,7 +370,7 @@ uint32_t RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETY
370 370
 	LONG_SAMPLETYPE temp, vol1;
371 371
 	while (this->iSlopeCount <= SCALE)
372 372
 	{
373
-		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
373
+		vol1 = SCALE - this->iSlopeCount;
374 374
 		temp = vol1 * this->sPrevSampleL + this->iSlopeCount * src[0];
375 375
 		dest[2 * i] = static_cast<SAMPLETYPE>(temp / SCALE);
376 376
 		temp = vol1 * this->sPrevSampleR + this->iSlopeCount * src[1];
... ...
@@ -391,7 +391,7 @@ uint32_t RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETY
391 391
 				goto end;
392 392
 		}
393 393
 		unsigned srcPos = 2 * used;
394
-		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
394
+		vol1 = SCALE - this->iSlopeCount;
395 395
 		temp = src[srcPos] * vol1 + this->iSlopeCount * src[srcPos + 2];
396 396
 		dest[2 * i] = static_cast<SAMPLETYPE>(temp / SCALE);
397 397
 		temp = src[srcPos + 1] * vol1 + this->iSlopeCount * src[srcPos + 3];
Browse code

Updating in_2sf to use a newish version of DeSmuME, 0.9.9 from SVN. Somewhat cleaned up as well, but not everything because it's a pain in the ass.

Naram Qashat authored on 2013/04/18 17:22:55
Showing 1 changed files
... ...
@@ -10,10 +10,10 @@
10 10
 ///
11 11
 ////////////////////////////////////////////////////////////////////////////////
12 12
 //
13
-// Last changed  : $Date: 2006/03/19 10:05:49 $
14
-// File revision : $Revision: 1.13 $
13
+// Last changed  : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
14
+// File revision : $Revision: 4 $
15 15
 //
16
-// $Id: RateTransposer.cpp,v 1.13 2006/03/19 10:05:49 Olli Exp $
16
+// $Id: RateTransposer.cpp 131 2011-09-02 18:56:11Z oparviai $
17 17
 //
18 18
 ////////////////////////////////////////////////////////////////////////////////
19 19
 //
... ...
@@ -50,7 +50,7 @@ class RateTransposerInteger : public RateTransposer
50 50
 {
51 51
 protected:
52 52
 	int iSlopeCount;
53
-	uint32_t uRate;
53
+	int iRate;
54 54
 	SAMPLETYPE sPrevSampleL, sPrevSampleR;
55 55
 
56 56
 	virtual void resetRegisters();
... ...
@@ -73,7 +73,6 @@ class RateTransposerFloat : public RateTransposer
73 73
 {
74 74
 protected:
75 75
 	float fSlopeCount;
76
-	float fRateStep;
77 76
 	SAMPLETYPE sPrevSampleL, sPrevSampleR;
78 77
 
79 78
 	virtual void resetRegisters();
... ...
@@ -86,406 +85,336 @@ public:
86 85
 	virtual ~RateTransposerFloat();
87 86
 };
88 87
 
89
-/*#ifndef min
90
-#define min(a,b) ((a > b) ? b : a)
91
-#define max(a,b) ((a < b) ? b : a)
92
-#endif*/
93
-
94
-
95 88
 // Operator 'new' is overloaded so that it automatically creates a suitable instance
96 89
 // depending on if we've a MMX/SSE/etc-capable CPU available or not.
97
-void * RateTransposer::operator new(size_t)
90
+void *RateTransposer::operator new(size_t)
98 91
 {
99
-    // Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
100
-    //assert(false);
101
-    //return NULL;
92
+	// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
93
+	//assert(false);
94
+	//return NULL;
102 95
 	throw std::runtime_error("Don't use 'new RateTransposer', use 'newInstance' member instead!");
103 96
 }
104 97
 
105
-
106 98
 RateTransposer *RateTransposer::newInstance()
107 99
 {
108
-#ifdef INTEGER_SAMPLES
109
-    return ::new RateTransposerInteger;
100
+#ifdef SOUNDTOUCH_INTEGER_SAMPLES
101
+	return ::new RateTransposerInteger;
110 102
 #else
111
-    return ::new RateTransposerFloat;
103
+	return ::new RateTransposerFloat;
112 104
 #endif
113 105
 }
114 106
 
115
-
116 107
 // Constructor
117 108
 RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
118 109
 {
119
-    uChannels = 2;
120
-    bUseAAFilter = true;
110
+	this->numChannels = 2;
111
+	this->bUseAAFilter = true;
112
+	this->fRate = 0;
121 113
 
122
-    // Instantiates the anti-alias filter with default tap length
123
-    // of 32
124
-    pAAFilter = new AAFilter(32);
114
+	// Instantiates the anti-alias filter with default tap length
115
+	// of 32
116
+	this->pAAFilter.reset(new AAFilter(32));
125 117
 }
126 118
 
127
-
128
-
129 119
 RateTransposer::~RateTransposer()
130 120
 {
131
-    delete pAAFilter;
132 121
 }
133 122
 
134
-
135
-
136 123
 /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
137
-void RateTransposer::enableAAFilter(const bool newMode)
124
+void RateTransposer::enableAAFilter(bool newMode)
138 125
 {
139
-    bUseAAFilter = newMode;
126
+	this->bUseAAFilter = newMode;
140 127
 }
141 128
 
142
-
143 129
 /// Returns nonzero if anti-alias filter is enabled.
144 130
 bool RateTransposer::isAAFilterEnabled() const
145 131
 {
146
-    return bUseAAFilter;
132
+	return this->bUseAAFilter;
147 133
 }
148 134
 
149
-
150
-AAFilter *RateTransposer::getAAFilter() const
135
+AAFilter *RateTransposer::getAAFilter()
151 136
 {
152
-    return pAAFilter;
137
+	return this->pAAFilter.get();
153 138
 }
154 139
 
155
-
156
-
157
-// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
158
-// uRate, larger faster uRates.
140
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
141
+// iRate, larger faster iRates.
159 142
 void RateTransposer::setRate(float newRate)
160 143
 {
161
-    float fCutoff;
162
-
163
-    fRate = newRate;
164
-
165
-    // design a new anti-alias filter
166
-    if (newRate > 1.0f)
167
-    {
168
-        fCutoff = 0.5f / newRate;
169
-    }
170
-    else
171
-    {
172
-        fCutoff = 0.5f * newRate;
173
-    }
174
-    pAAFilter->setCutoffFreq(fCutoff);
175
-}
144
+	double fCutoff;
176 145
 
146
+	this->fRate = newRate;
177 147
 
178
-// Outputs as many samples of the 'outputBuffer' as possible, and if there's
179
-// any room left, outputs also as many of the incoming samples as possible.
180
-// The goal is to drive the outputBuffer empty.
181
-//
182
-// It's allowed for 'output' and 'input' parameters to point to the same
183
-// memory position.
184
-void RateTransposer::flushStoreBuffer()
185
-{
186
-	if (storeBuffer.isEmpty())
187
-		return;
188
-
189
-	outputBuffer.moveSamples(storeBuffer);
148
+	// design a new anti-alias filter
149
+	if (newRate > 1.0f)
150
+		fCutoff = 0.5f / newRate;
151
+	else
152
+		fCutoff = 0.5f * newRate;
153
+    this->pAAFilter->setCutoffFreq(fCutoff);
190 154
 }
191 155
 
192
-
193
-// Adds 'numSamples' pcs of samples from the 'samples' memory position into
156
+// Adds 'nSamples' pcs of samples from the 'samples' memory position into
194 157
 // the input of the object.
195
-void RateTransposer::putSamples(const SAMPLETYPE *samples, uint32_t numsamples)
158
+void RateTransposer::putSamples(const SAMPLETYPE *samples, uint32_t nSamples)
196 159
 {
197
-    processSamples(samples, numsamples);
160
+	this->processSamples(samples, nSamples);
198 161
 }
199 162
 
200
-
201
-
202 163
 // Transposes up the sample rate, causing the observed playback 'rate' of the
203 164
 // sound to decrease
204
-void RateTransposer::upsample(const SAMPLETYPE *src, uint32_t numsamples)
165
+void RateTransposer::upsample(const SAMPLETYPE *src, uint32_t nSamples)
205 166
 {
206
-    int count, sizeTemp, num;
207
-
208
-    // If the parameter 'uRate' value is smaller than 'SCALE', first transpose
209
-    // the samples and then apply the anti-alias filter to remove aliasing.
167
+	// If the parameter 'uRate' value is smaller than 'SCALE', first transpose
168
+	// the samples and then apply the anti-alias filter to remove aliasing.
210 169
 
211
-    // First check that there's enough room in 'storeBuffer'
212
-    // (+16 is to reserve some slack in the destination buffer)
213
-    sizeTemp = (int)((float)numsamples / fRate + 16.0f);
170
+	// First check that there's enough room in 'storeBuffer'
171
+	// (+16 is to reserve some slack in the destination buffer)
172
+	uint32_t sizeTemp = static_cast<uint32_t>(nSamples / this->fRate + 16.0f);
214 173
 
215
-    // Transpose the samples, store the result into the end of "storeBuffer"
216
-    count = transpose(storeBuffer.ptrEnd(sizeTemp), src, numsamples);
217
-    storeBuffer.putSamples(count);
174
+	// Transpose the samples, store the result into the end of "storeBuffer"
175
+	uint32_t count = this->transpose(this->storeBuffer.ptrEnd(sizeTemp), src, nSamples);
176
+	this->storeBuffer.putSamples(count);
218 177
 
219
-    // Apply the anti-alias filter to samples in "store output", output the
220
-    // result to "dest"
221
-    num = storeBuffer.numSamples();
222
-    count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
223
-        storeBuffer.ptrBegin(), num, uChannels);
224
-    outputBuffer.putSamples(count);
178
+	// Apply the anti-alias filter to samples in "store output", output the
179
+	// result to "dest"
180
+	uint32_t num = this->storeBuffer.numSamples();
181
+	count = this->pAAFilter->evaluate(this->outputBuffer.ptrEnd(num), this->storeBuffer.ptrBegin(), num, this->numChannels);
182
+	this->outputBuffer.putSamples(count);
225 183
 
226
-    // Remove the processed samples from "storeBuffer"
227
-    storeBuffer.receiveSamples(count);
184
+	// Remove the processed samples from "storeBuffer"
185
+	this->storeBuffer.receiveSamples(count);
228 186
 }
229 187
 
230
-
231 188
 // Transposes down the sample rate, causing the observed playback 'rate' of the
232 189
 // sound to increase
233
-void RateTransposer::downsample(const SAMPLETYPE *src, uint32_t numsamples)
190
+void RateTransposer::downsample(const SAMPLETYPE *src, uint32_t nSamples)
234 191
 {
235
-    int count, sizeTemp;
236
-
237
-    // If the parameter 'uRate' value is larger than 'SCALE', first apply the
238
-    // anti-alias filter to remove high frequencies (prevent them from folding
239
-    // over the lover frequencies), then transpose. */
240
-
241
-    // Add the new samples to the end of the storeBuffer */
242
-    storeBuffer.putSamples(src, numsamples);
243
-
244
-    // Anti-alias filter the samples to prevent folding and output the filtered
245
-    // data to tempBuffer. Note : because of the FIR filter length, the
246
-    // filtering routine takes in 'filter_length' more samples than it outputs.
247
-    assert(tempBuffer.isEmpty());
248
-    sizeTemp = storeBuffer.numSamples();
249
-
250
-    count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
251
-        storeBuffer.ptrBegin(), sizeTemp, uChannels);
252
-
253
-    // Remove the filtered samples from 'storeBuffer'
254
-    storeBuffer.receiveSamples(count);
255
-
256
-    // Transpose the samples (+16 is to reserve some slack in the destination buffer)
257
-    sizeTemp = (int)((float)numsamples / fRate + 16.0f);
258
-    count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
259
-    outputBuffer.putSamples(count);
192
+	// If the parameter 'uRate' value is larger than 'SCALE', first apply the
193
+	// anti-alias filter to remove high frequencies (prevent them from folding
194
+	// over the lover frequencies), then transpose. */
195
+	
196
+	// Add the new samples to the end of the storeBuffer */
197
+	this->storeBuffer.putSamples(src, nSamples);
198
+
199
+	// Anti-alias filter the samples to prevent folding and output the filtered
200
+	// data to tempBuffer. Note : because of the FIR filter length, the
201
+	// filtering routine takes in 'filter_length' more samples than it outputs.
202
+	assert(this->tempBuffer.isEmpty());
203
+	uint32_t sizeTemp = this->storeBuffer.numSamples();
204
+
205
+	uint32_t count = this->pAAFilter->evaluate(this->tempBuffer.ptrEnd(sizeTemp), this->storeBuffer.ptrBegin(), sizeTemp, this->numChannels);
206
+
207
+	// Remove the filtered samples from 'storeBuffer'
208
+	this->storeBuffer.receiveSamples(count);
209
+
210
+	// Transpose the samples (+16 is to reserve some slack in the destination buffer)
211
+	sizeTemp = static_cast<uint32_t>(nSamples / this->fRate + 16.0f);
212
+	count = this->transpose(this->outputBuffer.ptrEnd(sizeTemp), this->tempBuffer.ptrBegin(), count);
213
+	this->outputBuffer.putSamples(count);
260 214
 }
261 215
 
262
-
263 216
 // Transposes sample rate by applying anti-alias filter to prevent folding.
264 217
 // Returns amount of samples returned in the "dest" buffer.
265 218
 // The maximum amount of samples that can be returned at a time is set by
266 219
 // the 'set_returnBuffer_size' function.
267
-void RateTransposer::processSamples(const SAMPLETYPE *src, uint32_t numsamples)
220
+void RateTransposer::processSamples(const SAMPLETYPE *src, uint32_t nSamples)
268 221
 {
269
-    uint32_t count;
270
-    uint32_t sizeReq;
271
-
272
-    if (numsamples == 0) return;
273
-    assert(pAAFilter);
274
-
275
-    // If anti-alias filter is turned off, simply transpose without applying
276
-    // the filter
277
-    if (bUseAAFilter == false)
278
-    {
279
-        sizeReq = (int)((float)numsamples / fRate + 1.0f);
280
-        count = transpose(outputBuffer.ptrEnd(sizeReq), src, numsamples);
281
-        outputBuffer.putSamples(count);
282
-        return;
283
-    }
284
-
285
-    // Transpose with anti-alias filter
286
-    if (fRate < 1.0f)
287
-    {
288
-        upsample(src, numsamples);
289
-    }
290
-    else
291
-    {
292
-        downsample(src, numsamples);
293
-    }
294
-}
222
+	if (!nSamples)
223
+		return;
224
+	assert(this->pAAFilter.get());
225
+
226
+	// If anti-alias filter is turned off, simply transpose without applying
227
+	// the filter
228
+	if (!bUseAAFilter)
229
+	{
230
+		uint32_t sizeReq = static_cast<uint32_t>(nSamples / this->fRate + 1.0f);
231
+		uint32_t count = this->transpose(this->outputBuffer.ptrEnd(sizeReq), src, nSamples);
232
+		this->outputBuffer.putSamples(count);
233
+		return;
234
+	}
295 235
 
236
+	// Transpose with anti-alias filter
237
+	if (this->fRate < 1.0f)
238
+		this->upsample(src, nSamples);
239
+	else
240
+		this->downsample(src, nSamples);
241
+}
296 242
 
297 243
 // Transposes the sample rate of the given samples using linear interpolation.
298 244
 // Returns the number of samples returned in the "dest" buffer
299
-inline uint32_t RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
245
+uint32_t RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
300 246
 {
301
-    if (uChannels == 2)
302
-    {
303
-        return transposeStereo(dest, src, numsamples);
304
-    }
305
-    else
306
-    {
307
-        return transposeMono(dest, src, numsamples);
308
-    }
247
+	if (this->numChannels == 2)
248
+		return this->transposeStereo(dest, src, nSamples);
249
+	else
250
+		return this->transposeMono(dest, src, nSamples);
309 251
 }
310 252
 
311
-
312 253
 // Sets the number of channels, 1 = mono, 2 = stereo
313
-void RateTransposer::setChannels(uint32_t numchannels)
254
+void RateTransposer::setChannels(int32_t nChannels)
314 255
 {
315
-    if (uChannels == numchannels) return;
256
+	assert(nChannels > 0);
257
+	if (this->numChannels == nChannels)
258
+		return;
316 259
 
317
-    assert(numchannels == 1 || numchannels == 2);
318
-    uChannels = numchannels;
260
+	assert(nChannels == 1 || nChannels == 2);
261
+	this->numChannels = nChannels;
319 262
 
320
-    storeBuffer.setChannels(uChannels);
321
-    tempBuffer.setChannels(uChannels);
322
-    outputBuffer.setChannels(uChannels);
263
+	this->storeBuffer.setChannels(this->numChannels);
264
+	this->tempBuffer.setChannels(this->numChannels);
265
+	this->outputBuffer.setChannels(this->numChannels);
323 266
 
324
-    // Inits the linear interpolation registers
325
-    resetRegisters();
267
+	// Inits the linear interpolation registers
268
+	this->resetRegisters();
326 269
 }
327 270
 
328
-
329 271
 // Clears all the samples in the object
330 272
 void RateTransposer::clear()
331 273
 {
332
-    outputBuffer.clear();
333
-    storeBuffer.clear();
274
+	this->outputBuffer.clear();
275
+	this->storeBuffer.clear();
334 276
 }
335 277
 
336
-
337 278
 // Returns nonzero if there aren't any samples available for outputting.
338 279
 bool RateTransposer::isEmpty() const
339 280
 {
340 281
 	bool res = FIFOProcessor::isEmpty();
341 282
 	if (!res)
342 283
 		return false;
343
-	return storeBuffer.isEmpty();
284
+	return this->storeBuffer.isEmpty();
344 285
 }
345 286
 
346
-
347 287
 //////////////////////////////////////////////////////////////////////////////
348 288
 //
349 289
 // RateTransposerInteger - integer arithmetic implementation
350 290
 //
351 291
 
352 292
 /// fixed-point interpolation routine precision
353
-#define SCALE    65536
293
+static const int SCALE = 65536;
354 294
 
355 295
 // Constructor
356 296
 RateTransposerInteger::RateTransposerInteger() : RateTransposer()
357 297
 {
358
-    // call these here as these are virtual functions; calling these
359
-    // from the base class constructor wouldn't execute the overloaded
360
-    // versions (<master yoda>peculiar C++ can be</my>).
361
-    resetRegisters();
362
-    setRate(1.0f);
298
+	// Notice: use local function calling syntax for sake of clarity,
299
+	// to indicate the fact that C++ constructor can't call virtual functions.
300
+	RateTransposerInteger::resetRegisters();
301
+	RateTransposerInteger::setRate(1.0f);
363 302
 }
364 303
 
365
-
366 304
 RateTransposerInteger::~RateTransposerInteger()
367 305
 {
368 306
 }
369 307
 
370
-
371 308
 void RateTransposerInteger::resetRegisters()
372 309
 {
373
-    iSlopeCount = 0;
374
-    sPrevSampleL =
375
-    sPrevSampleR = 0;
310
+	this->iSlopeCount = 0;
311
+	this->sPrevSampleL = this->sPrevSampleR = 0;
376 312
 }
377 313
 
378
-
379
-
380 314
 // Transposes the sample rate of the given samples using linear interpolation.
381 315
 // 'Mono' version of the routine. Returns the number of samples returned in
382 316
 // the "dest" buffer
383
-uint32_t RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
317
+uint32_t RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
384 318
 {
385
-    unsigned int i, used;
386
-    LONG_SAMPLETYPE temp, vol1;
387
-
388
-    used = 0;
389
-    i = 0;
390
-
391
-    // Process the last sample saved from the previous call first...
392
-    while (iSlopeCount <= SCALE)
393
-    {
394
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
395
-        temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
396
-        dest[i] = (SAMPLETYPE)(temp / SCALE);
397
-        i++;
398
-        iSlopeCount += uRate;
399
-    }
400
-    // now always (iSlopeCount > SCALE)
401
-    iSlopeCount -= SCALE;
402
-
403
-    while (1)
404
-    {
405
-        while (iSlopeCount > SCALE)
406
-        {
407
-            iSlopeCount -= SCALE;
408
-            used ++;
409
-            if (used >= numsamples - 1) goto end;
410
-        }
411
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
412
-        temp = src[used] * vol1 + iSlopeCount * src[used + 1];
413
-        dest[i] = (SAMPLETYPE)(temp / SCALE);
414
-
415
-        i++;
416
-        iSlopeCount += uRate;
417
-    }
319
+	if (!nSamples)
320
+		return 0; // no samples, no work
321
+
322
+	unsigned used = 0, i = 0;
323
+
324
+	// Process the last sample saved from the previous call first...
325
+	LONG_SAMPLETYPE temp, vol1;
326
+	while (this->iSlopeCount <= SCALE)
327
+	{
328
+		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
329
+		temp = vol1 * this->sPrevSampleL + this->iSlopeCount * src[0];
330
+		dest[i] = static_cast<SAMPLETYPE>(temp / SCALE);
331
+		++i;
332
+		this->iSlopeCount += this->iRate;
333
+	}
334
+	// now always (iSlopeCount > SCALE)
335
+	this->iSlopeCount -= SCALE;
336
+
337
+	while (1)
338
+	{
339
+		while (this->iSlopeCount > SCALE)
340
+		{
341
+			this->iSlopeCount -= SCALE;
342
+			++used;
343
+			if (used >= nSamples - 1)
344
+				goto end;
345
+		}
346
+		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
347
+		temp = src[used] * vol1 + this->iSlopeCount * src[used + 1];
348
+		dest[i] = static_cast<SAMPLETYPE>(temp / SCALE);
349
+		++i;
350
+		this->iSlopeCount += this->iRate;
351
+	}
418 352
 end:
419
-    // Store the last sample for the next round
420
-    sPrevSampleL = src[numsamples - 1];
353
+	// Store the last sample for the next round
354
+	this->sPrevSampleL = src[nSamples - 1];
421 355
 
422
-    return i;
356
+	return i;
423 357
 }
424 358
 
425
-
426 359
 // Transposes the sample rate of the given samples using linear interpolation.
427 360
 // 'Stereo' version of the routine. Returns the number of samples returned in
428 361
 // the "dest" buffer
429
-uint32_t RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
362
+uint32_t RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
430 363
 {
431
-    unsigned int srcPos, i, used;
432
-    LONG_SAMPLETYPE temp, vol1;
433
-
434
-    if (numsamples == 0) return 0;  // no samples, no work
435
-
436
-    used = 0;
437
-    i = 0;
438
-
439
-    // Process the last sample saved from the sPrevSampleLious call first...
440
-    while (iSlopeCount <= SCALE)
441
-    {
442
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
443
-        temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
444
-        dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
445
-        temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
446
-        dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
447
-        i++;
448
-        iSlopeCount += uRate;
449
-    }
450
-    // now always (iSlopeCount > SCALE)
451
-    iSlopeCount -= SCALE;
452
-
453
-    while (1)
454
-    {
455
-        while (iSlopeCount > SCALE)
456
-        {
457
-            iSlopeCount -= SCALE;
458
-            used ++;
459
-            if (used >= numsamples - 1) goto end;
460
-        }
461
-        srcPos = 2 * used;
462
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
463
-        temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
464
-        dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
465
-        temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
466
-        dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
467
-
468
-        i++;
469
-        iSlopeCount += uRate;
470
-    }
364
+	if (!nSamples)
365
+		return 0; // no samples, no work
366
+
367
+	unsigned used = 0, i = 0;
368
+
369
+	// Process the last sample saved from the sPrevSampleLious call first...
370
+	LONG_SAMPLETYPE temp, vol1;
371
+	while (this->iSlopeCount <= SCALE)
372
+	{
373
+		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
374
+		temp = vol1 * this->sPrevSampleL + this->iSlopeCount * src[0];
375
+		dest[2 * i] = static_cast<SAMPLETYPE>(temp / SCALE);
376
+		temp = vol1 * this->sPrevSampleR + this->iSlopeCount * src[1];
377
+		dest[2 * i + 1] = static_cast<SAMPLETYPE>(temp / SCALE);
378
+		++i;
379
+		this->iSlopeCount += this->iRate;
380
+	}
381
+	// now always (iSlopeCount > SCALE)
382
+	this->iSlopeCount -= SCALE;
383
+
384
+	while (1)
385
+	{
386
+		while (this->iSlopeCount > SCALE)
387
+		{
388
+			this->iSlopeCount -= SCALE;
389
+			++used;
390
+			if (used >= nSamples - 1)
391
+				goto end;
392
+		}
393
+		unsigned srcPos = 2 * used;
394
+		vol1 = static_cast<LONG_SAMPLETYPE>(SCALE - this->iSlopeCount);
395
+		temp = src[srcPos] * vol1 + this->iSlopeCount * src[srcPos + 2];
396
+		dest[2 * i] = static_cast<SAMPLETYPE>(temp / SCALE);
397
+		temp = src[srcPos + 1] * vol1 + this->iSlopeCount * src[srcPos + 3];
398
+		dest[2 * i + 1] = static_cast<SAMPLETYPE>(temp / SCALE);
399
+		++i;
400
+		this->iSlopeCount += this->iRate;
401
+	}
471 402
 end:
472
-    // Store the last sample for the next round
473
-    sPrevSampleL = src[2 * numsamples - 2];
474
-    sPrevSampleR = src[2 * numsamples - 1];
403
+	// Store the last sample for the next round
404
+	this->sPrevSampleL = src[2 * nSamples - 2];
405
+	this->sPrevSampleR = src[2 * nSamples - 1];
475 406
 
476
-    return i;
407
+	return i;
477 408
 }
478 409
 
479
-
480
-// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
481
-// uRate, larger faster uRates.
410
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
411
+// iRate, larger faster iRates.
482 412
 void RateTransposerInteger::setRate(float newRate)
483 413
 {
484
-    uRate = (int)(newRate * SCALE + 0.5f);
485
-    RateTransposer::setRate(newRate);
414
+	this->iRate = static_cast<int>(newRate * SCALE + 0.5f);
415
+	RateTransposer::setRate(newRate);
486 416
 }
487 417
 
488
-
489 418
 //////////////////////////////////////////////////////////////////////////////
490 419
 //
491 420
 // RateTransposerFloat - floating point arithmetic implementation
... ...
@@ -495,116 +424,105 @@ void RateTransposerInteger::setRate(float newRate)
495 424
 // Constructor
496 425
 RateTransposerFloat::RateTransposerFloat() : RateTransposer()
497 426
 {
498
-    // call these here as these are virtual functions; calling these
499
-    // from the base class constructor wouldn't execute the overloaded
500
-    // versions (<master yoda>peculiar C++ can be</my>).
501
-    resetRegisters();
502
-    setRate(1.0f);
427
+	// Notice: use local function calling syntax for sake of clarity,
428
+	// to indicate the fact that C++ constructor can't call virtual functions.
429
+	RateTransposerFloat::resetRegisters();
430
+	RateTransposerFloat::setRate(1.0f);
503 431
 }
504 432
 
505
-
506 433
 RateTransposerFloat::~RateTransposerFloat()
507 434
 {
508 435
 }
509 436
 
510
-
511 437
 void RateTransposerFloat::resetRegisters()
512 438
 {
513
-    fSlopeCount = 0;
514
-    sPrevSampleL =
515
-    sPrevSampleR = 0;
439
+	this->fSlopeCount = 0;
440
+	this->sPrevSampleL = this->sPrevSampleR = 0;
516 441
 }
517 442
 
518
-
519
-
520 443
 // Transposes the sample rate of the given samples using linear interpolation.
521 444
 // 'Mono' version of the routine. Returns the number of samples returned in
522 445
 // the "dest" buffer
523
-uint32_t RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
446
+uint32_t RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
524 447
 {
525
-    unsigned int i, used;
526
-
527
-    used = 0;
528
-    i = 0;
529
-
530
-    // Process the last sample saved from the previous call first...
531
-    while (fSlopeCount <= 1.0f)
532
-    {
533
-        dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
534
-        i++;
535
-        fSlopeCount += fRate;
536
-    }
537
-    fSlopeCount -= 1.0f;
538
-
539
-    if (numsamples == 1) goto end;
540
-
541
-    while (1)
542
-    {
543
-        while (fSlopeCount > 1.0f)
544
-        {
545
-            fSlopeCount -= 1.0f;
546
-            used ++;
547
-            if (used >= numsamples - 1) goto end;
548
-        }
549
-        dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
550
-        i++;
551
-        fSlopeCount += fRate;
552
-    }
448
+	unsigned used = 0, i = 0;
449
+
450
+	// Process the last sample saved from the previous call first...
451
+	while (this->fSlopeCount <= 1.0f)
452
+	{
453
+		dest[i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * this->sPrevSampleL + this->fSlopeCount * src[0]);
454
+		++i;
455
+		this->fSlopeCount += this->fRate;
456
+	}
457
+	this->fSlopeCount -= 1.0f;
458
+
459
+	if (nSamples > 1)
460
+	{
461
+		while (1)
462
+		{
463
+			while (this->fSlopeCount > 1.0f)
464
+			{
465
+				this->fSlopeCount -= 1.0f;
466
+				++used;
467
+				if (used >= nSamples - 1)
468
+					goto end;
469
+			}
470
+			dest[i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * src[used] + this->fSlopeCount * src[used + 1]);
471
+			++i;
472
+			this->fSlopeCount += this->fRate;
473
+		}
474
+	}
553 475
 end:
554
-    // Store the last sample for the next round
555
-    sPrevSampleL = src[numsamples - 1];
476
+	// Store the last sample for the next round
477
+	this->sPrevSampleL = src[nSamples - 1];
556 478
 
557
-    return i;
479
+	return i;
558 480
 }
559 481
 
560
-
561 482
 // Transposes the sample rate of the given samples using linear interpolation.
562 483
 // 'Mono' version of the routine. Returns the number of samples returned in
563 484
 // the "dest" buffer
564
-uint32_t RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
485
+uint32_t RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t nSamples)
565 486
 {
566
-    unsigned int srcPos, i, used;
567
-
568
-    if (numsamples == 0) return 0;  // no samples, no work
569
-
570
-    used = 0;
571
-    i = 0;
572
-
573
-    // Process the last sample saved from the sPrevSampleLious call first...
574
-    while (fSlopeCount <= 1.0f)
575
-    {
576
-        dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
577
-        dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
578
-        i++;
579
-        fSlopeCount += fRate;
580
-    }
581
-    // now always (iSlopeCount > 1.0f)
582
-    fSlopeCount -= 1.0f;
583
-
584
-    if (numsamples == 1) goto end;
585
-
586
-    while (1)
587
-    {
588
-        while (fSlopeCount > 1.0f)
589
-        {
590
-            fSlopeCount -= 1.0f;
591
-            used ++;
592
-            if (used >= numsamples - 1) goto end;
593
-        }
594
-        srcPos = 2 * used;
595
-
596
-        dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
597
-            + fSlopeCount * src[srcPos + 2]);
598
-        dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
599
-            + fSlopeCount * src[srcPos + 3]);
600
-
601
-        i++;
602
-        fSlopeCount += fRate;
603
-    }
487
+	if (!nSamples)
488
+		return 0; // no samples, no work
489
+
490
+	unsigned used = 0, i = 0;
491
+
492
+	// Process the last sample saved from the sPrevSampleLious call first...
493
+	while (this->fSlopeCount <= 1.0f)
494
+	{
495
+		dest[2 * i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * this->sPrevSampleL + this->fSlopeCount * src[0]);
496
+		dest[2 * i + 1] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * this->sPrevSampleR + this->fSlopeCount * src[1]);
497
+		++i;
498
+		this->fSlopeCount += this->fRate;
499
+	}
500
+	// now always (iSlopeCount > 1.0f)
501
+	this->fSlopeCount -= 1.0f;
502
+
503
+	if (nSamples > 1)
504
+	{
505
+		while (1)
506
+		{
507
+			while (this->fSlopeCount > 1.0f)
508
+			{
509
+				this->fSlopeCount -= 1.0f;
510
+				++used;
511
+				if (used >= nSamples - 1)
512
+					goto end;
513
+			}
514
+			unsigned srcPos = 2 * used;
515
+
516
+			dest[2 * i] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * src[srcPos] + this->fSlopeCount * src[srcPos + 2]);
517
+			dest[2 * i + 1] = static_cast<SAMPLETYPE>((1.0f - this->fSlopeCount) * src[srcPos + 1] + this->fSlopeCount * src[srcPos + 3]);
518
+			++i;
519
+			this->fSlopeCount += this->fRate;
520
+		}
521
+	}
604 522
 end:
605
-    // Store the last sample for the next round
606
-    sPrevSampleL = src[2 * numsamples - 2];
607
-    sPrevSampleR = src[2 * numsamples - 1];
523
+	// Store the last sample for the next round
524
+	this->sPrevSampleL = src[2 * nSamples - 2];
525
+	this->sPrevSampleR = src[2 * nSamples - 1];
608 526
 
609
-    return i;
527
+	return i;
610 528
 }
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,610 @@
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: 2006/03/19 10:05:49 $
14
+// File revision : $Revision: 1.13 $
15
+//
16
+// $Id: RateTransposer.cpp,v 1.13 2006/03/19 10:05:49 Olli Exp $
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
+
41
+#include <stdexcept>
42
+#include "RateTransposer.h"
43
+#include "AAFilter.h"
44
+
45
+using namespace soundtouch;
46
+
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
+	uint32_t uRate;
54
+	SAMPLETYPE sPrevSampleL, sPrevSampleR;
55
+
56
+	virtual void resetRegisters();
57
+
58
+	virtual uint32_t transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
59
+	virtual uint32_t transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
60
+
61
+public:
62
+	RateTransposerInteger();
63
+	virtual ~RateTransposerInteger();
64
+
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
+
70
+/// A linear samplerate transposer class that uses floating point arithmetics
71
+/// for the transposing.
72
+class RateTransposerFloat : public RateTransposer
73
+{
74
+protected:
75
+	float fSlopeCount;
76
+	float fRateStep;
77
+	SAMPLETYPE sPrevSampleL, sPrevSampleR;
78
+
79
+	virtual void resetRegisters();
80
+
81
+	virtual uint32_t transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
82
+	virtual uint32_t transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numSamples);
83
+
84
+public:
85
+	RateTransposerFloat();
86
+	virtual ~RateTransposerFloat();
87
+};
88
+
89
+/*#ifndef min
90
+#define min(a,b) ((a > b) ? b : a)
91
+#define max(a,b) ((a < b) ? b : a)
92
+#endif*/
93
+
94
+
95
+// Operator 'new' is overloaded so that it automatically creates a suitable instance
96
+// depending on if we've a MMX/SSE/etc-capable CPU available or not.
97
+void * RateTransposer::operator new(size_t)
98
+{
99
+    // Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
100
+    //assert(false);
101
+    //return NULL;
102
+	throw std::runtime_error("Don't use 'new RateTransposer', use 'newInstance' member instead!");
103
+}
104
+
105
+
106
+RateTransposer *RateTransposer::newInstance()
107
+{
108
+#ifdef INTEGER_SAMPLES
109
+    return ::new RateTransposerInteger;
110
+#else
111
+    return ::new RateTransposerFloat;
112
+#endif
113
+}
114
+
115
+
116
+// Constructor
117
+RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
118
+{
119
+    uChannels = 2;
120
+    bUseAAFilter = true;
121
+
122
+    // Instantiates the anti-alias filter with default tap length
123
+    // of 32
124
+    pAAFilter = new AAFilter(32);
125
+}
126
+
127
+
128
+
129
+RateTransposer::~RateTransposer()
130
+{
131
+    delete pAAFilter;
132
+}
133
+
134
+
135
+
136
+/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
137
+void RateTransposer::enableAAFilter(const bool newMode)
138
+{
139
+    bUseAAFilter = newMode;
140
+}
141
+
142
+
143
+/// Returns nonzero if anti-alias filter is enabled.
144
+bool RateTransposer::isAAFilterEnabled() const
145
+{
146
+    return bUseAAFilter;
147
+}
148
+
149
+
150
+AAFilter *RateTransposer::getAAFilter() const
151
+{
152
+    return pAAFilter;
153
+}
154
+
155
+
156
+
157
+// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
158
+// uRate, larger faster uRates.
159
+void RateTransposer::setRate(float newRate)
160
+{
161
+    float fCutoff;
162
+
163
+    fRate = newRate;
164
+
165
+    // design a new anti-alias filter
166
+    if (newRate > 1.0f)
167
+    {
168
+        fCutoff = 0.5f / newRate;
169
+    }
170
+    else
171
+    {
172
+        fCutoff = 0.5f * newRate;
173
+    }
174
+    pAAFilter->setCutoffFreq(fCutoff);
175
+}
176
+
177
+
178
+// Outputs as many samples of the 'outputBuffer' as possible, and if there's
179
+// any room left, outputs also as many of the incoming samples as possible.
180
+// The goal is to drive the outputBuffer empty.
181
+//
182
+// It's allowed for 'output' and 'input' parameters to point to the same
183
+// memory position.
184
+void RateTransposer::flushStoreBuffer()
185
+{
186
+	if (storeBuffer.isEmpty())
187
+		return;
188
+
189
+	outputBuffer.moveSamples(storeBuffer);
190
+}
191
+
192
+
193
+// Adds 'numSamples' pcs of samples from the 'samples' memory position into
194
+// the input of the object.
195
+void RateTransposer::putSamples(const SAMPLETYPE *samples, uint32_t numsamples)
196
+{
197
+    processSamples(samples, numsamples);
198
+}
199
+
200
+
201
+
202
+// Transposes up the sample rate, causing the observed playback 'rate' of the
203
+// sound to decrease
204
+void RateTransposer::upsample(const SAMPLETYPE *src, uint32_t numsamples)
205
+{
206
+    int count, sizeTemp, num;
207
+
208
+    // If the parameter 'uRate' value is smaller than 'SCALE', first transpose
209
+    // the samples and then apply the anti-alias filter to remove aliasing.
210
+
211
+    // First check that there's enough room in 'storeBuffer'
212
+    // (+16 is to reserve some slack in the destination buffer)
213
+    sizeTemp = (int)((float)numsamples / fRate + 16.0f);
214
+
215
+    // Transpose the samples, store the result into the end of "storeBuffer"
216
+    count = transpose(storeBuffer.ptrEnd(sizeTemp), src, numsamples);
217
+    storeBuffer.putSamples(count);
218
+
219
+    // Apply the anti-alias filter to samples in "store output", output the
220
+    // result to "dest"
221
+    num = storeBuffer.numSamples();
222
+    count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
223
+        storeBuffer.ptrBegin(), num, uChannels);
224
+    outputBuffer.putSamples(count);
225
+
226
+    // Remove the processed samples from "storeBuffer"
227
+    storeBuffer.receiveSamples(count);
228
+}
229
+
230
+
231
+// Transposes down the sample rate, causing the observed playback 'rate' of the
232
+// sound to increase
233
+void RateTransposer::downsample(const SAMPLETYPE *src, uint32_t numsamples)
234
+{
235
+    int count, sizeTemp;
236
+
237
+    // If the parameter 'uRate' value is larger than 'SCALE', first apply the
238
+    // anti-alias filter to remove high frequencies (prevent them from folding
239
+    // over the lover frequencies), then transpose. */
240
+
241
+    // Add the new samples to the end of the storeBuffer */
242
+    storeBuffer.putSamples(src, numsamples);
243
+
244
+    // Anti-alias filter the samples to prevent folding and output the filtered
245
+    // data to tempBuffer. Note : because of the FIR filter length, the
246
+    // filtering routine takes in 'filter_length' more samples than it outputs.
247
+    assert(tempBuffer.isEmpty());
248
+    sizeTemp = storeBuffer.numSamples();
249
+
250
+    count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
251
+        storeBuffer.ptrBegin(), sizeTemp, uChannels);
252
+
253
+    // Remove the filtered samples from 'storeBuffer'
254
+    storeBuffer.receiveSamples(count);
255
+
256
+    // Transpose the samples (+16 is to reserve some slack in the destination buffer)
257
+    sizeTemp = (int)((float)numsamples / fRate + 16.0f);
258
+    count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
259
+    outputBuffer.putSamples(count);
260
+}
261
+
262
+
263
+// Transposes sample rate by applying anti-alias filter to prevent folding.
264
+// Returns amount of samples returned in the "dest" buffer.
265
+// The maximum amount of samples that can be returned at a time is set by
266
+// the 'set_returnBuffer_size' function.
267
+void RateTransposer::processSamples(const SAMPLETYPE *src, uint32_t numsamples)
268
+{
269
+    uint32_t count;
270
+    uint32_t sizeReq;
271
+
272
+    if (numsamples == 0) return;
273
+    assert(pAAFilter);
274
+
275
+    // If anti-alias filter is turned off, simply transpose without applying
276
+    // the filter
277
+    if (bUseAAFilter == false)
278
+    {
279
+        sizeReq = (int)((float)numsamples / fRate + 1.0f);
280
+        count = transpose(outputBuffer.ptrEnd(sizeReq), src, numsamples);
281
+        outputBuffer.putSamples(count);
282
+        return;
283
+    }
284
+
285
+    // Transpose with anti-alias filter
286
+    if (fRate < 1.0f)
287
+    {
288
+        upsample(src, numsamples);
289
+    }
290
+    else
291
+    {
292
+        downsample(src, numsamples);
293
+    }
294
+}
295
+
296
+
297
+// Transposes the sample rate of the given samples using linear interpolation.
298
+// Returns the number of samples returned in the "dest" buffer
299
+inline uint32_t RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
300
+{
301
+    if (uChannels == 2)
302
+    {
303
+        return transposeStereo(dest, src, numsamples);
304
+    }
305
+    else
306
+    {
307
+        return transposeMono(dest, src, numsamples);
308
+    }
309
+}
310
+
311
+
312
+// Sets the number of channels, 1 = mono, 2 = stereo
313
+void RateTransposer::setChannels(uint32_t numchannels)
314
+{
315
+    if (uChannels == numchannels) return;
316
+
317
+    assert(numchannels == 1 || numchannels == 2);
318
+    uChannels = numchannels;
319
+
320
+    storeBuffer.setChannels(uChannels);
321
+    tempBuffer.setChannels(uChannels);
322
+    outputBuffer.setChannels(uChannels);
323
+
324
+    // Inits the linear interpolation registers
325
+    resetRegisters();
326
+}
327
+
328
+
329
+// Clears all the samples in the object
330
+void RateTransposer::clear()
331
+{
332
+    outputBuffer.clear();
333
+    storeBuffer.clear();
334
+}
335
+
336
+
337
+// Returns nonzero if there aren't any samples available for outputting.
338
+bool RateTransposer::isEmpty() const
339
+{
340
+	bool res = FIFOProcessor::isEmpty();
341
+	if (!res)
342
+		return false;
343
+	return storeBuffer.isEmpty();
344
+}
345
+
346
+
347
+//////////////////////////////////////////////////////////////////////////////
348
+//
349
+// RateTransposerInteger - integer arithmetic implementation
350
+//
351
+
352
+/// fixed-point interpolation routine precision
353
+#define SCALE    65536
354
+
355
+// Constructor
356
+RateTransposerInteger::RateTransposerInteger() : RateTransposer()
357
+{
358
+    // call these here as these are virtual functions; calling these
359
+    // from the base class constructor wouldn't execute the overloaded
360
+    // versions (<master yoda>peculiar C++ can be</my>).
361
+    resetRegisters();
362
+    setRate(1.0f);
363
+}
364
+
365
+
366
+RateTransposerInteger::~RateTransposerInteger()
367
+{
368
+}
369
+
370
+
371
+void RateTransposerInteger::resetRegisters()
372
+{
373
+    iSlopeCount = 0;
374
+    sPrevSampleL =
375
+    sPrevSampleR = 0;
376
+}
377
+
378
+
379
+
380
+// Transposes the sample rate of the given samples using linear interpolation.
381
+// 'Mono' version of the routine. Returns the number of samples returned in
382
+// the "dest" buffer
383
+uint32_t RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
384
+{
385
+    unsigned int i, used;
386
+    LONG_SAMPLETYPE temp, vol1;
387
+
388
+    used = 0;
389
+    i = 0;
390
+
391
+    // Process the last sample saved from the previous call first...
392
+    while (iSlopeCount <= SCALE)
393
+    {
394
+        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
395
+        temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
396
+        dest[i] = (SAMPLETYPE)(temp / SCALE);
397
+        i++;
398
+        iSlopeCount += uRate;
399
+    }
400
+    // now always (iSlopeCount > SCALE)
401
+    iSlopeCount -= SCALE;
402
+
403
+    while (1)
404
+    {
405
+        while (iSlopeCount > SCALE)
406
+        {
407
+            iSlopeCount -= SCALE;
408
+            used ++;
409
+            if (used >= numsamples - 1) goto end;
410
+        }
411
+        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
412
+        temp = src[used] * vol1 + iSlopeCount * src[used + 1];
413
+        dest[i] = (SAMPLETYPE)(temp / SCALE);
414
+
415
+        i++;
416
+        iSlopeCount += uRate;
417
+    }
418
+end:
419
+    // Store the last sample for the next round
420
+    sPrevSampleL = src[numsamples - 1];
421
+
422
+    return i;
423
+}
424
+
425
+
426
+// Transposes the sample rate of the given samples using linear interpolation.
427
+// 'Stereo' version of the routine. Returns the number of samples returned in
428
+// the "dest" buffer
429
+uint32_t RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
430
+{
431
+    unsigned int srcPos, i, used;
432
+    LONG_SAMPLETYPE temp, vol1;
433
+
434
+    if (numsamples == 0) return 0;  // no samples, no work
435
+
436
+    used = 0;
437
+    i = 0;
438
+
439
+    // Process the last sample saved from the sPrevSampleLious call first...
440
+    while (iSlopeCount <= SCALE)
441
+    {
442
+        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
443
+        temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
444
+        dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
445
+        temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
446
+        dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
447
+        i++;
448
+        iSlopeCount += uRate;
449
+    }
450
+    // now always (iSlopeCount > SCALE)
451
+    iSlopeCount -= SCALE;
452
+
453
+    while (1)
454
+    {
455
+        while (iSlopeCount > SCALE)
456
+        {
457
+            iSlopeCount -= SCALE;
458
+            used ++;
459
+            if (used >= numsamples - 1) goto end;
460
+        }
461
+        srcPos = 2 * used;
462
+        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
463
+        temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
464
+        dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
465
+        temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
466
+        dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
467
+
468
+        i++;
469
+        iSlopeCount += uRate;
470
+    }
471
+end:
472
+    // Store the last sample for the next round
473
+    sPrevSampleL = src[2 * numsamples - 2];
474
+    sPrevSampleR = src[2 * numsamples - 1];
475
+
476
+    return i;
477
+}
478
+
479
+
480
+// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
481
+// uRate, larger faster uRates.
482
+void RateTransposerInteger::setRate(float newRate)
483
+{
484
+    uRate = (int)(newRate * SCALE + 0.5f);
485
+    RateTransposer::setRate(newRate);
486
+}
487
+
488
+
489
+//////////////////////////////////////////////////////////////////////////////
490
+//
491
+// RateTransposerFloat - floating point arithmetic implementation
492
+//
493
+//////////////////////////////////////////////////////////////////////////////
494
+
495
+// Constructor
496
+RateTransposerFloat::RateTransposerFloat() : RateTransposer()
497
+{
498
+    // call these here as these are virtual functions; calling these
499
+    // from the base class constructor wouldn't execute the overloaded
500
+    // versions (<master yoda>peculiar C++ can be</my>).
501
+    resetRegisters();
502
+    setRate(1.0f);
503
+}
504
+
505
+
506
+RateTransposerFloat::~RateTransposerFloat()
507
+{
508
+}
509
+
510
+
511
+void RateTransposerFloat::resetRegisters()
512
+{
513
+    fSlopeCount = 0;
514
+    sPrevSampleL =
515
+    sPrevSampleR = 0;
516
+}
517
+
518
+
519
+
520
+// Transposes the sample rate of the given samples using linear interpolation.
521
+// 'Mono' version of the routine. Returns the number of samples returned in
522
+// the "dest" buffer
523
+uint32_t RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
524
+{
525
+    unsigned int i, used;
526
+
527
+    used = 0;
528
+    i = 0;
529
+
530
+    // Process the last sample saved from the previous call first...
531
+    while (fSlopeCount <= 1.0f)
532
+    {
533
+        dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
534
+        i++;
535
+        fSlopeCount += fRate;
536
+    }
537
+    fSlopeCount -= 1.0f;
538
+
539
+    if (numsamples == 1) goto end;
540
+
541
+    while (1)
542
+    {
543
+        while (fSlopeCount > 1.0f)
544
+        {
545
+            fSlopeCount -= 1.0f;
546
+            used ++;
547
+            if (used >= numsamples - 1) goto end;
548
+        }
549
+        dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
550
+        i++;
551
+        fSlopeCount += fRate;
552
+    }
553
+end:
554
+    // Store the last sample for the next round
555
+    sPrevSampleL = src[numsamples - 1];
556
+
557
+    return i;
558
+}
559
+
560
+
561
+// Transposes the sample rate of the given samples using linear interpolation.
562
+// 'Mono' version of the routine. Returns the number of samples returned in
563
+// the "dest" buffer
564
+uint32_t RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint32_t numsamples)
565
+{
566
+    unsigned int srcPos, i, used;
567
+
568
+    if (numsamples == 0) return 0;  // no samples, no work
569
+
570
+    used = 0;
571
+    i = 0;
572
+
573
+    // Process the last sample saved from the sPrevSampleLious call first...
574
+    while (fSlopeCount <= 1.0f)
575
+    {
576
+        dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
577
+        dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
578
+        i++;
579
+        fSlopeCount += fRate;
580
+    }
581
+    // now always (iSlopeCount > 1.0f)
582
+    fSlopeCount -= 1.0f;
583
+
584
+    if (numsamples == 1) goto end;
585
+
586
+    while (1)
587
+    {
588
+        while (fSlopeCount > 1.0f)
589
+        {
590
+            fSlopeCount -= 1.0f;
591
+            used ++;
592
+            if (used >= numsamples - 1) goto end;
593
+        }
594
+        srcPos = 2 * used;
595
+
596
+        dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
597
+            + fSlopeCount * src[srcPos + 2]);
598
+        dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
599
+            + fSlopeCount * src[srcPos + 3]);
600
+
601
+        i++;
602
+        fSlopeCount += fRate;
603
+    }
604
+end:
605
+    // Store the last sample for the next round
606
+    sPrevSampleL = src[2 * numsamples - 2];
607
+    sPrevSampleR = src[2 * numsamples - 1];
608
+
609
+    return i;
610
+}