00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00043
00044 #ifndef TDStretch_H
00045 #define TDStretch_H
00046
00047 #include "STTypes.h"
00048 #include "RateTransposer.h"
00049 #include "FIFOSamplePipe.h"
00050
00051 #ifdef MULTICHANNEL
00052 #define USE_MULTI_MMX
00053 #endif
00054
00055 namespace soundtouch
00056 {
00057
00058
00059
00068 #define DEFAULT_SEQUENCE_MS 82
00069
00082 #define DEFAULT_SEEKWINDOW_MS 14
00083
00092 #define DEFAULT_OVERLAP_MS 12
00093
00094
00097 class TDStretch : public FIFOProcessor
00098 {
00099 protected:
00100 uint channels;
00101 uint sampleReq;
00102 float tempo;
00103
00104 SAMPLETYPE *pMidBuffer;
00105 SAMPLETYPE *pRefMidBuffer;
00106 SAMPLETYPE *pRefMidBufferUnaligned;
00107 uint midBufferLength;
00108 uint overlapLength;
00109 uint overlapDividerBits;
00110 uint slopingDivider;
00111 uint seekLength;
00112 uint seekWindowLength;
00113 uint maxOffset;
00114 float nominalSkip;
00115 float skipFract;
00116 FIFOSampleBuffer outputBuffer;
00117 FIFOSampleBuffer inputBuffer;
00118 BOOL bQuickseek;
00119 BOOL bMidBufferDirty;
00120
00121 uint sampleRate;
00122 uint sequenceMs;
00123 uint seekWindowMs;
00124 uint overlapMs;
00125
00126 void acceptNewOverlapLength(uint newOverlapLength);
00127
00128 virtual void clearCrossCorrState();
00129 void calculateOverlapLength(uint overlapMs);
00130
00131 #ifdef MULTICHANNEL
00132 virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
00133 #endif
00134 virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
00135 virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
00136
00137 #ifdef MULTICHANNEL
00138 virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos);
00139 virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos);
00140 #endif
00141 virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
00142 virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
00143 virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
00144 virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
00145 uint seekBestOverlapPosition(const SAMPLETYPE *refPos);
00146
00147 #ifdef MULTICHANNEL
00148 virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const;
00149 #endif
00150 virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
00151 virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
00152
00153 void clearMidBuffer();
00154 void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
00155
00156 #ifdef MULTICHANNEL
00157 void precalcCorrReference();
00158 #endif
00159 void precalcCorrReferenceMono();
00160 void precalcCorrReferenceStereo();
00161
00162 void processNominalTempo();
00163
00168 void processSamples();
00169
00170 public:
00171 TDStretch();
00172 virtual ~TDStretch();
00173
00176 void *operator new(size_t s);
00177
00181 static TDStretch *newInstance();
00182
00184 FIFOSamplePipe *getOutput() { return &outputBuffer; };
00185
00187 FIFOSamplePipe *getInput() { return &inputBuffer; };
00188
00191 void setTempo(float newTempo);
00192
00194 virtual void clear();
00195
00197 void clearInput();
00198
00200 void setChannels(uint numChannels);
00201
00204 void enableQuickSeek(BOOL enable);
00205
00207 BOOL isQuickSeekEnabled() const;
00208
00211
00217 void setParameters(uint sampleRate,
00218 uint sequenceMS = DEFAULT_SEQUENCE_MS,
00219 uint seekwindowMS = DEFAULT_SEEKWINDOW_MS,
00220 uint overlapMS = DEFAULT_OVERLAP_MS
00221 );
00222
00226 void getParameters(uint *pSampleRate, uint *pSequenceMs, uint *pSeekWindowMs, uint *pOverlapMs);
00227
00230 virtual void putSamples(
00231 const SAMPLETYPE *samples,
00232 uint numSamples
00233
00234 );
00235 };
00236
00237
00238
00239
00240
00241 #ifdef ALLOW_MMX
00243 class TDStretchMMX : public TDStretch
00244 {
00245 protected:
00246 #ifdef USE_MULTI_MMX
00247 #ifdef MULTICHANNEL
00248 long calcCrossCorrMulti(const short *mixingPos, const short *compare) const;
00249 #endif
00250 #endif
00251 long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
00252 virtual void overlapStereo(short *output, const short *input) const;
00253 virtual void clearCrossCorrState();
00254 };
00255 #endif
00256
00257
00258 #ifdef ALLOW_3DNOW
00260 class TDStretch3DNow : public TDStretch
00261 {
00262 protected:
00263 #ifdef MULTICHANNEL
00264
00265 #endif
00266 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
00267 };
00268 #endif
00269
00270
00271 #ifdef ALLOW_SSE
00273 class TDStretchSSE : public TDStretch
00274 {
00275 protected:
00276 #ifdef MULTICHANNEL
00277
00278 #endif
00279 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
00280 };
00281
00282 #endif
00283
00284 }
00285 #endif