From efbc9d9043ff8ff92716ddd00a5f61412d535593 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Fri, 9 Apr 2010 14:12:59 +0000 Subject: revert r1783 git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@1785 10f7b99b-c216-0410-bff0-8a66a9350fd8 --- .../SoundTouch/Include/BPMDetect.h | 30 +- .../SoundTouch/Include/FIFOSampleBuffer.h | 64 ++--- .../SoundTouch/Include/FIFOSamplePipe.h | 52 ++-- .../MpcAudioRenderer/SoundTouch/Include/STTypes.h | 160 +++++------ .../SoundTouch/Include/SoundTouch.h | 68 ++--- .../SoundTouch/source/3dnow_win.cpp | 66 ++--- .../SoundTouch/source/AAFilter.cpp | 26 +- .../MpcAudioRenderer/SoundTouch/source/AAFilter.h | 20 +- .../SoundTouch/source/BPMDetect.cpp | 58 ++-- .../SoundTouch/source/FIFOSampleBuffer.cpp | 54 ++-- .../SoundTouch/source/FIRFilter.cpp | 68 +++-- .../MpcAudioRenderer/SoundTouch/source/FIRFilter.h | 106 ++++---- .../SoundTouch/source/PeakFinder.cpp | 50 ++-- .../SoundTouch/source/PeakFinder.h | 20 +- .../SoundTouch/source/RateTransposer.cpp | 170 ++++++------ .../SoundTouch/source/RateTransposer.h | 60 ++-- .../SoundTouch/source/SoundTouch.cpp | 192 ++++++------- .../SoundTouch/source/TDStretch.cpp | 302 ++++++++++----------- .../MpcAudioRenderer/SoundTouch/source/TDStretch.h | 102 ++++--- .../SoundTouch/source/cpu_detect.h | 4 +- .../SoundTouch/source/mmx_optimized.cpp | 36 +-- .../SoundTouch/source/sse_optimized.cpp | 98 +++---- 22 files changed, 889 insertions(+), 917 deletions(-) (limited to 'src/filters/renderer/MpcAudioRenderer/SoundTouch') diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/BPMDetect.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/BPMDetect.h index b87e0ecc5..4def43f1e 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/BPMDetect.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/BPMDetect.h @@ -14,10 +14,10 @@ /// taking absolute value that's smoothed by sliding average. Signal levels that /// are below a couple of times the general RMS amplitude level are cut away to /// leave only notable peaks there. -/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term +/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term /// autocorrelation function of the enveloped signal. -/// - After whole sound data file has been analyzed as above, the bpm level is -/// detected by function 'getBpm' that finds the highest peak of the autocorrelation +/// - After whole sound data file has been analyzed as above, the bpm level is +/// detected by function 'getBpm' that finds the highest peak of the autocorrelation /// function, calculates it's precise location and converts this reading to bpm's. /// /// Author : Copyright (c) Olli Parviainen @@ -76,7 +76,7 @@ class BPMDetect protected: /// Auto-correlation accumulator bins. float *xcorr; - + /// Amplitude envelope sliding average approximation level accumulator float envelopeAccu; @@ -104,15 +104,15 @@ protected: /// Beginning of auto-correlation window: Autocorrelation isn't being updated for /// the first these many correlation bins. int windowStart; - + /// FIFO-buffer for decimated processing samples. soundtouch::FIFOSampleBuffer *buffer; - /// Updates auto-correlation function for given number of decimated samples that - /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe + /// Updates auto-correlation function for given number of decimated samples that + /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe /// though). void updateXCorr(int process_samples /// How many samples are processed. - ); + ); /// Decimates samples to approx. 500 Hz. /// @@ -120,32 +120,32 @@ protected: int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer const soundtouch::SAMPLETYPE *src, ///< Source sample buffer int numsamples ///< Number of source samples. - ); + ); /// Calculates amplitude envelope for the buffer of samples. /// Result is output to 'samples'. void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer int numsamples ///< Number of samples in buffer - ); + ); public: /// Constructor. BPMDetect(int numChannels, ///< Number of channels in sample data. int sampleRate ///< Sample rate in Hz. - ); + ); /// Destructor. virtual ~BPMDetect(); /// Inputs a block of samples for analyzing: Envelopes the samples and then /// updates the autocorrelation estimation. When whole song data has been input - /// in smaller blocks using this function, read the resulting bpm with 'getBpm' - /// function. - /// + /// in smaller blocks using this function, read the resulting bpm with 'getBpm' + /// function. + /// /// Notice that data in 'samples' array can be disrupted in processing. void inputSamples(const soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer int numSamples ///< Number of samples in buffer - ); + ); /// Analyzes the results and returns the BPM rate. Use this function to read result diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSampleBuffer.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSampleBuffer.h index 69755c598..76cbf9514 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSampleBuffer.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSampleBuffer.h @@ -1,12 +1,12 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// A buffer class for temporarily storaging sound samples, operates as a +/// A buffer class for temporarily storaging sound samples, operates as a /// first-in-first-out pipe. /// -/// Samples are added to the end of the sample buffer with the 'putSamples' +/// Samples are added to the end of the sample buffer with the 'putSamples' /// function, and are received from the beginning of the buffer by calling -/// the 'receiveSamples' function. The class automatically removes the -/// output samples from the buffer as well as grows the storage size +/// the 'receiveSamples' function. The class automatically removes the +/// output samples from the buffer as well as grows the storage size /// whenever necessary. /// /// Author : Copyright (c) Olli Parviainen @@ -54,7 +54,7 @@ namespace soundtouch /// Sample buffer working in FIFO (first-in-first-out) principle. The class takes /// care of storage size adjustment and data moving during input/output operations. /// -/// Notice that in case of stereo audio, one sample is considered to consist of +/// Notice that in case of stereo audio, one sample is considered to consist of /// both channel data. class FIFOSampleBuffer : public FIFOSamplePipe { @@ -75,12 +75,12 @@ private: /// Channels, 1=mono, 2=stereo. uint channels; - /// Current position pointer to the buffer. This pointer is increased when samples are + /// Current position pointer to the buffer. This pointer is increased when samples are /// removed from the pipe so that it's necessary to actually rewind buffer (move data) /// only new data when is put to the pipe. uint bufferPos; - /// Rewind the buffer by moving data from position pointed by 'bufferPos' to real + /// Rewind the buffer by moving data from position pointed by 'bufferPos' to real /// beginning of the buffer. void rewind(); @@ -89,72 +89,72 @@ private: /// Returns current capacity. uint getCapacity() const; - + public: /// Constructor FIFOSampleBuffer(int numChannels = 2 ///< Number of channels, 1=mono, 2=stereo. - ///< Default is stereo. - ); + ///< Default is stereo. + ); /// destructor ~FIFOSampleBuffer(); - /// Returns a pointer to the beginning of the output samples. - /// This function is provided for accessing the output samples directly. + /// Returns a pointer to the beginning of the output samples. + /// This function is provided for accessing the output samples directly. /// Please be careful for not to corrupt the book-keeping! /// /// When using this function to output samples, also remember to 'remove' the - /// output samples from the buffer by calling the + /// output samples from the buffer by calling the /// 'receiveSamples(numSamples)' function virtual SAMPLETYPE *ptrBegin(); - /// Returns a pointer to the end of the used part of the sample buffer (i.e. - /// where the new samples are to be inserted). This function may be used for + /// Returns a pointer to the end of the used part of the sample buffer (i.e. + /// where the new samples are to be inserted). This function may be used for /// inserting new samples into the sample buffer directly. Please be careful /// not corrupt the book-keeping! /// - /// When using this function as means for inserting new samples, also remember - /// to increase the sample count afterwards, by calling the + /// When using this function as means for inserting new samples, also remember + /// to increase the sample count afterwards, by calling the /// 'putSamples(numSamples)' function. SAMPLETYPE *ptrEnd( - uint slackCapacity ///< How much free capacity (in samples) there _at least_ - ///< should be so that the caller can succesfully insert the - ///< desired samples to the buffer. If necessary, the function - ///< grows the buffer size to comply with this requirement. - ); + uint slackCapacity ///< How much free capacity (in samples) there _at least_ + ///< should be so that the caller can succesfully insert the + ///< desired samples to the buffer. If necessary, the function + ///< grows the buffer size to comply with this requirement. + ); /// Adds 'numSamples' pcs of samples from the 'samples' memory position to /// the sample buffer. virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples. uint numSamples ///< Number of samples to insert. - ); + ); - /// Adjusts the book-keeping to increase number of samples in the buffer without + /// Adjusts the book-keeping to increase number of samples in the buffer without /// copying any actual samples. /// /// This function is used to update the number of samples in the sample buffer - /// when accessing the buffer directly with 'ptrEnd' function. Please be + /// when accessing the buffer directly with 'ptrEnd' function. Please be /// careful though! virtual void putSamples(uint numSamples ///< Number of samples been inserted. - ); + ); - /// Output samples from beginning of the sample buffer. Copies requested samples to - /// output buffer and removes them from the sample buffer. If there are less than + /// Output samples from beginning of the sample buffer. Copies requested samples to + /// output buffer and removes them from the sample buffer. If there are less than /// 'numsample' samples in the buffer, returns all that available. /// /// \return Number of samples returned. virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples. uint maxSamples ///< How many samples to receive at max. - ); + ); - /// Adjusts book-keeping so that given number of samples are removed from beginning of the - /// sample buffer without copying them anywhere. + /// Adjusts book-keeping so that given number of samples are removed from beginning of the + /// sample buffer without copying them anywhere. /// /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly /// with 'ptrBegin' function. virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe. - ); + ); /// Returns number of samples currently available. virtual uint numSamples() const; diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSamplePipe.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSamplePipe.h index 017b132e8..b5fc3b779 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSamplePipe.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/FIFOSamplePipe.h @@ -5,7 +5,7 @@ /// into one end of the pipe with the 'putSamples' function, and the processed /// samples are received from the other end with the 'receiveSamples' function. /// -/// 'FIFOProcessor' : A base class for classes the do signal processing with +/// 'FIFOProcessor' : A base class for classes the do signal processing with /// the samples while operating like a first-in-first-out pipe. When samples /// are input with the 'putSamples' function, the class processes them /// and moves the processed samples to the given 'output' pipe object, which @@ -63,12 +63,12 @@ public: virtual ~FIFOSamplePipe() {} - /// Returns a pointer to the beginning of the output samples. - /// This function is provided for accessing the output samples directly. + /// Returns a pointer to the beginning of the output samples. + /// This function is provided for accessing the output samples directly. /// Please be careful for not to corrupt the book-keeping! /// /// When using this function to output samples, also remember to 'remove' the - /// output samples from the buffer by calling the + /// output samples from the buffer by calling the /// 'receiveSamples(numSamples)' function virtual SAMPLETYPE *ptrBegin() = 0; @@ -76,12 +76,12 @@ public: /// the sample buffer. virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples. uint numSamples ///< Number of samples to insert. - ) = 0; + ) = 0; // Moves samples from the 'other' pipe instance to this instance. void moveSamples(FIFOSamplePipe &other ///< Other pipe instance where from the receive the data. - ) + ) { int oNumSamples = other.numSamples(); @@ -89,22 +89,22 @@ public: other.receiveSamples(oNumSamples); }; - /// Output samples from beginning of the sample buffer. Copies requested samples to - /// output buffer and removes them from the sample buffer. If there are less than + /// Output samples from beginning of the sample buffer. Copies requested samples to + /// output buffer and removes them from the sample buffer. If there are less than /// 'numsample' samples in the buffer, returns all that available. /// /// \return Number of samples returned. virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples. uint maxSamples ///< How many samples to receive at max. - ) = 0; + ) = 0; - /// Adjusts book-keeping so that given number of samples are removed from beginning of the - /// sample buffer without copying them anywhere. + /// Adjusts book-keeping so that given number of samples are removed from beginning of the + /// sample buffer without copying them anywhere. /// /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly /// with 'ptrBegin' function. virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe. - ) = 0; + ) = 0; /// Returns number of samples currently available. virtual uint numSamples() const = 0; @@ -118,15 +118,15 @@ public: -/// Base-class for sound processing routines working in FIFO principle. With this base +/// Base-class for sound processing routines working in FIFO principle. With this base /// class it's easy to implement sound processing stages that can be chained together, -/// so that samples that are fed into beginning of the pipe automatically go through +/// so that samples that are fed into beginning of the pipe automatically go through /// all the processing stages. /// -/// When samples are input to this class, they're first processed and then put to +/// When samples are input to this class, they're first processed and then put to /// the FIFO pipe that's defined as output of this class. This output pipe can be /// either other processing stage or a FIFO sample buffer. -class FIFOProcessor : public FIFOSamplePipe +class FIFOProcessor :public FIFOSamplePipe { protected: /// Internal pipe where processed samples are put. @@ -141,7 +141,7 @@ protected: } - /// Constructor. Doesn't define output pipe; it has to be set be + /// Constructor. Doesn't define output pipe; it has to be set be /// 'setOutPipe' function. FIFOProcessor() { @@ -163,12 +163,12 @@ protected: } - /// Returns a pointer to the beginning of the output samples. - /// This function is provided for accessing the output samples directly. + /// Returns a pointer to the beginning of the output samples. + /// This function is provided for accessing the output samples directly. /// Please be careful for not to corrupt the book-keeping! /// /// When using this function to output samples, also remember to 'remove' the - /// output samples from the buffer by calling the + /// output samples from the buffer by calling the /// 'receiveSamples(numSamples)' function virtual SAMPLETYPE *ptrBegin() { @@ -177,26 +177,26 @@ protected: public: - /// Output samples from beginning of the sample buffer. Copies requested samples to - /// output buffer and removes them from the sample buffer. If there are less than + /// Output samples from beginning of the sample buffer. Copies requested samples to + /// output buffer and removes them from the sample buffer. If there are less than /// 'numsample' samples in the buffer, returns all that available. /// /// \return Number of samples returned. virtual uint receiveSamples(SAMPLETYPE *outBuffer, ///< Buffer where to copy output samples. uint maxSamples ///< How many samples to receive at max. - ) + ) { return output->receiveSamples(outBuffer, maxSamples); } - /// Adjusts book-keeping so that given number of samples are removed from beginning of the - /// sample buffer without copying them anywhere. + /// Adjusts book-keeping so that given number of samples are removed from beginning of the + /// sample buffer without copying them anywhere. /// /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly /// with 'ptrBegin' function. virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe. - ) + ) { return output->receiveSamples(maxSamples); } diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/STTypes.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/STTypes.h index 33ff19d28..cad502ffa 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/STTypes.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/STTypes.h @@ -43,17 +43,17 @@ typedef unsigned int uint; typedef unsigned long ulong; #ifdef __GNUC__ -// In GCC, include soundtouch_config.h made by config scritps -#include "soundtouch_config.h" + // In GCC, include soundtouch_config.h made by config scritps + #include "soundtouch_config.h" #endif #ifndef _WINDEF_ -// if these aren't defined already by Windows headers, define now + // if these aren't defined already by Windows headers, define now -typedef int BOOL; + typedef int BOOL; -#define FALSE 0 -#define TRUE 1 + #define FALSE 0 + #define TRUE 1 #endif // _WINDEF_ @@ -61,88 +61,88 @@ typedef int BOOL; namespace soundtouch { -/// Activate these undef's to overrule the possible sampletype +/// Activate these undef's to overrule the possible sampletype /// setting inherited from some other header file: //#undef INTEGER_SAMPLES //#undef FLOAT_SAMPLES #if !(INTEGER_SAMPLES || FLOAT_SAMPLES) - -/// Choose either 32bit floating point or 16bit integer sampletype -/// by choosing one of the following defines, unless this selection -/// has already been done in some other file. -//// -/// Notes: -/// - In Windows environment, choose the sample format with the -/// following defines. -/// - In GNU environment, the floating point samples are used by -/// default, but integer samples can be chosen by giving the -/// following switch to the configure script: -/// ./configure --enable-integer-samples -/// However, if you still prefer to select the sample format here -/// also in GNU environment, then please #undef the INTEGER_SAMPLE -/// and FLOAT_SAMPLE defines first as in comments above. -//#define INTEGER_SAMPLES 1 //< 16bit integer samples -#define FLOAT_SAMPLES 1 //< 32bit float samples - -#endif - -#ifndef _WIN64 -/// Define this to allow X86-specific assembler/intrinsic optimizations. -/// Notice that library contains also usual C++ versions of each of these -/// these routines, so if you're having difficulties getting the optimized -/// routines compiled for whatever reason, you may disable these optimizations -/// to make the library compile. - -#define ALLOW_X86_OPTIMIZATIONS 1 - -#endif - -// If defined, allows the SIMD-optimized routines to take minor shortcuts -// for improved performance. Undefine to require faithfully similar SIMD -// calculations as in normal C implementation. -#define ALLOW_NONEXACT_SIMD_OPTIMIZATION 1 - - -#ifdef INTEGER_SAMPLES -// 16bit integer sample type -typedef short SAMPLETYPE; -// data type for sample accumulation: Use 32bit integer to prevent overflows -typedef long LONG_SAMPLETYPE; - -#ifdef FLOAT_SAMPLES -// check that only one sample type is defined -#error "conflicting sample types defined" -#endif // FLOAT_SAMPLES - -#ifdef ALLOW_X86_OPTIMIZATIONS -// Allow MMX optimizations -#define ALLOW_MMX 1 -#endif - -#else - -// floating point samples -typedef float SAMPLETYPE; -// data type for sample accumulation: Use double to utilize full precision. -typedef double LONG_SAMPLETYPE; - -#ifdef ALLOW_X86_OPTIMIZATIONS -// Allow 3DNow! and SSE optimizations -#if WIN32 -#define ALLOW_3DNOW 1 -#endif - -#define ALLOW_SSE 1 -#endif - -#endif // INTEGER_SAMPLES + + /// Choose either 32bit floating point or 16bit integer sampletype + /// by choosing one of the following defines, unless this selection + /// has already been done in some other file. + //// + /// Notes: + /// - In Windows environment, choose the sample format with the + /// following defines. + /// - In GNU environment, the floating point samples are used by + /// default, but integer samples can be chosen by giving the + /// following switch to the configure script: + /// ./configure --enable-integer-samples + /// However, if you still prefer to select the sample format here + /// also in GNU environment, then please #undef the INTEGER_SAMPLE + /// and FLOAT_SAMPLE defines first as in comments above. + //#define INTEGER_SAMPLES 1 //< 16bit integer samples + #define FLOAT_SAMPLES 1 //< 32bit float samples + + #endif + + #ifndef _WIN64 + /// Define this to allow X86-specific assembler/intrinsic optimizations. + /// Notice that library contains also usual C++ versions of each of these + /// these routines, so if you're having difficulties getting the optimized + /// routines compiled for whatever reason, you may disable these optimizations + /// to make the library compile. + + #define ALLOW_X86_OPTIMIZATIONS 1 + + #endif + + // If defined, allows the SIMD-optimized routines to take minor shortcuts + // for improved performance. Undefine to require faithfully similar SIMD + // calculations as in normal C implementation. + #define ALLOW_NONEXACT_SIMD_OPTIMIZATION 1 + + + #ifdef INTEGER_SAMPLES + // 16bit integer sample type + typedef short SAMPLETYPE; + // data type for sample accumulation: Use 32bit integer to prevent overflows + typedef long LONG_SAMPLETYPE; + + #ifdef FLOAT_SAMPLES + // check that only one sample type is defined + #error "conflicting sample types defined" + #endif // FLOAT_SAMPLES + + #ifdef ALLOW_X86_OPTIMIZATIONS + // Allow MMX optimizations + #define ALLOW_MMX 1 + #endif + + #else + + // floating point samples + typedef float SAMPLETYPE; + // data type for sample accumulation: Use double to utilize full precision. + typedef double LONG_SAMPLETYPE; + + #ifdef ALLOW_X86_OPTIMIZATIONS + // Allow 3DNow! and SSE optimizations + #if WIN32 + #define ALLOW_3DNOW 1 + #endif + + #define ALLOW_SSE 1 + #endif + + #endif // INTEGER_SAMPLES }; -// When this #define is active, eliminates a clicking sound when the "rate" or "pitch" -// parameter setting crosses from value <1 to >=1 or vice versa during processing. -// Default is off as such crossover is untypical case and involves a slight sound +// When this #define is active, eliminates a clicking sound when the "rate" or "pitch" +// parameter setting crosses from value <1 to >=1 or vice versa during processing. +// Default is off as such crossover is untypical case and involves a slight sound // quality compromise. //#define PREVENT_CLICK_AT_RATE_CROSSOVER 1 diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/SoundTouch.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/SoundTouch.h index e382faafd..0e042d3c0 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/SoundTouch.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/Include/SoundTouch.h @@ -1,27 +1,27 @@ ////////////////////////////////////////////////////////////////////////////// /// -/// SoundTouch - main class for tempo/pitch/rate adjusting routines. +/// SoundTouch - main class for tempo/pitch/rate adjusting routines. /// /// Notes: -/// - Initialize the SoundTouch object instance by setting up the sound stream -/// parameters with functions 'setSampleRate' and 'setChannels', then set +/// - Initialize the SoundTouch object instance by setting up the sound stream +/// parameters with functions 'setSampleRate' and 'setChannels', then set /// desired tempo/pitch/rate settings with the corresponding functions. /// -/// - The SoundTouch class behaves like a first-in-first-out pipeline: The +/// - The SoundTouch class behaves like a first-in-first-out pipeline: The /// samples that are to be processed are fed into one of the pipe by calling -/// function 'putSamples', while the ready processed samples can be read +/// function 'putSamples', while the ready processed samples can be read /// from the other end of the pipeline with function 'receiveSamples'. -/// -/// - The SoundTouch processing classes require certain sized 'batches' of -/// samples in order to process the sound. For this reason the classes buffer -/// incoming samples until there are enough of samples available for +/// +/// - The SoundTouch processing classes require certain sized 'batches' of +/// samples in order to process the sound. For this reason the classes buffer +/// incoming samples until there are enough of samples available for /// processing, then they carry out the processing step and consequently /// make the processed samples available for outputting. -/// -/// - For the above reason, the processing routines introduce a certain +/// +/// - For the above reason, the processing routines introduce a certain /// 'latency' between the input and output, so that the samples input to -/// SoundTouch may not be immediately available in the output, and neither -/// the amount of outputtable samples may not immediately be in direct +/// SoundTouch may not be immediately available in the output, and neither +/// the amount of outputtable samples may not immediately be in direct /// relationship with the amount of previously input samples. /// /// - The tempo/pitch/rate control parameters can be altered during processing. @@ -30,8 +30,8 @@ /// required. /// /// - This class utilizes classes 'TDStretch' for tempo change (without modifying -/// pitch) and 'RateTransposer' for changing the playback rate (that is, both -/// tempo and pitch in the same ratio) of the sound. The third available control +/// pitch) and 'RateTransposer' for changing the playback rate (that is, both +/// tempo and pitch in the same ratio) of the sound. The third available control /// 'pitch' (change pitch but maintain tempo) is produced by a combination of /// combining the two other controls. /// @@ -98,20 +98,20 @@ namespace soundtouch /// quality compromising) #define SETTING_USE_QUICKSEEK 2 -/// Time-stretch algorithm single processing sequence length in milliseconds. This determines -/// to how long sequences the original sound is chopped in the time-stretch algorithm. +/// Time-stretch algorithm single processing sequence length in milliseconds. This determines +/// to how long sequences the original sound is chopped in the time-stretch algorithm. /// See "STTypes.h" or README for more information. #define SETTING_SEQUENCE_MS 3 -/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the -/// best possible overlapping location. This determines from how wide window the algorithm -/// may look for an optimal joining location when mixing the sound sequences back together. +/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the +/// best possible overlapping location. This determines from how wide window the algorithm +/// may look for an optimal joining location when mixing the sound sequences back together. /// See "STTypes.h" or README for more information. #define SETTING_SEEKWINDOW_MS 4 -/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences -/// are mixed back together, to form a continuous sound stream, this parameter defines over -/// how long period the two consecutive sequences are let to overlap each other. +/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences +/// are mixed back together, to form a continuous sound stream, this parameter defines over +/// how long period the two consecutive sequences are let to overlap each other. /// See "STTypes.h" or README for more information. #define SETTING_OVERLAP_MS 5 @@ -137,7 +137,7 @@ private: /// Flag: Has sample rate been set? BOOL bSrateSet; - /// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and + /// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and /// 'virtualPitch' parameters. void calcEffectiveRateAndTempo(); @@ -181,7 +181,7 @@ public: /// represent lower pitches, larger values higher pitch. void setPitch(float newPitch); - /// Sets pitch change in octaves compared to the original pitch + /// Sets pitch change in octaves compared to the original pitch /// (-1.00 .. +1.00) void setPitchOctaves(float newPitch); @@ -209,11 +209,11 @@ public: /// the input of the object. Notice that sample rate _has_to_ be set before /// calling this function, otherwise throws a runtime_error exception. virtual void putSamples( - const SAMPLETYPE *samples, ///< Pointer to sample buffer. - uint numSamples ///< Number of samples in buffer. Notice - ///< that in case of stereo-sound a single sample - ///< contains data for both channels. - ); + const SAMPLETYPE *samples, ///< Pointer to sample buffer. + uint numSamples ///< Number of samples in buffer. Notice + ///< that in case of stereo-sound a single sample + ///< contains data for both channels. + ); /// Clears all the samples in the object's output and internal processing /// buffers. @@ -221,18 +221,18 @@ public: /// Changes a setting controlling the processing system behaviour. See the /// 'SETTING_...' defines for available setting ID's. - /// + /// /// \return 'TRUE' if the setting was succesfully changed BOOL setSetting(int settingId, ///< Setting ID number. see SETTING_... defines. int value ///< New setting value. - ); + ); /// Reads a setting controlling the processing system behaviour. See the /// 'SETTING_...' defines for available setting ID's. /// /// \return the setting value. int getSetting(int settingId ///< Setting ID number, see SETTING_... defines. - ) const; + ) const; /// Returns number of samples currently unprocessed. virtual uint numUnprocessedSamples() const; @@ -242,7 +242,7 @@ public: /// classes 'FIFOProcessor' and 'FIFOSamplePipe') /// /// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch. - /// - numSamples() : Get number of 'ready' samples that can be received with + /// - numSamples() : Get number of 'ready' samples that can be received with /// function 'receiveSamples()' /// - isEmpty() : Returns nonzero if there aren't any 'ready' samples. /// - clear() : Clears all samples from ready/processing buffers. diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/3dnow_win.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/3dnow_win.cpp index 7b309a427..f0a9d7ecc 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/3dnow_win.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/3dnow_win.cpp @@ -1,32 +1,32 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon +/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon /// processors. All 3DNow! optimized functions have been gathered into this -/// single source code file, regardless to their class or original source code -/// file, in order to ease porting the library to other compiler and processor +/// single source code file, regardless to their class or original source code +/// file, in order to ease porting the library to other compiler and processor /// platforms. /// -/// By the way; the performance gain depends heavily on the CPU generation: On -/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the -/// difference to the original routines stayed at unremarkable 8%! Such a small -/// improvement on Athlon is due to 3DNow can perform only two operations in +/// By the way; the performance gain depends heavily on the CPU generation: On +/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the +/// difference to the original routines stayed at unremarkable 8%! Such a small +/// improvement on Athlon is due to 3DNow can perform only two operations in /// parallel, and obviously also the Athlon FPU is doing a very good job with -/// the standard C floating point routines! Here these routines are anyway, -/// although it might not be worth the effort to convert these to GCC platform, -/// for Athlon CPU at least. The situation is different regarding the SSE -/// optimizations though, thanks to the four parallel operations of SSE that +/// the standard C floating point routines! Here these routines are anyway, +/// although it might not be worth the effort to convert these to GCC platform, +/// for Athlon CPU at least. The situation is different regarding the SSE +/// optimizations though, thanks to the four parallel operations of SSE that /// already make a difference. -/// -/// This file is to be compiled in Windows platform with Microsoft Visual C++ +/// +/// This file is to be compiled in Windows platform with Microsoft Visual C++ /// Compiler. Please see '3dnow_gcc.cpp' for the gcc compiler version for all /// GNU platforms (if file supplied). /// -/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ -/// 6.0 processor pack" update to support 3DNow! instruction set. The update is +/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ +/// 6.0 processor pack" update to support 3DNow! instruction set. The update is /// available for download at Microsoft Developers Network, see here: /// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx /// -/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and +/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and /// perform a search with keywords "processor pack". /// /// Author : Copyright (c) Olli Parviainen @@ -73,7 +73,7 @@ using namespace soundtouch; #ifdef ALLOW_3DNOW -// 3DNow! routines available only with float sample type +// 3DNow! routines available only with float sample type ////////////////////////////////////////////////////////////////////////////// // @@ -111,10 +111,10 @@ double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) c } */ - _asm + _asm { // give prefetch hints to CPU of what data are to be needed soonish. - // give more aggressive hints on pV1 as that changes more between different calls + // give more aggressive hints on pV1 as that changes more between different calls // while pV2 stays the same. prefetch [pV1] prefetch [pV2] @@ -128,7 +128,7 @@ double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) c mov ecx, overlapLengthLocal shr ecx, 2 // div by four - loop1: + loop1: movq mm1, [eax] prefetch [eax + 32] // give a prefetch hint to CPU what data are to be needed soonish pfmul mm1, [ebx] @@ -153,7 +153,7 @@ double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) c dec ecx jnz loop1 - // add halfs of mm0 together and return the result. + // add halfs of mm0 together and return the result. // note: mm1 is used as a dummy parameter only, we actually don't care about it's value pfacc mm0, mm1 movd corr, mm0 @@ -202,15 +202,15 @@ void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint u // Ensure that filter coeffs array is aligned to 16-byte boundary delete[] filterCoeffsUnalign; filterCoeffsUnalign = new float[2 * newLength + 4]; - filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & (uint) - 16); + filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & (uint)-16); fDivider = (float)resultDivider; - // rearrange the filter coefficients for mmx routines - for(i = 0; i < newLength; i ++) + // rearrange the filter coefficients for mmx routines + for (i = 0; i < newLength; i ++) { filterCoeffsAlign[2 * i + 0] = - filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider; + filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider; } } @@ -219,7 +219,7 @@ void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint u uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint numSamples) const { float *filterCoeffsLocal = filterCoeffsAlign; - uint count = (numSamples - length) & (uint) - 2; + uint count = (numSamples - length) & (uint)-2; uint lengthLocal = length / 4; assert(length != 0); @@ -239,26 +239,26 @@ uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint nu suml2 = sumr2 = 0.0; ptr = src; filterCoeffsLocal = filterCoeffs; - for (i = 0; i < lengthLocal; i ++) + for (i = 0; i < lengthLocal; i ++) { // unroll loop for efficiency. - suml1 += ptr[0] * filterCoeffsLocal[0] + + suml1 += ptr[0] * filterCoeffsLocal[0] + ptr[2] * filterCoeffsLocal[2] + ptr[4] * filterCoeffsLocal[4] + ptr[6] * filterCoeffsLocal[6]; - sumr1 += ptr[1] * filterCoeffsLocal[1] + + sumr1 += ptr[1] * filterCoeffsLocal[1] + ptr[3] * filterCoeffsLocal[3] + ptr[5] * filterCoeffsLocal[5] + ptr[7] * filterCoeffsLocal[7]; - suml2 += ptr[8] * filterCoeffsLocal[0] + + suml2 += ptr[8] * filterCoeffsLocal[0] + ptr[10] * filterCoeffsLocal[2] + ptr[12] * filterCoeffsLocal[4] + ptr[14] * filterCoeffsLocal[6]; - sumr2 += ptr[9] * filterCoeffsLocal[1] + + sumr2 += ptr[9] * filterCoeffsLocal[1] + ptr[11] * filterCoeffsLocal[3] + ptr[13] * filterCoeffsLocal[5] + ptr[15] * filterCoeffsLocal[7]; @@ -283,7 +283,7 @@ uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint nu mov edx, count shr edx, 1 - loop1: + loop1: // "outer loop" : during each round 2*2 output samples are calculated prefetch [ebx] // give a prefetch hint to CPU what data are to be needed soonish prefetch [filterCoeffsLocal] // give a prefetch hint to CPU what data are to be needed soonish @@ -294,7 +294,7 @@ uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint nu pxor mm1, mm1 mov ecx, lengthLocal - loop2: + loop2: // "inner loop" : during each round four FIR filter taps are evaluated for 2*2 output samples movq mm2, [edi] movq mm3, mm2 diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.cpp index fc7ff4716..96abda49c 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.cpp @@ -1,9 +1,9 @@ //////////////////////////////////////////////////////////////////////////////// /// /// FIR low-pass (anti-alias) filter with filter coefficient design routine and -/// MMX optimization. -/// -/// Anti-alias filter is used to prevent folding of high frequencies when +/// MMX optimization. +/// +/// Anti-alias filter is used to prevent folding of high frequencies when /// transposing the sample rate with interpolation. /// /// Author : Copyright (c) Olli Parviainen @@ -98,7 +98,7 @@ void AAFilter::setLength(uint newLength) void AAFilter::calculateCoeffs() { uint i; - double cntTemp, temp, tempCoeff, h, w; + double cntTemp, temp, tempCoeff,h, w; double fc2, wc; double scaleCoeff, sum; double *work; @@ -112,21 +112,21 @@ void AAFilter::calculateCoeffs() work = new double[length]; coeffs = new SAMPLETYPE[length]; - fc2 = 2.0 * cutoffFreq; + fc2 = 2.0 * cutoffFreq; wc = PI * fc2; tempCoeff = TWOPI / (double)length; sum = 0; - for(i = 0; i < length; i ++) + for (i = 0; i < length; i ++) { cntTemp = (double)i - (double)(length / 2); temp = cntTemp * wc; - if(temp != 0) + if (temp != 0) { h = fc2 * sin(temp) / temp; // sinc function - } - else + } + else { h = 1.0; } @@ -135,7 +135,7 @@ void AAFilter::calculateCoeffs() temp = w * h; work[i] = temp; - // calc net sum of coefficients + // calc net sum of coefficients sum += temp; } @@ -151,7 +151,7 @@ void AAFilter::calculateCoeffs() // divided by 16384 scaleCoeff = 16384.0f / sum; - for(i = 0; i < length; i ++) + for (i = 0; i < length; i ++) { // scale & round to nearest integer temp = work[i] * scaleCoeff; @@ -169,8 +169,8 @@ void AAFilter::calculateCoeffs() } -// Applies the filter to the given sequence of samples. -// Note : The amount of outputted samples is by value of 'filter length' +// Applies the filter to the given sequence of samples. +// Note : The amount of outputted samples is by value of 'filter length' // smaller than the amount of input samples. uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const { diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.h index e17b08c72..d5c8ce4ca 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/AAFilter.h @@ -1,10 +1,10 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo -/// while maintaining the original pitch by using a time domain WSOLA-like method +/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo +/// while maintaining the original pitch by using a time domain WSOLA-like method /// with several performance-increasing tweaks. /// -/// Anti-alias filter is used to prevent folding of high frequencies when +/// Anti-alias filter is used to prevent folding of high frequencies when /// transposing the sample rate with interpolation. /// /// Author : Copyright (c) Olli Parviainen @@ -67,8 +67,8 @@ public: ~AAFilter(); - /// Sets new anti-alias filter cut-off edge frequency, scaled to sampling - /// frequency (nyquist frequency = 0.5). The filter will cut off the + /// Sets new anti-alias filter cut-off edge frequency, scaled to sampling + /// frequency (nyquist frequency = 0.5). The filter will cut off the /// frequencies than that. void setCutoffFreq(double newCutoffFreq); @@ -77,12 +77,12 @@ public: uint getLength() const; - /// Applies the filter to the given sequence of samples. - /// Note : The amount of outputted samples is by value of 'filter length' + /// Applies the filter to the given sequence of samples. + /// Note : The amount of outputted samples is by value of 'filter length' /// smaller than the amount of input samples. - uint evaluate(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples, + uint evaluate(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples, uint numChannels) const; }; diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/BPMDetect.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/BPMDetect.cpp index bae075e6d..405f514bf 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/BPMDetect.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/BPMDetect.cpp @@ -14,10 +14,10 @@ /// taking absolute value that's smoothed by sliding average. Signal levels that /// are below a couple of times the general RMS amplitude level are cut away to /// leave only notable peaks there. -/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term +/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term /// autocorrelation function of the enveloped signal. -/// - After whole sound data file has been analyzed as above, the bpm level is -/// detected by function 'getBpm' that finds the highest peak of the autocorrelation +/// - After whole sound data file has been analyzed as above, the bpm level is +/// detected by function 'getBpm' that finds the highest peak of the autocorrelation /// function, calculates it's precise location and converts this reading to bpm's. /// /// Author : Copyright (c) Olli Parviainen @@ -66,7 +66,7 @@ using namespace soundtouch; #define INPUT_BLOCK_SAMPLES 2048 #define DECIMATED_BLOCK_SAMPLES 256 -/// decay constant for calculating RMS volume sliding average approximation +/// decay constant for calculating RMS volume sliding average approximation /// (time constant is about 10 sec) const float avgdecay = 0.99986f; @@ -128,16 +128,16 @@ BPMDetect::~BPMDetect() -/// convert to mono, low-pass filter & decimate to about 500 Hz. +/// convert to mono, low-pass filter & decimate to about 500 Hz. /// return number of outputted samples. /// -/// Decimation is used to remove the unnecessary frequencies and thus to reduce -/// the amount of data needed to be processed as calculating autocorrelation +/// Decimation is used to remove the unnecessary frequencies and thus to reduce +/// the amount of data needed to be processed as calculating autocorrelation /// function is a very-very heavy operation. /// -/// Anti-alias filtering is done simply by averaging the samples. This is really a +/// Anti-alias filtering is done simply by averaging the samples. This is really a /// poor-man's anti-alias filtering, but it's not so critical in this kind of application -/// (it'd also be difficult to design a high-quality filter with steep cut-off at very +/// (it'd also be difficult to design a high-quality filter with steep cut-off at very /// narrow band) int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples) { @@ -147,19 +147,19 @@ int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples) assert(channels > 0); assert(decimateBy > 0); outcount = 0; - for(count = 0; count < numsamples; count ++) + for (count = 0; count < numsamples; count ++) { int j; // convert to mono and accumulate - for(j = 0; j < channels; j ++) + for (j = 0; j < channels; j ++) { decimateSum += src[j]; } src += j; decimateCount ++; - if(decimateCount >= decimateBy) + if (decimateCount >= decimateBy) { // Store every Nth sample only out = (LONG_SAMPLETYPE)(decimateSum / (decimateBy * channels)); @@ -167,11 +167,11 @@ int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples) decimateCount = 0; #ifdef INTEGER_SAMPLES // check ranges for sure (shouldn't actually be necessary) - if(out > 32767) + if (out > 32767) { out = 32767; - } - else if(out < -32768) + } + else if (out < -32768) { out = -32768; } @@ -190,25 +190,25 @@ void BPMDetect::updateXCorr(int process_samples) { int offs; SAMPLETYPE *pBuffer; - + assert(buffer->numSamples() >= (uint)(process_samples + windowLen)); pBuffer = buffer->ptrBegin(); - for(offs = windowStart; offs < windowLen; offs ++) + for (offs = windowStart; offs < windowLen; offs ++) { LONG_SAMPLETYPE sum; int i; sum = 0; - for(i = 0; i < process_samples; i ++) + for (i = 0; i < process_samples; i ++) { sum += pBuffer[i] * pBuffer[i + offs]; // scaling the sub-result shouldn't be necessary } -// xcorr[offs] *= xcorr_decay; // decay 'xcorr' here with suitable coefficients - // if it's desired that the system adapts automatically to - // various bpms, e.g. in processing continouos music stream. - // The 'xcorr_decay' should be a value that's smaller than but - // close to one, and should also depend on 'process_samples' value. +// xcorr[offs] *= xcorr_decay; // decay 'xcorr' here with suitable coefficients + // if it's desired that the system adapts automatically to + // various bpms, e.g. in processing continouos music stream. + // The 'xcorr_decay' should be a value that's smaller than but + // close to one, and should also depend on 'process_samples' value. xcorr[offs] += (float)sum; } @@ -217,7 +217,7 @@ void BPMDetect::updateXCorr(int process_samples) // Calculates envelope of the sample data -void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples) +void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples) { const float decay = 0.7f; // decay constant for smoothing the envelope const float norm = (1 - decay); @@ -226,7 +226,7 @@ void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples) LONG_SAMPLETYPE out; float val; - for(i = 0; i < numsamples; i ++) + for (i = 0; i < numsamples; i ++) { // calc average RMS volume RMSVolumeAccu *= avgdecay; @@ -245,7 +245,7 @@ void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples) #ifdef INTEGER_SAMPLES // cut peaks (shouldn't be necessary though) - if(out > 32767) out = 32767; + if (out > 32767) out = 32767; #endif // INTEGER_SAMPLES samples[i] = (SAMPLETYPE)out; } @@ -258,7 +258,7 @@ void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples) SAMPLETYPE decimated[DECIMATED_BLOCK_SAMPLES]; // iterate so that max INPUT_BLOCK_SAMPLES processed per iteration - while(numSamples > 0) + while (numSamples > 0) { int block; int decSamples; @@ -276,7 +276,7 @@ void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples) } // when the buffer has enought samples for processing... - if((int)buffer->numSamples() > windowLen) + if ((int)buffer->numSamples() > windowLen) { int processLength; @@ -301,7 +301,7 @@ float BPMDetect::getBpm() peakPos = peakFinder.detectPeak(xcorr, windowStart, windowLen); assert(decimateBy != 0); - if(peakPos < 1e-6) return 0.0; // detection failed. + if (peakPos < 1e-6) return 0.0; // detection failed. // calculate BPM return (float)(60.0 * (((double)sampleRate / (double)decimateBy) / peakPos)); diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIFOSampleBuffer.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIFOSampleBuffer.cpp index 1e467a12c..01f64b083 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIFOSampleBuffer.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIFOSampleBuffer.cpp @@ -1,12 +1,12 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// A buffer class for temporarily storaging sound samples, operates as a +/// A buffer class for temporarily storaging sound samples, operates as a /// first-in-first-out pipe. /// -/// Samples are added to the end of the sample buffer with the 'putSamples' +/// Samples are added to the end of the sample buffer with the 'putSamples' /// function, and are received from the beginning of the buffer by calling -/// the 'receiveSamples' function. The class automatically removes the -/// outputted samples from the buffer, as well as grows the buffer size +/// the 'receiveSamples' function. The class automatically removes the +/// outputted samples from the buffer, as well as grows the buffer size /// whenever necessary. /// /// Author : Copyright (c) Olli Parviainen @@ -63,7 +63,7 @@ FIFOSampleBuffer::FIFOSampleBuffer(int numChannels) samplesInBuffer = 0; bufferPos = 0; channels = (uint)numChannels; - ensureCapacity(32); // allocate initial capacity + ensureCapacity(32); // allocate initial capacity } @@ -89,11 +89,11 @@ void FIFOSampleBuffer::setChannels(int numChannels) // if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and -// zeroes this pointer by copying samples from the 'bufferPos' pointer +// zeroes this pointer by copying samples from the 'bufferPos' pointer // location on to the beginning of the buffer. void FIFOSampleBuffer::rewind() { - if(buffer && bufferPos) + if (buffer && bufferPos) { memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer); bufferPos = 0; @@ -101,7 +101,7 @@ void FIFOSampleBuffer::rewind() } -// Adds 'numSamples' pcs of samples from the 'samples' memory position to +// Adds 'numSamples' pcs of samples from the 'samples' memory position to // the sample buffer. void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples) { @@ -114,7 +114,7 @@ void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples) // samples. // // This function is used to update the number of samples in the sample buffer -// when accessing the buffer directly with 'ptrEnd' function. Please be +// when accessing the buffer directly with 'ptrEnd' function. Please be // careful though! void FIFOSampleBuffer::putSamples(uint nSamples) { @@ -126,31 +126,31 @@ void FIFOSampleBuffer::putSamples(uint nSamples) } -// Returns a pointer to the end of the used part of the sample buffer (i.e. -// where the new samples are to be inserted). This function may be used for -// inserting new samples into the sample buffer directly. Please be careful! +// Returns a pointer to the end of the used part of the sample buffer (i.e. +// where the new samples are to be inserted). This function may be used for +// inserting new samples into the sample buffer directly. Please be careful! // // Parameter 'slackCapacity' tells the function how much free capacity (in // terms of samples) there _at least_ should be, in order to the caller to -// succesfully insert all the required samples to the buffer. When necessary, +// succesfully insert all the required samples to the buffer. When necessary, // the function grows the buffer size to comply with this requirement. // -// When using this function as means for inserting new samples, also remember -// to increase the sample count afterwards, by calling the +// When using this function as means for inserting new samples, also remember +// to increase the sample count afterwards, by calling the // 'putSamples(numSamples)' function. -SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity) +SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity) { ensureCapacity(samplesInBuffer + slackCapacity); return buffer + samplesInBuffer * channels; } -// Returns a pointer to the beginning of the currently non-outputted samples. -// This function is provided for accessing the output samples directly. +// Returns a pointer to the beginning of the currently non-outputted samples. +// This function is provided for accessing the output samples directly. // Please be careful! // // When using this function to output samples, also remember to 'remove' the -// outputted samples from the buffer by calling the +// outputted samples from the buffer by calling the // 'receiveSamples(numSamples)' function SAMPLETYPE *FIFOSampleBuffer::ptrBegin() { @@ -167,19 +167,19 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement) { SAMPLETYPE *tempUnaligned, *temp; - if(capacityRequirement > getCapacity()) + if (capacityRequirement > getCapacity()) { // enlarge the buffer in 4kbyte steps (round up to next 4k boundary) - sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint) - 4096; + sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096; assert(sizeInBytes % 2 == 0); tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)]; - if(tempUnaligned == NULL) + if (tempUnaligned == NULL) { throw std::runtime_error("Couldn't allocate memory!\n"); } // Align the buffer to begin at 16byte cache line boundary for optimal performance - temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong) - 16); - if(samplesInBuffer) + temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong)-16); + if (samplesInBuffer) { memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE)); } @@ -187,8 +187,8 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement) buffer = temp; bufferUnaligned = tempUnaligned; bufferPos = 0; - } - else + } + else { // simply rewind the buffer (if necessary) rewind(); @@ -231,7 +231,7 @@ uint FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint maxSamples) // the sample buffer with the 'ptrBegin' function. uint FIFOSampleBuffer::receiveSamples(uint maxSamples) { - if(maxSamples >= samplesInBuffer) + if (maxSamples >= samplesInBuffer) { uint temp; diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.cpp index 8cc0635f8..159df256d 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.cpp @@ -1,8 +1,8 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// General FIR digital filter routines with MMX optimization. +/// General FIR digital filter routines with MMX optimization. /// -/// Note : MMX optimized functions reside in a separate, platform-specific file, +/// Note : MMX optimized functions reside in a separate, platform-specific file, /// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp' /// /// Author : Copyright (c) Olli Parviainen @@ -88,14 +88,14 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui end = 2 * (numSamples - length); - for(j = 0; j < end; j += 2) + for (j = 0; j < end; j += 2) { const SAMPLETYPE *ptr; suml = sumr = 0; ptr = src + j; - for(i = 0; i < length; i += 4) + for (i = 0; i < length; i += 4) { // loop is unrolled by factor of 4 here for efficiency suml += ptr[2 * i + 0] * filterCoeffs[i + 0] + @@ -143,15 +143,15 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint assert(length != 0); end = numSamples - length; - for(j = 0; j < end; j ++) + for (j = 0; j < end; j ++) { sum = 0; - for(i = 0; i < length; i += 4) + for (i = 0; i < length; i += 4) { // loop is unrolled by factor of 4 here for efficiency - sum += src[i + 0] * filterCoeffs[i + 0] + - src[i + 1] * filterCoeffs[i + 1] + - src[i + 2] * filterCoeffs[i + 2] + + sum += src[i + 0] * filterCoeffs[i + 0] + + src[i + 1] * filterCoeffs[i + 1] + + src[i + 2] * filterCoeffs[i + 2] + src[i + 3] * filterCoeffs[i + 3]; } #ifdef INTEGER_SAMPLES @@ -174,7 +174,7 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor) { assert(newLength > 0); - if(newLength % 8) throw std::runtime_error("FIR filter length not divisible by 8"); + if (newLength % 8) throw std::runtime_error("FIR filter length not divisible by 8"); lengthDiv8 = newLength / 8; length = lengthDiv8 * 8; @@ -196,9 +196,9 @@ uint FIRFilter::getLength() const -// Applies the filter to the given sequence of samples. +// Applies the filter to the given sequence of samples. // -// Note : The amount of outputted samples is by value of 'filter_length' +// Note : The amount of outputted samples is by value of 'filter_length' // smaller than the amount of input samples. uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const { @@ -206,20 +206,18 @@ uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSample assert(length > 0); assert(lengthDiv8 * 8 == length); - if(numSamples < length) return 0; - if(numChannels == 2) + if (numSamples < length) return 0; + if (numChannels == 2) { return evaluateFilterStereo(dest, src, numSamples); - } - else - { + } else { return evaluateFilterMono(dest, src, numSamples); } } -// Operator 'new' is overloaded so that it automatically creates a suitable instance +// Operator 'new' is overloaded so that it automatically creates a suitable instance // depending on if we've a MMX-capable CPU available or not. void * FIRFilter::operator new(size_t s) { @@ -240,7 +238,7 @@ FIRFilter * FIRFilter::newInstance() #ifdef ALLOW_MMX // MMX routines available only with integer sample types - if(uExtensions & SUPPORT_MMX) + if (uExtensions & SUPPORT_MMX) { return ::new FIRFilterMMX; } @@ -248,27 +246,27 @@ FIRFilter * FIRFilter::newInstance() #endif // ALLOW_MMX #ifdef ALLOW_SSE - if(uExtensions & SUPPORT_SSE) - { - // SSE support - return ::new FIRFilterSSE; - } - else + if (uExtensions & SUPPORT_SSE) + { + // SSE support + return ::new FIRFilterSSE; + } + else #endif // ALLOW_SSE #ifdef ALLOW_3DNOW - if(uExtensions & SUPPORT_3DNOW) - { - // 3DNow! support - return ::new FIRFilter3DNow; - } - else + if (uExtensions & SUPPORT_3DNOW) + { + // 3DNow! support + return ::new FIRFilter3DNow; + } + else #endif // ALLOW_3DNOW #endif // _WIN64 - { - // ISA optimizations not supported, use plain C version - return ::new FIRFilter; - } + { + // ISA optimizations not supported, use plain C version + return ::new FIRFilter; + } } diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.h index 2458131d1..5713f7bb2 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/FIRFilter.h @@ -1,8 +1,8 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// General FIR digital filter routines with MMX optimization. +/// General FIR digital filter routines with MMX optimization. /// -/// Note : MMX optimized functions reside in a separate, platform-specific file, +/// Note : MMX optimized functions reside in a separate, platform-specific file, /// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp' /// /// Author : Copyright (c) Olli Parviainen @@ -48,11 +48,11 @@ namespace soundtouch { -class FIRFilter +class FIRFilter { protected: // Number of FIR filter taps - uint length; + uint length; // Number of FIR filter taps divided by 8 uint lengthDiv8; @@ -65,37 +65,37 @@ protected: // Memory for filter coefficients SAMPLETYPE *filterCoeffs; - virtual uint evaluateFilterStereo(SAMPLETYPE *dest, - const SAMPLETYPE *src, + virtual uint evaluateFilterStereo(SAMPLETYPE *dest, + const SAMPLETYPE *src, uint numSamples) const; - virtual uint evaluateFilterMono(SAMPLETYPE *dest, - const SAMPLETYPE *src, + virtual uint evaluateFilterMono(SAMPLETYPE *dest, + const SAMPLETYPE *src, uint numSamples) const; public: FIRFilter(); virtual ~FIRFilter(); - /// Operator 'new' is overloaded so that it automatically creates a suitable instance + /// Operator 'new' is overloaded so that it automatically creates a suitable instance /// depending on if we've a MMX-capable CPU available or not. static void * operator new(size_t s); static FIRFilter *newInstance(); - /// Applies the filter to the given sequence of samples. - /// Note : The amount of outputted samples is by value of 'filter_length' + /// Applies the filter to the given sequence of samples. + /// Note : The amount of outputted samples is by value of 'filter_length' /// smaller than the amount of input samples. /// /// \return Number of samples copied to 'dest'. - uint evaluate(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples, + uint evaluate(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples, uint numChannels) const; uint getLength() const; - virtual void setCoefficients(const SAMPLETYPE *coeffs, - uint newLength, + virtual void setCoefficients(const SAMPLETYPE *coeffs, + uint newLength, uint uResultDivFactor); }; @@ -105,57 +105,57 @@ public: #ifdef ALLOW_MMX /// Class that implements MMX optimized functions exclusive for 16bit integer samples type. -class FIRFilterMMX : public FIRFilter -{ -protected: - short *filterCoeffsUnalign; - short *filterCoeffsAlign; + class FIRFilterMMX : public FIRFilter + { + protected: + short *filterCoeffsUnalign; + short *filterCoeffsAlign; - virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const; -public: - FIRFilterMMX(); - ~FIRFilterMMX(); + virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const; + public: + FIRFilterMMX(); + ~FIRFilterMMX(); - virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor); -}; + virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor); + }; #endif // ALLOW_MMX #ifdef ALLOW_3DNOW -/// Class that implements 3DNow! optimized functions exclusive for floating point samples type. -class FIRFilter3DNow : public FIRFilter -{ -protected: - float *filterCoeffsUnalign; - float *filterCoeffsAlign; + /// Class that implements 3DNow! optimized functions exclusive for floating point samples type. + class FIRFilter3DNow : public FIRFilter + { + protected: + float *filterCoeffsUnalign; + float *filterCoeffsAlign; - virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const; -public: - FIRFilter3DNow(); - ~FIRFilter3DNow(); - virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor); -}; + virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const; + public: + FIRFilter3DNow(); + ~FIRFilter3DNow(); + virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor); + }; #endif // ALLOW_3DNOW #ifdef ALLOW_SSE -/// Class that implements SSE optimized functions exclusive for floating point samples type. -class FIRFilterSSE : public FIRFilter -{ -protected: - float *filterCoeffsUnalign; - float *filterCoeffsAlign; - - virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const; -public: - FIRFilterSSE(); - ~FIRFilterSSE(); - - virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor); -}; + /// Class that implements SSE optimized functions exclusive for floating point samples type. + class FIRFilterSSE : public FIRFilter + { + protected: + float *filterCoeffsUnalign; + float *filterCoeffsAlign; + + virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const; + public: + FIRFilterSSE(); + ~FIRFilterSSE(); + + virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor); + }; #endif // ALLOW_SSE diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.cpp index 2df0e10fc..03f60bfa9 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.cpp @@ -1,8 +1,8 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// Peak detection routine. +/// Peak detection routine. /// -/// The routine detects highest value on an array of values and calculates the +/// The routine detects highest value on an array of values and calculates the /// precise peak location as a mass-center of the 'hump' around the peak value. /// /// Author : Copyright (c) Olli Parviainen @@ -56,7 +56,7 @@ PeakFinder::PeakFinder() // Finds 'ground level' of a peak hump by starting from 'peakpos' and proceeding -// to direction defined by 'direction' until next 'hump' after minimum value will +// to direction defined by 'direction' until next 'hump' after minimum value will // begin int PeakFinder::findGround(const float *data, int peakpos, int direction) const { @@ -72,7 +72,7 @@ int PeakFinder::findGround(const float *data, int peakpos, int direction) const pos = peakpos; - while((pos > minPos) && (pos < maxPos)) + while ((pos > minPos) && (pos < maxPos)) { int prevpos; @@ -81,16 +81,16 @@ int PeakFinder::findGround(const float *data, int peakpos, int direction) const // calculate derivate delta = data[pos] - data[prevpos]; - if(delta <= 0) + if (delta <= 0) { // going downhill, ok - if(climb_count) + if (climb_count) { climb_count --; // decrease climb count } // check if new minimum found - if(data[pos] < refvalue) + if (data[pos] < refvalue) { // new minimum found lowpos = pos; @@ -101,7 +101,7 @@ int PeakFinder::findGround(const float *data, int peakpos, int direction) const { // going uphill, increase climbing counter climb_count ++; - if(climb_count > 5) break; // we've been climbing too long => it's next uphill => quit + if (climb_count > 5) break; // we've been climbing too long => it's next uphill => quit } } return lowpos; @@ -118,9 +118,9 @@ int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, i peaklevel = data[peakpos]; assert(peaklevel >= level); pos = peakpos; - while((pos >= minPos) && (pos < maxPos)) + while ((pos >= minPos) && (pos < maxPos)) { - if(data[pos + direction] < level) return pos; // crossing found + if (data[pos + direction] < level) return pos; // crossing found pos += direction; } return -1; // not found @@ -136,13 +136,13 @@ double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos) sum = 0; wsum = 0; - for(i = firstPos; i <= lastPos; i ++) + for (i = firstPos; i <= lastPos; i ++) { sum += (float)i * data[i]; wsum += data[i]; } - if(wsum < 1e-6) return 0; + if (wsum < 1e-6) return 0; return sum / wsum; } @@ -164,8 +164,8 @@ double PeakFinder::getPeakCenter(const float *data, int peakpos) const groundLevel = max(data[gp1], data[gp2]); peakLevel = data[peakpos]; - if(groundLevel < 1e-6) return 0; // ground level too small => detection failed - if((peakLevel / groundLevel) < 1.3) return 0; // peak less than 30% of the ground level => no good peak detected + if (groundLevel < 1e-6) return 0; // ground level too small => detection failed + if ((peakLevel / groundLevel) < 1.3) return 0; // peak less than 30% of the ground level => no good peak detected // calculate 70%-level of the peak cutLevel = 0.70f * peakLevel + 0.30f * groundLevel; @@ -173,7 +173,7 @@ double PeakFinder::getPeakCenter(const float *data, int peakpos) const crosspos1 = findCrossingLevel(data, cutLevel, peakpos, -1); crosspos2 = findCrossingLevel(data, cutLevel, peakpos, 1); - if((crosspos1 < 0) || (crosspos2 < 0)) return 0; // no crossing, no peak.. + if ((crosspos1 < 0) || (crosspos2 < 0)) return 0; // no crossing, no peak.. // calculate mass center of the peak surroundings return calcMassCenter(data, crosspos1, crosspos2); @@ -181,7 +181,7 @@ double PeakFinder::getPeakCenter(const float *data, int peakpos) const -double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos) +double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos) { int i; @@ -194,29 +194,29 @@ double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos) // find absolute peak peakpos = minPos; peak = data[minPos]; - for(i = minPos + 1; i < maxPos; i ++) + for (i = minPos + 1; i < maxPos; i ++) { - if(data[i] > peak) + if (data[i] > peak) { peak = data[i]; peakpos = i; } } - + // Calculate exact location of the highest peak mass center highPeak = getPeakCenter(data, peakpos); peak = highPeak; - // Now check if the highest peak were in fact harmonic of the true base beat peak - // - sometimes the highest peak can be Nth harmonic of the true base peak yet + // Now check if the highest peak were in fact harmonic of the true base beat peak + // - sometimes the highest peak can be Nth harmonic of the true base peak yet // just a slightly higher than the true base - for(i = 2; i < 10; i ++) + for (i = 2; i < 10; i ++) { double peaktmp, tmp; - int i1, i2; + int i1,i2; peakpos = (int)(highPeak / (double)i + 0.5f); - if(peakpos < minPos) break; + if (peakpos < minPos) break; // calculate mass-center of possible base peak peaktmp = getPeakCenter(data, peakpos); @@ -225,7 +225,7 @@ double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos) i1 = (int)(highPeak + 0.5); i2 = (int)(peaktmp + 0.5); tmp = 2 * (data[i2] - data[i1]) / (data[i2] + data[i1]); - if(fabs(tmp) < 0.1) + if (fabs(tmp) < 0.1) { // The highest peak is harmonic of almost as high base peak, // thus use the base peak instead diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.h index c72ec033d..e3640cc6d 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/PeakFinder.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// The routine detects highest value on an array of values and calculates the +/// The routine detects highest value on an array of values and calculates the /// precise peak location as a mass-center of the 'hump' around the peak value. /// /// Author : Copyright (c) Olli Parviainen @@ -51,8 +51,8 @@ protected: /// Calculates the mass center between given vector items. double calcMassCenter(const float *data, ///< Data vector. - int firstPos, ///< Index of first vector item beloging to the peak. - int lastPos ///< Index of last vector item beloging to the peak. + int firstPos, ///< Index of first vector item beloging to the peak. + int lastPos ///< Index of last vector item beloging to the peak. ) const; /// Finds the data vector index where the monotoniously decreasing signal crosses the @@ -61,20 +61,20 @@ protected: float level, ///< Goal crossing level. int peakpos, ///< Peak position index within the data vector. int direction /// Direction where to proceed from the peak: 1 = right, -1 = left. - ) const; + ) const; - /// Finds the 'ground' level, i.e. smallest level between two neighbouring peaks, to right- + /// Finds the 'ground' level, i.e. smallest level between two neighbouring peaks, to right- /// or left-hand side of the given peak position. int findGround(const float *data, /// Data vector. int peakpos, /// Peak position index within the data vector. int direction /// Direction where to proceed from the peak: 1 = right, -1 = left. - ) const; + ) const; /// get exact center of peak near given position by calculating local mass of center double getPeakCenter(const float *data, int peakpos) const; public: - /// Constructor. + /// Constructor. PeakFinder(); /// Detect exact peak position of the data vector by finding the largest peak 'hump' @@ -82,9 +82,9 @@ public: /// /// \return The location of the largest base harmonic peak hump. double detectPeak(const float *data, /// Data vector to be analyzed. The data vector has - /// to be at least 'maxPos' items long. - int minPos, ///< Min allowed peak location within the vector data. - int maxPos ///< Max allowed peak location within the vector data. + /// to be at least 'maxPos' items long. + int minPos, ///< Min allowed peak location within the vector data. + int maxPos ///< Max allowed peak location within the vector data. ); }; diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.cpp index f8dc7915d..7e0b277d6 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// -/// -/// Sample rate transposer. Changes sample rate by using linear interpolation +/// +/// Sample rate transposer. Changes sample rate by using linear interpolation /// together with anti-alias filtering (first order interpolation with anti- /// alias filtering should be quite adequate for this application) /// @@ -61,18 +61,18 @@ protected: virtual void resetRegisters(); - virtual uint transposeStereo(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples); - virtual uint transposeMono(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples); + virtual uint transposeStereo(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples); + virtual uint transposeMono(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples); public: RateTransposerInteger(); virtual ~RateTransposerInteger(); - /// Sets new target rate. Normal rate = 1.0, smaller values represent slower + /// Sets new target rate. Normal rate = 1.0, smaller values represent slower /// rate, larger faster rates. virtual void setRate(float newRate); @@ -89,12 +89,12 @@ protected: virtual void resetRegisters(); - virtual uint transposeStereo(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples); - virtual uint transposeMono(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples); + virtual uint transposeStereo(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples); + virtual uint transposeMono(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples); public: RateTransposerFloat(); @@ -104,7 +104,7 @@ public: -// Operator 'new' is overloaded so that it automatically creates a suitable instance +// Operator 'new' is overloaded so that it automatically creates a suitable instance // depending on if we've a MMX/SSE/etc-capable CPU available or not. void * RateTransposer::operator new(size_t s) { @@ -165,7 +165,7 @@ AAFilter *RateTransposer::getAAFilter() -// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower +// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower // iRate, larger faster iRates. void RateTransposer::setRate(float newRate) { @@ -174,11 +174,11 @@ void RateTransposer::setRate(float newRate) fRate = newRate; // design a new anti-alias filter - if(newRate > 1.0f) + if (newRate > 1.0f) { fCutoff = 0.5f / newRate; - } - else + } + else { fCutoff = 0.5f * newRate; } @@ -220,7 +220,7 @@ void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples) // If the parameter 'uRate' value is smaller than 'SCALE', first transpose // the samples and then apply the anti-alias filter to remove aliasing. - // First check that there's enough room in 'storeBuffer' + // First check that there's enough room in 'storeBuffer' // (+16 is to reserve some slack in the destination buffer) sizeTemp = (uint)((float)nSamples / fRate + 16.0f); @@ -231,8 +231,8 @@ void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples) // Apply the anti-alias filter to samples in "store output", output the // result to "dest" num = storeBuffer.numSamples(); - count = pAAFilter->evaluate(outputBuffer.ptrEnd(num), - storeBuffer.ptrBegin(), num, (uint)numChannels); + count = pAAFilter->evaluate(outputBuffer.ptrEnd(num), + storeBuffer.ptrBegin(), num, (uint)numChannels); outputBuffer.putSamples(count); // Remove the processed samples from "storeBuffer" @@ -253,16 +253,16 @@ void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples) // Add the new samples to the end of the storeBuffer storeBuffer.putSamples(src, nSamples); - // Anti-alias filter the samples to prevent folding and output the filtered + // Anti-alias filter the samples to prevent folding and output the filtered // data to tempBuffer. Note : because of the FIR filter length, the // filtering routine takes in 'filter_length' more samples than it outputs. assert(tempBuffer.isEmpty()); sizeTemp = storeBuffer.numSamples(); - count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp), - storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels); + count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp), + storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels); - if(count == 0) return; + if (count == 0) return; // Remove the filtered samples from 'storeBuffer' storeBuffer.receiveSamples(count); @@ -274,7 +274,7 @@ void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples) } -// Transposes sample rate by applying anti-alias filter to prevent folding. +// Transposes sample rate by applying anti-alias filter to prevent folding. // Returns amount of samples returned in the "dest" buffer. // The maximum amount of samples that can be returned at a time is set by // the 'set_returnBuffer_size' function. @@ -283,12 +283,12 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples) uint count; uint sizeReq; - if(nSamples == 0) return; + if (nSamples == 0) return; assert(pAAFilter); // If anti-alias filter is turned off, simply transpose without applying // the filter - if(bUseAAFilter == FALSE) + if (bUseAAFilter == FALSE) { sizeReq = (uint)((float)nSamples / fRate + 1.0f); count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples); @@ -297,26 +297,26 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples) } // Transpose with anti-alias filter - if(fRate < 1.0f) + if (fRate < 1.0f) { upsample(src, nSamples); - } - else + } + else { downsample(src, nSamples); } } -// Transposes the sample rate of the given samples using linear interpolation. +// Transposes the sample rate of the given samples using linear interpolation. // Returns the number of samples returned in the "dest" buffer inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples) { - if(numChannels == 2) + if (numChannels == 2) { return transposeStereo(dest, src, nSamples); - } - else + } + else { return transposeMono(dest, src, nSamples); } @@ -327,7 +327,7 @@ inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, u void RateTransposer::setChannels(int nChannels) { assert(nChannels > 0); - if(numChannels == nChannels) return; + if (numChannels == nChannels) return; assert(nChannels == 1 || nChannels == 2); numChannels = nChannels; @@ -355,7 +355,7 @@ int RateTransposer::isEmpty() const int res; res = FIFOProcessor::isEmpty(); - if(res == 0) return 0; + if (res == 0) return 0; return storeBuffer.isEmpty(); } @@ -363,7 +363,7 @@ int RateTransposer::isEmpty() const ////////////////////////////////////////////////////////////////////////////// // // RateTransposerInteger - integer arithmetic implementation -// +// /// fixed-point interpolation routine precision #define SCALE 65536 @@ -371,7 +371,7 @@ int RateTransposer::isEmpty() const // Constructor RateTransposerInteger::RateTransposerInteger() : RateTransposer() { - // Notice: use local function calling syntax for sake of clarity, + // Notice: use local function calling syntax for sake of clarity, // to indicate the fact that C++ constructor can't call virtual functions. RateTransposerInteger::resetRegisters(); RateTransposerInteger::setRate(1.0f); @@ -386,27 +386,27 @@ RateTransposerInteger::~RateTransposerInteger() void RateTransposerInteger::resetRegisters() { iSlopeCount = 0; - sPrevSampleL = - sPrevSampleR = 0; + sPrevSampleL = + sPrevSampleR = 0; } -// Transposes the sample rate of the given samples using linear interpolation. -// 'Mono' version of the routine. Returns the number of samples returned in +// Transposes the sample rate of the given samples using linear interpolation. +// 'Mono' version of the routine. Returns the number of samples returned in // the "dest" buffer uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples) { unsigned int i, used; LONG_SAMPLETYPE temp, vol1; - if(nSamples == 0) return 0; // no samples, no work + if (nSamples == 0) return 0; // no samples, no work - used = 0; + used = 0; i = 0; // Process the last sample saved from the previous call first... - while(iSlopeCount <= SCALE) + while (iSlopeCount <= SCALE) { vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; @@ -417,13 +417,13 @@ uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *sr // now always (iSlopeCount > SCALE) iSlopeCount -= SCALE; - while(1) + while (1) { - while(iSlopeCount > SCALE) + while (iSlopeCount > SCALE) { iSlopeCount -= SCALE; used ++; - if(used >= nSamples - 1) goto end; + if (used >= nSamples - 1) goto end; } vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); temp = src[used] * vol1 + iSlopeCount * src[used + 1]; @@ -440,21 +440,21 @@ end: } -// Transposes the sample rate of the given samples using linear interpolation. -// 'Stereo' version of the routine. Returns the number of samples returned in +// Transposes the sample rate of the given samples using linear interpolation. +// 'Stereo' version of the routine. Returns the number of samples returned in // the "dest" buffer uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples) { unsigned int srcPos, i, used; LONG_SAMPLETYPE temp, vol1; - if(nSamples == 0) return 0; // no samples, no work + if (nSamples == 0) return 0; // no samples, no work - used = 0; + used = 0; i = 0; // Process the last sample saved from the sPrevSampleLious call first... - while(iSlopeCount <= SCALE) + while (iSlopeCount <= SCALE) { vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; @@ -467,13 +467,13 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE * // now always (iSlopeCount > SCALE) iSlopeCount -= SCALE; - while(1) + while (1) { - while(iSlopeCount > SCALE) + while (iSlopeCount > SCALE) { iSlopeCount -= SCALE; used ++; - if(used >= nSamples - 1) goto end; + if (used >= nSamples - 1) goto end; } srcPos = 2 * used; vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); @@ -494,7 +494,7 @@ end: } -// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower +// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower // iRate, larger faster iRates. void RateTransposerInteger::setRate(float newRate) { @@ -506,13 +506,13 @@ void RateTransposerInteger::setRate(float newRate) ////////////////////////////////////////////////////////////////////////////// // // RateTransposerFloat - floating point arithmetic implementation -// +// ////////////////////////////////////////////////////////////////////////////// // Constructor RateTransposerFloat::RateTransposerFloat() : RateTransposer() { - // Notice: use local function calling syntax for sake of clarity, + // Notice: use local function calling syntax for sake of clarity, // to indicate the fact that C++ constructor can't call virtual functions. RateTransposerFloat::resetRegisters(); RateTransposerFloat::setRate(1.0f); @@ -527,24 +527,24 @@ RateTransposerFloat::~RateTransposerFloat() void RateTransposerFloat::resetRegisters() { fSlopeCount = 0; - sPrevSampleL = - sPrevSampleR = 0; + sPrevSampleL = + sPrevSampleR = 0; } -// Transposes the sample rate of the given samples using linear interpolation. -// 'Mono' version of the routine. Returns the number of samples returned in +// Transposes the sample rate of the given samples using linear interpolation. +// 'Mono' version of the routine. Returns the number of samples returned in // the "dest" buffer uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples) { unsigned int i, used; - used = 0; + used = 0; i = 0; // Process the last sample saved from the previous call first... - while(fSlopeCount <= 1.0f) + while (fSlopeCount <= 1.0f) { dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]); i++; @@ -552,15 +552,15 @@ uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, } fSlopeCount -= 1.0f; - if(nSamples > 1) + if (nSamples > 1) { - while(1) + while (1) { - while(fSlopeCount > 1.0f) + while (fSlopeCount > 1.0f) { fSlopeCount -= 1.0f; used ++; - if(used >= nSamples - 1) goto end; + if (used >= nSamples - 1) goto end; } dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]); i++; @@ -575,20 +575,20 @@ end: } -// Transposes the sample rate of the given samples using linear interpolation. -// 'Mono' version of the routine. Returns the number of samples returned in +// Transposes the sample rate of the given samples using linear interpolation. +// 'Mono' version of the routine. Returns the number of samples returned in // the "dest" buffer uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples) { unsigned int srcPos, i, used; - if(nSamples == 0) return 0; // no samples, no work + if (nSamples == 0) return 0; // no samples, no work - used = 0; + used = 0; i = 0; // Process the last sample saved from the sPrevSampleLious call first... - while(fSlopeCount <= 1.0f) + while (fSlopeCount <= 1.0f) { dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]); dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]); @@ -598,22 +598,22 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr // now always (iSlopeCount > 1.0f) fSlopeCount -= 1.0f; - if(nSamples > 1) + if (nSamples > 1) { - while(1) + while (1) { - while(fSlopeCount > 1.0f) + while (fSlopeCount > 1.0f) { fSlopeCount -= 1.0f; used ++; - if(used >= nSamples - 1) goto end; + if (used >= nSamples - 1) goto end; } srcPos = 2 * used; - dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos] - + fSlopeCount * src[srcPos + 2]); - dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1] - + fSlopeCount * src[srcPos + 3]); + dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos] + + fSlopeCount * src[srcPos + 2]); + dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1] + + fSlopeCount * src[srcPos + 3]); i++; fSlopeCount += fRate; diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.h index 776136ac8..f035af2c0 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/RateTransposer.h @@ -1,10 +1,10 @@ //////////////////////////////////////////////////////////////////////////////// -/// -/// Sample rate transposer. Changes sample rate by using linear interpolation +/// +/// Sample rate transposer. Changes sample rate by using linear interpolation /// together with anti-alias filtering (first order interpolation with anti- /// alias filtering should be quite adequate for this application). /// -/// Use either of the derived classes of 'RateTransposerInteger' or +/// Use either of the derived classes of 'RateTransposerInteger' or /// 'RateTransposerFloat' for corresponding integer/floating point tranposing /// algorithm implementation. /// @@ -57,9 +57,9 @@ namespace soundtouch /// A common linear samplerate transposer class. /// -/// Note: Use function "RateTransposer::newInstance()" to create a new class -/// instance instead of the "new" operator; that function automatically -/// chooses a correct implementation depending on if integer or floating +/// Note: Use function "RateTransposer::newInstance()" to create a new class +/// instance instead of the "new" operator; that function automatically +/// chooses a correct implementation depending on if integer or floating /// arithmetics are to be used. class RateTransposer : public FIFOProcessor { @@ -85,26 +85,26 @@ protected: virtual void resetRegisters() = 0; - virtual uint transposeStereo(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples) = 0; - virtual uint transposeMono(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples) = 0; - inline uint transpose(SAMPLETYPE *dest, - const SAMPLETYPE *src, - uint numSamples); - - void downsample(const SAMPLETYPE *src, + virtual uint transposeStereo(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples) = 0; + virtual uint transposeMono(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples) = 0; + inline uint transpose(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples); + + void downsample(const SAMPLETYPE *src, uint numSamples); - void upsample(const SAMPLETYPE *src, - uint numSamples); + void upsample(const SAMPLETYPE *src, + uint numSamples); - /// Transposes sample rate by applying anti-alias filter to prevent folding. + /// Transposes sample rate by applying anti-alias filter to prevent folding. /// Returns amount of samples returned in the "dest" buffer. /// The maximum amount of samples that can be returned at a time is set by /// the 'set_returnBuffer_size' function. - void processSamples(const SAMPLETYPE *src, + void processSamples(const SAMPLETYPE *src, uint numSamples); @@ -112,26 +112,20 @@ public: RateTransposer(); virtual ~RateTransposer(); - /// Operator 'new' is overloaded so that it automatically creates a suitable instance + /// Operator 'new' is overloaded so that it automatically creates a suitable instance /// depending on if we're to use integer or floating point arithmetics. static void *operator new(size_t s); - /// Use this function instead of "new" operator to create a new instance of this class. - /// This function automatically chooses a correct implementation, depending on if + /// Use this function instead of "new" operator to create a new instance of this class. + /// This function automatically chooses a correct implementation, depending on if /// integer ot floating point arithmetics are to be used. static RateTransposer *newInstance(); /// Returns the output buffer object - FIFOSamplePipe *getOutput() - { - return &outputBuffer; - }; + FIFOSamplePipe *getOutput() { return &outputBuffer; }; /// Returns the store buffer object - FIFOSamplePipe *getStore() - { - return &storeBuffer; - }; + FIFOSamplePipe *getStore() { return &storeBuffer; }; /// Return anti-alias filter object AAFilter *getAAFilter(); @@ -142,7 +136,7 @@ public: /// Returns nonzero if anti-alias filter is enabled. BOOL isAAFilterEnabled() const; - /// Sets new target rate. Normal rate = 1.0, smaller values represent slower + /// Sets new target rate. Normal rate = 1.0, smaller values represent slower /// rate, larger faster rates. virtual void setRate(float newRate); diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/SoundTouch.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/SoundTouch.cpp index bd7b2f77d..aa7ac0284 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/SoundTouch.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/SoundTouch.cpp @@ -1,27 +1,27 @@ ////////////////////////////////////////////////////////////////////////////// /// -/// SoundTouch - main class for tempo/pitch/rate adjusting routines. +/// SoundTouch - main class for tempo/pitch/rate adjusting routines. /// /// Notes: -/// - Initialize the SoundTouch object instance by setting up the sound stream -/// parameters with functions 'setSampleRate' and 'setChannels', then set +/// - Initialize the SoundTouch object instance by setting up the sound stream +/// parameters with functions 'setSampleRate' and 'setChannels', then set /// desired tempo/pitch/rate settings with the corresponding functions. /// -/// - The SoundTouch class behaves like a first-in-first-out pipeline: The +/// - The SoundTouch class behaves like a first-in-first-out pipeline: The /// samples that are to be processed are fed into one of the pipe by calling -/// function 'putSamples', while the ready processed samples can be read +/// function 'putSamples', while the ready processed samples can be read /// from the other end of the pipeline with function 'receiveSamples'. -/// -/// - The SoundTouch processing classes require certain sized 'batches' of -/// samples in order to process the sound. For this reason the classes buffer -/// incoming samples until there are enough of samples available for +/// +/// - The SoundTouch processing classes require certain sized 'batches' of +/// samples in order to process the sound. For this reason the classes buffer +/// incoming samples until there are enough of samples available for /// processing, then they carry out the processing step and consequently /// make the processed samples available for outputting. -/// -/// - For the above reason, the processing routines introduce a certain +/// +/// - For the above reason, the processing routines introduce a certain /// 'latency' between the input and output, so that the samples input to -/// SoundTouch may not be immediately available in the output, and neither -/// the amount of outputtable samples may not immediately be in direct +/// SoundTouch may not be immediately available in the output, and neither +/// the amount of outputtable samples may not immediately be in direct /// relationship with the amount of previously input samples. /// /// - The tempo/pitch/rate control parameters can be altered during processing. @@ -30,8 +30,8 @@ /// required. /// /// - This class utilizes classes 'TDStretch' for tempo change (without modifying -/// pitch) and 'RateTransposer' for changing the playback rate (that is, both -/// tempo and pitch in the same ratio) of the sound. The third available control +/// pitch) and 'RateTransposer' for changing the playback rate (that is, both +/// tempo and pitch in the same ratio) of the sound. The third available control /// 'pitch' (change pitch but maintain tempo) is produced by a combination of /// combining the two other controls. /// @@ -82,7 +82,7 @@ #include "cpu_detect.h" using namespace soundtouch; - + /// test if two floating point numbers are equal #define TEST_FLOAT_EQUAL(a, b) (fabs(a - b) < 1e-10) @@ -90,8 +90,8 @@ using namespace soundtouch; /// Print library version string for autoconf extern "C" void soundtouch_ac_test() { - printf("SoundTouch Version: %s\n", SOUNDTOUCH_VERSION); -} + printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION); +} SoundTouch::SoundTouch() @@ -105,9 +105,9 @@ SoundTouch::SoundTouch() rate = tempo = 0; - virtualPitch = - virtualRate = - virtualTempo = 1.0; + virtualPitch = + virtualRate = + virtualTempo = 1.0; calcEffectiveRateAndTempo(); @@ -144,7 +144,7 @@ uint SoundTouch::getVersionId() // Sets the number of channels, 1 = mono, 2 = stereo void SoundTouch::setChannels(uint numChannels) { - if(numChannels != 1 && numChannels != 2) + if (numChannels != 1 && numChannels != 2) { throw std::runtime_error("Illegal number of channels"); } @@ -240,13 +240,13 @@ void SoundTouch::calcEffectiveRateAndTempo() tempo = virtualTempo / virtualPitch; rate = virtualPitch * virtualRate; - if(!TEST_FLOAT_EQUAL(rate, oldRate)) pRateTransposer->setRate(rate); - if(!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo); + if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate); + if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo); #ifndef PREVENT_CLICK_AT_RATE_CROSSOVER - if(rate <= 1.0f) + if (rate <= 1.0f) { - if(output != pTDStretch) + if (output != pTDStretch) { FIFOSamplePipe *tempoOut; @@ -263,7 +263,7 @@ void SoundTouch::calcEffectiveRateAndTempo() else #endif { - if(output != pRateTransposer) + if (output != pRateTransposer) { FIFOSamplePipe *transOut; @@ -276,7 +276,7 @@ void SoundTouch::calcEffectiveRateAndTempo() output = pRateTransposer; } - } + } } @@ -293,42 +293,42 @@ void SoundTouch::setSampleRate(uint srate) // the input of the object. void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples) { - if(bSrateSet == FALSE) + if (bSrateSet == FALSE) { throw std::runtime_error("SoundTouch : Sample rate not defined"); - } - else if(channels == 0) + } + else if (channels == 0) { throw std::runtime_error("SoundTouch : Number of channels not defined"); } // Transpose the rate of the new samples if necessary /* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value... - if (rate == 1.0f) + if (rate == 1.0f) { - // The rate value is same as the original, simply evaluate the tempo changer. + // The rate value is same as the original, simply evaluate the tempo changer. assert(output == pTDStretch); - if (pRateTransposer->isEmpty() == 0) + if (pRateTransposer->isEmpty() == 0) { // yet flush the last samples in the pitch transposer buffer // (may happen if 'rate' changes from a non-zero value to zero) pTDStretch->moveSamples(*pRateTransposer); } pTDStretch->putSamples(samples, nSamples); - } + } */ #ifndef PREVENT_CLICK_AT_RATE_CROSSOVER - else if(rate <= 1.0f) + else if (rate <= 1.0f) { // transpose the rate down, output the transposed sound to tempo changer buffer assert(output == pTDStretch); pRateTransposer->putSamples(samples, nSamples); pTDStretch->moveSamples(*pRateTransposer); - } - else + } + else #endif { - // evaluate the tempo changer, then transpose the rate up, + // evaluate the tempo changer, then transpose the rate up, assert(output == pRateTransposer); pTDStretch->putSamples(samples, nSamples); pRateTransposer->moveSamples(*pTDStretch); @@ -353,13 +353,13 @@ void SoundTouch::flush() memset(buff, 0, 128 * sizeof(SAMPLETYPE)); // "Push" the last active samples out from the processing pipeline by - // feeding blank samples into the processing pipeline until new, - // processed samples appear in the output (not however, more than + // feeding blank samples into the processing pipeline until new, + // processed samples appear in the output (not however, more than // 8ksamples in any case) - for(i = 0; i < 128; i ++) + for (i = 0; i < 128; i ++) { putSamples(buff, 64); - if(numSamples() != nOut) break; // new samples have appeared in the output! + if (numSamples() != nOut) break; // new samples have appeared in the output! } // Clear working buffers @@ -379,40 +379,40 @@ BOOL SoundTouch::setSetting(int settingId, int value) // read current tdstretch routine parameters pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs); - switch(settingId) + switch (settingId) { - case SETTING_USE_AA_FILTER : - // enables / disabless anti-alias filter - pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE); - return TRUE; - - case SETTING_AA_FILTER_LENGTH : - // sets anti-alias filter length - pRateTransposer->getAAFilter()->setLength(value); - return TRUE; - - case SETTING_USE_QUICKSEEK : - // enables / disables tempo routine quick seeking algorithm - pTDStretch->enableQuickSeek((value != 0) ? TRUE : FALSE); - return TRUE; - - case SETTING_SEQUENCE_MS: - // change time-stretch sequence duration parameter - pTDStretch->setParameters(sampleRate, value, seekWindowMs, overlapMs); - return TRUE; - - case SETTING_SEEKWINDOW_MS: - // change time-stretch seek window length parameter - pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs); - return TRUE; - - case SETTING_OVERLAP_MS: - // change time-stretch overlap length parameter - pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value); - return TRUE; - - default : - return FALSE; + case SETTING_USE_AA_FILTER : + // enables / disabless anti-alias filter + pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE); + return TRUE; + + case SETTING_AA_FILTER_LENGTH : + // sets anti-alias filter length + pRateTransposer->getAAFilter()->setLength(value); + return TRUE; + + case SETTING_USE_QUICKSEEK : + // enables / disables tempo routine quick seeking algorithm + pTDStretch->enableQuickSeek((value != 0) ? TRUE : FALSE); + return TRUE; + + case SETTING_SEQUENCE_MS: + // change time-stretch sequence duration parameter + pTDStretch->setParameters(sampleRate, value, seekWindowMs, overlapMs); + return TRUE; + + case SETTING_SEEKWINDOW_MS: + // change time-stretch seek window length parameter + pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs); + return TRUE; + + case SETTING_OVERLAP_MS: + // change time-stretch overlap length parameter + pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value); + return TRUE; + + default : + return FALSE; } } @@ -425,31 +425,31 @@ int SoundTouch::getSetting(int settingId) const { int temp; - switch(settingId) + switch (settingId) { - case SETTING_USE_AA_FILTER : - return (uint)pRateTransposer->isAAFilterEnabled(); + case SETTING_USE_AA_FILTER : + return (uint)pRateTransposer->isAAFilterEnabled(); - case SETTING_AA_FILTER_LENGTH : - return pRateTransposer->getAAFilter()->getLength(); + case SETTING_AA_FILTER_LENGTH : + return pRateTransposer->getAAFilter()->getLength(); - case SETTING_USE_QUICKSEEK : - return (uint) pTDStretch->isQuickSeekEnabled(); + case SETTING_USE_QUICKSEEK : + return (uint) pTDStretch->isQuickSeekEnabled(); - case SETTING_SEQUENCE_MS: - pTDStretch->getParameters(NULL, &temp, NULL, NULL); - return temp; + case SETTING_SEQUENCE_MS: + pTDStretch->getParameters(NULL, &temp, NULL, NULL); + return temp; - case SETTING_SEEKWINDOW_MS: - pTDStretch->getParameters(NULL, NULL, &temp, NULL); - return temp; + case SETTING_SEEKWINDOW_MS: + pTDStretch->getParameters(NULL, NULL, &temp, NULL); + return temp; - case SETTING_OVERLAP_MS: - pTDStretch->getParameters(NULL, NULL, NULL, &temp); - return temp; + case SETTING_OVERLAP_MS: + pTDStretch->getParameters(NULL, NULL, NULL, &temp); + return temp; - default : - return 0; + default : + return 0; } } @@ -468,10 +468,10 @@ void SoundTouch::clear() uint SoundTouch::numUnprocessedSamples() const { FIFOSamplePipe * psp; - if(pTDStretch) + if (pTDStretch) { psp = pTDStretch->getInput(); - if(psp) + if (psp) { return psp->numSamples(); } diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.cpp index e4d9577d7..062524c84 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.cpp @@ -1,10 +1,10 @@ //////////////////////////////////////////////////////////////////////////////// -/// -/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo -/// while maintaining the original pitch by using a time domain WSOLA-like +/// +/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo +/// while maintaining the original pitch by using a time domain WSOLA-like /// method with several performance-increasing tweaks. /// -/// Note : MMX optimized functions reside in a separate, platform-specific +/// Note : MMX optimized functions reside in a separate, platform-specific /// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp' /// /// Author : Copyright (c) Olli Parviainen @@ -66,29 +66,17 @@ using namespace soundtouch; *****************************************************************************/ // Table for the hierarchical mixing position seeking algorithm -static const short _scanOffsets[5][24] = -{ - { - 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806, - 868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0 - }, - { - -100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }, - { - -20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }, - { - -4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }, - { - 121, 114, 97, 114, 98, 105, 108, 32, 104, 99, 117, 111, - 116, 100, 110, 117, 111, 115, 0, 0, 0, 0, 0, 0 - } -}; +static const short _scanOffsets[5][24]={ + { 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806, + 868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0}, + {-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { -20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { -4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 121, 114, 97, 114, 98, 105, 108, 32, 104, 99, 117, 111, + 116, 100, 110, 117, 111, 115, 0, 0, 0, 0, 0, 0}}; /***************************************************************************** * @@ -134,34 +122,34 @@ TDStretch::~TDStretch() // // 'sampleRate' = sample rate of the sound // 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms) -// 'seekwindowMS' = seeking window length for scanning the best overlapping +// 'seekwindowMS' = seeking window length for scanning the best overlapping // position (default = 28 ms) // 'overlapMS' = overlapping length (default = 12 ms) -void TDStretch::setParameters(int aSampleRate, int aSequenceMS, +void TDStretch::setParameters(int aSampleRate, int aSequenceMS, int aSeekWindowMS, int aOverlapMS) { // accept only positive parameter values - if zero or negative, use old values instead - if(aSampleRate > 0) this->sampleRate = aSampleRate; - if(aOverlapMS > 0) this->overlapMs = aOverlapMS; + if (aSampleRate > 0) this->sampleRate = aSampleRate; + if (aOverlapMS > 0) this->overlapMs = aOverlapMS; - if(aSequenceMS > 0) + if (aSequenceMS > 0) { this->sequenceMs = aSequenceMS; bAutoSeqSetting = FALSE; - } - else if(aSequenceMS == 0) + } + else if (aSequenceMS == 0) { // if zero, use automatic setting bAutoSeqSetting = TRUE; } - if(aSeekWindowMS > 0) + if (aSeekWindowMS > 0) { this->seekWindowMs = aSeekWindowMS; bAutoSeekSetting = FALSE; - } - else if(aSeekWindowMS == 0) + } + else if (aSeekWindowMS == 0) { // if zero, use automatic setting bAutoSeekSetting = TRUE; @@ -183,22 +171,22 @@ void TDStretch::setParameters(int aSampleRate, int aSequenceMS, /// value isn't returned. void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const { - if(pSampleRate) + if (pSampleRate) { *pSampleRate = sampleRate; } - if(pSequenceMs) + if (pSequenceMs) { *pSequenceMs = (bAutoSeqSetting) ? (USE_AUTO_SEQUENCE_LEN) : sequenceMs; } - if(pSeekWindowMs) + if (pSeekWindowMs) { *pSeekWindowMs = (bAutoSeekSetting) ? (USE_AUTO_SEEKWINDOW_LEN) : seekWindowMs; } - if(pOverlapMs) + if (pOverlapMs) { *pOverlapMs = overlapMs; } @@ -210,10 +198,10 @@ void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const { int i, itemp; - for(i = 0; i < overlapLength ; i ++) + for (i = 0; i < overlapLength ; i ++) { itemp = overlapLength - i; - pOutput[i] = (pInput[i] * i + pMidBuffer[i] * itemp) / overlapLength; // >> overlapDividerBits; + pOutput[i] = (pInput[i] * i + pMidBuffer[i] * itemp ) / overlapLength; // >> overlapDividerBits; } } @@ -259,26 +247,26 @@ BOOL TDStretch::isQuickSeekEnabled() const // Seeks for the optimal overlap-mixing position. int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos) { - if(channels == 2) + if (channels == 2) { // stereo sound - if(bQuickSeek) + if (bQuickSeek) { return seekBestOverlapPositionStereoQuick(refPos); - } - else + } + else { return seekBestOverlapPositionStereo(refPos); } - } - else + } + else { // mono sound - if(bQuickSeek) + if (bQuickSeek) { return seekBestOverlapPositionMonoQuick(refPos); - } - else + } + else { return seekBestOverlapPositionMono(refPos); } @@ -292,13 +280,11 @@ int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos) // of 'ovlPos'. inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const { - if(channels == 2) + if (channels == 2) { // stereo sound overlapStereo(pOutput, pInput + 2 * ovlPos); - } - else - { + } else { // mono sound. overlapMono(pOutput, pInput + ovlPos); } @@ -313,7 +299,7 @@ inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, ui // The best position is determined as the position where the two overlapped // sample sequences are 'most alike', in terms of the highest cross-correlation // value over the overlapping period -int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) +int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) { int bestOffs; double bestCorr, corr; @@ -327,7 +313,7 @@ int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) // Scans for the best correlation value by testing each possible position // over the permitted range. - for(i = 0; i < seekLength; i ++) + for (i = 0; i < seekLength; i ++) { // Calculates correlation value for the mixing position corresponding // to 'i' @@ -337,7 +323,7 @@ int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp)); // Checks for the highest correlation value - if(corr > bestCorr) + if (corr > bestCorr) { bestCorr = corr; bestOffs = i; @@ -356,7 +342,7 @@ int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) // The best position is determined as the position where the two overlapped // sample sequences are 'most alike', in terms of the highest cross-correlation // value over the overlapping period -int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos) +int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos) { int j; int bestOffs; @@ -374,16 +360,16 @@ int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos) // Scans for the best correlation value using four-pass hierarchical search. // // The look-up table 'scans' has hierarchical position adjusting steps. - // In first pass the routine searhes for the highest correlation with + // In first pass the routine searhes for the highest correlation with // relatively coarse steps, then rescans the neighbourhood of the highest // correlation with better resolution and so on. - for(scanCount = 0; scanCount < 4; scanCount ++) + for (scanCount = 0;scanCount < 4; scanCount ++) { j = 0; - while(_scanOffsets[scanCount][j]) + while (_scanOffsets[scanCount][j]) { tempOffset = corrOffset + _scanOffsets[scanCount][j]; - if(tempOffset >= seekLength) break; + if (tempOffset >= seekLength) break; // Calculates correlation value for the mixing position corresponding // to 'tempOffset' @@ -393,7 +379,7 @@ int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos) corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp)); // Checks for the highest correlation value - if(corr > bestCorr) + if (corr > bestCorr) { bestCorr = corr; bestOffs = tempOffset; @@ -416,7 +402,7 @@ int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos) // The best position is determined as the position where the two overlapped // sample sequences are 'most alike', in terms of the highest cross-correlation // value over the overlapping period -int TDStretch::seekBestOverlapPositionMono(const SAMPLETYPE *refPos) +int TDStretch::seekBestOverlapPositionMono(const SAMPLETYPE *refPos) { int bestOffs; double bestCorr, corr; @@ -431,7 +417,7 @@ int TDStretch::seekBestOverlapPositionMono(const SAMPLETYPE *refPos) // Scans for the best correlation value by testing each possible position // over the permitted range. - for(tempOffset = 0; tempOffset < seekLength; tempOffset ++) + for (tempOffset = 0; tempOffset < seekLength; tempOffset ++) { compare = refPos + tempOffset; @@ -443,7 +429,7 @@ int TDStretch::seekBestOverlapPositionMono(const SAMPLETYPE *refPos) corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp)); // Checks for the highest correlation value - if(corr > bestCorr) + if (corr > bestCorr) { bestCorr = corr; bestOffs = tempOffset; @@ -462,7 +448,7 @@ int TDStretch::seekBestOverlapPositionMono(const SAMPLETYPE *refPos) // The best position is determined as the position where the two overlapped // sample sequences are 'most alike', in terms of the highest cross-correlation // value over the overlapping period -int TDStretch::seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos) +int TDStretch::seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos) { int j; int bestOffs; @@ -480,16 +466,16 @@ int TDStretch::seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos) // Scans for the best correlation value using four-pass hierarchical search. // // The look-up table 'scans' has hierarchical position adjusting steps. - // In first pass the routine searhes for the highest correlation with + // In first pass the routine searhes for the highest correlation with // relatively coarse steps, then rescans the neighbourhood of the highest // correlation with better resolution and so on. - for(scanCount = 0; scanCount < 4; scanCount ++) + for (scanCount = 0;scanCount < 4; scanCount ++) { j = 0; - while(_scanOffsets[scanCount][j]) + while (_scanOffsets[scanCount][j]) { tempOffset = corrOffset + _scanOffsets[scanCount][j]; - if(tempOffset >= seekLength) break; + if (tempOffset >= seekLength) break; // Calculates correlation value for the mixing position corresponding // to 'tempOffset' @@ -499,7 +485,7 @@ int TDStretch::seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos) corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp)); // Checks for the highest correlation value - if(corr > bestCorr) + if (corr > bestCorr) { bestCorr = corr; bestOffs = tempOffset; @@ -515,7 +501,7 @@ int TDStretch::seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos) } -/// clear cross correlation routine state if necessary +/// clear cross correlation routine state if necessary void TDStretch::clearCrossCorrState() { // default implementation is empty. @@ -527,33 +513,33 @@ void TDStretch::calcSeqParameters() { // Adjust tempo param according to tempo, so that variating processing sequence length is used // at varius tempo settings, between the given low...top limits -#define AUTOSEQ_TEMPO_LOW 0.5 // auto setting low tempo range (-50%) -#define AUTOSEQ_TEMPO_TOP 2.0 // auto setting top tempo range (+100%) + #define AUTOSEQ_TEMPO_LOW 0.5 // auto setting low tempo range (-50%) + #define AUTOSEQ_TEMPO_TOP 2.0 // auto setting top tempo range (+100%) // sequence-ms setting values at above low & top tempo -#define AUTOSEQ_AT_MIN 125.0 -#define AUTOSEQ_AT_MAX 50.0 -#define AUTOSEQ_K ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW)) -#define AUTOSEQ_C (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW)) + #define AUTOSEQ_AT_MIN 125.0 + #define AUTOSEQ_AT_MAX 50.0 + #define AUTOSEQ_K ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW)) + #define AUTOSEQ_C (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW)) // seek-window-ms setting values at above low & top tempo -#define AUTOSEEK_AT_MIN 25.0 -#define AUTOSEEK_AT_MAX 15.0 -#define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW)) -#define AUTOSEEK_C (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW)) + #define AUTOSEEK_AT_MIN 25.0 + #define AUTOSEEK_AT_MAX 15.0 + #define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW)) + #define AUTOSEEK_C (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW)) -#define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x))) + #define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x))) double seq, seek; - - if(bAutoSeqSetting) + + if (bAutoSeqSetting) { seq = AUTOSEQ_C + AUTOSEQ_K * tempo; seq = CHECK_LIMITS(seq, AUTOSEQ_AT_MAX, AUTOSEQ_AT_MIN); sequenceMs = (int)(seq + 0.5); } - if(bAutoSeekSetting) + if (bAutoSeekSetting) { seek = AUTOSEEK_C + AUTOSEEK_K * tempo; seek = CHECK_LIMITS(seek, AUTOSEEK_AT_MAX, AUTOSEEK_AT_MIN); @@ -562,7 +548,7 @@ void TDStretch::calcSeqParameters() // Update seek window lengths seekWindowLength = (sampleRate * sequenceMs) / 1000; - if(seekWindowLength < 2 * overlapLength) + if (seekWindowLength < 2 * overlapLength) { seekWindowLength = 2 * overlapLength; } @@ -571,7 +557,7 @@ void TDStretch::calcSeqParameters() -// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower +// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower // tempo, larger faster tempo. void TDStretch::setTempo(float newTempo) { @@ -582,11 +568,11 @@ void TDStretch::setTempo(float newTempo) // Calculate new sequence duration calcSeqParameters(); - // Calculate ideal skip length (according to tempo value) + // Calculate ideal skip length (according to tempo value) nominalSkip = tempo * (seekWindowLength - overlapLength); intskip = (int)(nominalSkip + 0.5f); - // Calculate how many samples are needed in the 'inputBuffer' to + // Calculate how many samples are needed in the 'inputBuffer' to // process another batch of samples //sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength / 2; sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength; @@ -598,7 +584,7 @@ void TDStretch::setTempo(float newTempo) void TDStretch::setChannels(int numChannels) { assert(numChannels > 0); - if(channels == numChannels) return; + if (channels == numChannels) return; assert(numChannels == 1 || numChannels == 2); channels = numChannels; @@ -614,18 +600,18 @@ void TDStretch::processNominalTempo() { assert(tempo == 1.0f); - if (bMidBufferDirty) + if (bMidBufferDirty) { // If there are samples in pMidBuffer waiting for overlapping, - // do a single sliding overlapping with them in order to prevent a + // do a single sliding overlapping with them in order to prevent a // clicking distortion in the output sound - if (inputBuffer.numSamples() < overlapLength) + if (inputBuffer.numSamples() < overlapLength) { // wait until we've got overlapLength input samples return; } - // Mix the samples in the beginning of 'inputBuffer' with the - // samples in 'midBuffer' using sliding overlapping + // Mix the samples in the beginning of 'inputBuffer' with the + // samples in 'midBuffer' using sliding overlapping overlap(outputBuffer.ptrEnd(overlapLength), inputBuffer.ptrBegin(), 0); outputBuffer.putSamples(overlapLength); inputBuffer.receiveSamples(overlapLength); @@ -650,7 +636,7 @@ void TDStretch::processSamples() /* Removed this small optimization - can introduce a click to sound when tempo setting crosses the nominal value - if (tempo == 1.0f) + if (tempo == 1.0f) { // tempo not changed from the original, so bypass the processing processNominalTempo(); @@ -660,14 +646,14 @@ void TDStretch::processSamples() // Process samples as long as there are enough samples in 'inputBuffer' // to form a processing frame. -// while ((int)inputBuffer.numSamples() >= sampleReq - (outDebt / 4)) - while((int)inputBuffer.numSamples() >= sampleReq) +// while ((int)inputBuffer.numSamples() >= sampleReq - (outDebt / 4)) + while ((int)inputBuffer.numSamples() >= sampleReq) { // If tempo differs from the normal ('SCALE'), scan for the best overlapping // position offset = seekBestOverlapPosition(inputBuffer.ptrBegin()); - // Mix the samples in the 'inputBuffer' at position of 'offset' with the + // Mix the samples in the 'inputBuffer' at position of 'offset' with the // samples in 'midBuffer' using sliding overlapping // ... first partially overlap with the end of the previous sequence // (that's in 'midBuffer') @@ -680,7 +666,7 @@ void TDStretch::processSamples() // compensate cumulated output length diff vs. ideal output // temp -= outDebt / 4; - // update ideal vs. true output difference + // update ideal vs. true output difference // outDebt += temp; // length of sequence @@ -688,19 +674,19 @@ void TDStretch::processSamples() temp = (seekWindowLength - 2 * overlapLength); // crosscheck that we don't have buffer overflow... - if((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2)) + if ((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2)) { continue; // just in case, shouldn't really happen } - outputBuffer.putSamples(inputBuffer.ptrBegin() + channels *(offset + overlapLength), (uint)temp); + outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp); - // Copies the end of the current sequence from 'inputBuffer' to - // 'midBuffer' for being mixed with the beginning of the next + // Copies the end of the current sequence from 'inputBuffer' to + // 'midBuffer' for being mixed with the beginning of the next // processing sequence and so on assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples()); - memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels *(offset + temp + overlapLength), - channels * sizeof(SAMPLETYPE) * overlapLength); + memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength), + channels * sizeof(SAMPLETYPE) * overlapLength); // Remove the processed samples from the input buffer. Update // the difference between integer & nominal skip step to 'skipFract' @@ -734,7 +720,7 @@ void TDStretch::acceptNewOverlapLength(int newOverlapLength) prevOvl = overlapLength; overlapLength = newOverlapLength; - if(overlapLength > prevOvl) + if (overlapLength > prevOvl) { delete[] pMidBuffer; delete[] pRefMidBufferUnaligned; @@ -744,12 +730,12 @@ void TDStretch::acceptNewOverlapLength(int newOverlapLength) pRefMidBufferUnaligned = new SAMPLETYPE[2 * overlapLength + 16 / sizeof(SAMPLETYPE)]; // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency - pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & (ulong) - 16); + pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & (ulong)-16); } } -// Operator 'new' is overloaded so that it automatically creates a suitable instance +// Operator 'new' is overloaded so that it automatically creates a suitable instance // depending on if we've a MMX/SSE/etc-capable CPU available or not. void * TDStretch::operator new(size_t s) { @@ -762,7 +748,7 @@ void * TDStretch::operator new(size_t s) TDStretch * TDStretch::newInstance() { #ifndef _WIN64 - uint uExtensions; + uint uExtensions; uExtensions = detectCPUextensions(); @@ -770,7 +756,7 @@ TDStretch * TDStretch::newInstance() #ifdef ALLOW_MMX // MMX routines available only with integer sample types - if(uExtensions & SUPPORT_MMX) + if (uExtensions & SUPPORT_MMX) { return ::new TDStretchMMX; } @@ -779,30 +765,30 @@ TDStretch * TDStretch::newInstance() #ifdef ALLOW_SSE - if(uExtensions & SUPPORT_SSE) - { - // SSE support - return ::new TDStretchSSE; - } - else + if (uExtensions & SUPPORT_SSE) + { + // SSE support + return ::new TDStretchSSE; + } + else #endif // ALLOW_SSE #ifdef ALLOW_3DNOW - if(uExtensions & SUPPORT_3DNOW) - { - // 3DNow! support - return ::new TDStretch3DNow; - } - else + if (uExtensions & SUPPORT_3DNOW) + { + // 3DNow! support + return ::new TDStretch3DNow; + } + else #endif // ALLOW_3DNOW #endif // _WIN64 - { - // ISA optimizations not supported, use plain C version - return ::new TDStretch; - } + { + // ISA optimizations not supported, use plain C version + return ::new TDStretch; + } } @@ -821,7 +807,7 @@ void TDStretch::precalcCorrReferenceStereo() int i, cnt2; int temp, temp2; - for(i = 0 ; i < (int)overlapLength ; i ++) + for (i=0 ; i < (int)overlapLength ;i ++) { temp = i * (overlapLength - i); cnt2 = i * 2; @@ -842,7 +828,7 @@ void TDStretch::precalcCorrReferenceMono() long temp; long temp2; - for(i = 0 ; i < (int)overlapLength ; i ++) + for (i=0 ; i < (int)overlapLength ;i ++) { temp = i * (overlapLength - i); temp2 = (pMidBuffer[i] * temp) / slopingDivider; @@ -851,7 +837,7 @@ void TDStretch::precalcCorrReferenceMono() } -// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' +// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' // version of the routine. void TDStretch::overlapStereo(short *poutput, const short *input) const { @@ -859,12 +845,12 @@ void TDStretch::overlapStereo(short *poutput, const short *input) const short temp; int cnt2; - for(i = 0; i < overlapLength ; i ++) + for (i = 0; i < overlapLength ; i ++) { temp = (short)(overlapLength - i); cnt2 = 2 * i; - poutput[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp) / overlapLength; - poutput[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp) / overlapLength; + poutput[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp ) / overlapLength; + poutput[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength; } } @@ -885,17 +871,17 @@ void TDStretch::calculateOverlapLength(int aoverlapMs) assert(aoverlapMs >= 0); // calculate overlap length so that it's power of 2 - thus it's easy to do - // integer division by right-shifting. Term "-1" at end is to account for - // the extra most significatnt bit left unused in result by signed multiplication + // integer division by right-shifting. Term "-1" at end is to account for + // the extra most significatnt bit left unused in result by signed multiplication overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1; - if(overlapDividerBits > 9) overlapDividerBits = 9; - if(overlapDividerBits < 3) overlapDividerBits = 3; + if (overlapDividerBits > 9) overlapDividerBits = 9; + if (overlapDividerBits < 3) overlapDividerBits = 3; newOvl = (int)pow(2.0, (int)overlapDividerBits + 1); // +1 => account for -1 above acceptNewOverlapLength(newOvl); - // calculate sloping divider so that crosscorrelation operation won't - // overflow 32-bit register. Max. sum of the crosscorrelation sum without + // calculate sloping divider so that crosscorrelation operation won't + // overflow 32-bit register. Max. sum of the crosscorrelation sum without // divider would be 2^30*(N^3-N)/3, where N = overlap length slopingDivider = (newOvl * newOvl - 1) / 3; } @@ -908,15 +894,15 @@ long TDStretch::calcCrossCorrMono(const short *mixingPos, const short *compare) int i; corr = norm = 0; - for(i = 1; i < overlapLength; i ++) + for (i = 1; i < overlapLength; i ++) { corr += (mixingPos[i] * compare[i]) >> overlapDividerBits; norm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBits; } - // Normalize result by dividing by sqrt(norm) - this step is easiest + // Normalize result by dividing by sqrt(norm) - this step is easiest // done using floating point operation - if(norm == 0) norm = 1; // to avoid div by zero + if (norm == 0) norm = 1; // to avoid div by zero return (long)((double)corr * SHRT_MAX / sqrt((double)norm)); } @@ -928,16 +914,16 @@ long TDStretch::calcCrossCorrStereo(const short *mixingPos, const short *compare int i; corr = norm = 0; - for(i = 2; i < 2 * overlapLength; i += 2) + for (i = 2; i < 2 * overlapLength; i += 2) { corr += (mixingPos[i] * compare[i] + mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits; norm += (mixingPos[i] * mixingPos[i] + mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBits; } - // Normalize result by dividing by sqrt(norm) - this step is easiest + // Normalize result by dividing by sqrt(norm) - this step is easiest // done using floating point operation - if(norm == 0) norm = 1; // to avoid div by zero + if (norm == 0) norm = 1; // to avoid div by zero return (long)((double)corr * SHRT_MAX / sqrt((double)norm)); } @@ -958,7 +944,7 @@ void TDStretch::precalcCorrReferenceStereo() int i, cnt2; float temp; - for(i = 0 ; i < (int)overlapLength ; i ++) + for (i=0 ; i < (int)overlapLength ;i ++) { temp = (float)i * (float)(overlapLength - i); cnt2 = i * 2; @@ -975,7 +961,7 @@ void TDStretch::precalcCorrReferenceMono() int i; float temp; - for(i = 0 ; i < (int)overlapLength ; i ++) + for (i=0 ; i < (int)overlapLength ;i ++) { temp = (float)i * (float)(overlapLength - i); pRefMidBuffer[i] = (float)(pMidBuffer[i] * temp); @@ -994,7 +980,7 @@ void TDStretch::overlapStereo(float *pOutput, const float *pInput) const fScale = 1.0f / (float)overlapLength; - for(i = 0; i < (int)overlapLength ; i ++) + for (i = 0; i < (int)overlapLength ; i ++) { fTemp = (float)(overlapLength - i) * fScale; fi = (float)i * fScale; @@ -1012,7 +998,7 @@ void TDStretch::calculateOverlapLength(int overlapInMsec) assert(overlapInMsec >= 0); newOvl = (sampleRate * overlapInMsec) / 1000; - if(newOvl < 16) newOvl = 16; + if (newOvl < 16) newOvl = 16; // must be divisible by 8 newOvl -= newOvl % 8; @@ -1029,13 +1015,13 @@ double TDStretch::calcCrossCorrMono(const float *mixingPos, const float *compare int i; corr = norm = 0; - for(i = 1; i < overlapLength; i ++) + for (i = 1; i < overlapLength; i ++) { corr += mixingPos[i] * compare[i]; norm += mixingPos[i] * mixingPos[i]; } - if(norm < 1e-9) norm = 1.0; // to avoid div by zero + if (norm < 1e-9) norm = 1.0; // to avoid div by zero return corr / sqrt(norm); } @@ -1047,15 +1033,15 @@ double TDStretch::calcCrossCorrStereo(const float *mixingPos, const float *compa int i; corr = norm = 0; - for(i = 2; i < 2 * overlapLength; i += 2) + for (i = 2; i < 2 * overlapLength; i += 2) { corr += mixingPos[i] * compare[i] + mixingPos[i + 1] * compare[i + 1]; - norm += mixingPos[i] * mixingPos[i] + + norm += mixingPos[i] * mixingPos[i] + mixingPos[i + 1] * mixingPos[i + 1]; } - if(norm < 1e-9) norm = 1.0; // to avoid div by zero + if (norm < 1e-9) norm = 1.0; // to avoid div by zero return corr / sqrt(norm); } diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.h index fc035d5b5..00d1f3e31 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/TDStretch.h @@ -1,10 +1,10 @@ //////////////////////////////////////////////////////////////////////////////// -/// -/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo -/// while maintaining the original pitch by using a time domain WSOLA-like method +/// +/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo +/// while maintaining the original pitch by using a time domain WSOLA-like method /// with several performance-increasing tweaks. /// -/// Note : MMX/SSE optimized functions reside in separate, platform-specific files +/// Note : MMX/SSE optimized functions reside in separate, platform-specific files /// 'mmx_optimized.cpp' and 'sse_optimized.cpp' /// /// Author : Copyright (c) Olli Parviainen @@ -53,14 +53,14 @@ namespace soundtouch { /// Default values for sound processing parameters: -/// Notice that the default parameters are tuned for contemporary popular music +/// Notice that the default parameters are tuned for contemporary popular music /// processing. For speech processing applications these parameters suit better: /// #define DEFAULT_SEQUENCE_MS 40 /// #define DEFAULT_SEEKWINDOW_MS 15 /// #define DEFAULT_OVERLAP_MS 8 /// -/// Default length of a single processing sequence, in milliseconds. This determines to how +/// Default length of a single processing sequence, in milliseconds. This determines to how /// long sequences the original sound is chopped in the time-stretch algorithm. /// /// The larger this value is, the lesser sequences are used in processing. In principle @@ -75,15 +75,15 @@ namespace soundtouch /// according to tempo setting (recommended) #define USE_AUTO_SEQUENCE_LEN 0 -/// Seeking window default length in milliseconds for algorithm that finds the best possible -/// overlapping location. This determines from how wide window the algorithm may look for an -/// optimal joining location when mixing the sound sequences back together. +/// Seeking window default length in milliseconds for algorithm that finds the best possible +/// overlapping location. This determines from how wide window the algorithm may look for an +/// optimal joining location when mixing the sound sequences back together. /// /// The bigger this window setting is, the higher the possibility to find a better mixing /// position will become, but at the same time large values may cause a "drifting" artifact /// because consequent sequences will be taken at more uneven intervals. /// -/// If there's a disturbing artifact that sounds as if a constant frequency was drifting +/// If there's a disturbing artifact that sounds as if a constant frequency was drifting /// around, try reducing this setting. /// /// Increasing this value increases computational burden & vice versa. @@ -94,11 +94,11 @@ namespace soundtouch /// according to tempo setting (recommended) #define USE_AUTO_SEEKWINDOW_LEN 0 -/// Overlap length in milliseconds. When the chopped sound sequences are mixed back together, -/// to form a continuous sound stream, this parameter defines over how long period the two -/// consecutive sequences are let to overlap each other. +/// Overlap length in milliseconds. When the chopped sound sequences are mixed back together, +/// to form a continuous sound stream, this parameter defines over how long period the two +/// consecutive sequences are let to overlap each other. /// -/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting +/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting /// by a large amount, you might wish to try a smaller value on this. /// /// Increasing this value increases computational burden & vice versa. @@ -167,33 +167,27 @@ protected: /// The maximum amount of samples that can be returned at a time is set by /// the 'set_returnBuffer_size' function. void processSamples(); - + public: TDStretch(); virtual ~TDStretch(); - /// Operator 'new' is overloaded so that it automatically creates a suitable instance + /// Operator 'new' is overloaded so that it automatically creates a suitable instance /// depending on if we've a MMX/SSE/etc-capable CPU available or not. static void *operator new(size_t s); - /// Use this function instead of "new" operator to create a new instance of this class. + /// Use this function instead of "new" operator to create a new instance of this class. /// This function automatically chooses a correct feature set depending on if the CPU /// supports MMX/SSE/etc extensions. static TDStretch *newInstance(); - + /// Returns the output buffer object - FIFOSamplePipe *getOutput() - { - return &outputBuffer; - }; + FIFOSamplePipe *getOutput() { return &outputBuffer; }; /// Returns the input buffer object - FIFOSamplePipe *getInput() - { - return &inputBuffer; - }; + FIFOSamplePipe *getInput() { return &inputBuffer; }; - /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower + /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower /// tempo, larger faster tempo. void setTempo(float newTempo); @@ -206,7 +200,7 @@ public: /// Sets the number of channels, 1 = mono, 2 = stereo void setChannels(int numChannels); - /// Enables/disables the quick position seeking algorithm. Zero to disable, + /// Enables/disables the quick position seeking algorithm. Zero to disable, /// nonzero to enable void enableQuickSeek(BOOL enable); @@ -218,14 +212,14 @@ public: // /// 'sampleRate' = sample rate of the sound /// 'sequenceMS' = one processing sequence length in milliseconds - /// 'seekwindowMS' = seeking window length for scanning the best overlapping + /// 'seekwindowMS' = seeking window length for scanning the best overlapping /// position /// 'overlapMS' = overlapping length void setParameters(int sampleRate, ///< Samplerate of sound being processed (Hz) int sequenceMS = -1, ///< Single processing sequence length (ms) int seekwindowMS = -1, ///< Offset seeking window length (ms) int overlapMS = -1 ///< Sequence overlapping length (ms) - ); + ); /// Get routine control parameters, see setParameters() function. /// Any of the parameters to this function can be NULL, in such case corresponding parameter @@ -235,10 +229,10 @@ public: /// Adds 'numsamples' pcs of samples from the 'samples' memory position into /// the input of the object. virtual void putSamples( - const SAMPLETYPE *samples, ///< Input sample data - uint numSamples ///< Number of samples in 'samples' so that one sample - ///< contains both channels if stereo - ); + const SAMPLETYPE *samples, ///< Input sample data + uint numSamples ///< Number of samples in 'samples' so that one sample + ///< contains both channels if stereo + ); }; @@ -246,34 +240,34 @@ public: // Implementation-specific class declarations: #ifdef ALLOW_MMX -/// Class that implements MMX optimized routines for 16bit integer samples type. -class TDStretchMMX : public TDStretch -{ -protected: - long calcCrossCorrStereo(const short *mixingPos, const short *compare) const; - virtual void overlapStereo(short *output, const short *input) const; - virtual void clearCrossCorrState(); -}; + /// Class that implements MMX optimized routines for 16bit integer samples type. + class TDStretchMMX : public TDStretch + { + protected: + long calcCrossCorrStereo(const short *mixingPos, const short *compare) const; + virtual void overlapStereo(short *output, const short *input) const; + virtual void clearCrossCorrState(); + }; #endif /// ALLOW_MMX #ifdef ALLOW_3DNOW -/// Class that implements 3DNow! optimized routines for floating point samples type. -class TDStretch3DNow : public TDStretch -{ -protected: - double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; -}; + /// Class that implements 3DNow! optimized routines for floating point samples type. + class TDStretch3DNow : public TDStretch + { + protected: + double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; + }; #endif /// ALLOW_3DNOW #ifdef ALLOW_SSE -/// Class that implements SSE optimized routines for floating point samples type. -class TDStretchSSE : public TDStretch -{ -protected: - double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; -}; + /// Class that implements SSE optimized routines for floating point samples type. + class TDStretchSSE : public TDStretch + { + protected: + double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; + }; #endif /// ALLOW_SSE diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/cpu_detect.h b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/cpu_detect.h index c9f675128..025781dae 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/cpu_detect.h +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/cpu_detect.h @@ -2,8 +2,8 @@ /// /// A header file for detecting the Intel MMX instructions set extension. /// -/// Please see 'mmx_win.cpp', 'mmx_cpp.cpp' and 'mmx_non_x86.cpp' for the -/// routine implementations for x86 Windows, x86 gnu version and non-x86 +/// Please see 'mmx_win.cpp', 'mmx_cpp.cpp' and 'mmx_non_x86.cpp' for the +/// routine implementations for x86 Windows, x86 gnu version and non-x86 /// platforms, respectively. /// /// Author : Copyright (c) Olli Parviainen diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/mmx_optimized.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/mmx_optimized.cpp index d80bbbe46..539ee57c8 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/mmx_optimized.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/mmx_optimized.cpp @@ -1,15 +1,15 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// MMX optimized routines. All MMX optimized functions have been gathered into -/// this single source code file, regardless to their class or original source -/// code file, in order to ease porting the library to other compiler and +/// MMX optimized routines. All MMX optimized functions have been gathered into +/// this single source code file, regardless to their class or original source +/// code file, in order to ease porting the library to other compiler and /// processor platforms. /// /// The MMX-optimizations are programmed using MMX compiler intrinsics that /// are supported both by Microsoft Visual C++ and GCC compilers, so this file /// should compile with both toolsets. /// -/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ +/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ /// 6.0 processor pack" update to support compiler intrinsic syntax. The update /// is available for download at Microsoft Developers Network, see here: /// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx @@ -79,16 +79,16 @@ long TDStretchMMX::calcCrossCorrStereo(const short *pV1, const short *pV2) const __m64 accu, normaccu; long corr, norm; int i; - + pVec1 = (__m64*)pV1; pVec2 = (__m64*)pV2; shifter = _m_from_int(overlapDividerBits); normaccu = accu = _mm_setzero_si64(); - // Process 4 parallel sets of 2 * stereo samples each during each + // Process 4 parallel sets of 2 * stereo samples each during each // round to improve CPU-level parallellization. - for(i = 0; i < overlapLength / 8; i ++) + for (i = 0; i < overlapLength / 8; i ++) { __m64 temp, temp2; @@ -127,9 +127,9 @@ long TDStretchMMX::calcCrossCorrStereo(const short *pV1, const short *pV2) const // Clear MMS state _m_empty(); - // Normalize result by dividing by sqrt(norm) - this step is easiest + // Normalize result by dividing by sqrt(norm) - this step is easiest // done using floating point operation - if(norm == 0) norm = 1; // to avoid div by zero + if (norm == 0) norm = 1; // to avoid div by zero return (long)((double)corr * USHRT_MAX / sqrt((double)norm)); // Note: Warning about the missing EMMS instruction is harmless // as it'll be called elsewhere. @@ -161,7 +161,7 @@ void TDStretchMMX::overlapStereo(short *output, const short *input) const // mix1 = mixer values for 1st stereo sample // mix1 = mixer values for 2nd stereo sample // adder = adder for updating mixer values after each round - + mix1 = _mm_set_pi16(0, overlapLength, 0, overlapLength); adder = _mm_set_pi16(1, -1, 1, -1); mix2 = _mm_add_pi16(mix1, adder); @@ -171,10 +171,10 @@ void TDStretchMMX::overlapStereo(short *output, const short *input) const // overlapDividerBits calculation earlier. shifter = _m_from_int(overlapDividerBits + 1); - for(i = 0; i < overlapLength / 4; i ++) + for (i = 0; i < overlapLength / 4; i ++) { __m64 temp1, temp2; - + // load & shuffle data so that input & mixbuffer data samples are paired temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]); // = i0l m0l i0r m0r temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]); // = i1l m1l i1r m1r @@ -244,8 +244,8 @@ void FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uRe filterCoeffsUnalign = new short[2 * newLength + 8]; filterCoeffsAlign = (short *)(((ulong)filterCoeffsUnalign + 15) & -16); - // rearrange the filter coefficients for mmx routines - for(i = 0; i < length; i += 4) + // rearrange the filter coefficients for mmx routines + for (i = 0;i < length; i += 4) { filterCoeffsAlign[2 * i + 0] = coeffs[i + 0]; filterCoeffsAlign[2 * i + 1] = coeffs[i + 2]; @@ -268,9 +268,9 @@ uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numS uint i, j; __m64 *pVdest = (__m64*)dest; - if(length < 2) return 0; + if (length < 2) return 0; - for(i = 0; i < (numSamples - length) / 2; i ++) + for (i = 0; i < (numSamples - length) / 2; i ++) { __m64 accu1; __m64 accu2; @@ -278,7 +278,7 @@ uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numS const __m64 *pVfilter = (const __m64*)filterCoeffsAlign; accu1 = accu2 = _mm_setzero_si64(); - for(j = 0; j < lengthDiv8 * 2; j ++) + for (j = 0; j < lengthDiv8 * 2; j ++) { __m64 temp1, temp2; @@ -312,7 +312,7 @@ uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numS pVdest ++; } - _m_empty(); // clear emms state + _m_empty(); // clear emms state return (numSamples & 0xfffffffe) - length; } diff --git a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/sse_optimized.cpp b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/sse_optimized.cpp index 79d45cb8c..7659be682 100644 --- a/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/sse_optimized.cpp +++ b/src/filters/renderer/MpcAudioRenderer/SoundTouch/source/sse_optimized.cpp @@ -1,20 +1,20 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// SSE optimized routines for Pentium-III, Athlon-XP and later CPUs. All SSE -/// optimized functions have been gathered into this single source -/// code file, regardless to their class or original source code file, in order +/// SSE optimized routines for Pentium-III, Athlon-XP and later CPUs. All SSE +/// optimized functions have been gathered into this single source +/// code file, regardless to their class or original source code file, in order /// to ease porting the library to other compiler and processor platforms. /// /// The SSE-optimizations are programmed using SSE compiler intrinsics that /// are supported both by Microsoft Visual C++ and GCC compilers, so this file /// should compile with both toolsets. /// -/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ -/// 6.0 processor pack" update to support SSE instruction set. The update is +/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ +/// 6.0 processor pack" update to support SSE instruction set. The update is /// available for download at Microsoft Developers Network, see here: /// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx /// -/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and +/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and /// perform a search with keywords "processor pack". /// /// Author : Copyright (c) Olli Parviainen @@ -58,7 +58,7 @@ using namespace soundtouch; #ifdef ALLOW_SSE -// SSE routines available only with float sample type +// SSE routines available only with float sample type ////////////////////////////////////////////////////////////////////////////// // @@ -78,8 +78,8 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con const __m128 *pVec2; __m128 vSum, vNorm; - // Note. It means a major slow-down if the routine needs to tolerate - // unaligned __m128 memory accesses. It's way faster if we can skip + // Note. It means a major slow-down if the routine needs to tolerate + // unaligned __m128 memory accesses. It's way faster if we can skip // unaligned slots and use _mm_load_ps instruction instead of _mm_loadu_ps. // This can mean up to ~ 10-fold difference (incl. part of which is // due to skipping every second round for stereo sound though). @@ -88,18 +88,18 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con // for choosing if this little cheating is allowed. #ifdef ALLOW_NONEXACT_SIMD_OPTIMIZATION - // Little cheating allowed, return valid correlation only for + // Little cheating allowed, return valid correlation only for // aligned locations, meaning every second round for stereo sound. -#define _MM_LOAD _mm_load_ps + #define _MM_LOAD _mm_load_ps - if(((ulong)pV1) & 15) return -1e50; // skip unaligned locations + if (((ulong)pV1) & 15) return -1e50; // skip unaligned locations #else // No cheating allowed, use unaligned load & take the resulting // performance hit. -#define _MM_LOAD _mm_loadu_ps -#endif + #define _MM_LOAD _mm_loadu_ps +#endif // ensure overlapLength is divisible by 8 assert((overlapLength % 8) == 0); @@ -111,28 +111,28 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con vSum = vNorm = _mm_setzero_ps(); // Unroll the loop by factor of 4 * 4 operations - for(i = 0; i < overlapLength / 8; i ++) + for (i = 0; i < overlapLength / 8; i ++) { __m128 vTemp; // vSum += pV1[0..3] * pV2[0..3] vTemp = _MM_LOAD(pVec1); - vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp , pVec2[0])); - vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp , vTemp)); + vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp ,pVec2[0])); + vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp)); // vSum += pV1[4..7] * pV2[4..7] vTemp = _MM_LOAD(pVec1 + 4); vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp, pVec2[1])); - vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp , vTemp)); + vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp)); // vSum += pV1[8..11] * pV2[8..11] vTemp = _MM_LOAD(pVec1 + 8); vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp, pVec2[2])); - vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp , vTemp)); + vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp)); // vSum += pV1[12..15] * pV2[12..15] vTemp = _MM_LOAD(pVec1 + 12); vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp, pVec2[3])); - vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp , vTemp)); + vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp)); pVec1 += 16; pVec2 += 4; @@ -141,7 +141,7 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con // return value = vSum[0] + vSum[1] + vSum[2] + vSum[3] float *pvNorm = (float*)&vNorm; double norm = sqrt(pvNorm[0] + pvNorm[1] + pvNorm[2] + pvNorm[3]); - if(norm < 1e-9) norm = 1.0; // to avoid div by zero + if (norm < 1e-9) norm = 1.0; // to avoid div by zero float *pvSum = (float*)&vSum; return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]) / norm; @@ -152,7 +152,7 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors corr = norm = 0.0; - for (i = 0; i < overlapLength / 8; i ++) + for (i = 0; i < overlapLength / 8; i ++) { corr += pV1[0] * pV2[0] + pV1[1] * pV2[1] + @@ -171,7 +171,7 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con pV1[14] * pV2[14] + pV1[15] * pV2[15]; - for (j = 0; j < 15; j ++) norm += pV1[j] * pV1[j]; + for (j = 0; j < 15; j ++) norm += pV1[j] * pV1[j]; pV1 += 16; pV2 += 16; @@ -186,9 +186,9 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con uint overlapLengthLocal = overlapLength; float corr; - _asm + _asm { - // Very important note: data in 'pV2' _must_ be aligned to + // Very important note: data in 'pV2' _must_ be aligned to // 16-byte boundary! // give prefetch hints to CPU of what data are to be needed soonish @@ -234,7 +234,7 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con dec ecx jnz loop1 - // add the four floats of xmm0 together and return the result. + // add the four floats of xmm0 together and return the result. movhlps xmm1, xmm0 // move 3 & 4 of xmm0 to 1 & 2 of xmm1 addps xmm1, xmm0 @@ -285,15 +285,15 @@ void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uRe // Ensure that filter coeffs array is aligned to 16-byte boundary delete[] filterCoeffsUnalign; filterCoeffsUnalign = new float[2 * newLength + 4]; - filterCoeffsAlign = (float *)(((unsigned long)filterCoeffsUnalign + 15) & (ulong) - 16); + filterCoeffsAlign = (float *)(((unsigned long)filterCoeffsUnalign + 15) & (ulong)-16); fDivider = (float)resultDivider; - // rearrange the filter coefficients for mmx routines - for(i = 0; i < newLength; i ++) + // rearrange the filter coefficients for mmx routines + for (i = 0; i < newLength; i ++) { filterCoeffsAlign[2 * i + 0] = - filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider; + filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider; } } @@ -302,12 +302,12 @@ void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uRe // SSE-optimized version of the filter routine for stereo sound uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint numSamples) const { - int count = (int)((numSamples - length) & (uint) - 2); + int count = (int)((numSamples - length) & (uint)-2); int j; assert(count % 2 == 0); - if(count < 2) return 0; + if (count < 2) return 0; assert(source != NULL); assert(dest != NULL); @@ -316,7 +316,7 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n assert(((ulong)filterCoeffsAlign) % 16 == 0); // filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2' - for(j = 0; j < count; j += 2) + for (j = 0; j < count; j += 2) { const float *pSrc; const __m128 *pFil; @@ -324,13 +324,13 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n uint i; pSrc = (const float*)source; // source audio data - pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients - // are aligned to 16-byte boundary + pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients + // are aligned to 16-byte boundary sum1 = sum2 = _mm_setzero_ps(); - for(i = 0; i < length / 8; i ++) + for (i = 0; i < length / 8; i ++) { - // Unroll loop for efficiency & calculate filter for 2*2 stereo samples + // Unroll loop for efficiency & calculate filter for 2*2 stereo samples // at each pass // sum1 is accu for 2*2 filtered stereo sound data at the primary sound data offset @@ -357,22 +357,22 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n // post-shuffle & add the filtered values and store to dest. _mm_storeu_ps(dest, _mm_add_ps( - _mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(1, 0, 3, 2)), // s2_1 s2_0 s1_3 s1_2 - _mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(3, 2, 1, 0)) // s2_3 s2_2 s1_1 s1_0 - )); + _mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(1,0,3,2)), // s2_1 s2_0 s1_3 s1_2 + _mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(3,2,1,0)) // s2_3 s2_2 s1_1 s1_0 + )); source += 4; dest += 4; } // Ideas for further improvement: - // 1. If it could be guaranteed that 'source' were always aligned to 16-byte + // 1. If it could be guaranteed that 'source' were always aligned to 16-byte // boundary, a faster aligned '_mm_load_ps' instruction could be used. - // 2. If it could be guaranteed that 'dest' were always aligned to 16-byte + // 2. If it could be guaranteed that 'dest' were always aligned to 16-byte // boundary, a faster '_mm_store_ps' instruction could be used. return (uint)count; - /* original routine in C-language. please notice the C-version has differently + /* original routine in C-language. please notice the C-version has differently organized coefficients though. double suml1, suml2; double sumr1, sumr2; @@ -387,26 +387,26 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n suml2 = sumr2 = 0.0; ptr = src; pFil = filterCoeffs; - for (i = 0; i < lengthLocal; i ++) + for (i = 0; i < lengthLocal; i ++) { // unroll loop for efficiency. - suml1 += ptr[0] * pFil[0] + + suml1 += ptr[0] * pFil[0] + ptr[2] * pFil[2] + ptr[4] * pFil[4] + ptr[6] * pFil[6]; - sumr1 += ptr[1] * pFil[1] + + sumr1 += ptr[1] * pFil[1] + ptr[3] * pFil[3] + ptr[5] * pFil[5] + ptr[7] * pFil[7]; - suml2 += ptr[8] * pFil[0] + + suml2 += ptr[8] * pFil[0] + ptr[10] * pFil[2] + ptr[12] * pFil[4] + ptr[14] * pFil[6]; - sumr2 += ptr[9] * pFil[1] + + sumr2 += ptr[9] * pFil[1] + ptr[11] * pFil[3] + ptr[13] * pFil[5] + ptr[15] * pFil[7]; @@ -428,7 +428,7 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n /* Similar routine in assembly, again obsoleted due to maintainability _asm { - // Very important note: data in 'src' _must_ be aligned to + // Very important note: data in 'src' _must_ be aligned to // 16-byte boundary! mov edx, count mov ebx, dword ptr src -- cgit v1.2.3