1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libsoundtouch/src/TDStretch.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,272 @@ 1.4 +//////////////////////////////////////////////////////////////////////////////// 1.5 +/// 1.6 +/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo 1.7 +/// while maintaining the original pitch by using a time domain WSOLA-like method 1.8 +/// with several performance-increasing tweaks. 1.9 +/// 1.10 +/// Note : MMX/SSE optimized functions reside in separate, platform-specific files 1.11 +/// 'mmx_optimized.cpp' and 'sse_optimized.cpp' 1.12 +/// 1.13 +/// Author : Copyright (c) Olli Parviainen 1.14 +/// Author e-mail : oparviai 'at' iki.fi 1.15 +/// SoundTouch WWW: http://www.surina.net/soundtouch 1.16 +/// 1.17 +//////////////////////////////////////////////////////////////////////////////// 1.18 +// 1.19 +// Last changed : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $ 1.20 +// File revision : $Revision: 4 $ 1.21 +// 1.22 +// $Id: TDStretch.h 195 2014-04-06 15:57:21Z oparviai $ 1.23 +// 1.24 +//////////////////////////////////////////////////////////////////////////////// 1.25 +// 1.26 +// License : 1.27 +// 1.28 +// SoundTouch audio processing library 1.29 +// Copyright (c) Olli Parviainen 1.30 +// 1.31 +// This library is free software; you can redistribute it and/or 1.32 +// modify it under the terms of the GNU Lesser General Public 1.33 +// License as published by the Free Software Foundation; either 1.34 +// version 2.1 of the License, or (at your option) any later version. 1.35 +// 1.36 +// This library is distributed in the hope that it will be useful, 1.37 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 1.38 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.39 +// Lesser General Public License for more details. 1.40 +// 1.41 +// You should have received a copy of the GNU Lesser General Public 1.42 +// License along with this library; if not, write to the Free Software 1.43 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1.44 +// 1.45 +//////////////////////////////////////////////////////////////////////////////// 1.46 + 1.47 +#ifndef TDStretch_H 1.48 +#define TDStretch_H 1.49 + 1.50 +#include <stddef.h> 1.51 +#include "STTypes.h" 1.52 +#include "RateTransposer.h" 1.53 +#include "FIFOSamplePipe.h" 1.54 + 1.55 +namespace soundtouch 1.56 +{ 1.57 + 1.58 +/// Default values for sound processing parameters: 1.59 +/// Notice that the default parameters are tuned for contemporary popular music 1.60 +/// processing. For speech processing applications these parameters suit better: 1.61 +/// #define DEFAULT_SEQUENCE_MS 40 1.62 +/// #define DEFAULT_SEEKWINDOW_MS 15 1.63 +/// #define DEFAULT_OVERLAP_MS 8 1.64 +/// 1.65 + 1.66 +/// Default length of a single processing sequence, in milliseconds. This determines to how 1.67 +/// long sequences the original sound is chopped in the time-stretch algorithm. 1.68 +/// 1.69 +/// The larger this value is, the lesser sequences are used in processing. In principle 1.70 +/// a bigger value sounds better when slowing down tempo, but worse when increasing tempo 1.71 +/// and vice versa. 1.72 +/// 1.73 +/// Increasing this value reduces computational burden & vice versa. 1.74 +//#define DEFAULT_SEQUENCE_MS 40 1.75 +#define DEFAULT_SEQUENCE_MS USE_AUTO_SEQUENCE_LEN 1.76 + 1.77 +/// Giving this value for the sequence length sets automatic parameter value 1.78 +/// according to tempo setting (recommended) 1.79 +#define USE_AUTO_SEQUENCE_LEN 0 1.80 + 1.81 +/// Seeking window default length in milliseconds for algorithm that finds the best possible 1.82 +/// overlapping location. This determines from how wide window the algorithm may look for an 1.83 +/// optimal joining location when mixing the sound sequences back together. 1.84 +/// 1.85 +/// The bigger this window setting is, the higher the possibility to find a better mixing 1.86 +/// position will become, but at the same time large values may cause a "drifting" artifact 1.87 +/// because consequent sequences will be taken at more uneven intervals. 1.88 +/// 1.89 +/// If there's a disturbing artifact that sounds as if a constant frequency was drifting 1.90 +/// around, try reducing this setting. 1.91 +/// 1.92 +/// Increasing this value increases computational burden & vice versa. 1.93 +//#define DEFAULT_SEEKWINDOW_MS 15 1.94 +#define DEFAULT_SEEKWINDOW_MS USE_AUTO_SEEKWINDOW_LEN 1.95 + 1.96 +/// Giving this value for the seek window length sets automatic parameter value 1.97 +/// according to tempo setting (recommended) 1.98 +#define USE_AUTO_SEEKWINDOW_LEN 0 1.99 + 1.100 +/// Overlap length in milliseconds. When the chopped sound sequences are mixed back together, 1.101 +/// to form a continuous sound stream, this parameter defines over how long period the two 1.102 +/// consecutive sequences are let to overlap each other. 1.103 +/// 1.104 +/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting 1.105 +/// by a large amount, you might wish to try a smaller value on this. 1.106 +/// 1.107 +/// Increasing this value increases computational burden & vice versa. 1.108 +#define DEFAULT_OVERLAP_MS 8 1.109 + 1.110 + 1.111 +/// Class that does the time-stretch (tempo change) effect for the processed 1.112 +/// sound. 1.113 +class TDStretch : public FIFOProcessor 1.114 +{ 1.115 +protected: 1.116 + int channels; 1.117 + int sampleReq; 1.118 + float tempo; 1.119 + 1.120 + SAMPLETYPE *pMidBuffer; 1.121 + SAMPLETYPE *pMidBufferUnaligned; 1.122 + int overlapLength; 1.123 + int seekLength; 1.124 + int seekWindowLength; 1.125 + int overlapDividerBits; 1.126 + int slopingDivider; 1.127 + float nominalSkip; 1.128 + float skipFract; 1.129 + FIFOSampleBuffer outputBuffer; 1.130 + FIFOSampleBuffer inputBuffer; 1.131 + bool bQuickSeek; 1.132 + 1.133 + int sampleRate; 1.134 + int sequenceMs; 1.135 + int seekWindowMs; 1.136 + int overlapMs; 1.137 + bool bAutoSeqSetting; 1.138 + bool bAutoSeekSetting; 1.139 + 1.140 + void acceptNewOverlapLength(int newOverlapLength); 1.141 + 1.142 + virtual void clearCrossCorrState(); 1.143 + void calculateOverlapLength(int overlapMs); 1.144 + 1.145 + virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm) const; 1.146 + virtual double calcCrossCorrAccumulate(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm) const; 1.147 + 1.148 + virtual int seekBestOverlapPositionFull(const SAMPLETYPE *refPos); 1.149 + virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos); 1.150 + int seekBestOverlapPosition(const SAMPLETYPE *refPos); 1.151 + 1.152 + virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; 1.153 + virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const; 1.154 + virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const; 1.155 + 1.156 + void clearMidBuffer(); 1.157 + void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; 1.158 + 1.159 + void calcSeqParameters(); 1.160 + 1.161 + /// Changes the tempo of the given sound samples. 1.162 + /// Returns amount of samples returned in the "output" buffer. 1.163 + /// The maximum amount of samples that can be returned at a time is set by 1.164 + /// the 'set_returnBuffer_size' function. 1.165 + void processSamples(); 1.166 + 1.167 +public: 1.168 + TDStretch(); 1.169 + virtual ~TDStretch(); 1.170 + 1.171 + /// Operator 'new' is overloaded so that it automatically creates a suitable instance 1.172 + /// depending on if we've a MMX/SSE/etc-capable CPU available or not. 1.173 + static void *operator new(size_t s); 1.174 + 1.175 + /// Use this function instead of "new" operator to create a new instance of this class. 1.176 + /// This function automatically chooses a correct feature set depending on if the CPU 1.177 + /// supports MMX/SSE/etc extensions. 1.178 + static TDStretch *newInstance(); 1.179 + 1.180 + /// Returns the output buffer object 1.181 + FIFOSamplePipe *getOutput() { return &outputBuffer; }; 1.182 + 1.183 + /// Returns the input buffer object 1.184 + FIFOSamplePipe *getInput() { return &inputBuffer; }; 1.185 + 1.186 + /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower 1.187 + /// tempo, larger faster tempo. 1.188 + void setTempo(float newTempo); 1.189 + 1.190 + /// Returns nonzero if there aren't any samples available for outputting. 1.191 + virtual void clear(); 1.192 + 1.193 + /// Clears the input buffer 1.194 + void clearInput(); 1.195 + 1.196 + /// Sets the number of channels, 1 = mono, 2 = stereo 1.197 + void setChannels(int numChannels); 1.198 + 1.199 + /// Enables/disables the quick position seeking algorithm. Zero to disable, 1.200 + /// nonzero to enable 1.201 + void enableQuickSeek(bool enable); 1.202 + 1.203 + /// Returns nonzero if the quick seeking algorithm is enabled. 1.204 + bool isQuickSeekEnabled() const; 1.205 + 1.206 + /// Sets routine control parameters. These control are certain time constants 1.207 + /// defining how the sound is stretched to the desired duration. 1.208 + // 1.209 + /// 'sampleRate' = sample rate of the sound 1.210 + /// 'sequenceMS' = one processing sequence length in milliseconds 1.211 + /// 'seekwindowMS' = seeking window length for scanning the best overlapping 1.212 + /// position 1.213 + /// 'overlapMS' = overlapping length 1.214 + void setParameters(int sampleRate, ///< Samplerate of sound being processed (Hz) 1.215 + int sequenceMS = -1, ///< Single processing sequence length (ms) 1.216 + int seekwindowMS = -1, ///< Offset seeking window length (ms) 1.217 + int overlapMS = -1 ///< Sequence overlapping length (ms) 1.218 + ); 1.219 + 1.220 + /// Get routine control parameters, see setParameters() function. 1.221 + /// Any of the parameters to this function can be NULL, in such case corresponding parameter 1.222 + /// value isn't returned. 1.223 + void getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const; 1.224 + 1.225 + /// Adds 'numsamples' pcs of samples from the 'samples' memory position into 1.226 + /// the input of the object. 1.227 + virtual void putSamples( 1.228 + const SAMPLETYPE *samples, ///< Input sample data 1.229 + uint numSamples ///< Number of samples in 'samples' so that one sample 1.230 + ///< contains both channels if stereo 1.231 + ); 1.232 + 1.233 + /// return nominal input sample requirement for triggering a processing batch 1.234 + int getInputSampleReq() const 1.235 + { 1.236 + return (int)(nominalSkip + 0.5); 1.237 + } 1.238 + 1.239 + /// return nominal output sample amount when running a processing batch 1.240 + int getOutputBatchSize() const 1.241 + { 1.242 + return seekWindowLength - overlapLength; 1.243 + } 1.244 +}; 1.245 + 1.246 + 1.247 + 1.248 +// Implementation-specific class declarations: 1.249 + 1.250 +#ifdef SOUNDTOUCH_ALLOW_MMX 1.251 + /// Class that implements MMX optimized routines for 16bit integer samples type. 1.252 + class TDStretchMMX : public TDStretch 1.253 + { 1.254 + protected: 1.255 + double calcCrossCorr(const short *mixingPos, const short *compare, double &norm) const; 1.256 + double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) const; 1.257 + virtual void overlapStereo(short *output, const short *input) const; 1.258 + virtual void clearCrossCorrState(); 1.259 + }; 1.260 +#endif /// SOUNDTOUCH_ALLOW_MMX 1.261 + 1.262 + 1.263 +#ifdef SOUNDTOUCH_ALLOW_SSE 1.264 + /// Class that implements SSE optimized routines for floating point samples type. 1.265 + class TDStretchSSE : public TDStretch 1.266 + { 1.267 + protected: 1.268 + double calcCrossCorr(const float *mixingPos, const float *compare, double &norm) const; 1.269 + double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) const; 1.270 + }; 1.271 + 1.272 +#endif /// SOUNDTOUCH_ALLOW_SSE 1.273 + 1.274 +} 1.275 +#endif /// TDStretch_H