InterpolateCubic.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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. #include <stddef.h>
  32. #include <math.h>
  33. #include "InterpolateCubic.h"
  34. #include "STTypes.h"
  35. using namespace soundtouch;
  36. // cubic interpolation coefficients
  37. static const float _coeffs[]=
  38. { -0.5f, 1.0f, -0.5f, 0.0f,
  39. 1.5f, -2.5f, 0.0f, 1.0f,
  40. -1.5f, 2.0f, 0.5f, 0.0f,
  41. 0.5f, -0.5f, 0.0f, 0.0f};
  42. InterpolateCubic::InterpolateCubic()
  43. {
  44. fract = 0;
  45. }
  46. void InterpolateCubic::resetRegisters()
  47. {
  48. fract = 0;
  49. }
  50. /// Transpose mono audio. Returns number of produced output samples, and
  51. /// updates "srcSamples" to amount of consumed source samples
  52. int InterpolateCubic::transposeMono(SAMPLETYPE *pdest,
  53. const SAMPLETYPE *psrc,
  54. int &srcSamples)
  55. {
  56. int i;
  57. int srcSampleEnd = srcSamples - 4;
  58. int srcCount = 0;
  59. i = 0;
  60. while (srcCount < srcSampleEnd)
  61. {
  62. float out;
  63. const float x3 = 1.0f;
  64. const float x2 = (float)fract; // x
  65. const float x1 = x2*x2; // x^2
  66. const float x0 = x1*x2; // x^3
  67. float y0, y1, y2, y3;
  68. assert(fract < 1.0);
  69. y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
  70. y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
  71. y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
  72. y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
  73. out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3];
  74. pdest[i] = (SAMPLETYPE)out;
  75. i ++;
  76. // update position fraction
  77. fract += rate;
  78. // update whole positions
  79. int whole = (int)fract;
  80. fract -= whole;
  81. psrc += whole;
  82. srcCount += whole;
  83. }
  84. srcSamples = srcCount;
  85. return i;
  86. }
  87. /// Transpose stereo audio. Returns number of produced output samples, and
  88. /// updates "srcSamples" to amount of consumed source samples
  89. int InterpolateCubic::transposeStereo(SAMPLETYPE *pdest,
  90. const SAMPLETYPE *psrc,
  91. int &srcSamples)
  92. {
  93. int i;
  94. int srcSampleEnd = srcSamples - 4;
  95. int srcCount = 0;
  96. i = 0;
  97. while (srcCount < srcSampleEnd)
  98. {
  99. const float x3 = 1.0f;
  100. const float x2 = (float)fract; // x
  101. const float x1 = x2*x2; // x^2
  102. const float x0 = x1*x2; // x^3
  103. float y0, y1, y2, y3;
  104. float out0, out1;
  105. assert(fract < 1.0);
  106. y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
  107. y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
  108. y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
  109. y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
  110. out0 = y0 * psrc[0] + y1 * psrc[2] + y2 * psrc[4] + y3 * psrc[6];
  111. out1 = y0 * psrc[1] + y1 * psrc[3] + y2 * psrc[5] + y3 * psrc[7];
  112. pdest[2*i] = (SAMPLETYPE)out0;
  113. pdest[2*i+1] = (SAMPLETYPE)out1;
  114. i ++;
  115. // update position fraction
  116. fract += rate;
  117. // update whole positions
  118. int whole = (int)fract;
  119. fract -= whole;
  120. psrc += 2*whole;
  121. srcCount += whole;
  122. }
  123. srcSamples = srcCount;
  124. return i;
  125. }
  126. /// Transpose multi-channel audio. Returns number of produced output samples, and
  127. /// updates "srcSamples" to amount of consumed source samples
  128. int InterpolateCubic::transposeMulti(SAMPLETYPE *pdest,
  129. const SAMPLETYPE *psrc,
  130. int &srcSamples)
  131. {
  132. int i;
  133. int srcSampleEnd = srcSamples - 4;
  134. int srcCount = 0;
  135. i = 0;
  136. while (srcCount < srcSampleEnd)
  137. {
  138. const float x3 = 1.0f;
  139. const float x2 = (float)fract; // x
  140. const float x1 = x2*x2; // x^2
  141. const float x0 = x1*x2; // x^3
  142. float y0, y1, y2, y3;
  143. assert(fract < 1.0);
  144. y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
  145. y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
  146. y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
  147. y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
  148. for (int c = 0; c < numChannels; c ++)
  149. {
  150. float out;
  151. out = y0 * psrc[c] + y1 * psrc[c + numChannels] + y2 * psrc[c + 2 * numChannels] + y3 * psrc[c + 3 * numChannels];
  152. pdest[0] = (SAMPLETYPE)out;
  153. pdest ++;
  154. }
  155. i ++;
  156. // update position fraction
  157. fract += rate;
  158. // update whole positions
  159. int whole = (int)fract;
  160. fract -= whole;
  161. psrc += numChannels*whole;
  162. srcCount += whole;
  163. }
  164. srcSamples = srcCount;
  165. return i;
  166. }