InterpolateLinear.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. ////////////////////////////////////////////////////////////////////////////////
  2. ///
  3. /// Linear interpolation algorithm.
  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 <assert.h>
  32. #include <stdlib.h>
  33. #include "InterpolateLinear.h"
  34. using namespace soundtouch;
  35. //////////////////////////////////////////////////////////////////////////////
  36. //
  37. // InterpolateLinearInteger - integer arithmetic implementation
  38. //
  39. /// fixed-point interpolation routine precision
  40. #define SCALE 65536
  41. // Constructor
  42. InterpolateLinearInteger::InterpolateLinearInteger() : TransposerBase()
  43. {
  44. // Notice: use local function calling syntax for sake of clarity,
  45. // to indicate the fact that C++ constructor can't call virtual functions.
  46. resetRegisters();
  47. setRate(1.0f);
  48. }
  49. void InterpolateLinearInteger::resetRegisters()
  50. {
  51. iFract = 0;
  52. }
  53. // Transposes the sample rate of the given samples using linear interpolation.
  54. // 'Mono' version of the routine. Returns the number of samples returned in
  55. // the "dest" buffer
  56. int InterpolateLinearInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
  57. {
  58. int i;
  59. int srcSampleEnd = srcSamples - 1;
  60. int srcCount = 0;
  61. i = 0;
  62. while (srcCount < srcSampleEnd)
  63. {
  64. LONG_SAMPLETYPE temp;
  65. assert(iFract < SCALE);
  66. temp = (SCALE - iFract) * src[0] + iFract * src[1];
  67. dest[i] = (SAMPLETYPE)(temp / SCALE);
  68. i++;
  69. iFract += iRate;
  70. int iWhole = iFract / SCALE;
  71. iFract -= iWhole * SCALE;
  72. srcCount += iWhole;
  73. src += iWhole;
  74. }
  75. srcSamples = srcCount;
  76. return i;
  77. }
  78. // Transposes the sample rate of the given samples using linear interpolation.
  79. // 'Stereo' version of the routine. Returns the number of samples returned in
  80. // the "dest" buffer
  81. int InterpolateLinearInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
  82. {
  83. int i;
  84. int srcSampleEnd = srcSamples - 1;
  85. int srcCount = 0;
  86. i = 0;
  87. while (srcCount < srcSampleEnd)
  88. {
  89. LONG_SAMPLETYPE temp0;
  90. LONG_SAMPLETYPE temp1;
  91. assert(iFract < SCALE);
  92. temp0 = (SCALE - iFract) * src[0] + iFract * src[2];
  93. temp1 = (SCALE - iFract) * src[1] + iFract * src[3];
  94. dest[0] = (SAMPLETYPE)(temp0 / SCALE);
  95. dest[1] = (SAMPLETYPE)(temp1 / SCALE);
  96. dest += 2;
  97. i++;
  98. iFract += iRate;
  99. int iWhole = iFract / SCALE;
  100. iFract -= iWhole * SCALE;
  101. srcCount += iWhole;
  102. src += 2*iWhole;
  103. }
  104. srcSamples = srcCount;
  105. return i;
  106. }
  107. int InterpolateLinearInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
  108. {
  109. int i;
  110. int srcSampleEnd = srcSamples - 1;
  111. int srcCount = 0;
  112. i = 0;
  113. while (srcCount < srcSampleEnd)
  114. {
  115. LONG_SAMPLETYPE temp, vol1;
  116. assert(iFract < SCALE);
  117. vol1 = (LONG_SAMPLETYPE)(SCALE - iFract);
  118. for (int c = 0; c < numChannels; c ++)
  119. {
  120. temp = vol1 * src[c] + iFract * src[c + numChannels];
  121. dest[0] = (SAMPLETYPE)(temp / SCALE);
  122. dest ++;
  123. }
  124. i++;
  125. iFract += iRate;
  126. int iWhole = iFract / SCALE;
  127. iFract -= iWhole * SCALE;
  128. srcCount += iWhole;
  129. src += iWhole * numChannels;
  130. }
  131. srcSamples = srcCount;
  132. return i;
  133. }
  134. // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
  135. // iRate, larger faster iRates.
  136. void InterpolateLinearInteger::setRate(double newRate)
  137. {
  138. iRate = (int)(newRate * SCALE + 0.5);
  139. TransposerBase::setRate(newRate);
  140. }
  141. //////////////////////////////////////////////////////////////////////////////
  142. //
  143. // InterpolateLinearFloat - floating point arithmetic implementation
  144. //
  145. //////////////////////////////////////////////////////////////////////////////
  146. // Constructor
  147. InterpolateLinearFloat::InterpolateLinearFloat() : TransposerBase()
  148. {
  149. // Notice: use local function calling syntax for sake of clarity,
  150. // to indicate the fact that C++ constructor can't call virtual functions.
  151. resetRegisters();
  152. setRate(1.0);
  153. }
  154. void InterpolateLinearFloat::resetRegisters()
  155. {
  156. fract = 0;
  157. }
  158. // Transposes the sample rate of the given samples using linear interpolation.
  159. // 'Mono' version of the routine. Returns the number of samples returned in
  160. // the "dest" buffer
  161. int InterpolateLinearFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
  162. {
  163. int i;
  164. int srcSampleEnd = srcSamples - 1;
  165. int srcCount = 0;
  166. i = 0;
  167. while (srcCount < srcSampleEnd)
  168. {
  169. double out;
  170. assert(fract < 1.0);
  171. out = (1.0 - fract) * src[0] + fract * src[1];
  172. dest[i] = (SAMPLETYPE)out;
  173. i ++;
  174. // update position fraction
  175. fract += rate;
  176. // update whole positions
  177. int whole = (int)fract;
  178. fract -= whole;
  179. src += whole;
  180. srcCount += whole;
  181. }
  182. srcSamples = srcCount;
  183. return i;
  184. }
  185. // Transposes the sample rate of the given samples using linear interpolation.
  186. // 'Mono' version of the routine. Returns the number of samples returned in
  187. // the "dest" buffer
  188. int InterpolateLinearFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
  189. {
  190. int i;
  191. int srcSampleEnd = srcSamples - 1;
  192. int srcCount = 0;
  193. i = 0;
  194. while (srcCount < srcSampleEnd)
  195. {
  196. double out0, out1;
  197. assert(fract < 1.0);
  198. out0 = (1.0 - fract) * src[0] + fract * src[2];
  199. out1 = (1.0 - fract) * src[1] + fract * src[3];
  200. dest[2*i] = (SAMPLETYPE)out0;
  201. dest[2*i+1] = (SAMPLETYPE)out1;
  202. i ++;
  203. // update position fraction
  204. fract += rate;
  205. // update whole positions
  206. int whole = (int)fract;
  207. fract -= whole;
  208. src += 2*whole;
  209. srcCount += whole;
  210. }
  211. srcSamples = srcCount;
  212. return i;
  213. }
  214. int InterpolateLinearFloat::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
  215. {
  216. int i;
  217. int srcSampleEnd = srcSamples - 1;
  218. int srcCount = 0;
  219. i = 0;
  220. while (srcCount < srcSampleEnd)
  221. {
  222. float temp, vol1, fract_float;
  223. vol1 = (float)(1.0 - fract);
  224. fract_float = (float)fract;
  225. for (int c = 0; c < numChannels; c ++)
  226. {
  227. temp = vol1 * src[c] + fract_float * src[c + numChannels];
  228. *dest = (SAMPLETYPE)temp;
  229. dest ++;
  230. }
  231. i++;
  232. fract += rate;
  233. int iWhole = (int)fract;
  234. fract -= iWhole;
  235. srcCount += iWhole;
  236. src += iWhole * numChannels;
  237. }
  238. srcSamples = srcCount;
  239. return i;
  240. }