Line data Source code
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 0 : InterpolateCubic::InterpolateCubic()
52 : {
53 0 : fract = 0;
54 0 : }
55 :
56 :
57 0 : void InterpolateCubic::resetRegisters()
58 : {
59 0 : fract = 0;
60 0 : }
61 :
62 :
63 : /// Transpose mono audio. Returns number of produced output samples, and
64 : /// updates "srcSamples" to amount of consumed source samples
65 0 : int InterpolateCubic::transposeMono(SAMPLETYPE *pdest,
66 : const SAMPLETYPE *psrc,
67 : int &srcSamples)
68 : {
69 : int i;
70 0 : int srcSampleEnd = srcSamples - 4;
71 0 : int srcCount = 0;
72 :
73 0 : i = 0;
74 0 : while (srcCount < srcSampleEnd)
75 : {
76 : float out;
77 0 : const float x3 = 1.0f;
78 0 : const float x2 = (float)fract; // x
79 0 : const float x1 = x2*x2; // x^2
80 0 : const float x0 = x1*x2; // x^3
81 : float y0, y1, y2, y3;
82 :
83 0 : assert(fract < 1.0);
84 :
85 0 : y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
86 0 : y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
87 0 : y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
88 0 : y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
89 :
90 0 : out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3];
91 :
92 0 : pdest[i] = (SAMPLETYPE)out;
93 0 : i ++;
94 :
95 : // update position fraction
96 0 : fract += rate;
97 : // update whole positions
98 0 : int whole = (int)fract;
99 0 : fract -= whole;
100 0 : psrc += whole;
101 0 : srcCount += whole;
102 : }
103 0 : srcSamples = srcCount;
104 0 : 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 0 : int InterpolateCubic::transposeStereo(SAMPLETYPE *pdest,
111 : const SAMPLETYPE *psrc,
112 : int &srcSamples)
113 : {
114 : int i;
115 0 : int srcSampleEnd = srcSamples - 4;
116 0 : int srcCount = 0;
117 :
118 0 : i = 0;
119 0 : while (srcCount < srcSampleEnd)
120 : {
121 0 : const float x3 = 1.0f;
122 0 : const float x2 = (float)fract; // x
123 0 : const float x1 = x2*x2; // x^2
124 0 : const float x0 = x1*x2; // x^3
125 : float y0, y1, y2, y3;
126 : float out0, out1;
127 :
128 0 : assert(fract < 1.0);
129 :
130 0 : y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
131 0 : y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
132 0 : y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
133 0 : y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
134 :
135 0 : out0 = y0 * psrc[0] + y1 * psrc[2] + y2 * psrc[4] + y3 * psrc[6];
136 0 : out1 = y0 * psrc[1] + y1 * psrc[3] + y2 * psrc[5] + y3 * psrc[7];
137 :
138 0 : pdest[2*i] = (SAMPLETYPE)out0;
139 0 : pdest[2*i+1] = (SAMPLETYPE)out1;
140 0 : i ++;
141 :
142 : // update position fraction
143 0 : fract += rate;
144 : // update whole positions
145 0 : int whole = (int)fract;
146 0 : fract -= whole;
147 0 : psrc += 2*whole;
148 0 : srcCount += whole;
149 : }
150 0 : srcSamples = srcCount;
151 0 : 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 0 : int InterpolateCubic::transposeMulti(SAMPLETYPE *pdest,
158 : const SAMPLETYPE *psrc,
159 : int &srcSamples)
160 : {
161 : int i;
162 0 : int srcSampleEnd = srcSamples - 4;
163 0 : int srcCount = 0;
164 :
165 0 : i = 0;
166 0 : while (srcCount < srcSampleEnd)
167 : {
168 0 : const float x3 = 1.0f;
169 0 : const float x2 = (float)fract; // x
170 0 : const float x1 = x2*x2; // x^2
171 0 : const float x0 = x1*x2; // x^3
172 : float y0, y1, y2, y3;
173 :
174 0 : assert(fract < 1.0);
175 :
176 0 : y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
177 0 : y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
178 0 : y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
179 0 : y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
180 :
181 0 : for (int c = 0; c < numChannels; c ++)
182 : {
183 : float out;
184 0 : out = y0 * psrc[c] + y1 * psrc[c + numChannels] + y2 * psrc[c + 2 * numChannels] + y3 * psrc[c + 3 * numChannels];
185 0 : pdest[0] = (SAMPLETYPE)out;
186 0 : pdest ++;
187 : }
188 0 : i ++;
189 :
190 : // update position fraction
191 0 : fract += rate;
192 : // update whole positions
193 0 : int whole = (int)fract;
194 0 : fract -= whole;
195 0 : psrc += numChannels*whole;
196 0 : srcCount += whole;
197 : }
198 0 : srcSamples = srcCount;
199 0 : return i;
200 : }
|