smbPitchShift.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /****************************************************************************
  2. *
  3. * NAME: smbPitchShift.cpp
  4. * VERSION: 1.2
  5. * HOME URL: http://blogs.zynaptiq.com/bernsee
  6. * KNOWN BUGS: none
  7. *
  8. * SYNOPSIS: Routine for doing pitch shifting while maintaining
  9. * duration using the Short Time Fourier Transform.
  10. *
  11. * DESCRIPTION: The routine takes a pitchShift factor value which is between 0.5
  12. * (one octave down) and 2. (one octave up). A value of exactly 1 does not change
  13. * the pitch. numSampsToProcess tells the routine how many samples in indata[0...
  14. * numSampsToProcess-1] should be pitch shifted and moved to outdata[0 ...
  15. * numSampsToProcess-1]. The two buffers can be identical (ie. it can process the
  16. * data in-place). fftFrameSize defines the FFT frame size used for the
  17. * processing. Typical values are 1024, 2048 and 4096. It may be any value <=
  18. * MAX_FRAME_LENGTH but it MUST be a power of 2. osamp is the STFT
  19. * oversampling factor which also determines the overlap between adjacent STFT
  20. * frames. It should at least be 4 for moderate scaling ratios. A value of 32 is
  21. * recommended for best quality. sampleRate takes the sample rate for the signal
  22. * in unit Hz, ie. 44100 for 44.1 kHz audio. The data passed to the routine in
  23. * indata[] should be in the range [-1.0, 1.0), which is also the output range
  24. * for the data, make sure you scale the data accordingly (for 16bit signed integers
  25. * you would have to divide (and multiply) by 32768).
  26. *
  27. * COPYRIGHT 1999-2015 Stephan M. Bernsee <s.bernsee [AT] zynaptiq [DOT] com>
  28. *
  29. * The Wide Open License (WOL)
  30. *
  31. * Permission to use, copy, modify, distribute and sell this software and its
  32. * documentation for any purpose is hereby granted without fee, provided that
  33. * the above copyright notice and this license appear in all source copies.
  34. * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
  35. * ANY KIND. See http://www.dspguru.com/wol.htm for more information.
  36. *
  37. *****************************************************************************/
  38. #include "smbPitchShift.h" // OpenMPT
  39. #include <string.h>
  40. #include <math.h>
  41. #include <stdio.h>
  42. #define M_PI 3.14159265358979323846
  43. #if 0 // OpenMPT
  44. #define MAX_FRAME_LENGTH 8192
  45. #endif // OpenMPT
  46. void smbFft(float *fftBuffer, long fftFrameSize, long sign);
  47. double smbAtan2(double x, double y);
  48. // -----------------------------------------------------------------------------------------------------------------
  49. void smbPitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata)
  50. /*
  51. Routine smbPitchShift(). See top of file for explanation
  52. Purpose: doing pitch shifting while maintaining duration using the Short
  53. Time Fourier Transform.
  54. Author: (c)1999-2015 Stephan M. Bernsee <s.bernsee [AT] zynaptiq [DOT] com>
  55. */
  56. {
  57. static float gInFIFO[MAX_FRAME_LENGTH];
  58. static float gOutFIFO[MAX_FRAME_LENGTH];
  59. static float gFFTworksp[2*MAX_FRAME_LENGTH];
  60. static float gLastPhase[MAX_FRAME_LENGTH/2+1];
  61. static float gSumPhase[MAX_FRAME_LENGTH/2+1];
  62. static float gOutputAccum[2*MAX_FRAME_LENGTH];
  63. static float gAnaFreq[MAX_FRAME_LENGTH];
  64. static float gAnaMagn[MAX_FRAME_LENGTH];
  65. static float gSynFreq[MAX_FRAME_LENGTH];
  66. static float gSynMagn[MAX_FRAME_LENGTH];
  67. static long gRover = false, gInit = false;
  68. double magn, phase, tmp, window, real, imag;
  69. double freqPerBin, expct;
  70. long i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
  71. /* set up some handy variables */
  72. fftFrameSize2 = fftFrameSize/2;
  73. stepSize = fftFrameSize/osamp;
  74. freqPerBin = sampleRate/(double)fftFrameSize;
  75. expct = 2.*M_PI*(double)stepSize/(double)fftFrameSize;
  76. inFifoLatency = fftFrameSize-stepSize;
  77. if (gRover == false) gRover = inFifoLatency;
  78. /* initialize our static arrays */
  79. if (gInit == false) {
  80. memset(gInFIFO, 0, MAX_FRAME_LENGTH*sizeof(float));
  81. memset(gOutFIFO, 0, MAX_FRAME_LENGTH*sizeof(float));
  82. memset(gFFTworksp, 0, 2*MAX_FRAME_LENGTH*sizeof(float));
  83. memset(gLastPhase, 0, (MAX_FRAME_LENGTH/2+1)*sizeof(float));
  84. memset(gSumPhase, 0, (MAX_FRAME_LENGTH/2+1)*sizeof(float));
  85. memset(gOutputAccum, 0, 2*MAX_FRAME_LENGTH*sizeof(float));
  86. memset(gAnaFreq, 0, MAX_FRAME_LENGTH*sizeof(float));
  87. memset(gAnaMagn, 0, MAX_FRAME_LENGTH*sizeof(float));
  88. gInit = true;
  89. }
  90. /* main processing loop */
  91. for (i = 0; i < numSampsToProcess; i++){
  92. /* As long as we have not yet collected enough data just read in */
  93. gInFIFO[gRover] = indata[i];
  94. outdata[i] = gOutFIFO[gRover-inFifoLatency];
  95. gRover++;
  96. /* now we have enough data for processing */
  97. if (gRover >= fftFrameSize) {
  98. gRover = inFifoLatency;
  99. /* do windowing and re,im interleave */
  100. for (k = 0; k < fftFrameSize;k++) {
  101. window = -.5*cos(2.*M_PI*(double)k/(double)fftFrameSize)+.5;
  102. gFFTworksp[2*k] = gInFIFO[k] * window;
  103. gFFTworksp[2*k+1] = 0.;
  104. }
  105. /* ***************** ANALYSIS ******************* */
  106. /* do transform */
  107. smbFft(gFFTworksp, fftFrameSize, -1);
  108. /* this is the analysis step */
  109. for (k = 0; k <= fftFrameSize2; k++) {
  110. /* de-interlace FFT buffer */
  111. real = gFFTworksp[2*k];
  112. imag = gFFTworksp[2*k+1];
  113. /* compute magnitude and phase */
  114. magn = 2.*sqrt(real*real + imag*imag);
  115. phase = atan2(imag,real);
  116. /* compute phase difference */
  117. tmp = phase - gLastPhase[k];
  118. gLastPhase[k] = phase;
  119. /* subtract expected phase difference */
  120. tmp -= (double)k*expct;
  121. /* map delta phase into +/- Pi interval */
  122. qpd = tmp/M_PI;
  123. if (qpd >= 0) qpd += qpd&1;
  124. else qpd -= qpd&1;
  125. tmp -= M_PI*(double)qpd;
  126. /* get deviation from bin frequency from the +/- Pi interval */
  127. tmp = osamp*tmp/(2.*M_PI);
  128. /* compute the k-th partials' true frequency */
  129. tmp = (double)k*freqPerBin + tmp*freqPerBin;
  130. /* store magnitude and true frequency in analysis arrays */
  131. gAnaMagn[k] = magn;
  132. gAnaFreq[k] = tmp;
  133. }
  134. /* ***************** PROCESSING ******************* */
  135. /* this does the actual pitch shifting */
  136. memset(gSynMagn, 0, fftFrameSize*sizeof(float));
  137. memset(gSynFreq, 0, fftFrameSize*sizeof(float));
  138. for (k = 0; k <= fftFrameSize2; k++) {
  139. index = k*pitchShift;
  140. if (index <= fftFrameSize2) {
  141. gSynMagn[index] += gAnaMagn[k];
  142. gSynFreq[index] = gAnaFreq[k] * pitchShift;
  143. }
  144. }
  145. /* ***************** SYNTHESIS ******************* */
  146. /* this is the synthesis step */
  147. for (k = 0; k <= fftFrameSize2; k++) {
  148. /* get magnitude and true frequency from synthesis arrays */
  149. magn = gSynMagn[k];
  150. tmp = gSynFreq[k];
  151. /* subtract bin mid frequency */
  152. tmp -= (double)k*freqPerBin;
  153. /* get bin deviation from freq deviation */
  154. tmp /= freqPerBin;
  155. /* take osamp into account */
  156. tmp = 2.*M_PI*tmp/osamp;
  157. /* add the overlap phase advance back in */
  158. tmp += (double)k*expct;
  159. /* accumulate delta phase to get bin phase */
  160. gSumPhase[k] += tmp;
  161. phase = gSumPhase[k];
  162. /* get real and imag part and re-interleave */
  163. gFFTworksp[2*k] = magn*cos(phase);
  164. gFFTworksp[2*k+1] = magn*sin(phase);
  165. }
  166. /* zero negative frequencies */
  167. for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) gFFTworksp[k] = 0.;
  168. /* do inverse transform */
  169. smbFft(gFFTworksp, fftFrameSize, 1);
  170. /* do windowing and add to output accumulator */
  171. for(k=0; k < fftFrameSize; k++) {
  172. window = -.5*cos(2.*M_PI*(double)k/(double)fftFrameSize)+.5;
  173. gOutputAccum[k] += 2.*window*gFFTworksp[2*k]/(fftFrameSize2*osamp);
  174. }
  175. for (k = 0; k < stepSize; k++) gOutFIFO[k] = gOutputAccum[k];
  176. /* shift accumulator */
  177. memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float));
  178. /* move input FIFO */
  179. for (k = 0; k < inFifoLatency; k++) gInFIFO[k] = gInFIFO[k+stepSize];
  180. }
  181. }
  182. }
  183. // -----------------------------------------------------------------------------------------------------------------
  184. void smbFft(float *fftBuffer, long fftFrameSize, long sign)
  185. /*
  186. FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse)
  187. Fills fftBuffer[0...2*fftFrameSize-1] with the Fourier transform of the
  188. time domain data in fftBuffer[0...2*fftFrameSize-1]. The FFT array takes
  189. and returns the cosine and sine parts in an interleaved manner, ie.
  190. fftBuffer[0] = cosPart[0], fftBuffer[1] = sinPart[0], asf. fftFrameSize
  191. must be a power of 2. It expects a complex input signal (see footnote 2),
  192. ie. when working with 'common' audio signals our input signal has to be
  193. passed as {in[0],0.,in[1],0.,in[2],0.,...} asf. In that case, the transform
  194. of the frequencies of interest is in fftBuffer[0...fftFrameSize].
  195. */
  196. {
  197. float wr, wi, arg, *p1, *p2, temp;
  198. float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
  199. long i, bitm, j, le, le2, k;
  200. for (i = 2; i < 2*fftFrameSize-2; i += 2) {
  201. for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) {
  202. if (i & bitm) j++;
  203. j <<= 1;
  204. }
  205. if (i < j) {
  206. p1 = fftBuffer+i; p2 = fftBuffer+j;
  207. temp = *p1; *(p1++) = *p2;
  208. *(p2++) = temp; temp = *p1;
  209. *p1 = *p2; *p2 = temp;
  210. }
  211. }
  212. #if 0 // OpenMPT
  213. for (k = 0, le = 2; k < (long)(log(fftFrameSize)/log(2.)+.5); k++) {
  214. #else // OpenMPT
  215. for (k = 0, le = 2; k < (long)(log((double)fftFrameSize)/log(2.)+.5); k++) { // OpenMPT
  216. #endif // OpenMPT
  217. le <<= 1;
  218. le2 = le>>1;
  219. ur = 1.0;
  220. ui = 0.0;
  221. arg = M_PI / (le2>>1);
  222. wr = cos(arg);
  223. wi = sign*sin(arg);
  224. for (j = 0; j < le2; j += 2) {
  225. p1r = fftBuffer+j; p1i = p1r+1;
  226. p2r = p1r+le2; p2i = p2r+1;
  227. for (i = j; i < 2*fftFrameSize; i += le) {
  228. tr = *p2r * ur - *p2i * ui;
  229. ti = *p2r * ui + *p2i * ur;
  230. *p2r = *p1r - tr; *p2i = *p1i - ti;
  231. *p1r += tr; *p1i += ti;
  232. p1r += le; p1i += le;
  233. p2r += le; p2i += le;
  234. }
  235. tr = ur*wr - ui*wi;
  236. ui = ur*wi + ui*wr;
  237. ur = tr;
  238. }
  239. }
  240. }
  241. // -----------------------------------------------------------------------------------------------------------------
  242. /*
  243. 12/12/02, smb
  244. PLEASE NOTE:
  245. There have been some reports on domain errors when the atan2() function was used
  246. as in the above code. Usually, a domain error should not interrupt the program flow
  247. (maybe except in Debug mode) but rather be handled "silently" and a global variable
  248. should be set according to this error. However, on some occasions people ran into
  249. this kind of scenario, so a replacement atan2() function is provided here.
  250. If you are experiencing domain errors and your program stops, simply replace all
  251. instances of atan2() with calls to the smbAtan2() function below.
  252. */
  253. double smbAtan2(double x, double y)
  254. {
  255. double signx;
  256. if (x > 0.) signx = 1.;
  257. else signx = -1.;
  258. if (x == 0.) return 0.;
  259. if (y == 0.) return signx * M_PI / 2.;
  260. return atan2(x, y);
  261. }
  262. // -----------------------------------------------------------------------------------------------------------------
  263. // -----------------------------------------------------------------------------------------------------------------
  264. // -----------------------------------------------------------------------------------------------------------------