📄 ratetransposer.cpp
字号:
inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples){ if (uChannels == 2) { return transposeStereo(dest, src, numSamples); } else { return transposeMono(dest, src, numSamples); }}// Sets the number of channels, 1 = mono, 2 = stereovoid RateTransposer::setChannels(const uint numchannels){ if (uChannels == numchannels) return; assert(numchannels == 1 || numchannels == 2); uChannels = numchannels; storeBuffer.setChannels(uChannels); tempBuffer.setChannels(uChannels); outputBuffer.setChannels(uChannels); // Inits the linear interpolation registers resetRegisters();}// Clears all the samples in the objectvoid RateTransposer::clear(){ outputBuffer.clear(); storeBuffer.clear();}// Returns nonzero if there aren't any samples available for outputting.uint RateTransposer::isEmpty(){ int res; res = FIFOProcessor::isEmpty(); if (res == 0) return 0; return storeBuffer.isEmpty();}////////////////////////////////////////////////////////////////////////////////// RateTransposerInteger - integer arithmetic implementation// /// fixed-point interpolation routine precision#define SCALE 65536// ConstructorRateTransposerInteger::RateTransposerInteger() : RateTransposer(){ // call these here as these are virtual functions; calling these // from the base class constructor wouldn't execute the overloaded // versions (<master yoda>peculiar C++ can be</my>). resetRegisters(); setRate(1.0f);}RateTransposerInteger::~RateTransposerInteger(){}void RateTransposerInteger::resetRegisters(){ iSlopeCount = 0; sPrevSampleL = sPrevSampleR = 0;}// Transposes the sample rate of the given samples using linear interpolation. // 'Mono' version of the routine. Returns the number of samples returned in // the "dest" bufferuint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples){ unsigned int i, used; LONG_SAMPLETYPE temp, vol1; used = 0; i = 0; // Process the last sample saved from the previous call first... while (iSlopeCount <= SCALE) { vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; dest[i] = (SAMPLETYPE)(temp / SCALE); i++; iSlopeCount += uRate; } // now always (iSlopeCount > SCALE) iSlopeCount -= SCALE; while (1) { while (iSlopeCount > SCALE) { iSlopeCount -= SCALE; used ++; if (used >= numSamples - 1) goto end; } vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); temp = src[used] * vol1 + iSlopeCount * src[used + 1]; dest[i] = (SAMPLETYPE)(temp / SCALE); i++; iSlopeCount += uRate; }end: // Store the last sample for the next round sPrevSampleL = src[numSamples - 1]; return i;}// Transposes the sample rate of the given samples using linear interpolation. // 'Mono' version of the routine. Returns the number of samples returned in // the "dest" bufferuint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples){ unsigned int srcPos, i, used; LONG_SAMPLETYPE temp, vol1; if (numSamples == 0) return 0; // no samples, no work used = 0; i = 0; // Process the last sample saved from the sPrevSampleLious call first... while (iSlopeCount <= SCALE) { vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; dest[2 * i] = (SAMPLETYPE)(temp / SCALE); temp = vol1 * sPrevSampleR + iSlopeCount * src[1]; dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE); i++; iSlopeCount += uRate; } // now always (iSlopeCount > SCALE) iSlopeCount -= SCALE; while (1) { while (iSlopeCount > SCALE) { iSlopeCount -= SCALE; used ++; if (used >= numSamples - 1) goto end; } srcPos = 2 * used; vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2]; dest[2 * i] = (SAMPLETYPE)(temp / SCALE); temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3]; dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE); i++; iSlopeCount += uRate; }end: // Store the last sample for the next round sPrevSampleL = src[2 * numSamples - 2]; sPrevSampleR = src[2 * numSamples - 1]; return i;}// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower // uRate, larger faster uRates.void RateTransposerInteger::setRate(float newRate){ uRate = (int)(newRate * SCALE + 0.5f); RateTransposer::setRate(newRate);}////////////////////////////////////////////////////////////////////////////////// RateTransposerFloat - floating point arithmetic implementation// //////////////////////////////////////////////////////////////////////////////// ConstructorRateTransposerFloat::RateTransposerFloat() : RateTransposer(){ // call these here as these are virtual functions; calling these // from the base class constructor wouldn't execute the overloaded // versions (<master yoda>peculiar C++ can be</my>). resetRegisters(); setRate(1.0f);}RateTransposerFloat::~RateTransposerFloat(){}void RateTransposerFloat::resetRegisters(){ fSlopeCount = 0; sPrevSampleL = sPrevSampleR = 0;}// Transposes the sample rate of the given samples using linear interpolation. // 'Mono' version of the routine. Returns the number of samples returned in // the "dest" bufferuint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples){ unsigned int i, used; used = 0; i = 0; // Process the last sample saved from the previous call first... while (fSlopeCount <= 1.0f) { dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]); i++; fSlopeCount += fRate; } fSlopeCount -= 1.0f; while (1) { while (fSlopeCount > 1.0f) { fSlopeCount -= 1.0f; used ++; if (used >= numSamples - 1) goto end; } dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]); i++; fSlopeCount += fRate; }end: // Store the last sample for the next round sPrevSampleL = src[numSamples - 1]; return i;}// Transposes the sample rate of the given samples using linear interpolation. // 'Mono' version of the routine. Returns the number of samples returned in // the "dest" bufferuint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples){ unsigned int srcPos, i, used; if (numSamples == 0) return 0; // no samples, no work used = 0; i = 0; // Process the last sample saved from the sPrevSampleLious call first... while (fSlopeCount <= 1.0f) { dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]); dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]); i++; fSlopeCount += fRate; } // now always (iSlopeCount > 1.0f) fSlopeCount -= 1.0f; while (1) { while (fSlopeCount > 1.0f) { fSlopeCount -= 1.0f; used ++; if (used >= numSamples - 1) goto end; } srcPos = 2 * used; dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos] + fSlopeCount * src[srcPos + 2]); dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1] + fSlopeCount * src[srcPos + 3]); i++; fSlopeCount += fRate; }end: // Store the last sample for the next round sPrevSampleL = src[2 * numSamples - 2]; sPrevSampleR = src[2 * numSamples - 1]; return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -