Bug 1879774 [wpt PR 44524] - WebKit export: Implement field-sizing support for input...
[gecko.git] / media / libsoundtouch / src / InterpolateShannon.cpp
blob975d872ad60327c60007e177c84921eba5777023
1 ////////////////////////////////////////////////////////////////////////////////
2 ///
3 /// Sample interpolation routine using 8-tap band-limited Shannon interpolation
4 /// with kaiser window.
5 ///
6 /// Notice. This algorithm is remarkably much heavier than linear or cubic
7 /// interpolation, and not remarkably better than cubic algorithm. Thus mostly
8 /// for experimental purposes
9 ///
10 /// Author : Copyright (c) Olli Parviainen
11 /// Author e-mail : oparviai 'at' iki.fi
12 /// SoundTouch WWW: http://www.surina.net/soundtouch
13 ///
14 ////////////////////////////////////////////////////////////////////////////////
16 // License :
18 // SoundTouch audio processing library
19 // Copyright (c) Olli Parviainen
21 // This library is free software; you can redistribute it and/or
22 // modify it under the terms of the GNU Lesser General Public
23 // License as published by the Free Software Foundation; either
24 // version 2.1 of the License, or (at your option) any later version.
26 // This library is distributed in the hope that it will be useful,
27 // but WITHOUT ANY WARRANTY; without even the implied warranty of
28 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 // Lesser General Public License for more details.
31 // You should have received a copy of the GNU Lesser General Public
32 // License along with this library; if not, write to the Free Software
33 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 ////////////////////////////////////////////////////////////////////////////////
37 #include <math.h>
38 #include "InterpolateShannon.h"
39 #include "STTypes.h"
41 using namespace soundtouch;
44 /// Kaiser window with beta = 2.0
45 /// Values scaled down by 5% to avoid overflows
46 static const double _kaiser8[8] =
48 0.41778693317814,
49 0.64888025049173,
50 0.83508562409944,
51 0.93887857733412,
52 0.93887857733412,
53 0.83508562409944,
54 0.64888025049173,
55 0.41778693317814
59 InterpolateShannon::InterpolateShannon()
61 fract = 0;
65 void InterpolateShannon::resetRegisters()
67 fract = 0;
71 #define PI 3.1415926536
72 #define sinc(x) (sin(PI * (x)) / (PI * (x)))
74 /// Transpose mono audio. Returns number of produced output samples, and
75 /// updates "srcSamples" to amount of consumed source samples
76 int InterpolateShannon::transposeMono(SAMPLETYPE *pdest,
77 const SAMPLETYPE *psrc,
78 int &srcSamples)
80 int i;
81 int srcSampleEnd = srcSamples - 8;
82 int srcCount = 0;
84 i = 0;
85 while (srcCount < srcSampleEnd)
87 double out;
88 assert(fract < 1.0);
90 out = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0];
91 out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1];
92 out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2];
93 if (fract < 1e-6)
95 out += psrc[3] * _kaiser8[3]; // sinc(0) = 1
97 else
99 out += psrc[3] * sinc(- fract) * _kaiser8[3];
101 out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4];
102 out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5];
103 out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6];
104 out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7];
106 pdest[i] = (SAMPLETYPE)out;
107 i ++;
109 // update position fraction
110 fract += rate;
111 // update whole positions
112 int whole = (int)fract;
113 fract -= whole;
114 psrc += whole;
115 srcCount += whole;
117 srcSamples = srcCount;
118 return i;
122 /// Transpose stereo audio. Returns number of produced output samples, and
123 /// updates "srcSamples" to amount of consumed source samples
124 int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest,
125 const SAMPLETYPE *psrc,
126 int &srcSamples)
128 int i;
129 int srcSampleEnd = srcSamples - 8;
130 int srcCount = 0;
132 i = 0;
133 while (srcCount < srcSampleEnd)
135 double out0, out1, w;
136 assert(fract < 1.0);
138 w = sinc(-3.0 - fract) * _kaiser8[0];
139 out0 = psrc[0] * w; out1 = psrc[1] * w;
140 w = sinc(-2.0 - fract) * _kaiser8[1];
141 out0 += psrc[2] * w; out1 += psrc[3] * w;
142 w = sinc(-1.0 - fract) * _kaiser8[2];
143 out0 += psrc[4] * w; out1 += psrc[5] * w;
144 w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract)); // sinc(0) = 1
145 out0 += psrc[6] * w; out1 += psrc[7] * w;
146 w = sinc( 1.0 - fract) * _kaiser8[4];
147 out0 += psrc[8] * w; out1 += psrc[9] * w;
148 w = sinc( 2.0 - fract) * _kaiser8[5];
149 out0 += psrc[10] * w; out1 += psrc[11] * w;
150 w = sinc( 3.0 - fract) * _kaiser8[6];
151 out0 += psrc[12] * w; out1 += psrc[13] * w;
152 w = sinc( 4.0 - fract) * _kaiser8[7];
153 out0 += psrc[14] * w; out1 += psrc[15] * w;
155 pdest[2*i] = (SAMPLETYPE)out0;
156 pdest[2*i+1] = (SAMPLETYPE)out1;
157 i ++;
159 // update position fraction
160 fract += rate;
161 // update whole positions
162 int whole = (int)fract;
163 fract -= whole;
164 psrc += 2*whole;
165 srcCount += whole;
167 srcSamples = srcCount;
168 return i;
172 /// Transpose stereo audio. Returns number of produced output samples, and
173 /// updates "srcSamples" to amount of consumed source samples
174 int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest,
175 const SAMPLETYPE *psrc,
176 int &srcSamples)
178 // not implemented
179 assert(false);
180 return 0;