tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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