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