| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,91 +1,91 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// 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 | ||
| /// transposing the sample rate with interpolation. | ||
| /// | ||
| /// Author : Copyright (c) Olli Parviainen | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2008-02-10 16:26:55 +0000 (Sun, 10 Feb 2008) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef AAFilter_H | ||
| #define AAFilter_H | ||
|
|
||
| #include "STTypes.h" | ||
|
|
||
| namespace soundtouch | ||
| { | ||
|
|
||
| class AAFilter | ||
| { | ||
| protected: | ||
| class FIRFilter *pFIR; | ||
|
|
||
| /// Low-pass filter cut-off frequency, negative = invalid | ||
| double cutoffFreq; | ||
|
|
||
| /// num of filter taps | ||
| uint length; | ||
|
|
||
| /// Calculate the FIR coefficients realizing the given cutoff-frequency | ||
| void calculateCoeffs(); | ||
| public: | ||
| AAFilter(uint length); | ||
|
|
||
| ~AAFilter(); | ||
|
|
||
| /// 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); | ||
|
|
||
| /// Sets number of FIR filter taps, i.e. ~filter complexity | ||
| void setLength(uint newLength); | ||
|
|
||
| uint getLength() const; | ||
|
|
||
| /// 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 numChannels) const; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,164 +1,164 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// Beats-per-minute (BPM) detection routine. | ||
| /// | ||
| /// The beat detection algorithm works as follows: | ||
| /// - Use function 'inputSamples' to input a chunks of samples to the class for | ||
| /// analysis. It's a good idea to enter a large sound file or stream in smallish | ||
| /// chunks of around few kilosamples in order not to extinguish too much RAM memory. | ||
| /// - Input sound data is decimated to approx 500 Hz to reduce calculation burden, | ||
| /// which is basically ok as low (bass) frequencies mostly determine the beat rate. | ||
| /// Simple averaging is used for anti-alias filtering because the resulting signal | ||
| /// quality isn't of that high importance. | ||
| /// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by | ||
| /// 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 | ||
| /// 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 | ||
| /// function, calculates it's precise location and converts this reading to bpm's. | ||
| /// | ||
| /// Author : Copyright (c) Olli Parviainen | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2012-08-30 19:53:44 +0000 (Thu, 30 Aug 2012) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: BPMDetect.h 150 2012-08-30 19:53:44Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef _BPMDetect_H_ | ||
| #define _BPMDetect_H_ | ||
|
|
||
| #include "STTypes.h" | ||
| #include "FIFOSampleBuffer.h" | ||
|
|
||
| namespace soundtouch | ||
| { | ||
|
|
||
| /// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit. | ||
| #define MIN_BPM 29 | ||
|
|
||
| /// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit. | ||
| #define MAX_BPM 200 | ||
|
|
||
|
|
||
| /// Class for calculating BPM rate for audio data. | ||
| class BPMDetect | ||
| { | ||
| protected: | ||
| /// Auto-correlation accumulator bins. | ||
| float *xcorr; | ||
|
|
||
| /// Amplitude envelope sliding average approximation level accumulator | ||
| double envelopeAccu; | ||
|
|
||
| /// RMS volume sliding average approximation level accumulator | ||
| double RMSVolumeAccu; | ||
|
|
||
| /// Sample average counter. | ||
| int decimateCount; | ||
|
|
||
| /// Sample average accumulator for FIFO-like decimation. | ||
| soundtouch::LONG_SAMPLETYPE decimateSum; | ||
|
|
||
| /// Decimate sound by this coefficient to reach approx. 500 Hz. | ||
| int decimateBy; | ||
|
|
||
| /// Auto-correlation window length | ||
| int windowLen; | ||
|
|
||
| /// Number of channels (1 = mono, 2 = stereo) | ||
| int channels; | ||
|
|
||
| /// sample rate | ||
| int sampleRate; | ||
|
|
||
| /// 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 | ||
| /// though). | ||
| void updateXCorr(int process_samples /// How many samples are processed. | ||
| ); | ||
|
|
||
| /// Decimates samples to approx. 500 Hz. | ||
| /// | ||
| /// \return Number of output samples. | ||
| 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 | ||
| ); | ||
|
|
||
| /// remove constant bias from xcorr data | ||
| void removeBias(); | ||
|
|
||
| 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. | ||
| /// | ||
| /// 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 | ||
| /// after whole song data has been input to the class by consecutive calls of | ||
| /// 'inputSamples' function. | ||
| /// | ||
| /// \return Beats-per-minute rate, or zero if detection failed. | ||
| float getBpm(); | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif // _BPMDetect_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,178 +1,178 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// 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' | ||
| /// 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 | ||
| /// whenever necessary. | ||
| /// | ||
| /// Author : Copyright (c) Olli Parviainen | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2012-06-13 19:29:53 +0000 (Wed, 13 Jun 2012) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: FIFOSampleBuffer.h 143 2012-06-13 19:29:53Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef FIFOSampleBuffer_H | ||
| #define FIFOSampleBuffer_H | ||
|
|
||
| #include "FIFOSamplePipe.h" | ||
|
|
||
| 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 | ||
| /// both channel data. | ||
| class FIFOSampleBuffer : public FIFOSamplePipe | ||
| { | ||
| private: | ||
| /// Sample buffer. | ||
| SAMPLETYPE *buffer; | ||
|
|
||
| // Raw unaligned buffer memory. 'buffer' is made aligned by pointing it to first | ||
| // 16-byte aligned location of this buffer | ||
| SAMPLETYPE *bufferUnaligned; | ||
|
|
||
| /// Sample buffer size in bytes | ||
| uint sizeInBytes; | ||
|
|
||
| /// How many samples are currently in buffer. | ||
| uint samplesInBuffer; | ||
|
|
||
| /// Channels, 1=mono, 2=stereo. | ||
| uint channels; | ||
|
|
||
| /// 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 | ||
| /// beginning of the buffer. | ||
| void rewind(); | ||
|
|
||
| /// Ensures that the buffer has capacity for at least this many samples. | ||
| void ensureCapacity(uint capacityRequirement); | ||
|
|
||
| /// Returns current capacity. | ||
| uint getCapacity() const; | ||
|
|
||
| public: | ||
|
|
||
| /// Constructor | ||
| FIFOSampleBuffer(int numChannels = 2 ///< Number of channels, 1=mono, 2=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. | ||
| /// 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 | ||
| /// '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 | ||
| /// 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 | ||
| /// '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. | ||
| ); | ||
|
|
||
| /// 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 | ||
| /// 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 | ||
| /// 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 | ||
| /// '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. | ||
| /// | ||
| /// 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; | ||
|
|
||
| /// Sets number of channels, 1 = mono, 2 = stereo. | ||
| void setChannels(int numChannels); | ||
|
|
||
| /// Returns nonzero if there aren't any samples available for outputting. | ||
| virtual int isEmpty() const; | ||
|
|
||
| /// Clears all the samples. | ||
| virtual void clear(); | ||
|
|
||
| /// allow trimming (downwards) amount of samples in pipeline. | ||
| /// Returns adjusted amount of samples | ||
| uint adjustAmountOfSamples(uint numSamples); | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,145 +1,146 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// General FIR digital filter routines with MMX optimization. | ||
| /// | ||
| /// 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 | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2013-06-12 15:24:44 +0000 (Wed, 12 Jun 2013) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: FIRFilter.h 171 2013-06-12 15:24:44Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef FIRFilter_H | ||
| #define FIRFilter_H | ||
|
|
||
| #include <stddef.h> | ||
| #include "STTypes.h" | ||
|
|
||
| namespace soundtouch | ||
| { | ||
|
|
||
| class FIRFilter | ||
| { | ||
| protected: | ||
| // Number of FIR filter taps | ||
| uint length; | ||
| // Number of FIR filter taps divided by 8 | ||
| uint lengthDiv8; | ||
|
|
||
| // Result divider factor in 2^k format | ||
| uint resultDivFactor; | ||
|
|
||
| // Result divider value. | ||
| SAMPLETYPE resultDivider; | ||
|
|
||
| // Memory for filter coefficients | ||
| SAMPLETYPE *filterCoeffs; | ||
|
|
||
| virtual uint evaluateFilterStereo(SAMPLETYPE *dest, | ||
| const SAMPLETYPE *src, | ||
| uint numSamples) const; | ||
| virtual uint evaluateFilterMono(SAMPLETYPE *dest, | ||
| const SAMPLETYPE *src, | ||
| uint numSamples) const; | ||
| virtual uint evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const; | ||
|
|
||
| public: | ||
| FIRFilter(); | ||
| virtual ~FIRFilter(); | ||
|
|
||
| /// 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' | ||
| /// smaller than the amount of input samples. | ||
| /// | ||
| /// \return Number of samples copied to 'dest'. | ||
| uint evaluate(SAMPLETYPE *dest, | ||
| const SAMPLETYPE *src, | ||
| uint numSamples, | ||
| uint numChannels) const; | ||
|
|
||
| uint getLength() const; | ||
|
|
||
| virtual void setCoefficients(const SAMPLETYPE *coeffs, | ||
| uint newLength, | ||
| uint uResultDivFactor); | ||
| }; | ||
|
|
||
|
|
||
| // Optional subclasses that implement CPU-specific optimizations: | ||
|
|
||
| #ifdef SOUNDTOUCH_ALLOW_MMX | ||
|
|
||
| /// Class that implements MMX optimized functions exclusive for 16bit integer samples type. | ||
| class FIRFilterMMX : public FIRFilter | ||
| { | ||
| protected: | ||
| short *filterCoeffsUnalign; | ||
| short *filterCoeffsAlign; | ||
|
|
||
| virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const; | ||
| public: | ||
| FIRFilterMMX(); | ||
| ~FIRFilterMMX(); | ||
|
|
||
| virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor); | ||
| }; | ||
|
|
||
| #endif // SOUNDTOUCH_ALLOW_MMX | ||
|
|
||
|
|
||
| #ifdef SOUNDTOUCH_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); | ||
| }; | ||
|
|
||
| #endif // SOUNDTOUCH_ALLOW_SSE | ||
|
|
||
| } | ||
|
|
||
| #endif // FIRFilter_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,97 +1,97 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// 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 | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2011-12-30 20:33:46 +0000 (Fri, 30 Dec 2011) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: PeakFinder.h 132 2011-12-30 20:33:46Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef _PeakFinder_H_ | ||
| #define _PeakFinder_H_ | ||
|
|
||
| namespace soundtouch | ||
| { | ||
|
|
||
| class PeakFinder | ||
| { | ||
| protected: | ||
| /// Min, max allowed peak positions within the data vector | ||
| int minPos, maxPos; | ||
|
|
||
| /// 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. | ||
| ) const; | ||
|
|
||
| /// Finds the data vector index where the monotoniously decreasing signal crosses the | ||
| /// given level. | ||
| int findCrossingLevel(const float *data, ///< Data vector. | ||
| 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; | ||
|
|
||
| // Finds real 'top' of a peak hump from neighnourhood of the given 'peakpos'. | ||
| int findTop(const float *data, int peakpos) const; | ||
|
|
||
|
|
||
| /// 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; | ||
|
|
||
| /// get exact center of peak near given position by calculating local mass of center | ||
| double getPeakCenter(const float *data, int peakpos) const; | ||
|
|
||
| public: | ||
| /// Constructor. | ||
| PeakFinder(); | ||
|
|
||
| /// Detect exact peak position of the data vector by finding the largest peak 'hump' | ||
| /// and calculating the mass-center location of the peak hump. | ||
| /// | ||
| /// \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. | ||
| ); | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif // _PeakFinder_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,159 +1,160 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// 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 | ||
| /// 'RateTransposerFloat' for corresponding integer/floating point tranposing | ||
| /// algorithm implementation. | ||
| /// | ||
| /// Author : Copyright (c) Olli Parviainen | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2013-06-12 15:24:44 +0000 (Wed, 12 Jun 2013) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: RateTransposer.h 171 2013-06-12 15:24:44Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef RateTransposer_H | ||
| #define RateTransposer_H | ||
|
|
||
| #include <stddef.h> | ||
| #include "AAFilter.h" | ||
| #include "FIFOSamplePipe.h" | ||
| #include "FIFOSampleBuffer.h" | ||
|
|
||
| #include "STTypes.h" | ||
|
|
||
| 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 | ||
| /// arithmetics are to be used. | ||
| class RateTransposer : public FIFOProcessor | ||
| { | ||
| protected: | ||
| /// Anti-alias filter object | ||
| AAFilter *pAAFilter; | ||
|
|
||
| float fRate; | ||
|
|
||
| int numChannels; | ||
|
|
||
| /// Buffer for collecting samples to feed the anti-alias filter between | ||
| /// two batches | ||
| FIFOSampleBuffer storeBuffer; | ||
|
|
||
| /// Buffer for keeping samples between transposing & anti-alias filter | ||
| FIFOSampleBuffer tempBuffer; | ||
|
|
||
| /// Output sample buffer | ||
| FIFOSampleBuffer outputBuffer; | ||
|
|
||
| BOOL bUseAAFilter; | ||
|
|
||
| virtual void resetRegisters() = 0; | ||
|
|
||
| virtual int transposeStereo(SAMPLETYPE *dest, | ||
| const SAMPLETYPE *src, | ||
| uint numSamples) = 0; | ||
| virtual int transposeMono(SAMPLETYPE *dest, | ||
| const SAMPLETYPE *src, | ||
| uint numSamples) = 0; | ||
| virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples) = 0; | ||
| inline int transpose(SAMPLETYPE *dest, | ||
| const SAMPLETYPE *src, | ||
| uint numSamples); | ||
|
|
||
| void downsample(const SAMPLETYPE *src, | ||
| uint numSamples); | ||
| void upsample(const SAMPLETYPE *src, | ||
| uint numSamples); | ||
|
|
||
| /// 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, | ||
| uint numSamples); | ||
|
|
||
|
|
||
| public: | ||
| RateTransposer(); | ||
| virtual ~RateTransposer(); | ||
|
|
||
| /// 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 | ||
| /// integer ot floating point arithmetics are to be used. | ||
| static RateTransposer *newInstance(); | ||
|
|
||
| /// Returns the output buffer object | ||
| FIFOSamplePipe *getOutput() { return &outputBuffer; }; | ||
|
|
||
| /// Returns the store buffer object | ||
| FIFOSamplePipe *getStore() { return &storeBuffer; }; | ||
|
|
||
| /// Return anti-alias filter object | ||
| AAFilter *getAAFilter(); | ||
|
|
||
| /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable | ||
| void enableAAFilter(BOOL newMode); | ||
|
|
||
| /// Returns nonzero if anti-alias filter is enabled. | ||
| BOOL isAAFilterEnabled() const; | ||
|
|
||
| /// Sets new target rate. Normal rate = 1.0, smaller values represent slower | ||
| /// rate, larger faster rates. | ||
| virtual void setRate(float newRate); | ||
|
|
||
| /// Sets the number of channels, 1 = mono, 2 = stereo | ||
| void setChannels(int channels); | ||
|
|
||
| /// Adds 'numSamples' pcs of samples from the 'samples' memory position into | ||
| /// the input of the object. | ||
| void putSamples(const SAMPLETYPE *samples, uint numSamples); | ||
|
|
||
| /// Clears all the samples in the object | ||
| void clear(); | ||
|
|
||
| /// Returns nonzero if there aren't any samples available for outputting. | ||
| int isEmpty() const; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,191 +1,194 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// Common type definitions for SoundTouch audio processing library. | ||
| /// | ||
| /// Author : Copyright (c) Olli Parviainen | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2013-06-12 15:24:44 +0000 (Wed, 12 Jun 2013) $ | ||
| // File revision : $Revision: 3 $ | ||
| // | ||
| // $Id: STTypes.h 171 2013-06-12 15:24:44Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef STTypes_H | ||
| #define STTypes_H | ||
|
|
||
| typedef unsigned int uint; | ||
| typedef unsigned long ulong; | ||
|
|
||
| // Patch for MinGW: on Win64 long is 32-bit | ||
| #ifdef _WIN64 | ||
| typedef unsigned long long ulongptr; | ||
| #else | ||
| typedef ulong ulongptr; | ||
| #endif | ||
|
|
||
|
|
||
| // Helper macro for aligning pointer up to next 16-byte boundary | ||
| #define SOUNDTOUCH_ALIGN_POINTER_16(x) ( ( (ulongptr)(x) + 15 ) & ~(ulongptr)15 ) | ||
|
|
||
|
|
||
| #if (defined(__GNUC__) && !defined(ANDROID)) | ||
| // In GCC, include soundtouch_config.h made by config scritps. | ||
| // Skip this in Android compilation that uses GCC but without configure scripts. | ||
| #include "soundtouch_config.h" | ||
| #endif | ||
|
|
||
| #ifndef _WINDEF_ | ||
| // if these aren't defined already by Windows headers, define now | ||
|
|
||
| typedef int BOOL; | ||
|
|
||
| #define FALSE 0 | ||
| #define TRUE 1 | ||
|
|
||
| #endif // _WINDEF_ | ||
|
|
||
|
|
||
| namespace soundtouch | ||
| { | ||
| /// Activate these undef's to overrule the possible sampletype | ||
| /// setting inherited from some other header file: | ||
| //#undef SOUNDTOUCH_INTEGER_SAMPLES | ||
| //#undef SOUNDTOUCH_FLOAT_SAMPLES | ||
|
|
||
| /// If following flag is defined, always uses multichannel processing | ||
| /// routines also for mono and stero sound. This is for routine testing | ||
| /// purposes; output should be same with either routines, yet disabling | ||
| /// the dedicated mono/stereo processing routines will result in slower | ||
| /// runtime performance so recommendation is to keep this off. | ||
| // #define USE_MULTICH_ALWAYS | ||
|
|
||
| #if (defined(__SOFTFP__)) | ||
| // For Android compilation: Force use of Integer samples in case that | ||
| // compilation uses soft-floating point emulation - soft-fp is way too slow | ||
| #undef SOUNDTOUCH_FLOAT_SAMPLES | ||
| #define SOUNDTOUCH_INTEGER_SAMPLES 1 | ||
| #endif | ||
|
|
||
| #if !(SOUNDTOUCH_INTEGER_SAMPLES || SOUNDTOUCH_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 SOUNDTOUCH_INTEGER_SAMPLES 1 //< 16bit integer samples | ||
| #define SOUNDTOUCH_FLOAT_SAMPLES 1 //< 32bit float samples | ||
|
|
||
| #endif | ||
|
|
||
| #if (_M_IX86 || __i386__ || __x86_64__ || _M_X64) | ||
| /// 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 SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1 | ||
|
|
||
| /// In GNU environment, allow the user to override this setting by | ||
| /// giving the following switch to the configure script: | ||
| /// ./configure --disable-x86-optimizations | ||
| /// ./configure --enable-x86-optimizations=no | ||
| #ifdef SOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS | ||
| #undef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS | ||
| #endif | ||
| #else | ||
| /// Always disable optimizations when not using a x86 systems. | ||
| #undef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS | ||
|
|
||
| #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 SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION 1 | ||
|
|
||
|
|
||
| #ifdef SOUNDTOUCH_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 SOUNDTOUCH_FLOAT_SAMPLES | ||
| // check that only one sample type is defined | ||
| #error "conflicting sample types defined" | ||
| #endif // SOUNDTOUCH_FLOAT_SAMPLES | ||
|
|
||
| #ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS | ||
| // Allow MMX optimizations | ||
| #define SOUNDTOUCH_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 SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS | ||
| // Allow SSE optimizations | ||
| #define SOUNDTOUCH_ALLOW_SSE 1 | ||
| #endif | ||
|
|
||
| #endif // SOUNDTOUCH_INTEGER_SAMPLES | ||
|
|
||
| }; | ||
|
|
||
| // define ST_NO_EXCEPTION_HANDLING switch to disable throwing std exceptions: | ||
| // #define ST_NO_EXCEPTION_HANDLING 1 | ||
| #ifdef ST_NO_EXCEPTION_HANDLING | ||
| // Exceptions disabled. Throw asserts instead if enabled. | ||
| #include <assert.h> | ||
| #define ST_THROW_RT_ERROR(x) {assert((const char *)x);} | ||
| #else | ||
| // use c++ standard exceptions | ||
| #include <stdexcept> | ||
| #define ST_THROW_RT_ERROR(x) {throw std::runtime_error(x);} | ||
| #endif | ||
|
|
||
| // 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 SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER 1 | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,62 +1,62 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// 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 | ||
| /// platforms, respectively. | ||
| /// | ||
| /// Author : Copyright (c) Olli Parviainen | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2008-02-10 16:26:55 +0000 (Sun, 10 Feb 2008) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef _CPU_DETECT_H_ | ||
| #define _CPU_DETECT_H_ | ||
|
|
||
| #include "STTypes.h" | ||
|
|
||
| #define SUPPORT_MMX 0x0001 | ||
| #define SUPPORT_3DNOW 0x0002 | ||
| #define SUPPORT_ALTIVEC 0x0004 | ||
| #define SUPPORT_SSE 0x0008 | ||
| #define SUPPORT_SSE2 0x0010 | ||
|
|
||
| /// Checks which instruction set extensions are supported by the CPU. | ||
| /// | ||
| /// \return A bitmask of supported extensions, see SUPPORT_... defines. | ||
| uint detectCPUextensions(void); | ||
|
|
||
| /// Disables given set of instruction extensions. See SUPPORT_... defines. | ||
| void disableExtensions(uint wDisableMask); | ||
|
|
||
| #endif // _CPU_DETECT_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,137 +1,137 @@ | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// | ||
| /// Generic version of the x86 CPU extension detection routine. | ||
| /// | ||
| /// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp' | ||
| /// for the Microsoft compiler version. | ||
| /// | ||
| /// Author : Copyright (c) Olli Parviainen | ||
| /// Author e-mail : oparviai 'at' iki.fi | ||
| /// SoundTouch WWW: http://www.surina.net/soundtouch | ||
| /// | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Last changed : $Date: 2012-11-08 18:44:37 +0000 (Thu, 08 Nov 2012) $ | ||
| // File revision : $Revision: 4 $ | ||
| // | ||
| // $Id: cpu_detect_x86.cpp 159 2012-11-08 18:44:37Z oparviai $ | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // License : | ||
| // | ||
| // SoundTouch audio processing library | ||
| // Copyright (c) Olli Parviainen | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #include "cpu_detect.h" | ||
| #include "STTypes.h" | ||
|
|
||
| #if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) | ||
|
|
||
| #if defined(__GNUC__) && defined(__i386__) | ||
| // gcc | ||
| #include "cpuid.h" | ||
| #elif defined(_M_IX86) | ||
| // windows non-gcc | ||
| #include <intrin.h> | ||
| #define bit_MMX (1 << 23) | ||
| #define bit_SSE (1 << 25) | ||
| #define bit_SSE2 (1 << 26) | ||
| #endif | ||
|
|
||
| #endif | ||
|
|
||
|
|
||
| ////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // processor instructions extension detection routines | ||
| // | ||
| ////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| // Flag variable indicating whick ISA extensions are disabled (for debugging) | ||
| static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions | ||
|
|
||
| // Disables given set of instruction extensions. See SUPPORT_... defines. | ||
| void disableExtensions(uint dwDisableMask) | ||
| { | ||
| _dwDisabledISA = dwDisableMask; | ||
| } | ||
|
|
||
|
|
||
|
|
||
| /// Checks which instruction set extensions are supported by the CPU. | ||
| uint detectCPUextensions(void) | ||
| { | ||
| /// If building for a 64bit system (no Itanium) and the user wants optimizations. | ||
| /// Return the OR of SUPPORT_{MMX,SSE,SSE2}. 11001 or 0x19. | ||
| /// Keep the _dwDisabledISA test (2 more operations, could be eliminated). | ||
| #if ((defined(__GNUC__) && defined(__x86_64__)) \ | ||
| || defined(_M_X64)) \ | ||
| && defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) | ||
| return 0x19 & ~_dwDisabledISA; | ||
|
|
||
| /// If building for a 32bit system and the user wants optimizations. | ||
| /// Keep the _dwDisabledISA test (2 more operations, could be eliminated). | ||
| #elif ((defined(__GNUC__) && defined(__i386__)) \ | ||
| || defined(_M_IX86)) \ | ||
| && defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) | ||
|
|
||
| if (_dwDisabledISA == 0xffffffff) return 0; | ||
|
|
||
| uint res = 0; | ||
|
|
||
| #if defined(__GNUC__) | ||
| // GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support. | ||
| uint eax, ebx, ecx, edx; // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable. | ||
|
|
||
| // Check if no cpuid support. | ||
| if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; // always disable extensions. | ||
|
|
||
| if (edx & bit_MMX) res = res | SUPPORT_MMX; | ||
| if (edx & bit_SSE) res = res | SUPPORT_SSE; | ||
| if (edx & bit_SSE2) res = res | SUPPORT_SSE2; | ||
|
|
||
| #else | ||
| // Window / VS version of cpuid. Notice that Visual Studio 2005 or later required | ||
| // for __cpuid intrinsic support. | ||
| int reg[4] = {-1}; | ||
|
|
||
| // Check if no cpuid support. | ||
| __cpuid(reg,0); | ||
| if ((unsigned int)reg[0] == 0) return 0; // always disable extensions. | ||
|
|
||
| __cpuid(reg,1); | ||
| if ((unsigned int)reg[3] & bit_MMX) res = res | SUPPORT_MMX; | ||
| if ((unsigned int)reg[3] & bit_SSE) res = res | SUPPORT_SSE; | ||
| if ((unsigned int)reg[3] & bit_SSE2) res = res | SUPPORT_SSE2; | ||
|
|
||
| #endif | ||
|
|
||
| return res & ~_dwDisabledISA; | ||
|
|
||
| #else | ||
|
|
||
| /// One of these is true: | ||
| /// 1) We don't want optimizations. | ||
| /// 2) Using an unsupported compiler. | ||
| /// 3) Running on a non-x86 platform. | ||
| return 0; | ||
|
|
||
| #endif | ||
| } |