123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// Sample interpolation routine using 8-tap band-limited Shannon interpolation
- /// with kaiser window.
- ///
- /// Notice. This algorithm is remarkably much heavier than linear or cubic
- /// interpolation, and not remarkably better than cubic algorithm. Thus mostly
- /// for experimental purposes
- ///
- /// Author : Copyright (c) Olli Parviainen
- /// Author e-mail : oparviai 'at' iki.fi
- /// SoundTouch WWW: http://www.surina.net/soundtouch
- ///
- ////////////////////////////////////////////////////////////////////////////////
- //
- // License :
- //
- // SoundTouch audio processing library
- // Copyright (c) Olli Parviainen
- //
- // This library is free software; you can redistribute it and/or
- // modify it under the terms of the GNU Lesser General Public
- // License as published by the Free Software Foundation; either
- // version 2.1 of the License, or (at your option) any later version.
- //
- // This library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- // Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public
- // License along with this library; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- //
- ////////////////////////////////////////////////////////////////////////////////
- #include <math.h>
- #include "InterpolateShannon.h"
- #include "STTypes.h"
- using namespace soundtouch;
- /// Kaiser window with beta = 2.0
- /// Values scaled down by 5% to avoid overflows
- static const double _kaiser8[8] =
- {
- 0.41778693317814,
- 0.64888025049173,
- 0.83508562409944,
- 0.93887857733412,
- 0.93887857733412,
- 0.83508562409944,
- 0.64888025049173,
- 0.41778693317814
- };
- InterpolateShannon::InterpolateShannon()
- {
- fract = 0;
- }
- void InterpolateShannon::resetRegisters()
- {
- fract = 0;
- }
- #define PI 3.1415926536
- #define sinc(x) (sin(PI * (x)) / (PI * (x)))
- /// Transpose mono audio. Returns number of produced output samples, and
- /// updates "srcSamples" to amount of consumed source samples
- int InterpolateShannon::transposeMono(SAMPLETYPE *pdest,
- const SAMPLETYPE *psrc,
- int &srcSamples)
- {
- int i;
- int srcSampleEnd = srcSamples - 8;
- int srcCount = 0;
- i = 0;
- while (srcCount < srcSampleEnd)
- {
- double out;
- assert(fract < 1.0);
- out = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0];
- out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1];
- out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2];
- if (fract < 1e-6)
- {
- out += psrc[3] * _kaiser8[3]; // sinc(0) = 1
- }
- else
- {
- out += psrc[3] * sinc(- fract) * _kaiser8[3];
- }
- out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4];
- out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5];
- out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6];
- out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7];
- pdest[i] = (SAMPLETYPE)out;
- i ++;
- // update position fraction
- fract += rate;
- // update whole positions
- int whole = (int)fract;
- fract -= whole;
- psrc += whole;
- srcCount += whole;
- }
- srcSamples = srcCount;
- return i;
- }
- /// Transpose stereo audio. Returns number of produced output samples, and
- /// updates "srcSamples" to amount of consumed source samples
- int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest,
- const SAMPLETYPE *psrc,
- int &srcSamples)
- {
- int i;
- int srcSampleEnd = srcSamples - 8;
- int srcCount = 0;
- i = 0;
- while (srcCount < srcSampleEnd)
- {
- double out0, out1, w;
- assert(fract < 1.0);
- w = sinc(-3.0 - fract) * _kaiser8[0];
- out0 = psrc[0] * w; out1 = psrc[1] * w;
- w = sinc(-2.0 - fract) * _kaiser8[1];
- out0 += psrc[2] * w; out1 += psrc[3] * w;
- w = sinc(-1.0 - fract) * _kaiser8[2];
- out0 += psrc[4] * w; out1 += psrc[5] * w;
- w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract)); // sinc(0) = 1
- out0 += psrc[6] * w; out1 += psrc[7] * w;
- w = sinc( 1.0 - fract) * _kaiser8[4];
- out0 += psrc[8] * w; out1 += psrc[9] * w;
- w = sinc( 2.0 - fract) * _kaiser8[5];
- out0 += psrc[10] * w; out1 += psrc[11] * w;
- w = sinc( 3.0 - fract) * _kaiser8[6];
- out0 += psrc[12] * w; out1 += psrc[13] * w;
- w = sinc( 4.0 - fract) * _kaiser8[7];
- out0 += psrc[14] * w; out1 += psrc[15] * w;
- pdest[2*i] = (SAMPLETYPE)out0;
- pdest[2*i+1] = (SAMPLETYPE)out1;
- i ++;
- // update position fraction
- fract += rate;
- // update whole positions
- int whole = (int)fract;
- fract -= whole;
- psrc += 2*whole;
- srcCount += whole;
- }
- srcSamples = srcCount;
- return i;
- }
- /// Transpose stereo audio. Returns number of produced output samples, and
- /// updates "srcSamples" to amount of consumed source samples
- int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest,
- const SAMPLETYPE *psrc,
- int &srcSamples)
- {
- // not implemented
- assert(false);
- return 0;
- }
|