InterpolateCubic.cpp (6166B)
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 // License : 12 // 13 // SoundTouch audio processing library 14 // Copyright (c) Olli Parviainen 15 // 16 // This library is free software; you can redistribute it and/or 17 // modify it under the terms of the GNU Lesser General Public 18 // License as published by the Free Software Foundation; either 19 // version 2.1 of the License, or (at your option) any later version. 20 // 21 // This library is distributed in the hope that it will be useful, 22 // but WITHOUT ANY WARRANTY; without even the implied warranty of 23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 // Lesser General Public License for more details. 25 // 26 // You should have received a copy of the GNU Lesser General Public 27 // License along with this library; if not, write to the Free Software 28 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29 // 30 //////////////////////////////////////////////////////////////////////////////// 31 32 #include <stddef.h> 33 #include <math.h> 34 #include "InterpolateCubic.h" 35 #include "STTypes.h" 36 37 using namespace soundtouch; 38 39 // cubic interpolation coefficients 40 static const float _coeffs[]= 41 { -0.5f, 1.0f, -0.5f, 0.0f, 42 1.5f, -2.5f, 0.0f, 1.0f, 43 -1.5f, 2.0f, 0.5f, 0.0f, 44 0.5f, -0.5f, 0.0f, 0.0f}; 45 46 47 InterpolateCubic::InterpolateCubic() 48 { 49 fract = 0; 50 } 51 52 53 void InterpolateCubic::resetRegisters() 54 { 55 fract = 0; 56 } 57 58 59 /// Transpose mono audio. Returns number of produced output samples, and 60 /// updates "srcSamples" to amount of consumed source samples 61 int InterpolateCubic::transposeMono(SAMPLETYPE *pdest, 62 const SAMPLETYPE *psrc, 63 int &srcSamples) 64 { 65 int i; 66 int srcSampleEnd = srcSamples - 4; 67 int srcCount = 0; 68 69 i = 0; 70 while (srcCount < srcSampleEnd) 71 { 72 float out; 73 const float x3 = 1.0f; 74 const float x2 = (float)fract; // x 75 const float x1 = x2*x2; // x^2 76 const float x0 = x1*x2; // x^3 77 float y0, y1, y2, y3; 78 79 assert(fract < 1.0); 80 81 y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3; 82 y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3; 83 y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3; 84 y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3; 85 86 out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3]; 87 88 pdest[i] = (SAMPLETYPE)out; 89 i ++; 90 91 // update position fraction 92 fract += rate; 93 // update whole positions 94 int whole = (int)fract; 95 fract -= whole; 96 psrc += whole; 97 srcCount += whole; 98 } 99 srcSamples = srcCount; 100 return i; 101 } 102 103 104 /// Transpose stereo audio. Returns number of produced output samples, and 105 /// updates "srcSamples" to amount of consumed source samples 106 int InterpolateCubic::transposeStereo(SAMPLETYPE *pdest, 107 const SAMPLETYPE *psrc, 108 int &srcSamples) 109 { 110 int i; 111 int srcSampleEnd = srcSamples - 4; 112 int srcCount = 0; 113 114 i = 0; 115 while (srcCount < srcSampleEnd) 116 { 117 const float x3 = 1.0f; 118 const float x2 = (float)fract; // x 119 const float x1 = x2*x2; // x^2 120 const float x0 = x1*x2; // x^3 121 float y0, y1, y2, y3; 122 float out0, out1; 123 124 assert(fract < 1.0); 125 126 y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3; 127 y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3; 128 y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3; 129 y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3; 130 131 out0 = y0 * psrc[0] + y1 * psrc[2] + y2 * psrc[4] + y3 * psrc[6]; 132 out1 = y0 * psrc[1] + y1 * psrc[3] + y2 * psrc[5] + y3 * psrc[7]; 133 134 pdest[2*i] = (SAMPLETYPE)out0; 135 pdest[2*i+1] = (SAMPLETYPE)out1; 136 i ++; 137 138 // update position fraction 139 fract += rate; 140 // update whole positions 141 int whole = (int)fract; 142 fract -= whole; 143 psrc += 2*whole; 144 srcCount += whole; 145 } 146 srcSamples = srcCount; 147 return i; 148 } 149 150 151 /// Transpose multi-channel audio. Returns number of produced output samples, and 152 /// updates "srcSamples" to amount of consumed source samples 153 int InterpolateCubic::transposeMulti(SAMPLETYPE *pdest, 154 const SAMPLETYPE *psrc, 155 int &srcSamples) 156 { 157 int i; 158 int srcSampleEnd = srcSamples - 4; 159 int srcCount = 0; 160 161 i = 0; 162 while (srcCount < srcSampleEnd) 163 { 164 const float x3 = 1.0f; 165 const float x2 = (float)fract; // x 166 const float x1 = x2*x2; // x^2 167 const float x0 = x1*x2; // x^3 168 float y0, y1, y2, y3; 169 170 assert(fract < 1.0); 171 172 y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3; 173 y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3; 174 y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3; 175 y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3; 176 177 for (int c = 0; c < numChannels; c ++) 178 { 179 float out; 180 out = y0 * psrc[c] + y1 * psrc[c + numChannels] + y2 * psrc[c + 2 * numChannels] + y3 * psrc[c + 3 * numChannels]; 181 pdest[0] = (SAMPLETYPE)out; 182 pdest ++; 183 } 184 i ++; 185 186 // update position fraction 187 fract += rate; 188 // update whole positions 189 int whole = (int)fract; 190 fract -= whole; 191 psrc += numChannels*whole; 192 srcCount += whole; 193 } 194 srcSamples = srcCount; 195 return i; 196 }