|
MythTV
0.26-pre
|
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 // 00013 // Last changed : $Date$ 00014 // File revision : $Revision$ 00015 // 00016 // $Id$ 00017 // 00019 // 00020 // License : 00021 // 00022 // SoundTouch audio processing library 00023 // Copyright (c) Olli Parviainen 00024 // 00025 // This library is free software; you can redistribute it and/or 00026 // modify it under the terms of the GNU Lesser General Public 00027 // License as published by the Free Software Foundation; either 00028 // version 2.1 of the License, or (at your option) any later version. 00029 // 00030 // This library is distributed in the hope that it will be useful, 00031 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00032 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00033 // Lesser General Public License for more details. 00034 // 00035 // You should have received a copy of the GNU Lesser General Public 00036 // License along with this library; if not, write to the Free Software 00037 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00038 // 00040 00041 #include <memory.h> 00042 #include <assert.h> 00043 #include <stdlib.h> 00044 #include <stdio.h> 00045 #include <limits.h> 00046 #include "RateTransposer.h" 00047 #include "AAFilter.h" 00048 00049 using namespace soundtouch; 00050 00051 00054 class RateTransposerInteger : public RateTransposer 00055 { 00056 protected: 00057 int iSlopeCount; 00058 uint uRate; 00059 SAMPLETYPE sPrevSampleL, sPrevSampleR; 00060 00061 virtual void resetRegisters(); 00062 00063 virtual uint transposeStereo(SAMPLETYPE *dest, 00064 const SAMPLETYPE *src, 00065 uint numSamples); 00066 virtual uint transposeMono(SAMPLETYPE *dest, 00067 const SAMPLETYPE *src, 00068 uint numSamples); 00069 00070 public: 00071 RateTransposerInteger(); 00072 virtual ~RateTransposerInteger(); 00073 00076 virtual void setRate(float newRate); 00077 00078 }; 00079 00080 00083 class RateTransposerFloat : public RateTransposer 00084 { 00085 protected: 00086 float fSlopeCount; 00087 float fRateStep; 00088 SAMPLETYPE sPrevSampleL, sPrevSampleR; 00089 00090 virtual void resetRegisters(); 00091 00092 virtual uint transposeStereo(SAMPLETYPE *dest, 00093 const SAMPLETYPE *src, 00094 uint numSamples); 00095 virtual uint transposeMono(SAMPLETYPE *dest, 00096 const SAMPLETYPE *src, 00097 uint numSamples); 00098 00099 public: 00100 RateTransposerFloat(); 00101 virtual ~RateTransposerFloat(); 00102 }; 00103 00104 00105 00106 #ifndef min 00107 #define min(a,b) ((a > b) ? b : a) 00108 #define max(a,b) ((a < b) ? b : a) 00109 #endif 00110 00111 00112 // Operator 'new' is overloaded so that it automatically creates a suitable instance 00113 // depending on if we've a MMX/SSE/etc-capable CPU available or not. 00114 void * RateTransposer::operator new(size_t s) 00115 { 00116 // Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead! 00117 assert(FALSE); 00118 return NULL; 00119 } 00120 00121 00122 RateTransposer *RateTransposer::newInstance() 00123 { 00124 #ifdef INTEGER_SAMPLES 00125 return ::new RateTransposerInteger; 00126 #else 00127 return ::new RateTransposerFloat; 00128 #endif 00129 } 00130 00131 00132 // Constructor 00133 RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer) 00134 { 00135 fRate = 1.0f; 00136 uChannels = 2; 00137 bUseAAFilter = TRUE; 00138 00139 // Instantiates the anti-alias filter with default tap length 00140 // of 32 00141 pAAFilter = new AAFilter(32); 00142 } 00143 00144 00145 00146 RateTransposer::~RateTransposer() 00147 { 00148 delete pAAFilter; 00149 } 00150 00151 00152 00154 void RateTransposer::enableAAFilter(const BOOL newMode) 00155 { 00156 bUseAAFilter = newMode; 00157 } 00158 00159 00161 BOOL RateTransposer::isAAFilterEnabled() const 00162 { 00163 return bUseAAFilter; 00164 } 00165 00166 00167 AAFilter *RateTransposer::getAAFilter() const 00168 { 00169 return pAAFilter; 00170 } 00171 00172 00173 00174 // Sets new target uRate. Normal uRate = 1.0, smaller values represent slower 00175 // uRate, larger faster uRates. 00176 void RateTransposer::setRate(float newRate) 00177 { 00178 float fCutoff; 00179 00180 fRate = newRate; 00181 00182 // design a new anti-alias filter 00183 if (newRate > 1.0f) 00184 { 00185 fCutoff = 0.5f / newRate; 00186 } 00187 else 00188 { 00189 fCutoff = 0.5f * newRate; 00190 } 00191 pAAFilter->setCutoffFreq(fCutoff); 00192 } 00193 00194 00195 // Outputs as many samples of the 'outputBuffer' as possible, and if there's 00196 // any room left, outputs also as many of the incoming samples as possible. 00197 // The goal is to drive the outputBuffer empty. 00198 // 00199 // It's allowed for 'output' and 'input' parameters to point to the same 00200 // memory position. 00201 void RateTransposer::flushStoreBuffer() 00202 { 00203 if (storeBuffer.isEmpty()) return; 00204 00205 outputBuffer.moveSamples(storeBuffer); 00206 } 00207 00208 00209 // Adds 'numSamples' pcs of samples from the 'samples' memory position into 00210 // the input of the object. 00211 void RateTransposer::putSamples(const SAMPLETYPE *samples, uint numSamples) 00212 { 00213 processSamples(samples, numSamples); 00214 } 00215 00216 00217 00218 // Transposes up the sample rate, causing the observed playback 'rate' of the 00219 // sound to decrease 00220 void RateTransposer::upsample(const SAMPLETYPE *src, uint numSamples) 00221 { 00222 int count, sizeTemp, num; 00223 00224 // If the parameter 'uRate' value is smaller than 'SCALE', first transpose 00225 // the samples and then apply the anti-alias filter to remove aliasing. 00226 00227 // First check that there's enough room in 'storeBuffer' 00228 // (+16 is to reserve some slack in the destination buffer) 00229 sizeTemp = (int)((float)numSamples / fRate + 16.0f); 00230 00231 // Transpose the samples, store the result into the end of "storeBuffer" 00232 count = transpose(storeBuffer.ptrEnd(sizeTemp), src, numSamples); 00233 storeBuffer.putSamples(count); 00234 00235 // Apply the anti-alias filter to samples in "store output", output the 00236 // result to "dest" 00237 num = storeBuffer.numSamples(); 00238 count = pAAFilter->evaluate(outputBuffer.ptrEnd(num), 00239 storeBuffer.ptrBegin(), num, uChannels); 00240 outputBuffer.putSamples(count); 00241 00242 // Remove the processed samples from "storeBuffer" 00243 storeBuffer.receiveSamples(count); 00244 } 00245 00246 00247 // Transposes down the sample rate, causing the observed playback 'rate' of the 00248 // sound to increase 00249 void RateTransposer::downsample(const SAMPLETYPE *src, uint numSamples) 00250 { 00251 int count, sizeTemp; 00252 00253 // If the parameter 'uRate' value is larger than 'SCALE', first apply the 00254 // anti-alias filter to remove high frequencies (prevent them from folding 00255 // over the lover frequencies), then transpose. */ 00256 00257 // Add the new samples to the end of the storeBuffer */ 00258 storeBuffer.putSamples(src, numSamples); 00259 00260 // Anti-alias filter the samples to prevent folding and output the filtered 00261 // data to tempBuffer. Note : because of the FIR filter length, the 00262 // filtering routine takes in 'filter_length' more samples than it outputs. 00263 assert(tempBuffer.isEmpty()); 00264 sizeTemp = storeBuffer.numSamples(); 00265 00266 count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp), 00267 storeBuffer.ptrBegin(), sizeTemp, uChannels); 00268 00269 // Remove the filtered samples from 'storeBuffer' 00270 storeBuffer.receiveSamples(count); 00271 00272 // Transpose the samples (+16 is to reserve some slack in the destination buffer) 00273 sizeTemp = (int)((float)numSamples / fRate + 16.0f); 00274 count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count); 00275 outputBuffer.putSamples(count); 00276 } 00277 00278 00279 // Transposes sample rate by applying anti-alias filter to prevent folding. 00280 // Returns amount of samples returned in the "dest" buffer. 00281 // The maximum amount of samples that can be returned at a time is set by 00282 // the 'set_returnBuffer_size' function. 00283 void RateTransposer::processSamples(const SAMPLETYPE *src, uint numSamples) 00284 { 00285 uint count; 00286 uint sizeReq; 00287 00288 if (numSamples == 0) return; 00289 assert(pAAFilter); 00290 00291 // If anti-alias filter is turned off, simply transpose without applying 00292 // the filter 00293 if (bUseAAFilter == FALSE) 00294 { 00295 sizeReq = (int)((float)numSamples / fRate + 1.0f); 00296 count = transpose(outputBuffer.ptrEnd(sizeReq), src, numSamples); 00297 outputBuffer.putSamples(count); 00298 return; 00299 } 00300 00301 // Transpose with anti-alias filter 00302 if (fRate < 1.0f) 00303 { 00304 upsample(src, numSamples); 00305 } 00306 else 00307 { 00308 downsample(src, numSamples); 00309 } 00310 } 00311 00312 00313 // Transposes the sample rate of the given samples using linear interpolation. 00314 // Returns the number of samples returned in the "dest" buffer 00315 inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) 00316 { 00317 if (uChannels == 2) 00318 { 00319 return transposeStereo(dest, src, numSamples); 00320 } 00321 else 00322 { 00323 return transposeMono(dest, src, numSamples); 00324 } 00325 } 00326 00327 00328 // Sets the number of channels, 1 = mono, 2 = stereo 00329 void RateTransposer::setChannels(const uint numchannels) 00330 { 00331 if (uChannels == numchannels) return; 00332 00333 #ifdef MULTICHANNEL 00334 assert(numchannels >= 1 && numchannels <= MULTICHANNEL); 00335 #else 00336 assert(numchannels == 1 || numchannels == 2); 00337 #endif 00338 uChannels = numchannels; 00339 00340 storeBuffer.setChannels(uChannels); 00341 tempBuffer.setChannels(uChannels); 00342 outputBuffer.setChannels(uChannels); 00343 00344 // Inits the linear interpolation registers 00345 resetRegisters(); 00346 } 00347 00348 00349 // Clears all the samples in the object 00350 void RateTransposer::clear() 00351 { 00352 outputBuffer.clear(); 00353 storeBuffer.clear(); 00354 } 00355 00356 00357 // Returns nonzero if there aren't any samples available for outputting. 00358 int RateTransposer::isEmpty() const 00359 { 00360 int res; 00361 00362 res = FIFOProcessor::isEmpty(); 00363 if (res == 0) return 0; 00364 return storeBuffer.isEmpty(); 00365 } 00366 00367 00369 // 00370 // RateTransposerInteger - integer arithmetic implementation 00371 // 00372 00374 #define SCALE 65536 00375 00376 // Constructor 00377 RateTransposerInteger::RateTransposerInteger() : RateTransposer() 00378 { 00379 // call these here as these are virtual functions; calling these 00380 // from the base class constructor wouldn't execute the overloaded 00381 // versions (<master yoda>peculiar C++ can be</my>). 00382 resetRegisters(); 00383 setRate(1.0f); 00384 } 00385 00386 00387 RateTransposerInteger::~RateTransposerInteger() 00388 { 00389 } 00390 00391 00392 void RateTransposerInteger::resetRegisters() 00393 { 00394 iSlopeCount = 0; 00395 sPrevSampleL = 00396 sPrevSampleR = 0; 00397 } 00398 00399 00400 00401 // Transposes the sample rate of the given samples using linear interpolation. 00402 // 'Mono' version of the routine. Returns the number of samples returned in 00403 // the "dest" buffer 00404 uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) 00405 { 00406 unsigned int i, used; 00407 LONG_SAMPLETYPE temp, vol1; 00408 00409 used = 0; 00410 i = 0; 00411 00412 // Process the last sample saved from the previous call first... 00413 while (iSlopeCount <= SCALE) 00414 { 00415 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); 00416 temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; 00417 dest[i] = (SAMPLETYPE)(temp / SCALE); 00418 i++; 00419 iSlopeCount += uRate; 00420 } 00421 // now always (iSlopeCount > SCALE) 00422 iSlopeCount -= SCALE; 00423 00424 while (1) 00425 { 00426 while (iSlopeCount > SCALE) 00427 { 00428 iSlopeCount -= SCALE; 00429 used ++; 00430 if (used >= numSamples - 1) goto end; 00431 } 00432 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); 00433 temp = src[used] * vol1 + iSlopeCount * src[used + 1]; 00434 dest[i] = (SAMPLETYPE)(temp / SCALE); 00435 00436 i++; 00437 iSlopeCount += uRate; 00438 } 00439 end: 00440 // Store the last sample for the next round 00441 sPrevSampleL = src[numSamples - 1]; 00442 00443 return i; 00444 } 00445 00446 00447 // Transposes the sample rate of the given samples using linear interpolation. 00448 // 'Stereo' version of the routine. Returns the number of samples returned in 00449 // the "dest" buffer 00450 uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) 00451 { 00452 unsigned int srcPos, i, used; 00453 LONG_SAMPLETYPE temp, vol1; 00454 00455 if (numSamples == 0) return 0; // no samples, no work 00456 00457 used = 0; 00458 i = 0; 00459 00460 // Process the last sample saved from the sPrevSampleLious call first... 00461 while (iSlopeCount <= SCALE) 00462 { 00463 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); 00464 temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; 00465 dest[2 * i] = (SAMPLETYPE)(temp / SCALE); 00466 temp = vol1 * sPrevSampleR + iSlopeCount * src[1]; 00467 dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE); 00468 i++; 00469 iSlopeCount += uRate; 00470 } 00471 // now always (iSlopeCount > SCALE) 00472 iSlopeCount -= SCALE; 00473 00474 while (1) 00475 { 00476 while (iSlopeCount > SCALE) 00477 { 00478 iSlopeCount -= SCALE; 00479 used ++; 00480 if (used >= numSamples - 1) goto end; 00481 } 00482 srcPos = 2 * used; 00483 vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); 00484 temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2]; 00485 dest[2 * i] = (SAMPLETYPE)(temp / SCALE); 00486 temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3]; 00487 dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE); 00488 00489 i++; 00490 iSlopeCount += uRate; 00491 } 00492 end: 00493 // Store the last sample for the next round 00494 sPrevSampleL = src[2 * numSamples - 2]; 00495 sPrevSampleR = src[2 * numSamples - 1]; 00496 00497 return i; 00498 } 00499 00500 00501 // Sets new target uRate. Normal uRate = 1.0, smaller values represent slower 00502 // uRate, larger faster uRates. 00503 void RateTransposerInteger::setRate(float newRate) 00504 { 00505 uRate = (int)(newRate * SCALE + 0.5f); 00506 RateTransposer::setRate(newRate); 00507 } 00508 00509 00511 // 00512 // RateTransposerFloat - floating point arithmetic implementation 00513 // 00515 00516 // Constructor 00517 RateTransposerFloat::RateTransposerFloat() : RateTransposer() 00518 { 00519 // call these here as these are virtual functions; calling these 00520 // from the base class constructor wouldn't execute the overloaded 00521 // versions (<master yoda>peculiar C++ can be</my>). 00522 resetRegisters(); 00523 setRate(1.0f); 00524 } 00525 00526 00527 RateTransposerFloat::~RateTransposerFloat() 00528 { 00529 } 00530 00531 00532 void RateTransposerFloat::resetRegisters() 00533 { 00534 fSlopeCount = 0; 00535 sPrevSampleL = 00536 sPrevSampleR = 0; 00537 } 00538 00539 00540 00541 // Transposes the sample rate of the given samples using linear interpolation. 00542 // 'Mono' version of the routine. Returns the number of samples returned in 00543 // the "dest" buffer 00544 uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) 00545 { 00546 unsigned int i, used; 00547 00548 used = 0; 00549 i = 0; 00550 00551 // Process the last sample saved from the previous call first... 00552 while (fSlopeCount <= 1.0f) 00553 { 00554 dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]); 00555 i++; 00556 fSlopeCount += fRate; 00557 } 00558 fSlopeCount -= 1.0f; 00559 00560 if (numSamples == 1) goto end; 00561 00562 while (1) 00563 { 00564 while (fSlopeCount > 1.0f) 00565 { 00566 fSlopeCount -= 1.0f; 00567 used ++; 00568 if (used >= numSamples - 1) goto end; 00569 } 00570 dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]); 00571 i++; 00572 fSlopeCount += fRate; 00573 } 00574 end: 00575 // Store the last sample for the next round 00576 sPrevSampleL = src[numSamples - 1]; 00577 00578 return i; 00579 } 00580 00581 00582 // Transposes the sample rate of the given samples using linear interpolation. 00583 // 'Mono' version of the routine. Returns the number of samples returned in 00584 // the "dest" buffer 00585 uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) 00586 { 00587 unsigned int srcPos, i, used; 00588 00589 if (numSamples == 0) return 0; // no samples, no work 00590 00591 used = 0; 00592 i = 0; 00593 00594 // Process the last sample saved from the sPrevSampleLious call first... 00595 while (fSlopeCount <= 1.0f) 00596 { 00597 dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]); 00598 dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]); 00599 i++; 00600 fSlopeCount += fRate; 00601 } 00602 // now always (iSlopeCount > 1.0f) 00603 fSlopeCount -= 1.0f; 00604 00605 if (numSamples == 1) goto end; 00606 00607 while (1) 00608 { 00609 while (fSlopeCount > 1.0f) 00610 { 00611 fSlopeCount -= 1.0f; 00612 used ++; 00613 if (used >= numSamples - 1) goto end; 00614 } 00615 srcPos = 2 * used; 00616 00617 dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos] 00618 + fSlopeCount * src[srcPos + 2]); 00619 dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1] 00620 + fSlopeCount * src[srcPos + 3]); 00621 00622 i++; 00623 fSlopeCount += fRate; 00624 } 00625 end: 00626 // Store the last sample for the next round 00627 sPrevSampleL = src[2 * numSamples - 2]; 00628 sPrevSampleR = src[2 * numSamples - 1]; 00629 00630 return i; 00631 }
1.7.6.1