|
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 //////////////////////////////////////////////////////////////////////////////// |
|
35 |
|
36 #include <stddef.h> |
|
37 #include <math.h> |
|
38 #include "InterpolateCubic.h" |
|
39 #include "STTypes.h" |
|
40 |
|
41 using namespace soundtouch; |
|
42 |
|
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}; |
|
49 |
|
50 |
|
51 InterpolateCubic::InterpolateCubic() |
|
52 { |
|
53 fract = 0; |
|
54 } |
|
55 |
|
56 |
|
57 void InterpolateCubic::resetRegisters() |
|
58 { |
|
59 fract = 0; |
|
60 } |
|
61 |
|
62 |
|
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; |
|
72 |
|
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; |
|
82 |
|
83 assert(fract < 1.0); |
|
84 |
|
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; |
|
89 |
|
90 out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3]; |
|
91 |
|
92 pdest[i] = (SAMPLETYPE)out; |
|
93 i ++; |
|
94 |
|
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 } |
|
106 |
|
107 |
|
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; |
|
117 |
|
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; |
|
127 |
|
128 assert(fract < 1.0); |
|
129 |
|
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; |
|
134 |
|
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]; |
|
137 |
|
138 pdest[2*i] = (SAMPLETYPE)out0; |
|
139 pdest[2*i+1] = (SAMPLETYPE)out1; |
|
140 i ++; |
|
141 |
|
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 } |
|
153 |
|
154 |
|
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; |
|
164 |
|
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; |
|
173 |
|
174 assert(fract < 1.0); |
|
175 |
|
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; |
|
180 |
|
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 ++; |
|
189 |
|
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 } |