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