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