1 ////////////////////////////////////////////////////////////////////////////////
3 /// Sample interpolation routine using 8-tap band-limited Shannon interpolation
4 /// with kaiser window.
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
10 /// Author : Copyright (c) Olli Parviainen
11 /// Author e-mail : oparviai 'at' iki.fi
12 /// SoundTouch WWW: http://www.surina.net/soundtouch
14 ////////////////////////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////////////////////////
38 #include "InterpolateShannon.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] =
59 InterpolateShannon::InterpolateShannon()
65 void InterpolateShannon::resetRegisters()
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
,
81 int srcSampleEnd
= srcSamples
- 8;
85 while (srcCount
< srcSampleEnd
)
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];
95 out
+= psrc
[3] * _kaiser8
[3]; // sinc(0) = 1
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
;
109 // update position fraction
111 // update whole positions
112 int whole
= (int)fract
;
117 srcSamples
= srcCount
;
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
,
129 int srcSampleEnd
= srcSamples
- 8;
133 while (srcCount
< srcSampleEnd
)
135 double out0
, out1
, w
;
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
;
159 // update position fraction
161 // update whole positions
162 int whole
= (int)fract
;
167 srcSamples
= srcCount
;
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
,