/[pcsx2_0.9.7]/trunk/3rdparty/SoundTouch/RateTransposer.cpp
ViewVC logotype

Contents of /trunk/3rdparty/SoundTouch/RateTransposer.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22