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 /// Cubic interpolation routine.
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: InterpolateCubic.cpp 179 2014-01-06 18:41:42Z 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 <stddef.h>
37 #include <math.h>
38 #include "InterpolateCubic.h"
39 #include "STTypes.h"
41 using namespace soundtouch;
43 // cubic interpolation coefficients
44 static const float _coeffs[]=
45 { -0.5f, 1.0f, -0.5f, 0.0f,
46 1.5f, -2.5f, 0.0f, 1.0f,
47 -1.5f, 2.0f, 0.5f, 0.0f,
48 0.5f, -0.5f, 0.0f, 0.0f};
51 InterpolateCubic::InterpolateCubic()
52 {
53 fract = 0;
54 }
57 void InterpolateCubic::resetRegisters()
58 {
59 fract = 0;
60 }
63 /// Transpose mono audio. Returns number of produced output samples, and
64 /// updates "srcSamples" to amount of consumed source samples
65 int InterpolateCubic::transposeMono(SAMPLETYPE *pdest,
66 const SAMPLETYPE *psrc,
67 int &srcSamples)
68 {
69 int i;
70 int srcSampleEnd = srcSamples - 4;
71 int srcCount = 0;
73 i = 0;
74 while (srcCount < srcSampleEnd)
75 {
76 float out;
77 const float x3 = 1.0f;
78 const float x2 = (float)fract; // x
79 const float x1 = x2*x2; // x^2
80 const float x0 = x1*x2; // x^3
81 float y0, y1, y2, y3;
83 assert(fract < 1.0);
85 y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
86 y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
87 y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
88 y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
90 out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3];
92 pdest[i] = (SAMPLETYPE)out;
93 i ++;
95 // update position fraction
96 fract += rate;
97 // update whole positions
98 int whole = (int)fract;
99 fract -= whole;
100 psrc += whole;
101 srcCount += whole;
102 }
103 srcSamples = srcCount;
104 return i;
105 }
108 /// Transpose stereo audio. Returns number of produced output samples, and
109 /// updates "srcSamples" to amount of consumed source samples
110 int InterpolateCubic::transposeStereo(SAMPLETYPE *pdest,
111 const SAMPLETYPE *psrc,
112 int &srcSamples)
113 {
114 int i;
115 int srcSampleEnd = srcSamples - 4;
116 int srcCount = 0;
118 i = 0;
119 while (srcCount < srcSampleEnd)
120 {
121 const float x3 = 1.0f;
122 const float x2 = (float)fract; // x
123 const float x1 = x2*x2; // x^2
124 const float x0 = x1*x2; // x^3
125 float y0, y1, y2, y3;
126 float out0, out1;
128 assert(fract < 1.0);
130 y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
131 y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
132 y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
133 y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
135 out0 = y0 * psrc[0] + y1 * psrc[2] + y2 * psrc[4] + y3 * psrc[6];
136 out1 = y0 * psrc[1] + y1 * psrc[3] + y2 * psrc[5] + y3 * psrc[7];
138 pdest[2*i] = (SAMPLETYPE)out0;
139 pdest[2*i+1] = (SAMPLETYPE)out1;
140 i ++;
142 // update position fraction
143 fract += rate;
144 // update whole positions
145 int whole = (int)fract;
146 fract -= whole;
147 psrc += 2*whole;
148 srcCount += whole;
149 }
150 srcSamples = srcCount;
151 return i;
152 }
155 /// Transpose multi-channel audio. Returns number of produced output samples, and
156 /// updates "srcSamples" to amount of consumed source samples
157 int InterpolateCubic::transposeMulti(SAMPLETYPE *pdest,
158 const SAMPLETYPE *psrc,
159 int &srcSamples)
160 {
161 int i;
162 int srcSampleEnd = srcSamples - 4;
163 int srcCount = 0;
165 i = 0;
166 while (srcCount < srcSampleEnd)
167 {
168 const float x3 = 1.0f;
169 const float x2 = (float)fract; // x
170 const float x1 = x2*x2; // x^2
171 const float x0 = x1*x2; // x^3
172 float y0, y1, y2, y3;
174 assert(fract < 1.0);
176 y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
177 y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
178 y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
179 y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
181 for (int c = 0; c < numChannels; c ++)
182 {
183 float out;
184 out = y0 * psrc[c] + y1 * psrc[c + numChannels] + y2 * psrc[c + 2 * numChannels] + y3 * psrc[c + 3 * numChannels];
185 pdest[0] = (SAMPLETYPE)out;
186 pdest ++;
187 }
188 i ++;
190 // update position fraction
191 fract += rate;
192 // update whole positions
193 int whole = (int)fract;
194 fract -= whole;
195 psrc += numChannels*whole;
196 srcCount += whole;
197 }
198 srcSamples = srcCount;
199 return i;
200 }