media/libsoundtouch/src/InterpolateLinear.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 ////////////////////////////////////////////////////////////////////////////////
michael@0 2 ///
michael@0 3 /// Linear interpolation algorithm.
michael@0 4 ///
michael@0 5 /// Author : Copyright (c) Olli Parviainen
michael@0 6 /// Author e-mail : oparviai 'at' iki.fi
michael@0 7 /// SoundTouch WWW: http://www.surina.net/soundtouch
michael@0 8 ///
michael@0 9 ////////////////////////////////////////////////////////////////////////////////
michael@0 10 //
michael@0 11 // $Id: InterpolateLinear.cpp 180 2014-01-06 19:16:02Z oparviai $
michael@0 12 //
michael@0 13 ////////////////////////////////////////////////////////////////////////////////
michael@0 14 //
michael@0 15 // License :
michael@0 16 //
michael@0 17 // SoundTouch audio processing library
michael@0 18 // Copyright (c) Olli Parviainen
michael@0 19 //
michael@0 20 // This library is free software; you can redistribute it and/or
michael@0 21 // modify it under the terms of the GNU Lesser General Public
michael@0 22 // License as published by the Free Software Foundation; either
michael@0 23 // version 2.1 of the License, or (at your option) any later version.
michael@0 24 //
michael@0 25 // This library is distributed in the hope that it will be useful,
michael@0 26 // but WITHOUT ANY WARRANTY; without even the implied warranty of
michael@0 27 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@0 28 // Lesser General Public License for more details.
michael@0 29 //
michael@0 30 // You should have received a copy of the GNU Lesser General Public
michael@0 31 // License along with this library; if not, write to the Free Software
michael@0 32 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
michael@0 33 //
michael@0 34 ////////////////////////////////////////////////////////////////////////////////
michael@0 35
michael@0 36 #include <assert.h>
michael@0 37 #include <stdlib.h>
michael@0 38 #include "InterpolateLinear.h"
michael@0 39
michael@0 40 using namespace soundtouch;
michael@0 41
michael@0 42 //////////////////////////////////////////////////////////////////////////////
michael@0 43 //
michael@0 44 // InterpolateLinearInteger - integer arithmetic implementation
michael@0 45 //
michael@0 46
michael@0 47 /// fixed-point interpolation routine precision
michael@0 48 #define SCALE 65536
michael@0 49
michael@0 50
michael@0 51 // Constructor
michael@0 52 InterpolateLinearInteger::InterpolateLinearInteger() : TransposerBase()
michael@0 53 {
michael@0 54 // Notice: use local function calling syntax for sake of clarity,
michael@0 55 // to indicate the fact that C++ constructor can't call virtual functions.
michael@0 56 resetRegisters();
michael@0 57 setRate(1.0f);
michael@0 58 }
michael@0 59
michael@0 60
michael@0 61 void InterpolateLinearInteger::resetRegisters()
michael@0 62 {
michael@0 63 iFract = 0;
michael@0 64 }
michael@0 65
michael@0 66
michael@0 67 // Transposes the sample rate of the given samples using linear interpolation.
michael@0 68 // 'Mono' version of the routine. Returns the number of samples returned in
michael@0 69 // the "dest" buffer
michael@0 70 int InterpolateLinearInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
michael@0 71 {
michael@0 72 int i;
michael@0 73 int srcSampleEnd = srcSamples - 1;
michael@0 74 int srcCount = 0;
michael@0 75
michael@0 76 i = 0;
michael@0 77 while (srcCount < srcSampleEnd)
michael@0 78 {
michael@0 79 LONG_SAMPLETYPE temp;
michael@0 80
michael@0 81 assert(iFract < SCALE);
michael@0 82
michael@0 83 temp = (SCALE - iFract) * src[0] + iFract * src[1];
michael@0 84 dest[i] = (SAMPLETYPE)(temp / SCALE);
michael@0 85 i++;
michael@0 86
michael@0 87 iFract += iRate;
michael@0 88
michael@0 89 int iWhole = iFract / SCALE;
michael@0 90 iFract -= iWhole * SCALE;
michael@0 91 srcCount += iWhole;
michael@0 92 src += iWhole;
michael@0 93 }
michael@0 94 srcSamples = srcCount;
michael@0 95
michael@0 96 return i;
michael@0 97 }
michael@0 98
michael@0 99
michael@0 100 // Transposes the sample rate of the given samples using linear interpolation.
michael@0 101 // 'Stereo' version of the routine. Returns the number of samples returned in
michael@0 102 // the "dest" buffer
michael@0 103 int InterpolateLinearInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
michael@0 104 {
michael@0 105 int i;
michael@0 106 int srcSampleEnd = srcSamples - 1;
michael@0 107 int srcCount = 0;
michael@0 108
michael@0 109 i = 0;
michael@0 110 while (srcCount < srcSampleEnd)
michael@0 111 {
michael@0 112 LONG_SAMPLETYPE temp0;
michael@0 113 LONG_SAMPLETYPE temp1;
michael@0 114
michael@0 115 assert(iFract < SCALE);
michael@0 116
michael@0 117 temp0 = (SCALE - iFract) * src[0] + iFract * src[2];
michael@0 118 temp1 = (SCALE - iFract) * src[1] + iFract * src[3];
michael@0 119 dest[0] = (SAMPLETYPE)(temp0 / SCALE);
michael@0 120 dest[1] = (SAMPLETYPE)(temp1 / SCALE);
michael@0 121 dest += 2;
michael@0 122 i++;
michael@0 123
michael@0 124 iFract += iRate;
michael@0 125
michael@0 126 int iWhole = iFract / SCALE;
michael@0 127 iFract -= iWhole * SCALE;
michael@0 128 srcCount += iWhole;
michael@0 129 src += 2*iWhole;
michael@0 130 }
michael@0 131 srcSamples = srcCount;
michael@0 132
michael@0 133 return i;
michael@0 134 }
michael@0 135
michael@0 136
michael@0 137 int InterpolateLinearInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
michael@0 138 {
michael@0 139 int i;
michael@0 140 int srcSampleEnd = srcSamples - 1;
michael@0 141 int srcCount = 0;
michael@0 142
michael@0 143 i = 0;
michael@0 144 while (srcCount < srcSampleEnd)
michael@0 145 {
michael@0 146 LONG_SAMPLETYPE temp, vol1;
michael@0 147
michael@0 148 assert(iFract < SCALE);
michael@0 149 vol1 = (SCALE - iFract);
michael@0 150 for (int c = 0; c < numChannels; c ++)
michael@0 151 {
michael@0 152 temp = vol1 * src[c] + iFract * src[c + numChannels];
michael@0 153 dest[0] = (SAMPLETYPE)(temp / SCALE);
michael@0 154 dest ++;
michael@0 155 }
michael@0 156 i++;
michael@0 157
michael@0 158 iFract += iRate;
michael@0 159
michael@0 160 int iWhole = iFract / SCALE;
michael@0 161 iFract -= iWhole * SCALE;
michael@0 162 srcCount += iWhole;
michael@0 163 src += iWhole * numChannels;
michael@0 164 }
michael@0 165 srcSamples = srcCount;
michael@0 166
michael@0 167 return i;
michael@0 168 }
michael@0 169
michael@0 170
michael@0 171 // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
michael@0 172 // iRate, larger faster iRates.
michael@0 173 void InterpolateLinearInteger::setRate(float newRate)
michael@0 174 {
michael@0 175 iRate = (int)(newRate * SCALE + 0.5f);
michael@0 176 TransposerBase::setRate(newRate);
michael@0 177 }
michael@0 178
michael@0 179
michael@0 180 //////////////////////////////////////////////////////////////////////////////
michael@0 181 //
michael@0 182 // InterpolateLinearFloat - floating point arithmetic implementation
michael@0 183 //
michael@0 184 //////////////////////////////////////////////////////////////////////////////
michael@0 185
michael@0 186
michael@0 187 // Constructor
michael@0 188 InterpolateLinearFloat::InterpolateLinearFloat() : TransposerBase()
michael@0 189 {
michael@0 190 // Notice: use local function calling syntax for sake of clarity,
michael@0 191 // to indicate the fact that C++ constructor can't call virtual functions.
michael@0 192 resetRegisters();
michael@0 193 setRate(1.0f);
michael@0 194 }
michael@0 195
michael@0 196
michael@0 197 void InterpolateLinearFloat::resetRegisters()
michael@0 198 {
michael@0 199 fract = 0;
michael@0 200 }
michael@0 201
michael@0 202
michael@0 203 // Transposes the sample rate of the given samples using linear interpolation.
michael@0 204 // 'Mono' version of the routine. Returns the number of samples returned in
michael@0 205 // the "dest" buffer
michael@0 206 int InterpolateLinearFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
michael@0 207 {
michael@0 208 int i;
michael@0 209 int srcSampleEnd = srcSamples - 1;
michael@0 210 int srcCount = 0;
michael@0 211
michael@0 212 i = 0;
michael@0 213 while (srcCount < srcSampleEnd)
michael@0 214 {
michael@0 215 double out;
michael@0 216 assert(fract < 1.0);
michael@0 217
michael@0 218 out = (1.0 - fract) * src[0] + fract * src[1];
michael@0 219 dest[i] = (SAMPLETYPE)out;
michael@0 220 i ++;
michael@0 221
michael@0 222 // update position fraction
michael@0 223 fract += rate;
michael@0 224 // update whole positions
michael@0 225 int whole = (int)fract;
michael@0 226 fract -= whole;
michael@0 227 src += whole;
michael@0 228 srcCount += whole;
michael@0 229 }
michael@0 230 srcSamples = srcCount;
michael@0 231 return i;
michael@0 232 }
michael@0 233
michael@0 234
michael@0 235 // Transposes the sample rate of the given samples using linear interpolation.
michael@0 236 // 'Mono' version of the routine. Returns the number of samples returned in
michael@0 237 // the "dest" buffer
michael@0 238 int InterpolateLinearFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
michael@0 239 {
michael@0 240 int i;
michael@0 241 int srcSampleEnd = srcSamples - 1;
michael@0 242 int srcCount = 0;
michael@0 243
michael@0 244 i = 0;
michael@0 245 while (srcCount < srcSampleEnd)
michael@0 246 {
michael@0 247 double out0, out1;
michael@0 248 assert(fract < 1.0);
michael@0 249
michael@0 250 out0 = (1.0 - fract) * src[0] + fract * src[2];
michael@0 251 out1 = (1.0 - fract) * src[1] + fract * src[3];
michael@0 252 dest[2*i] = (SAMPLETYPE)out0;
michael@0 253 dest[2*i+1] = (SAMPLETYPE)out1;
michael@0 254 i ++;
michael@0 255
michael@0 256 // update position fraction
michael@0 257 fract += rate;
michael@0 258 // update whole positions
michael@0 259 int whole = (int)fract;
michael@0 260 fract -= whole;
michael@0 261 src += 2*whole;
michael@0 262 srcCount += whole;
michael@0 263 }
michael@0 264 srcSamples = srcCount;
michael@0 265 return i;
michael@0 266 }
michael@0 267
michael@0 268
michael@0 269 int InterpolateLinearFloat::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
michael@0 270 {
michael@0 271 int i;
michael@0 272 int srcSampleEnd = srcSamples - 1;
michael@0 273 int srcCount = 0;
michael@0 274
michael@0 275 i = 0;
michael@0 276 while (srcCount < srcSampleEnd)
michael@0 277 {
michael@0 278 float temp, vol1;
michael@0 279
michael@0 280 vol1 = (1.0f- fract);
michael@0 281 for (int c = 0; c < numChannels; c ++)
michael@0 282 {
michael@0 283 temp = vol1 * src[c] + fract * src[c + numChannels];
michael@0 284 *dest = (SAMPLETYPE)temp;
michael@0 285 dest ++;
michael@0 286 }
michael@0 287 i++;
michael@0 288
michael@0 289 fract += rate;
michael@0 290
michael@0 291 int iWhole = (int)fract;
michael@0 292 fract -= iWhole;
michael@0 293 srcCount += iWhole;
michael@0 294 src += iWhole * numChannels;
michael@0 295 }
michael@0 296 srcSamples = srcCount;
michael@0 297
michael@0 298 return i;
michael@0 299 }

mercurial