Line data Source code
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 : ////////////////////////////////////////////////////////////////////////////////
35 :
36 : #include <assert.h>
37 : #include <stdlib.h>
38 : #include "InterpolateLinear.h"
39 :
40 : using namespace soundtouch;
41 :
42 : //////////////////////////////////////////////////////////////////////////////
43 : //
44 : // InterpolateLinearInteger - integer arithmetic implementation
45 : //
46 :
47 : /// fixed-point interpolation routine precision
48 : #define SCALE 65536
49 :
50 :
51 : // Constructor
52 0 : 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 0 : resetRegisters();
57 0 : setRate(1.0f);
58 0 : }
59 :
60 :
61 0 : void InterpolateLinearInteger::resetRegisters()
62 : {
63 0 : iFract = 0;
64 0 : }
65 :
66 :
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 0 : int InterpolateLinearInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
71 : {
72 : int i;
73 0 : int srcSampleEnd = srcSamples - 1;
74 0 : int srcCount = 0;
75 :
76 0 : i = 0;
77 0 : while (srcCount < srcSampleEnd)
78 : {
79 : LONG_SAMPLETYPE temp;
80 :
81 0 : assert(iFract < SCALE);
82 :
83 0 : temp = (SCALE - iFract) * src[0] + iFract * src[1];
84 0 : dest[i] = (SAMPLETYPE)(temp / SCALE);
85 0 : i++;
86 :
87 0 : iFract += iRate;
88 :
89 0 : int iWhole = iFract / SCALE;
90 0 : iFract -= iWhole * SCALE;
91 0 : srcCount += iWhole;
92 0 : src += iWhole;
93 : }
94 0 : srcSamples = srcCount;
95 :
96 0 : return i;
97 : }
98 :
99 :
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 0 : int InterpolateLinearInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
104 : {
105 : int i;
106 0 : int srcSampleEnd = srcSamples - 1;
107 0 : int srcCount = 0;
108 :
109 0 : i = 0;
110 0 : while (srcCount < srcSampleEnd)
111 : {
112 : LONG_SAMPLETYPE temp0;
113 : LONG_SAMPLETYPE temp1;
114 :
115 0 : assert(iFract < SCALE);
116 :
117 0 : temp0 = (SCALE - iFract) * src[0] + iFract * src[2];
118 0 : temp1 = (SCALE - iFract) * src[1] + iFract * src[3];
119 0 : dest[0] = (SAMPLETYPE)(temp0 / SCALE);
120 0 : dest[1] = (SAMPLETYPE)(temp1 / SCALE);
121 0 : dest += 2;
122 0 : i++;
123 :
124 0 : iFract += iRate;
125 :
126 0 : int iWhole = iFract / SCALE;
127 0 : iFract -= iWhole * SCALE;
128 0 : srcCount += iWhole;
129 0 : src += 2*iWhole;
130 : }
131 0 : srcSamples = srcCount;
132 :
133 0 : return i;
134 : }
135 :
136 :
137 0 : int InterpolateLinearInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
138 : {
139 : int i;
140 0 : int srcSampleEnd = srcSamples - 1;
141 0 : int srcCount = 0;
142 :
143 0 : i = 0;
144 0 : while (srcCount < srcSampleEnd)
145 : {
146 : LONG_SAMPLETYPE temp, vol1;
147 :
148 0 : assert(iFract < SCALE);
149 0 : vol1 = (SCALE - iFract);
150 0 : for (int c = 0; c < numChannels; c ++)
151 : {
152 0 : temp = vol1 * src[c] + iFract * src[c + numChannels];
153 0 : dest[0] = (SAMPLETYPE)(temp / SCALE);
154 0 : dest ++;
155 : }
156 0 : i++;
157 :
158 0 : iFract += iRate;
159 :
160 0 : int iWhole = iFract / SCALE;
161 0 : iFract -= iWhole * SCALE;
162 0 : srcCount += iWhole;
163 0 : src += iWhole * numChannels;
164 : }
165 0 : srcSamples = srcCount;
166 :
167 0 : return i;
168 : }
169 :
170 :
171 : // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
172 : // iRate, larger faster iRates.
173 0 : void InterpolateLinearInteger::setRate(float newRate)
174 : {
175 0 : iRate = (int)(newRate * SCALE + 0.5f);
176 0 : TransposerBase::setRate(newRate);
177 0 : }
178 :
179 :
180 : //////////////////////////////////////////////////////////////////////////////
181 : //
182 : // InterpolateLinearFloat - floating point arithmetic implementation
183 : //
184 : //////////////////////////////////////////////////////////////////////////////
185 :
186 :
187 : // Constructor
188 0 : 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 0 : resetRegisters();
193 0 : setRate(1.0f);
194 0 : }
195 :
196 :
197 0 : void InterpolateLinearFloat::resetRegisters()
198 : {
199 0 : fract = 0;
200 0 : }
201 :
202 :
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 0 : int InterpolateLinearFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
207 : {
208 : int i;
209 0 : int srcSampleEnd = srcSamples - 1;
210 0 : int srcCount = 0;
211 :
212 0 : i = 0;
213 0 : while (srcCount < srcSampleEnd)
214 : {
215 : double out;
216 0 : assert(fract < 1.0);
217 :
218 0 : out = (1.0 - fract) * src[0] + fract * src[1];
219 0 : dest[i] = (SAMPLETYPE)out;
220 0 : i ++;
221 :
222 : // update position fraction
223 0 : fract += rate;
224 : // update whole positions
225 0 : int whole = (int)fract;
226 0 : fract -= whole;
227 0 : src += whole;
228 0 : srcCount += whole;
229 : }
230 0 : srcSamples = srcCount;
231 0 : return i;
232 : }
233 :
234 :
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 0 : int InterpolateLinearFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
239 : {
240 : int i;
241 0 : int srcSampleEnd = srcSamples - 1;
242 0 : int srcCount = 0;
243 :
244 0 : i = 0;
245 0 : while (srcCount < srcSampleEnd)
246 : {
247 : double out0, out1;
248 0 : assert(fract < 1.0);
249 :
250 0 : out0 = (1.0 - fract) * src[0] + fract * src[2];
251 0 : out1 = (1.0 - fract) * src[1] + fract * src[3];
252 0 : dest[2*i] = (SAMPLETYPE)out0;
253 0 : dest[2*i+1] = (SAMPLETYPE)out1;
254 0 : i ++;
255 :
256 : // update position fraction
257 0 : fract += rate;
258 : // update whole positions
259 0 : int whole = (int)fract;
260 0 : fract -= whole;
261 0 : src += 2*whole;
262 0 : srcCount += whole;
263 : }
264 0 : srcSamples = srcCount;
265 0 : return i;
266 : }
267 :
268 :
269 0 : int InterpolateLinearFloat::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
270 : {
271 : int i;
272 0 : int srcSampleEnd = srcSamples - 1;
273 0 : int srcCount = 0;
274 :
275 0 : i = 0;
276 0 : while (srcCount < srcSampleEnd)
277 : {
278 : float temp, vol1;
279 :
280 0 : vol1 = (1.0f- fract);
281 0 : for (int c = 0; c < numChannels; c ++)
282 : {
283 0 : temp = vol1 * src[c] + fract * src[c + numChannels];
284 0 : *dest = (SAMPLETYPE)temp;
285 0 : dest ++;
286 : }
287 0 : i++;
288 :
289 0 : fract += rate;
290 :
291 0 : int iWhole = (int)fract;
292 0 : fract -= iWhole;
293 0 : srcCount += iWhole;
294 0 : src += iWhole * numChannels;
295 : }
296 0 : srcSamples = srcCount;
297 :
298 0 : return i;
299 : }
|