tor-browser

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

SoundTouch.h (15020B)


      1 //////////////////////////////////////////////////////////////////////////////
      2 ///
      3 /// SoundTouch - main class for tempo/pitch/rate adjusting routines. 
      4 ///
      5 /// Notes:
      6 /// - Initialize the SoundTouch object instance by setting up the sound stream 
      7 ///   parameters with functions 'setSampleRate' and 'setChannels', then set 
      8 ///   desired tempo/pitch/rate settings with the corresponding functions.
      9 ///
     10 /// - The SoundTouch class behaves like a first-in-first-out pipeline: The 
     11 ///   samples that are to be processed are fed into one of the pipe by calling
     12 ///   function 'putSamples', while the ready processed samples can be read 
     13 ///   from the other end of the pipeline with function 'receiveSamples'.
     14 /// 
     15 /// - The SoundTouch processing classes require certain sized 'batches' of 
     16 ///   samples in order to process the sound. For this reason the classes buffer 
     17 ///   incoming samples until there are enough of samples available for 
     18 ///   processing, then they carry out the processing step and consequently
     19 ///   make the processed samples available for outputting.
     20 /// 
     21 /// - For the above reason, the processing routines introduce a certain 
     22 ///   'latency' between the input and output, so that the samples input to
     23 ///   SoundTouch may not be immediately available in the output, and neither 
     24 ///   the amount of outputtable samples may not immediately be in direct 
     25 ///   relationship with the amount of previously input samples.
     26 ///
     27 /// - The tempo/pitch/rate control parameters can be altered during processing.
     28 ///   Please notice though that they aren't currently protected by semaphores,
     29 ///   so in multi-thread application external semaphore protection may be
     30 ///   required.
     31 ///
     32 /// - This class utilizes classes 'TDStretch' for tempo change (without modifying
     33 ///   pitch) and 'RateTransposer' for changing the playback rate (that is, both 
     34 ///   tempo and pitch in the same ratio) of the sound. The third available control 
     35 ///   'pitch' (change pitch but maintain tempo) is produced by a combination of
     36 ///   combining the two other controls.
     37 ///
     38 /// Author        : Copyright (c) Olli Parviainen
     39 /// Author e-mail : oparviai 'at' iki.fi
     40 /// SoundTouch WWW: http://www.surina.net/soundtouch
     41 ///
     42 ////////////////////////////////////////////////////////////////////////////////
     43 //
     44 // License :
     45 //
     46 //  SoundTouch audio processing library
     47 //  Copyright (c) Olli Parviainen
     48 //
     49 //  This library is free software; you can redistribute it and/or
     50 //  modify it under the terms of the GNU Lesser General Public
     51 //  License as published by the Free Software Foundation; either
     52 //  version 2.1 of the License, or (at your option) any later version.
     53 //
     54 //  This library is distributed in the hope that it will be useful,
     55 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
     56 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     57 //  Lesser General Public License for more details.
     58 //
     59 //  You should have received a copy of the GNU Lesser General Public
     60 //  License along with this library; if not, write to the Free Software
     61 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     62 //
     63 ////////////////////////////////////////////////////////////////////////////////
     64 
     65 #ifndef SoundTouch_H
     66 #define SoundTouch_H
     67 
     68 #include "FIFOSamplePipe.h"
     69 #include "STTypes.h"
     70 
     71 namespace soundtouch
     72 {
     73 
     74 /// Soundtouch library version string
     75 #define SOUNDTOUCH_VERSION          "2.2"
     76 
     77 /// SoundTouch library version id
     78 #define SOUNDTOUCH_VERSION_ID       (20200)
     79 
     80 //
     81 // Available setting IDs for the 'setSetting' & 'get_setting' functions:
     82 
     83 /// Enable/disable anti-alias filter in pitch transposer (0 = disable)
     84 #define SETTING_USE_AA_FILTER       0
     85 
     86 /// Pitch transposer anti-alias filter length (8 .. 128 taps, default = 32)
     87 #define SETTING_AA_FILTER_LENGTH    1
     88 
     89 /// Enable/disable quick seeking algorithm in tempo changer routine
     90 /// (enabling quick seeking lowers CPU utilization but causes a minor sound
     91 ///  quality compromising)
     92 #define SETTING_USE_QUICKSEEK       2
     93 
     94 /// Time-stretch algorithm single processing sequence length in milliseconds. This determines 
     95 /// to how long sequences the original sound is chopped in the time-stretch algorithm. 
     96 /// See "STTypes.h" or README for more information.
     97 #define SETTING_SEQUENCE_MS         3
     98 
     99 /// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the 
    100 /// best possible overlapping location. This determines from how wide window the algorithm 
    101 /// may look for an optimal joining location when mixing the sound sequences back together. 
    102 /// See "STTypes.h" or README for more information.
    103 #define SETTING_SEEKWINDOW_MS       4
    104 
    105 /// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences 
    106 /// are mixed back together, to form a continuous sound stream, this parameter defines over 
    107 /// how long period the two consecutive sequences are let to overlap each other. 
    108 /// See "STTypes.h" or README for more information.
    109 #define SETTING_OVERLAP_MS          5
    110 
    111 
    112 /// Call "getSetting" with this ID to query processing sequence size in samples. 
    113 /// This value gives approximate value of how many input samples you'll need to 
    114 /// feed into SoundTouch after initial buffering to get out a new batch of
    115 /// output samples. 
    116 ///
    117 /// This value does not include initial buffering at beginning of a new processing 
    118 /// stream, use SETTING_INITIAL_LATENCY to get the initial buffering size.
    119 ///
    120 /// Notices: 
    121 /// - This is read-only parameter, i.e. setSetting ignores this parameter
    122 /// - This parameter value is not constant but change depending on 
    123 ///   tempo/pitch/rate/samplerate settings.
    124 #define SETTING_NOMINAL_INPUT_SEQUENCE      6
    125 
    126 
    127 /// Call "getSetting" with this ID to query nominal average processing output 
    128 /// size in samples. This value tells approcimate value how many output samples 
    129 /// SoundTouch outputs once it does DSP processing run for a batch of input samples.
    130 ///
    131 /// Notices: 
    132 /// - This is read-only parameter, i.e. setSetting ignores this parameter
    133 /// - This parameter value is not constant but change depending on 
    134 ///   tempo/pitch/rate/samplerate settings.
    135 #define SETTING_NOMINAL_OUTPUT_SEQUENCE     7
    136 
    137 
    138 /// Call "getSetting" with this ID to query initial processing latency, i.e.
    139 /// approx. how many samples you'll need to enter to SoundTouch pipeline before 
    140 /// you can expect to get first batch of ready output samples out. 
    141 ///
    142 /// After the first output batch, you can then expect to get approx. 
    143 /// SETTING_NOMINAL_OUTPUT_SEQUENCE ready samples out for every
    144 /// SETTING_NOMINAL_INPUT_SEQUENCE samples that you enter into SoundTouch.
    145 ///
    146 /// Example:
    147 ///     processing with parameter -tempo=5
    148 ///     => initial latency = 5509 samples
    149 ///        input sequence  = 4167 samples
    150 ///        output sequence = 3969 samples
    151 ///
    152 /// Accordingly, you can expect to feed in approx. 5509 samples at beginning of 
    153 /// the stream, and then you'll get out the first 3969 samples. After that, for 
    154 /// every approx. 4167 samples that you'll put in, you'll receive again approx. 
    155 /// 3969 samples out.
    156 ///
    157 /// This also means that average latency during stream processing is 
    158 /// INITIAL_LATENCY-OUTPUT_SEQUENCE/2, in the above example case 5509-3969/2 
    159 /// = 3524 samples
    160 /// 
    161 /// Notices: 
    162 /// - This is read-only parameter, i.e. setSetting ignores this parameter
    163 /// - This parameter value is not constant but change depending on 
    164 ///   tempo/pitch/rate/samplerate settings.
    165 #define SETTING_INITIAL_LATENCY             8
    166 
    167 
    168 class SoundTouch : public FIFOProcessor
    169 {
    170 private:
    171    /// Rate transposer class instance
    172    class RateTransposer *pRateTransposer;
    173 
    174    /// Time-stretch class instance
    175    class TDStretch *pTDStretch;
    176 
    177    /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
    178    double virtualRate;
    179 
    180    /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
    181    double virtualTempo;
    182 
    183    /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
    184    double virtualPitch;
    185 
    186    /// Flag: Has sample rate been set?
    187    bool  bSrateSet;
    188 
    189    /// Accumulator for how many samples in total will be expected as output vs. samples put in,
    190    /// considering current processing settings.
    191    double samplesExpectedOut;
    192 
    193    /// Accumulator for how many samples in total have been read out from the processing so far
    194    long   samplesOutput;
    195 
    196    /// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and 
    197    /// 'virtualPitch' parameters.
    198    void calcEffectiveRateAndTempo();
    199 
    200 protected :
    201    /// Number of channels
    202    uint  channels;
    203 
    204    /// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
    205    double rate;
    206 
    207    /// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
    208    double tempo;
    209 
    210 public:
    211    SoundTouch();
    212    virtual ~SoundTouch();
    213 
    214    /// Get SoundTouch library version string
    215    static const char *getVersionString();
    216 
    217    /// Get SoundTouch library version Id
    218    static uint getVersionId();
    219 
    220    /// Sets new rate control value. Normal rate = 1.0, smaller values
    221    /// represent slower rate, larger faster rates.
    222    void setRate(double newRate);
    223 
    224    /// Sets new tempo control value. Normal tempo = 1.0, smaller values
    225    /// represent slower tempo, larger faster tempo.
    226    void setTempo(double newTempo);
    227 
    228    /// Sets new rate control value as a difference in percents compared
    229    /// to the original rate (-50 .. +100 %)
    230    void setRateChange(double newRate);
    231 
    232    /// Sets new tempo control value as a difference in percents compared
    233    /// to the original tempo (-50 .. +100 %)
    234    void setTempoChange(double newTempo);
    235 
    236    /// Sets new pitch control value. Original pitch = 1.0, smaller values
    237    /// represent lower pitches, larger values higher pitch.
    238    void setPitch(double newPitch);
    239 
    240    /// Sets pitch change in octaves compared to the original pitch  
    241    /// (-1.00 .. +1.00)
    242    void setPitchOctaves(double newPitch);
    243 
    244    /// Sets pitch change in semi-tones compared to the original pitch
    245    /// (-12 .. +12)
    246    void setPitchSemiTones(int newPitch);
    247    void setPitchSemiTones(double newPitch);
    248 
    249    /// Sets the number of channels, 1 = mono, 2 = stereo
    250    void setChannels(uint numChannels);
    251 
    252    /// Sets sample rate.
    253    void setSampleRate(uint srate);
    254 
    255    /// Get ratio between input and output audio durations, useful for calculating
    256    /// processed output duration: if you'll process a stream of N samples, then 
    257    /// you can expect to get out N * getInputOutputSampleRatio() samples.
    258    ///
    259    /// This ratio will give accurate target duration ratio for a full audio track, 
    260    /// given that the the whole track is processed with same processing parameters.
    261    /// 
    262    /// If this ratio is applied to calculate intermediate offsets inside a processing
    263    /// stream, then this ratio is approximate and can deviate +- some tens of milliseconds 
    264    /// from ideal offset, yet by end of the audio stream the duration ratio will become
    265    /// exact.
    266    ///
    267    /// Example: if processing with parameters "-tempo=15 -pitch=-3", the function
    268    /// will return value 0.8695652... Now, if processing an audio stream whose duration
    269    /// is exactly one million audio samples, then you can expect the processed 
    270    /// output duration  be 0.869565 * 1000000 = 869565 samples.
    271    double getInputOutputSampleRatio();
    272 
    273    /// Flushes the last samples from the processing pipeline to the output.
    274    /// Clears also the internal processing buffers.
    275    //
    276    /// Note: This function is meant for extracting the last samples of a sound
    277    /// stream. This function may introduce additional blank samples in the end
    278    /// of the sound stream, and thus it's not recommended to call this function
    279    /// in the middle of a sound stream.
    280    void flush();
    281 
    282    /// Adds 'numSamples' pcs of samples from the 'samples' memory position into
    283    /// the input of the object. Notice that sample rate _has_to_ be set before
    284    /// calling this function, otherwise throws a runtime_error exception.
    285    virtual void putSamples(
    286            const SAMPLETYPE *samples,  ///< Pointer to sample buffer.
    287            uint numSamples                         ///< Number of samples in buffer. Notice
    288                                                    ///< that in case of stereo-sound a single sample
    289                                                    ///< contains data for both channels.
    290            );
    291 
    292    /// Output samples from beginning of the sample buffer. Copies requested samples to 
    293    /// output buffer and removes them from the sample buffer. If there are less than 
    294    /// 'numsample' samples in the buffer, returns all that available.
    295    ///
    296    /// \return Number of samples returned.
    297    virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
    298        uint maxSamples                 ///< How many samples to receive at max.
    299        );
    300 
    301    /// Adjusts book-keeping so that given number of samples are removed from beginning of the 
    302    /// sample buffer without copying them anywhere. 
    303    ///
    304    /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
    305    /// with 'ptrBegin' function.
    306    virtual uint receiveSamples(uint maxSamples   ///< Remove this many samples from the beginning of pipe.
    307        );
    308 
    309    /// Clears all the samples in the object's output and internal processing
    310    /// buffers.
    311    virtual void clear();
    312 
    313    /// Changes a setting controlling the processing system behaviour. See the
    314    /// 'SETTING_...' defines for available setting ID's.
    315    /// 
    316    /// \return 'true' if the setting was successfully changed
    317    bool setSetting(int settingId,   ///< Setting ID number. see SETTING_... defines.
    318                    int value        ///< New setting value.
    319                    );
    320 
    321    /// Reads a setting controlling the processing system behaviour. See the
    322    /// 'SETTING_...' defines for available setting ID's.
    323    ///
    324    /// \return the setting value.
    325    int getSetting(int settingId    ///< Setting ID number, see SETTING_... defines.
    326                   ) const;
    327 
    328    /// Returns number of samples currently unprocessed.
    329    virtual uint numUnprocessedSamples() const;
    330 
    331    /// Return number of channels
    332    uint numChannels() const
    333    {
    334        return channels;
    335    }
    336 
    337    /// Other handy functions that are implemented in the ancestor classes (see
    338    /// classes 'FIFOProcessor' and 'FIFOSamplePipe')
    339    ///
    340    /// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
    341    /// - numSamples()     : Get number of 'ready' samples that can be received with 
    342    ///                      function 'receiveSamples()'
    343    /// - isEmpty()        : Returns nonzero if there aren't any 'ready' samples.
    344    /// - clear()          : Clears all samples from ready/processing buffers.
    345 };
    346 
    347 }
    348 #endif