TDStretch.h (10752B)
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 // License : 17 // 18 // SoundTouch audio processing library 19 // Copyright (c) Olli Parviainen 20 // 21 // This library is free software; you can redistribute it and/or 22 // modify it under the terms of the GNU Lesser General Public 23 // License as published by the Free Software Foundation; either 24 // version 2.1 of the License, or (at your option) any later version. 25 // 26 // This library is distributed in the hope that it will be useful, 27 // but WITHOUT ANY WARRANTY; without even the implied warranty of 28 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29 // Lesser General Public License for more details. 30 // 31 // You should have received a copy of the GNU Lesser General Public 32 // License along with this library; if not, write to the Free Software 33 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 34 // 35 //////////////////////////////////////////////////////////////////////////////// 36 37 #ifndef TDStretch_H 38 #define TDStretch_H 39 40 #include <stddef.h> 41 #include "STTypes.h" 42 #include "RateTransposer.h" 43 #include "FIFOSamplePipe.h" 44 45 namespace soundtouch 46 { 47 48 /// Default values for sound processing parameters: 49 /// Notice that the default parameters are tuned for contemporary popular music 50 /// processing. For speech processing applications these parameters suit better: 51 /// #define DEFAULT_SEQUENCE_MS 40 52 /// #define DEFAULT_SEEKWINDOW_MS 15 53 /// #define DEFAULT_OVERLAP_MS 8 54 /// 55 56 /// Default length of a single processing sequence, in milliseconds. This determines to how 57 /// long sequences the original sound is chopped in the time-stretch algorithm. 58 /// 59 /// The larger this value is, the lesser sequences are used in processing. In principle 60 /// a bigger value sounds better when slowing down tempo, but worse when increasing tempo 61 /// and vice versa. 62 /// 63 /// Increasing this value reduces computational burden & vice versa. 64 //#define DEFAULT_SEQUENCE_MS 40 65 #define DEFAULT_SEQUENCE_MS USE_AUTO_SEQUENCE_LEN 66 67 /// Giving this value for the sequence length sets automatic parameter value 68 /// according to tempo setting (recommended) 69 #define USE_AUTO_SEQUENCE_LEN 0 70 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 86 /// Giving this value for the seek window length sets automatic parameter value 87 /// according to tempo setting (recommended) 88 #define USE_AUTO_SEEKWINDOW_LEN 0 89 90 /// Overlap length in milliseconds. When the chopped sound sequences are mixed back together, 91 /// to form a continuous sound stream, this parameter defines over how long period the two 92 /// consecutive sequences are let to overlap each other. 93 /// 94 /// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting 95 /// by a large amount, you might wish to try a smaller value on this. 96 /// 97 /// Increasing this value increases computational burden & vice versa. 98 #define DEFAULT_OVERLAP_MS 8 99 100 101 /// Class that does the time-stretch (tempo change) effect for the processed 102 /// sound. 103 class TDStretch : public FIFOProcessor 104 { 105 protected: 106 int channels; 107 int sampleReq; 108 109 int overlapLength; 110 int seekLength; 111 int seekWindowLength; 112 int overlapDividerBitsNorm; 113 int overlapDividerBitsPure; 114 int slopingDivider; 115 int sampleRate; 116 int sequenceMs; 117 int seekWindowMs; 118 int overlapMs; 119 120 unsigned long maxnorm; 121 float maxnormf; 122 123 double tempo; 124 double nominalSkip; 125 double skipFract; 126 127 bool bQuickSeek; 128 bool bAutoSeqSetting; 129 bool bAutoSeekSetting; 130 bool isBeginning; 131 132 SAMPLETYPE *pMidBuffer; 133 SAMPLETYPE *pMidBufferUnaligned; 134 135 FIFOSampleBuffer outputBuffer; 136 FIFOSampleBuffer inputBuffer; 137 138 void acceptNewOverlapLength(int newOverlapLength); 139 140 virtual void clearCrossCorrState(); 141 void calculateOverlapLength(int overlapMs); 142 143 virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm); 144 virtual double calcCrossCorrAccumulate(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm); 145 146 virtual int seekBestOverlapPositionFull(const SAMPLETYPE *refPos); 147 virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos); 148 virtual int seekBestOverlapPosition(const SAMPLETYPE *refPos); 149 150 virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; 151 virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const; 152 virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const; 153 154 void clearMidBuffer(); 155 void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; 156 157 void calcSeqParameters(); 158 void adaptNormalizer(); 159 160 /// Changes the tempo of the given sound samples. 161 /// Returns amount of samples returned in the "output" buffer. 162 /// The maximum amount of samples that can be returned at a time is set by 163 /// the 'set_returnBuffer_size' function. 164 void processSamples(); 165 166 public: 167 TDStretch(); 168 virtual ~TDStretch(); 169 170 /// Operator 'new' is overloaded so that it automatically creates a suitable instance 171 /// depending on if we've a MMX/SSE/etc-capable CPU available or not. 172 static void *operator new(size_t s); 173 174 /// Use this function instead of "new" operator to create a new instance of this class. 175 /// This function automatically chooses a correct feature set depending on if the CPU 176 /// supports MMX/SSE/etc extensions. 177 static TDStretch *newInstance(); 178 179 /// Returns the output buffer object 180 FIFOSamplePipe *getOutput() { return &outputBuffer; }; 181 182 /// Returns the input buffer object 183 FIFOSamplePipe *getInput() { return &inputBuffer; }; 184 185 /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower 186 /// tempo, larger faster tempo. 187 void setTempo(double newTempo); 188 189 /// Returns nonzero if there aren't any samples available for outputting. 190 virtual void clear(); 191 192 /// Clears the input buffer 193 void clearInput(); 194 195 /// Sets the number of channels, 1 = mono, 2 = stereo 196 void setChannels(int numChannels); 197 198 /// Enables/disables the quick position seeking algorithm. Zero to disable, 199 /// nonzero to enable 200 void enableQuickSeek(bool enable); 201 202 /// Returns nonzero if the quick seeking algorithm is enabled. 203 bool isQuickSeekEnabled() const; 204 205 /// Sets routine control parameters. These control are certain time constants 206 /// defining how the sound is stretched to the desired duration. 207 // 208 /// 'sampleRate' = sample rate of the sound 209 /// 'sequenceMS' = one processing sequence length in milliseconds 210 /// 'seekwindowMS' = seeking window length for scanning the best overlapping 211 /// position 212 /// 'overlapMS' = overlapping length 213 void setParameters(int sampleRate, ///< Samplerate of sound being processed (Hz) 214 int sequenceMS = -1, ///< Single processing sequence length (ms) 215 int seekwindowMS = -1, ///< Offset seeking window length (ms) 216 int overlapMS = -1 ///< Sequence overlapping length (ms) 217 ); 218 219 /// Get routine control parameters, see setParameters() function. 220 /// Any of the parameters to this function can be NULL, in such case corresponding parameter 221 /// value isn't returned. 222 void getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const; 223 224 /// Adds 'numsamples' pcs of samples from the 'samples' memory position into 225 /// the input of the object. 226 virtual void putSamples( 227 const SAMPLETYPE *samples, ///< Input sample data 228 uint numSamples ///< Number of samples in 'samples' so that one sample 229 ///< contains both channels if stereo 230 ); 231 232 /// return nominal input sample requirement for triggering a processing batch 233 int getInputSampleReq() const 234 { 235 return (int)(nominalSkip + 0.5); 236 } 237 238 /// return nominal output sample amount when running a processing batch 239 int getOutputBatchSize() const 240 { 241 return seekWindowLength - overlapLength; 242 } 243 244 /// return approximate initial input-output latency 245 int getLatency() const 246 { 247 return sampleReq; 248 } 249 }; 250 251 252 // Implementation-specific class declarations: 253 254 #ifdef SOUNDTOUCH_ALLOW_MMX 255 /// Class that implements MMX optimized routines for 16bit integer samples type. 256 class TDStretchMMX : public TDStretch 257 { 258 protected: 259 double calcCrossCorr(const short *mixingPos, const short *compare, double &norm); 260 double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm); 261 virtual void overlapStereo(short *output, const short *input) const; 262 virtual void clearCrossCorrState(); 263 }; 264 #endif /// SOUNDTOUCH_ALLOW_MMX 265 266 267 #ifdef SOUNDTOUCH_ALLOW_SSE 268 /// Class that implements SSE optimized routines for floating point samples type. 269 class TDStretchSSE : public TDStretch 270 { 271 protected: 272 double calcCrossCorr(const float *mixingPos, const float *compare, double &norm); 273 double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm); 274 }; 275 276 #endif /// SOUNDTOUCH_ALLOW_SSE 277 278 } 279 #endif /// TDStretch_H