Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/sampleutil.h

Go to the documentation of this file.
00001 // sampleutil.h
00002 // Created 10/5/2009 by RJ Ryan (rryan@mit.edu)
00003 
00004 #ifndef SAMPLEUTIL_H
00005 #define SAMPLEUTIL_H
00006 
00007 #include "defs.h"
00008 
00009 // MSVC does this
00010 // __declspec(align(16))
00011 // while GCC does
00012 // __attribute__((aligned(16)))
00013 // IntelCC does
00014 // _MM_ALIGN_16
00015 // but I dont know how to test for ICC.
00016 
00017 #if !_ALIGN_16
00018 #define _ALIGN_16
00019 #define _ALIGN_STACK
00020 #elif (defined __GNUC__)
00021 #define _ALIGN_16 __attribute__((aligned(16)))
00022 #define _ALIGN_STACK __attribute__((force_align_arg_pointer, aligned(16)))
00023 #elif (defined _MSC_VER)
00024 #define _ALIGN_16 __declspec(align(16))
00025 #define _ALIGN_STACK
00026 #else
00027 #error Please email mixxx-devel@lists.sourceforge.net and tell us what is the equivalent of __attribute__((aligned(16))) for your compiler.
00028 #endif
00029 
00030 #define assert_aligned(data) (Q_ASSERT(reinterpret_cast<int64_t>(data) % 16 == 0));
00031 
00032 // A group of utilities for working with samples. Automatically use SSE/SSE2
00033 // optimizations where possible.
00034 class SampleUtil {
00035   public:
00036 
00037     // Allocated a buffer of CSAMPLE's with length size. Ensures that the buffer
00038     // is 16-byte aligned for use for use with SampleUtil SSE enhanced
00039     // functions.
00040     static CSAMPLE* alloc(int size);
00041 
00042     // Frees a 16-byte aligned buffer allocated by SampleUtil::alloc()
00043     static void free(CSAMPLE* pBuffer);
00044 
00045     // Multiply every sample in pBuffer by gain
00046     static void applyGain(CSAMPLE* pBuffer, CSAMPLE gain, int iNumSamples);
00047 
00048     // Apply a different gain to every other sample.
00049     static void applyAlternatingGain(CSAMPLE* pBuffer,
00050                                      CSAMPLE gain1, CSAMPLE gain2,
00051                                      int iNumSamples);
00052 
00053     // Add each sample of pSrc, multiplied by the gain, to pDest
00054     static void addWithGain(CSAMPLE* pDest, const CSAMPLE* pSrc,
00055                             CSAMPLE gain, int iNumSamples);
00056 
00057     // Add to each sample of pDest, pSrc1 multiplied by gain1 plus pSrc2
00058     // multiplied by gain2
00059     static void add2WithGain(CSAMPLE* pDest,
00060                              const CSAMPLE* pSrc1, CSAMPLE gain1,
00061                              const CSAMPLE* pSrc2, CSAMPLE gain2,
00062                              int iNumSamples);
00063 
00064     // Add to each sample of pDest, pSrc1 multiplied by gain1 plus pSrc2
00065     // multiplied by gain2 plus pSrc3 multiplied by gain3
00066     static void add3WithGain(CSAMPLE* pDest,
00067                              const CSAMPLE* pSrc1, CSAMPLE gain1,
00068                              const CSAMPLE* pSrc2, CSAMPLE gain2,
00069                              const CSAMPLE* pSrc3, CSAMPLE gain3,
00070                              int iNumSamples);
00071 
00072     // Copy pSrc to pDest and multiply each sample by a factor of gain.
00073     static void copyWithGain(CSAMPLE* pDest, const CSAMPLE* pSrc,
00074                              CSAMPLE gain, int iNumSamples);
00075 
00076     // Copies the sum of each channel, multiplied by its gain into pDest
00077     static void copy2WithGain(CSAMPLE* pDest,
00078                               const CSAMPLE* pSrc1, CSAMPLE gain1,
00079                               const CSAMPLE* pSrc2, CSAMPLE gain2,
00080                               int iNumSamples);
00081 
00082     // Copies the sum of each channel, multiplied by its gain into pDest
00083     static void copy3WithGain(CSAMPLE* pDest,
00084                               const CSAMPLE* pSrc1, CSAMPLE gain1,
00085                               const CSAMPLE* pSrc2, CSAMPLE gain2,
00086                               const CSAMPLE* pSrc3, CSAMPLE gain3,
00087                               int iNumSamples);
00088 
00089     // Copies the sum of each channel, multiplied by its gain into pDest
00090     static void copy4WithGain(CSAMPLE* pDest,
00091                               const CSAMPLE* pSrc1, CSAMPLE gain1,
00092                               const CSAMPLE* pSrc2, CSAMPLE gain2,
00093                               const CSAMPLE* pSrc3, CSAMPLE gain3,
00094                               const CSAMPLE* pSrc4, CSAMPLE gain4,
00095                               int iNumSamples);
00096 
00097     // Copies the sum of each channel, multiplied by its gain into pDest
00098     static void copy5WithGain(CSAMPLE* pDest,
00099                               const CSAMPLE* pSrc1, CSAMPLE gain1,
00100                               const CSAMPLE* pSrc2, CSAMPLE gain2,
00101                               const CSAMPLE* pSrc3, CSAMPLE gain3,
00102                               const CSAMPLE* pSrc4, CSAMPLE gain4,
00103                               const CSAMPLE* pSrc5, CSAMPLE gain5,
00104                               int iNumSamples);
00105 
00106     // Copies the sum of each channel, multiplied by its gain into pDest
00107     static void copy6WithGain(CSAMPLE* pDest,
00108                               const CSAMPLE* pSrc1, CSAMPLE gain1,
00109                               const CSAMPLE* pSrc2, CSAMPLE gain2,
00110                               const CSAMPLE* pSrc3, CSAMPLE gain3,
00111                               const CSAMPLE* pSrc4, CSAMPLE gain4,
00112                               const CSAMPLE* pSrc5, CSAMPLE gain5,
00113                               const CSAMPLE* pSrc6, CSAMPLE gain6,
00114                               int iNumSamples);
00115 
00116     // Copies the sum of each channel, multiplied by its gain into pDest
00117     static void copy7WithGain(CSAMPLE* pDest,
00118                               const CSAMPLE* pSrc1, CSAMPLE gain1,
00119                               const CSAMPLE* pSrc2, CSAMPLE gain2,
00120                               const CSAMPLE* pSrc3, CSAMPLE gain3,
00121                               const CSAMPLE* pSrc4, CSAMPLE gain4,
00122                               const CSAMPLE* pSrc5, CSAMPLE gain5,
00123                               const CSAMPLE* pSrc6, CSAMPLE gain6,
00124                               const CSAMPLE* pSrc7, CSAMPLE gain7,
00125                               int iNumSamples);
00126 
00127     // Convert a buffer of SAMPLEs to a buffer of CSAMPLEs. Does not work
00128     // in-place! pDest and pSrc must not be aliased.
00129     static void convert(CSAMPLE* pDest, const SAMPLE* pSrc, int iNumSamples);
00130 
00131     // For each pair of samples in pBuffer (l,r) -- stores the sum of the
00132     // absolute values of l in pfAbsL, and the sum of the absolute values of r
00133     // in pfAbsR.
00134     static void sumAbsPerChannel(CSAMPLE* pfAbsL, CSAMPLE* pfAbsR,
00135                                  const CSAMPLE* pBuffer, int iNumSamples);
00136 
00137     // Returns true if the buffer contains any samples outside of the range
00138     // [fMin,fMax].
00139     static bool isOutsideRange(CSAMPLE fMax, CSAMPLE fMin,
00140                                const CSAMPLE* pBuffer, int iNumSamples);
00141 
00142     // Copied every sample in pSrc to pDest, limiting the values in pDest to the
00143     // range [fMin, fMax]. If pDest and pSrc are aliases, will not copy -- will
00144     // only clamp. Returns true if any samples in pSrc were outside the range
00145     // [fMin, fMax].
00146     static bool copyClampBuffer(CSAMPLE fMax, CSAMPLE fMin,
00147                                 CSAMPLE* pDest, const CSAMPLE* pSrc,
00148                                 int iNumSamples);
00149 
00150     // Interleave the samples in pSrc1 and pSrc2 into pDest. iNumSamples must be
00151     // the number of samples in pSrc1 and pSrc2, and pDest must have at least
00152     // space for iNumSamples*2 samples. pDest must not be an alias of pSrc1 or
00153     // pSrc2.
00154     static void interleaveBuffer(CSAMPLE* pDest,
00155                                  const CSAMPLE* pSrc1, const CSAMPLE* pSrc2,
00156                                  int iNumSamples);
00157 
00158     // Deinterleave the samples in pSrc alternately into pDest1 and
00159     // pDest2. iNumSamples must be the number of samples in pDest1 and pDest2,
00160     // and pSrc must have at least iNumSamples*2 samples. Neither pDest1 or
00161     // pDest2 can be aliases of pSrc.
00162     static void deinterleaveBuffer(CSAMPLE* pDest1, CSAMPLE* pDest2,
00163                                    const CSAMPLE* pSrc, int iNumSamples);
00164 
00165     static void setOptimizations(bool opt);
00166 
00167   private:
00168     static bool m_sOptimizationsOn;
00169     static void sseApplyGain(CSAMPLE* pBuffer,
00170                              CSAMPLE gain, int iNumSamples) _ALIGN_STACK;
00171     static void sseApplyAlternatingGain(CSAMPLE* pBuffer,
00172                                         CSAMPLE gain1, CSAMPLE gain2,
00173                                         int iNumSamples) _ALIGN_STACK;
00174     static void sseAddWithGain(CSAMPLE* pDest, const CSAMPLE* pSrc,
00175                                CSAMPLE gain, int iNumSamples) _ALIGN_STACK;
00176     static void sseAdd2WithGain(CSAMPLE* pDest,
00177                                 const CSAMPLE* pSrc1, CSAMPLE gain1,
00178                                 const CSAMPLE* pSrc2, CSAMPLE gain2,
00179                                 int iNumSamples) _ALIGN_STACK;
00180     static void sseAdd3WithGain(CSAMPLE* pDest,
00181                                 const CSAMPLE* pSrc1, CSAMPLE gain1,
00182                                 const CSAMPLE* pSrc2, CSAMPLE gain2,
00183                                 const CSAMPLE* pSrc3, CSAMPLE gain3,
00184                                 int iNumSamples) _ALIGN_STACK;
00185 
00186     static void sseCopyWithGain(CSAMPLE* pDest, const CSAMPLE* pSrc,
00187                                 CSAMPLE gain, int iNumSamples) _ALIGN_STACK;
00188     static void sseCopy2WithGain(CSAMPLE* pDest,
00189                                  const CSAMPLE* pSrc1, CSAMPLE gain1,
00190                                  const CSAMPLE* pSrc2, CSAMPLE gain2,
00191                                  int iNumSamples) _ALIGN_STACK;
00192     static void sseCopy3WithGain(CSAMPLE* pDest,
00193                                  const CSAMPLE* pSrc1, CSAMPLE gain1,
00194                                  const CSAMPLE* pSrc2, CSAMPLE gain2,
00195                                  const CSAMPLE* pSrc3, CSAMPLE gain3,
00196                                  int iNumSamples) _ALIGN_STACK;
00197     static void sseConvert(CSAMPLE* pDest,
00198                            const SAMPLE* pSrc, int iNumSamples) _ALIGN_STACK;
00199     static void sseSumAbsPerChannel(CSAMPLE* pfAbsL, CSAMPLE* pfAbsR,
00200                                     const CSAMPLE* pBuffer,
00201                                     int iNumSamples) _ALIGN_STACK;
00202     static bool sseIsOutsideRange(CSAMPLE fMax, CSAMPLE fMin,
00203                                   const CSAMPLE* pBuffer,
00204                                   int iNumSamples) _ALIGN_STACK;
00205     static bool sseCopyClampBuffer(CSAMPLE fMax, CSAMPLE fMin,
00206                                    CSAMPLE* pDest, const CSAMPLE* pSrc,
00207                                    int iNumSamples) _ALIGN_STACK;
00208     static void sseInterleaveBuffer(CSAMPLE* pDest,
00209                                     const CSAMPLE* pSrc1, const CSAMPLE* pSrc2,
00210                                     int iNumSamples) _ALIGN_STACK;
00211     static void sseDeinterleaveBuffer(CSAMPLE* pDest1, CSAMPLE* pDest2,
00212                                       const CSAMPLE* pSrc,
00213                                       int iNumSamples) _ALIGN_STACK;
00214 
00215 
00216 
00217 };
00218 
00219 
00220 #endif /* SAMPLEUTIL_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines