1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libsoundtouch/src/InterpolateLinear.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,299 @@ 1.4 +//////////////////////////////////////////////////////////////////////////////// 1.5 +/// 1.6 +/// Linear interpolation algorithm. 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: InterpolateLinear.cpp 180 2014-01-06 19:16:02Z 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 <assert.h> 1.40 +#include <stdlib.h> 1.41 +#include "InterpolateLinear.h" 1.42 + 1.43 +using namespace soundtouch; 1.44 + 1.45 +////////////////////////////////////////////////////////////////////////////// 1.46 +// 1.47 +// InterpolateLinearInteger - integer arithmetic implementation 1.48 +// 1.49 + 1.50 +/// fixed-point interpolation routine precision 1.51 +#define SCALE 65536 1.52 + 1.53 + 1.54 +// Constructor 1.55 +InterpolateLinearInteger::InterpolateLinearInteger() : TransposerBase() 1.56 +{ 1.57 + // Notice: use local function calling syntax for sake of clarity, 1.58 + // to indicate the fact that C++ constructor can't call virtual functions. 1.59 + resetRegisters(); 1.60 + setRate(1.0f); 1.61 +} 1.62 + 1.63 + 1.64 +void InterpolateLinearInteger::resetRegisters() 1.65 +{ 1.66 + iFract = 0; 1.67 +} 1.68 + 1.69 + 1.70 +// Transposes the sample rate of the given samples using linear interpolation. 1.71 +// 'Mono' version of the routine. Returns the number of samples returned in 1.72 +// the "dest" buffer 1.73 +int InterpolateLinearInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) 1.74 +{ 1.75 + int i; 1.76 + int srcSampleEnd = srcSamples - 1; 1.77 + int srcCount = 0; 1.78 + 1.79 + i = 0; 1.80 + while (srcCount < srcSampleEnd) 1.81 + { 1.82 + LONG_SAMPLETYPE temp; 1.83 + 1.84 + assert(iFract < SCALE); 1.85 + 1.86 + temp = (SCALE - iFract) * src[0] + iFract * src[1]; 1.87 + dest[i] = (SAMPLETYPE)(temp / SCALE); 1.88 + i++; 1.89 + 1.90 + iFract += iRate; 1.91 + 1.92 + int iWhole = iFract / SCALE; 1.93 + iFract -= iWhole * SCALE; 1.94 + srcCount += iWhole; 1.95 + src += iWhole; 1.96 + } 1.97 + srcSamples = srcCount; 1.98 + 1.99 + return i; 1.100 +} 1.101 + 1.102 + 1.103 +// Transposes the sample rate of the given samples using linear interpolation. 1.104 +// 'Stereo' version of the routine. Returns the number of samples returned in 1.105 +// the "dest" buffer 1.106 +int InterpolateLinearInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) 1.107 +{ 1.108 + int i; 1.109 + int srcSampleEnd = srcSamples - 1; 1.110 + int srcCount = 0; 1.111 + 1.112 + i = 0; 1.113 + while (srcCount < srcSampleEnd) 1.114 + { 1.115 + LONG_SAMPLETYPE temp0; 1.116 + LONG_SAMPLETYPE temp1; 1.117 + 1.118 + assert(iFract < SCALE); 1.119 + 1.120 + temp0 = (SCALE - iFract) * src[0] + iFract * src[2]; 1.121 + temp1 = (SCALE - iFract) * src[1] + iFract * src[3]; 1.122 + dest[0] = (SAMPLETYPE)(temp0 / SCALE); 1.123 + dest[1] = (SAMPLETYPE)(temp1 / SCALE); 1.124 + dest += 2; 1.125 + i++; 1.126 + 1.127 + iFract += iRate; 1.128 + 1.129 + int iWhole = iFract / SCALE; 1.130 + iFract -= iWhole * SCALE; 1.131 + srcCount += iWhole; 1.132 + src += 2*iWhole; 1.133 + } 1.134 + srcSamples = srcCount; 1.135 + 1.136 + return i; 1.137 +} 1.138 + 1.139 + 1.140 +int InterpolateLinearInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) 1.141 +{ 1.142 + int i; 1.143 + int srcSampleEnd = srcSamples - 1; 1.144 + int srcCount = 0; 1.145 + 1.146 + i = 0; 1.147 + while (srcCount < srcSampleEnd) 1.148 + { 1.149 + LONG_SAMPLETYPE temp, vol1; 1.150 + 1.151 + assert(iFract < SCALE); 1.152 + vol1 = (SCALE - iFract); 1.153 + for (int c = 0; c < numChannels; c ++) 1.154 + { 1.155 + temp = vol1 * src[c] + iFract * src[c + numChannels]; 1.156 + dest[0] = (SAMPLETYPE)(temp / SCALE); 1.157 + dest ++; 1.158 + } 1.159 + i++; 1.160 + 1.161 + iFract += iRate; 1.162 + 1.163 + int iWhole = iFract / SCALE; 1.164 + iFract -= iWhole * SCALE; 1.165 + srcCount += iWhole; 1.166 + src += iWhole * numChannels; 1.167 + } 1.168 + srcSamples = srcCount; 1.169 + 1.170 + return i; 1.171 +} 1.172 + 1.173 + 1.174 +// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 1.175 +// iRate, larger faster iRates. 1.176 +void InterpolateLinearInteger::setRate(float newRate) 1.177 +{ 1.178 + iRate = (int)(newRate * SCALE + 0.5f); 1.179 + TransposerBase::setRate(newRate); 1.180 +} 1.181 + 1.182 + 1.183 +////////////////////////////////////////////////////////////////////////////// 1.184 +// 1.185 +// InterpolateLinearFloat - floating point arithmetic implementation 1.186 +// 1.187 +////////////////////////////////////////////////////////////////////////////// 1.188 + 1.189 + 1.190 +// Constructor 1.191 +InterpolateLinearFloat::InterpolateLinearFloat() : TransposerBase() 1.192 +{ 1.193 + // Notice: use local function calling syntax for sake of clarity, 1.194 + // to indicate the fact that C++ constructor can't call virtual functions. 1.195 + resetRegisters(); 1.196 + setRate(1.0f); 1.197 +} 1.198 + 1.199 + 1.200 +void InterpolateLinearFloat::resetRegisters() 1.201 +{ 1.202 + fract = 0; 1.203 +} 1.204 + 1.205 + 1.206 +// Transposes the sample rate of the given samples using linear interpolation. 1.207 +// 'Mono' version of the routine. Returns the number of samples returned in 1.208 +// the "dest" buffer 1.209 +int InterpolateLinearFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) 1.210 +{ 1.211 + int i; 1.212 + int srcSampleEnd = srcSamples - 1; 1.213 + int srcCount = 0; 1.214 + 1.215 + i = 0; 1.216 + while (srcCount < srcSampleEnd) 1.217 + { 1.218 + double out; 1.219 + assert(fract < 1.0); 1.220 + 1.221 + out = (1.0 - fract) * src[0] + fract * src[1]; 1.222 + dest[i] = (SAMPLETYPE)out; 1.223 + i ++; 1.224 + 1.225 + // update position fraction 1.226 + fract += rate; 1.227 + // update whole positions 1.228 + int whole = (int)fract; 1.229 + fract -= whole; 1.230 + src += whole; 1.231 + srcCount += whole; 1.232 + } 1.233 + srcSamples = srcCount; 1.234 + return i; 1.235 +} 1.236 + 1.237 + 1.238 +// Transposes the sample rate of the given samples using linear interpolation. 1.239 +// 'Mono' version of the routine. Returns the number of samples returned in 1.240 +// the "dest" buffer 1.241 +int InterpolateLinearFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) 1.242 +{ 1.243 + int i; 1.244 + int srcSampleEnd = srcSamples - 1; 1.245 + int srcCount = 0; 1.246 + 1.247 + i = 0; 1.248 + while (srcCount < srcSampleEnd) 1.249 + { 1.250 + double out0, out1; 1.251 + assert(fract < 1.0); 1.252 + 1.253 + out0 = (1.0 - fract) * src[0] + fract * src[2]; 1.254 + out1 = (1.0 - fract) * src[1] + fract * src[3]; 1.255 + dest[2*i] = (SAMPLETYPE)out0; 1.256 + dest[2*i+1] = (SAMPLETYPE)out1; 1.257 + i ++; 1.258 + 1.259 + // update position fraction 1.260 + fract += rate; 1.261 + // update whole positions 1.262 + int whole = (int)fract; 1.263 + fract -= whole; 1.264 + src += 2*whole; 1.265 + srcCount += whole; 1.266 + } 1.267 + srcSamples = srcCount; 1.268 + return i; 1.269 +} 1.270 + 1.271 + 1.272 +int InterpolateLinearFloat::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) 1.273 +{ 1.274 + int i; 1.275 + int srcSampleEnd = srcSamples - 1; 1.276 + int srcCount = 0; 1.277 + 1.278 + i = 0; 1.279 + while (srcCount < srcSampleEnd) 1.280 + { 1.281 + float temp, vol1; 1.282 + 1.283 + vol1 = (1.0f- fract); 1.284 + for (int c = 0; c < numChannels; c ++) 1.285 + { 1.286 + temp = vol1 * src[c] + fract * src[c + numChannels]; 1.287 + *dest = (SAMPLETYPE)temp; 1.288 + dest ++; 1.289 + } 1.290 + i++; 1.291 + 1.292 + fract += rate; 1.293 + 1.294 + int iWhole = (int)fract; 1.295 + fract -= iWhole; 1.296 + srcCount += iWhole; 1.297 + src += iWhole * numChannels; 1.298 + } 1.299 + srcSamples = srcCount; 1.300 + 1.301 + return i; 1.302 +}