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