1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libsoundtouch/src/InterpolateShannon.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,185 @@ 1.4 +//////////////////////////////////////////////////////////////////////////////// 1.5 +/// 1.6 +/// Sample interpolation routine using 8-tap band-limited Shannon interpolation 1.7 +/// with kaiser window. 1.8 +/// 1.9 +/// Notice. This algorithm is remarkably much heavier than linear or cubic 1.10 +/// interpolation, and not remarkably better than cubic algorithm. Thus mostly 1.11 +/// for experimental purposes 1.12 +/// 1.13 +/// Author : Copyright (c) Olli Parviainen 1.14 +/// Author e-mail : oparviai 'at' iki.fi 1.15 +/// SoundTouch WWW: http://www.surina.net/soundtouch 1.16 +/// 1.17 +//////////////////////////////////////////////////////////////////////////////// 1.18 +// 1.19 +// $Id: InterpolateShannon.cpp 195 2014-04-06 15:57:21Z oparviai $ 1.20 +// 1.21 +//////////////////////////////////////////////////////////////////////////////// 1.22 +// 1.23 +// License : 1.24 +// 1.25 +// SoundTouch audio processing library 1.26 +// Copyright (c) Olli Parviainen 1.27 +// 1.28 +// This library is free software; you can redistribute it and/or 1.29 +// modify it under the terms of the GNU Lesser General Public 1.30 +// License as published by the Free Software Foundation; either 1.31 +// version 2.1 of the License, or (at your option) any later version. 1.32 +// 1.33 +// This library is distributed in the hope that it will be useful, 1.34 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 1.35 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.36 +// Lesser General Public License for more details. 1.37 +// 1.38 +// You should have received a copy of the GNU Lesser General Public 1.39 +// License along with this library; if not, write to the Free Software 1.40 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1.41 +// 1.42 +//////////////////////////////////////////////////////////////////////////////// 1.43 + 1.44 +#include <math.h> 1.45 +#include "InterpolateShannon.h" 1.46 +#include "STTypes.h" 1.47 + 1.48 +using namespace soundtouch; 1.49 + 1.50 + 1.51 +/// Kaiser window with beta = 2.0 1.52 +/// Values scaled down by 5% to avoid overflows 1.53 +static const double _kaiser8[8] = 1.54 +{ 1.55 + 0.41778693317814, 1.56 + 0.64888025049173, 1.57 + 0.83508562409944, 1.58 + 0.93887857733412, 1.59 + 0.93887857733412, 1.60 + 0.83508562409944, 1.61 + 0.64888025049173, 1.62 + 0.41778693317814 1.63 +}; 1.64 + 1.65 + 1.66 +InterpolateShannon::InterpolateShannon() 1.67 +{ 1.68 + fract = 0; 1.69 +} 1.70 + 1.71 + 1.72 +void InterpolateShannon::resetRegisters() 1.73 +{ 1.74 + fract = 0; 1.75 +} 1.76 + 1.77 + 1.78 +#define PI 3.1415926536 1.79 +#define sinc(x) (sin(PI * (x)) / (PI * (x))) 1.80 + 1.81 +/// Transpose mono audio. Returns number of produced output samples, and 1.82 +/// updates "srcSamples" to amount of consumed source samples 1.83 +int InterpolateShannon::transposeMono(SAMPLETYPE *pdest, 1.84 + const SAMPLETYPE *psrc, 1.85 + int &srcSamples) 1.86 +{ 1.87 + int i; 1.88 + int srcSampleEnd = srcSamples - 8; 1.89 + int srcCount = 0; 1.90 + 1.91 + i = 0; 1.92 + while (srcCount < srcSampleEnd) 1.93 + { 1.94 + double out; 1.95 + assert(fract < 1.0); 1.96 + 1.97 + out = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0]; 1.98 + out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1]; 1.99 + out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2]; 1.100 + if (fract < 1e-6) 1.101 + { 1.102 + out += psrc[3] * _kaiser8[3]; // sinc(0) = 1 1.103 + } 1.104 + else 1.105 + { 1.106 + out += psrc[3] * sinc(- fract) * _kaiser8[3]; 1.107 + } 1.108 + out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4]; 1.109 + out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5]; 1.110 + out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6]; 1.111 + out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7]; 1.112 + 1.113 + pdest[i] = (SAMPLETYPE)out; 1.114 + i ++; 1.115 + 1.116 + // update position fraction 1.117 + fract += rate; 1.118 + // update whole positions 1.119 + int whole = (int)fract; 1.120 + fract -= whole; 1.121 + psrc += whole; 1.122 + srcCount += whole; 1.123 + } 1.124 + srcSamples = srcCount; 1.125 + return i; 1.126 +} 1.127 + 1.128 + 1.129 +/// Transpose stereo audio. Returns number of produced output samples, and 1.130 +/// updates "srcSamples" to amount of consumed source samples 1.131 +int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest, 1.132 + const SAMPLETYPE *psrc, 1.133 + int &srcSamples) 1.134 +{ 1.135 + int i; 1.136 + int srcSampleEnd = srcSamples - 8; 1.137 + int srcCount = 0; 1.138 + 1.139 + i = 0; 1.140 + while (srcCount < srcSampleEnd) 1.141 + { 1.142 + double out0, out1, w; 1.143 + assert(fract < 1.0); 1.144 + 1.145 + w = sinc(-3.0 - fract) * _kaiser8[0]; 1.146 + out0 = psrc[0] * w; out1 = psrc[1] * w; 1.147 + w = sinc(-2.0 - fract) * _kaiser8[1]; 1.148 + out0 += psrc[2] * w; out1 += psrc[3] * w; 1.149 + w = sinc(-1.0 - fract) * _kaiser8[2]; 1.150 + out0 += psrc[4] * w; out1 += psrc[5] * w; 1.151 + w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract)); // sinc(0) = 1 1.152 + out0 += psrc[6] * w; out1 += psrc[7] * w; 1.153 + w = sinc( 1.0 - fract) * _kaiser8[4]; 1.154 + out0 += psrc[8] * w; out1 += psrc[9] * w; 1.155 + w = sinc( 2.0 - fract) * _kaiser8[5]; 1.156 + out0 += psrc[10] * w; out1 += psrc[11] * w; 1.157 + w = sinc( 3.0 - fract) * _kaiser8[6]; 1.158 + out0 += psrc[12] * w; out1 += psrc[13] * w; 1.159 + w = sinc( 4.0 - fract) * _kaiser8[7]; 1.160 + out0 += psrc[14] * w; out1 += psrc[15] * w; 1.161 + 1.162 + pdest[2*i] = (SAMPLETYPE)out0; 1.163 + pdest[2*i+1] = (SAMPLETYPE)out1; 1.164 + i ++; 1.165 + 1.166 + // update position fraction 1.167 + fract += rate; 1.168 + // update whole positions 1.169 + int whole = (int)fract; 1.170 + fract -= whole; 1.171 + psrc += 2*whole; 1.172 + srcCount += whole; 1.173 + } 1.174 + srcSamples = srcCount; 1.175 + return i; 1.176 +} 1.177 + 1.178 + 1.179 +/// Transpose stereo audio. Returns number of produced output samples, and 1.180 +/// updates "srcSamples" to amount of consumed source samples 1.181 +int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest, 1.182 + const SAMPLETYPE *psrc, 1.183 + int &srcSamples) 1.184 +{ 1.185 + // not implemented 1.186 + assert(false); 1.187 + return 0; 1.188 +}