TDStretch.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. ////////////////////////////////////////////////////////////////////////////////
  2. ///
  3. /// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
  4. /// while maintaining the original pitch by using a time domain WSOLA-like method
  5. /// with several performance-increasing tweaks.
  6. ///
  7. /// Note : MMX/SSE optimized functions reside in separate, platform-specific files
  8. /// 'mmx_optimized.cpp' and 'sse_optimized.cpp'
  9. ///
  10. /// Author : Copyright (c) Olli Parviainen
  11. /// Author e-mail : oparviai 'at' iki.fi
  12. /// SoundTouch WWW: http://www.surina.net/soundtouch
  13. ///
  14. ////////////////////////////////////////////////////////////////////////////////
  15. //
  16. // Last changed : $Date: 2012-04-01 22:49:30 +0300 (Sun, 01 Apr 2012) $
  17. // File revision : $Revision: 4 $
  18. //
  19. // $Id: TDStretch.h 137 2012-04-01 19:49:30Z oparviai $
  20. //
  21. ////////////////////////////////////////////////////////////////////////////////
  22. //
  23. // License :
  24. //
  25. // SoundTouch audio processing library
  26. // Copyright (c) Olli Parviainen
  27. //
  28. // This library is free software; you can redistribute it and/or
  29. // modify it under the terms of the GNU Lesser General Public
  30. // License as published by the Free Software Foundation; either
  31. // version 2.1 of the License, or (at your option) any later version.
  32. //
  33. // This library is distributed in the hope that it will be useful,
  34. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  36. // Lesser General Public License for more details.
  37. //
  38. // You should have received a copy of the GNU Lesser General Public
  39. // License along with this library; if not, write to the Free Software
  40. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  41. //
  42. ////////////////////////////////////////////////////////////////////////////////
  43. #ifndef TDStretch_H
  44. #define TDStretch_H
  45. #include <stddef.h>
  46. #include "STTypes.h"
  47. #include "RateTransposer.h"
  48. #include "FIFOSamplePipe.h"
  49. namespace soundtouch
  50. {
  51. /// Default values for sound processing parameters:
  52. /// Notice that the default parameters are tuned for contemporary popular music
  53. /// processing. For speech processing applications these parameters suit better:
  54. /// #define DEFAULT_SEQUENCE_MS 40
  55. /// #define DEFAULT_SEEKWINDOW_MS 15
  56. /// #define DEFAULT_OVERLAP_MS 8
  57. ///
  58. /// Default length of a single processing sequence, in milliseconds. This determines to how
  59. /// long sequences the original sound is chopped in the time-stretch algorithm.
  60. ///
  61. /// The larger this value is, the lesser sequences are used in processing. In principle
  62. /// a bigger value sounds better when slowing down tempo, but worse when increasing tempo
  63. /// and vice versa.
  64. ///
  65. /// Increasing this value reduces computational burden & vice versa.
  66. //#define DEFAULT_SEQUENCE_MS 40
  67. #define DEFAULT_SEQUENCE_MS USE_AUTO_SEQUENCE_LEN
  68. /// Giving this value for the sequence length sets automatic parameter value
  69. /// according to tempo setting (recommended)
  70. #define USE_AUTO_SEQUENCE_LEN 0
  71. /// Seeking window default length in milliseconds for algorithm that finds the best possible
  72. /// overlapping location. This determines from how wide window the algorithm may look for an
  73. /// optimal joining location when mixing the sound sequences back together.
  74. ///
  75. /// The bigger this window setting is, the higher the possibility to find a better mixing
  76. /// position will become, but at the same time large values may cause a "drifting" artifact
  77. /// because consequent sequences will be taken at more uneven intervals.
  78. ///
  79. /// If there's a disturbing artifact that sounds as if a constant frequency was drifting
  80. /// around, try reducing this setting.
  81. ///
  82. /// Increasing this value increases computational burden & vice versa.
  83. //#define DEFAULT_SEEKWINDOW_MS 15
  84. #define DEFAULT_SEEKWINDOW_MS USE_AUTO_SEEKWINDOW_LEN
  85. /// Giving this value for the seek window length sets automatic parameter value
  86. /// according to tempo setting (recommended)
  87. #define USE_AUTO_SEEKWINDOW_LEN 0
  88. /// Overlap length in milliseconds. When the chopped sound sequences are mixed back together,
  89. /// to form a continuous sound stream, this parameter defines over how long period the two
  90. /// consecutive sequences are let to overlap each other.
  91. ///
  92. /// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting
  93. /// by a large amount, you might wish to try a smaller value on this.
  94. ///
  95. /// Increasing this value increases computational burden & vice versa.
  96. #define DEFAULT_OVERLAP_MS 8
  97. /// Class that does the time-stretch (tempo change) effect for the processed
  98. /// sound.
  99. class TDStretch : public FIFOProcessor
  100. {
  101. protected:
  102. int channels;
  103. int sampleReq;
  104. float tempo;
  105. SAMPLETYPE *pMidBuffer;
  106. SAMPLETYPE *pMidBufferUnaligned;
  107. int overlapLength;
  108. int seekLength;
  109. int seekWindowLength;
  110. int overlapDividerBits;
  111. int slopingDivider;
  112. float nominalSkip;
  113. float skipFract;
  114. FIFOSampleBuffer outputBuffer;
  115. FIFOSampleBuffer inputBuffer;
  116. SBOOL bQuickSeek;
  117. int sampleRate;
  118. int sequenceMs;
  119. int seekWindowMs;
  120. int overlapMs;
  121. SBOOL bAutoSeqSetting;
  122. SBOOL bAutoSeekSetting;
  123. void acceptNewOverlapLength(int newOverlapLength);
  124. virtual void clearCrossCorrState();
  125. void calculateOverlapLength(int overlapMs);
  126. virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
  127. virtual int seekBestOverlapPositionFull(const SAMPLETYPE *refPos);
  128. virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos);
  129. int seekBestOverlapPosition(const SAMPLETYPE *refPos);
  130. virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
  131. virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
  132. void clearMidBuffer();
  133. void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
  134. void calcSeqParameters();
  135. /// Changes the tempo of the given sound samples.
  136. /// Returns amount of samples returned in the "output" buffer.
  137. /// The maximum amount of samples that can be returned at a time is set by
  138. /// the 'set_returnBuffer_size' function.
  139. void processSamples();
  140. public:
  141. TDStretch();
  142. virtual ~TDStretch();
  143. /// Operator 'new' is overloaded so that it automatically creates a suitable instance
  144. /// depending on if we've a MMX/SSE/etc-capable CPU available or not.
  145. static void *operator new(size_t s);
  146. /// Use this function instead of "new" operator to create a new instance of this class.
  147. /// This function automatically chooses a correct feature set depending on if the CPU
  148. /// supports MMX/SSE/etc extensions.
  149. static TDStretch *newInstance();
  150. /// Returns the output buffer object
  151. FIFOSamplePipe *getOutput() { return &outputBuffer; };
  152. /// Returns the input buffer object
  153. FIFOSamplePipe *getInput() { return &inputBuffer; };
  154. /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
  155. /// tempo, larger faster tempo.
  156. void setTempo(float newTempo);
  157. /// Returns nonzero if there aren't any samples available for outputting.
  158. virtual void clear();
  159. /// Clears the input buffer
  160. void clearInput();
  161. /// Sets the number of channels, 1 = mono, 2 = stereo
  162. void setChannels(int numChannels);
  163. /// Enables/disables the quick position seeking algorithm. Zero to disable,
  164. /// nonzero to enable
  165. void enableQuickSeek(SBOOL enable);
  166. /// Returns nonzero if the quick seeking algorithm is enabled.
  167. SBOOL isQuickSeekEnabled() const;
  168. /// Sets routine control parameters. These control are certain time constants
  169. /// defining how the sound is stretched to the desired duration.
  170. //
  171. /// 'sampleRate' = sample rate of the sound
  172. /// 'sequenceMS' = one processing sequence length in milliseconds
  173. /// 'seekwindowMS' = seeking window length for scanning the best overlapping
  174. /// position
  175. /// 'overlapMS' = overlapping length
  176. void setParameters(int sampleRate, ///< Samplerate of sound being processed (Hz)
  177. int sequenceMS = -1, ///< Single processing sequence length (ms)
  178. int seekwindowMS = -1, ///< Offset seeking window length (ms)
  179. int overlapMS = -1 ///< Sequence overlapping length (ms)
  180. );
  181. /// Get routine control parameters, see setParameters() function.
  182. /// Any of the parameters to this function can be NULL, in such case corresponding parameter
  183. /// value isn't returned.
  184. void getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const;
  185. /// Adds 'numsamples' pcs of samples from the 'samples' memory position into
  186. /// the input of the object.
  187. virtual void putSamples(
  188. const SAMPLETYPE *samples, ///< Input sample data
  189. uint numSamples ///< Number of samples in 'samples' so that one sample
  190. ///< contains both channels if stereo
  191. );
  192. /// return nominal input sample requirement for triggering a processing batch
  193. int getInputSampleReq() const
  194. {
  195. return (int)(nominalSkip + 0.5);
  196. }
  197. /// return nominal output sample amount when running a processing batch
  198. int getOutputBatchSize() const
  199. {
  200. return seekWindowLength - overlapLength;
  201. }
  202. };
  203. // Implementation-specific class declarations:
  204. #ifdef SOUNDTOUCH_ALLOW_MMX
  205. /// Class that implements MMX optimized routines for 16bit integer samples type.
  206. class TDStretchMMX : public TDStretch
  207. {
  208. protected:
  209. double calcCrossCorr(const short *mixingPos, const short *compare) const;
  210. virtual void overlapStereo(short *output, const short *input) const;
  211. virtual void clearCrossCorrState();
  212. };
  213. #endif /// SOUNDTOUCH_ALLOW_MMX
  214. #ifdef SOUNDTOUCH_ALLOW_SSE
  215. /// Class that implements SSE optimized routines for floating point samples type.
  216. class TDStretchSSE : public TDStretch
  217. {
  218. protected:
  219. double calcCrossCorr(const float *mixingPos, const float *compare) const;
  220. };
  221. #endif /// SOUNDTOUCH_ALLOW_SSE
  222. }
  223. #endif /// TDStretch_H