MythTV  0.26-pre
audiooutpututil.cpp
Go to the documentation of this file.
00001 #include <math.h>
00002 
00003 #include "mythconfig.h"
00004 #include "audiooutpututil.h"
00005 #include <sys/types.h>
00006 #include <inttypes.h>
00007 #include "bswap.h"
00008 
00009 #define LOC QString("AOUtil: ")
00010 
00011 #if ARCH_X86
00012 static int has_sse2 = -1;
00013 
00014 // Check cpuid for SSE2 support on x86 / x86_64
00015 static inline bool sse_check()
00016 {
00017     if (has_sse2 != -1)
00018         return (bool)has_sse2;
00019     __asm__(
00020         // -fPIC - we may not clobber ebx/rbx
00021 #if ARCH_X86_64
00022         "push       %%rbx               \n\t"
00023 #else
00024         "push       %%ebx               \n\t"
00025 #endif
00026         "mov        $1, %%eax           \n\t"
00027         "cpuid                          \n\t"
00028         "and        $0x4000000, %%edx   \n\t"
00029         "shr        $26, %%edx          \n\t"
00030 #if ARCH_X86_64
00031         "pop        %%rbx               \n\t"
00032 #else
00033         "pop        %%ebx               \n\t"
00034 #endif
00035         :"=d"(has_sse2)
00036         ::"%eax","%ecx"
00037     );
00038     return (bool)has_sse2;
00039 }
00040 #endif //ARCH_x86
00041 
00042 #if !HAVE_LRINTF
00043 static av_always_inline av_const long int lrintf(float x)
00044 {
00045     return (int)(rint(x));
00046 }
00047 #endif /* HAVE_LRINTF */
00048 
00049 static inline float clipcheck(float f) {
00050     if (f > 1.0f) f = 1.0f;
00051     else if (f < -1.0f) f = -1.0f;
00052     return f;
00053 }
00054 
00055 /*
00056  All toFloat variants require 16 byte aligned input and output buffers on x86
00057  The SSE code processes 16 bytes at a time and leaves any remainder for the C
00058  - there is no remainder in practice */
00059 
00060 static int toFloat8(float *out, uchar *in, int len)
00061 {
00062     int i = 0;
00063     float f = 1.0f / ((1<<7) - 1);
00064 
00065 #if ARCH_X86
00066     if (sse_check() && len >= 16)
00067     {
00068         int loops = len >> 4;
00069         i = loops << 4;
00070         int a = 0x80808080;
00071 
00072         __asm__ volatile (
00073             "movd       %3, %%xmm0          \n\t"
00074             "movd       %4, %%xmm7          \n\t"
00075             "punpckldq  %%xmm0, %%xmm0      \n\t"
00076             "punpckldq  %%xmm7, %%xmm7      \n\t"
00077             "punpckldq  %%xmm0, %%xmm0      \n\t"
00078             "punpckldq  %%xmm7, %%xmm7      \n\t"
00079             "1:                             \n\t"
00080             "movdqa     (%1), %%xmm1        \n\t"
00081             "xorpd      %%xmm2, %%xmm2      \n\t"
00082             "xorpd      %%xmm3, %%xmm3      \n\t"
00083             "psubb      %%xmm0, %%xmm1      \n\t"
00084             "xorpd      %%xmm4, %%xmm4      \n\t"
00085             "punpcklbw  %%xmm1, %%xmm2      \n\t"
00086             "xorpd      %%xmm5, %%xmm5      \n\t"
00087             "punpckhbw  %%xmm1, %%xmm3      \n\t"
00088             "punpcklwd  %%xmm2, %%xmm4      \n\t"
00089             "xorpd      %%xmm6, %%xmm6      \n\t"
00090             "punpckhwd  %%xmm2, %%xmm5      \n\t"
00091             "psrad      $24,    %%xmm4      \n\t"
00092             "punpcklwd  %%xmm3, %%xmm6      \n\t"
00093             "psrad      $24,    %%xmm5      \n\t"
00094             "punpckhwd  %%xmm3, %%xmm1      \n\t"
00095             "psrad      $24,    %%xmm6      \n\t"
00096             "cvtdq2ps   %%xmm4, %%xmm4      \n\t"
00097             "psrad      $24,    %%xmm1      \n\t"
00098             "cvtdq2ps   %%xmm5, %%xmm5      \n\t"
00099             "mulps      %%xmm7, %%xmm4      \n\t"
00100             "cvtdq2ps   %%xmm6, %%xmm6      \n\t"
00101             "mulps      %%xmm7, %%xmm5      \n\t"
00102             "movaps     %%xmm4, (%0)        \n\t"
00103             "cvtdq2ps   %%xmm1, %%xmm1      \n\t"
00104             "mulps      %%xmm7, %%xmm6      \n\t"
00105             "movaps     %%xmm5, 16(%0)      \n\t"
00106             "mulps      %%xmm7, %%xmm1      \n\t"
00107             "movaps     %%xmm6, 32(%0)      \n\t"
00108             "add        $16,    %1          \n\t"
00109             "movaps     %%xmm1, 48(%0)      \n\t"
00110             "add        $64,    %0          \n\t"
00111             "sub        $1, %%ecx           \n\t"
00112             "jnz        1b                  \n\t"
00113             :"+r"(out),"+r"(in)
00114             :"c"(loops), "r"(a), "r"(f)
00115         );
00116     }
00117 #endif //ARCH_x86
00118     for (; i < len; i++)
00119         *out++ = (*in++ - 0x80) * f;
00120     return len << 2;
00121 }
00122 
00123 /*
00124   The SSE code processes 16 bytes at a time and leaves any remainder for the C
00125   - there is no remainder in practice */
00126 
00127 static int fromFloat8(uchar *out, float *in, int len)
00128 {
00129     int i = 0;
00130     float f = (1<<7) - 1;
00131 
00132 #if ARCH_X86
00133     if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0)
00134     {
00135         int loops = len >> 4;
00136         i = loops << 4;
00137         int a = 0x80808080;
00138 
00139         __asm__ volatile (
00140             "movd       %3, %%xmm0          \n\t"
00141             "movd       %4, %%xmm7          \n\t"
00142             "punpckldq  %%xmm0, %%xmm0      \n\t"
00143             "punpckldq  %%xmm7, %%xmm7      \n\t"
00144             "punpckldq  %%xmm0, %%xmm0      \n\t"
00145             "punpckldq  %%xmm7, %%xmm7      \n\t"
00146             "1:                             \n\t"
00147             "movups     (%1), %%xmm1        \n\t"
00148             "movups     16(%1), %%xmm2      \n\t"
00149             "mulps      %%xmm7, %%xmm1      \n\t"
00150             "movups     32(%1), %%xmm3      \n\t"
00151             "mulps      %%xmm7, %%xmm2      \n\t"
00152             "cvtps2dq   %%xmm1, %%xmm1      \n\t"
00153             "movups     48(%1), %%xmm4      \n\t"
00154             "mulps      %%xmm7, %%xmm3      \n\t"
00155             "cvtps2dq   %%xmm2, %%xmm2      \n\t"
00156             "mulps      %%xmm7, %%xmm4      \n\t"
00157             "cvtps2dq   %%xmm3, %%xmm3      \n\t"
00158             "packssdw   %%xmm2, %%xmm1      \n\t"
00159             "cvtps2dq   %%xmm4, %%xmm4      \n\t"
00160             "packssdw   %%xmm4, %%xmm3      \n\t"
00161             "add        $64,    %1          \n\t"
00162             "packsswb   %%xmm3, %%xmm1      \n\t"
00163             "paddb      %%xmm0, %%xmm1      \n\t"
00164             "movdqu     %%xmm1, (%0)        \n\t"
00165             "add        $16,    %0          \n\t"
00166             "sub        $1, %%ecx           \n\t"
00167             "jnz        1b                  \n\t"
00168             :"+r"(out),"+r"(in)
00169             :"c"(loops), "r"(a), "r"(f)
00170         );
00171     }
00172 #endif //ARCH_x86
00173     for (;i < len; i++)
00174         *out++ = lrintf(clipcheck(*in++) * f) + 0x80;
00175     return len;
00176 }
00177 
00178 static int toFloat16(float *out, short *in, int len)
00179 {
00180     int i = 0;
00181     float f = 1.0f / ((1<<15) - 1);
00182 
00183 #if ARCH_X86
00184     if (sse_check() && len >= 16)
00185     {
00186         int loops = len >> 4;
00187         i = loops << 4;
00188 
00189         __asm__ volatile (
00190             "movd       %3, %%xmm7          \n\t"
00191             "punpckldq  %%xmm7, %%xmm7      \n\t"
00192             "punpckldq  %%xmm7, %%xmm7      \n\t"
00193             "1:                             \n\t"
00194             "xorpd      %%xmm2, %%xmm2      \n\t"
00195             "movdqa     (%1),   %%xmm1      \n\t"
00196             "xorpd      %%xmm3, %%xmm3      \n\t"
00197             "punpcklwd  %%xmm1, %%xmm2      \n\t"
00198             "movdqa     16(%1), %%xmm4      \n\t"
00199             "punpckhwd  %%xmm1, %%xmm3      \n\t"
00200             "psrad      $16,    %%xmm2      \n\t"
00201             "punpcklwd  %%xmm4, %%xmm5      \n\t"
00202             "psrad      $16,    %%xmm3      \n\t"
00203             "cvtdq2ps   %%xmm2, %%xmm2      \n\t"
00204             "punpckhwd  %%xmm4, %%xmm6      \n\t"
00205             "psrad      $16,    %%xmm5      \n\t"
00206             "mulps      %%xmm7, %%xmm2      \n\t"
00207             "cvtdq2ps   %%xmm3, %%xmm3      \n\t"
00208             "psrad      $16,    %%xmm6      \n\t"
00209             "mulps      %%xmm7, %%xmm3      \n\t"
00210             "cvtdq2ps   %%xmm5, %%xmm5      \n\t"
00211             "movaps     %%xmm2, (%0)        \n\t"
00212             "cvtdq2ps   %%xmm6, %%xmm6      \n\t"
00213             "mulps      %%xmm7, %%xmm5      \n\t"
00214             "movaps     %%xmm3, 16(%0)      \n\t"
00215             "mulps      %%xmm7, %%xmm6      \n\t"
00216             "movaps     %%xmm5, 32(%0)      \n\t"
00217             "add        $32, %1             \n\t"
00218             "movaps     %%xmm6, 48(%0)      \n\t"
00219             "add        $64, %0             \n\t"
00220             "sub        $1, %%ecx           \n\t"
00221             "jnz        1b                  \n\t"
00222             :"+r"(out),"+r"(in)
00223             :"c"(loops), "r"(f)
00224         );
00225     }
00226 #endif //ARCH_x86
00227     for (; i < len; i++)
00228         *out++ = *in++ * f;
00229     return len << 2;
00230 }
00231 
00232 static int fromFloat16(short *out, float *in, int len)
00233 {
00234     int i = 0;
00235     float f = (1<<15) - 1;
00236 
00237 #if ARCH_X86
00238     if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0)
00239     {
00240         int loops = len >> 4;
00241         i = loops << 4;
00242 
00243         __asm__ volatile (
00244             "movd       %3, %%xmm7          \n\t"
00245             "punpckldq  %%xmm7, %%xmm7      \n\t"
00246             "punpckldq  %%xmm7, %%xmm7      \n\t"
00247             "1:                             \n\t"
00248             "movups     (%1), %%xmm1        \n\t"
00249             "movups     16(%1), %%xmm2      \n\t"
00250             "mulps      %%xmm7, %%xmm1      \n\t"
00251             "movups     32(%1), %%xmm3      \n\t"
00252             "mulps      %%xmm7, %%xmm2      \n\t"
00253             "cvtps2dq   %%xmm1, %%xmm1      \n\t"
00254             "movups     48(%1), %%xmm4      \n\t"
00255             "mulps      %%xmm7, %%xmm3      \n\t"
00256             "cvtps2dq   %%xmm2, %%xmm2      \n\t"
00257             "mulps      %%xmm7, %%xmm4      \n\t"
00258             "cvtps2dq   %%xmm3, %%xmm3      \n\t"
00259             "cvtps2dq   %%xmm4, %%xmm4      \n\t"
00260             "packssdw   %%xmm2, %%xmm1      \n\t"
00261             "packssdw   %%xmm4, %%xmm3      \n\t"
00262             "add        $64,    %1          \n\t"
00263             "movdqu     %%xmm1, (%0)        \n\t"
00264             "movdqu     %%xmm3, 16(%0)      \n\t"
00265             "add        $32,    %0          \n\t"
00266             "sub        $1, %%ecx           \n\t"
00267             "jnz        1b                  \n\t"
00268             :"+r"(out),"+r"(in)
00269             :"c"(loops), "r"(f)
00270         );
00271     }
00272 #endif //ARCH_x86
00273     for (;i < len;i++)
00274         *out++ = lrintf(clipcheck(*in++) * f);
00275     return len << 1;
00276 }
00277 
00278 static int toFloat32(AudioFormat format, float *out, int *in, int len)
00279 {
00280     int i = 0;
00281     int bits = AudioOutputSettings::FormatToBits(format);
00282     float f = 1.0f / ((uint)(1<<(bits-1)) - 128);
00283     int shift = 32 - bits;
00284 
00285     if (format == FORMAT_S24LSB)
00286         shift = 0;
00287 
00288 #if ARCH_X86
00289     if (sse_check() && len >= 16)
00290     {
00291         int loops = len >> 4;
00292         i = loops << 4;
00293 
00294         __asm__ volatile (
00295             "movd       %3, %%xmm7          \n\t"
00296             "punpckldq  %%xmm7, %%xmm7      \n\t"
00297             "movd       %4, %%xmm6          \n\t"
00298             "punpckldq  %%xmm7, %%xmm7      \n\t"
00299             "1:                             \n\t"
00300             "movdqa     (%1),   %%xmm1      \n\t"
00301             "movdqa     16(%1), %%xmm2      \n\t"
00302             "psrad      %%xmm6, %%xmm1      \n\t"
00303             "movdqa     32(%1), %%xmm3      \n\t"
00304             "cvtdq2ps   %%xmm1, %%xmm1      \n\t"
00305             "psrad      %%xmm6, %%xmm2      \n\t"
00306             "movdqa     48(%1), %%xmm4      \n\t"
00307             "cvtdq2ps   %%xmm2, %%xmm2      \n\t"
00308             "psrad      %%xmm6, %%xmm3      \n\t"
00309             "mulps      %%xmm7, %%xmm1      \n\t"
00310             "psrad      %%xmm6, %%xmm4      \n\t"
00311             "cvtdq2ps   %%xmm3, %%xmm3      \n\t"
00312             "movaps     %%xmm1, (%0)        \n\t"
00313             "mulps      %%xmm7, %%xmm2      \n\t"
00314             "cvtdq2ps   %%xmm4, %%xmm4      \n\t"
00315             "movaps     %%xmm2, 16(%0)      \n\t"
00316             "mulps      %%xmm7, %%xmm3      \n\t"
00317             "mulps      %%xmm7, %%xmm4      \n\t"
00318             "movaps     %%xmm3, 32(%0)      \n\t"
00319             "add        $64,    %1          \n\t"
00320             "movaps     %%xmm4, 48(%0)      \n\t"
00321             "add        $64,    %0          \n\t"
00322             "sub        $1, %%ecx           \n\t"
00323             "jnz        1b                  \n\t"
00324             :"+r"(out),"+r"(in)
00325             :"c"(loops), "r"(f), "r"(shift)
00326         );
00327     }
00328 #endif //ARCH_x86
00329     for (; i < len; i++)
00330         *out++ = (*in++ >> shift) * f;
00331     return len << 2;
00332 }
00333 
00334 static int fromFloat32(AudioFormat format, int *out, float *in, int len)
00335 {
00336     int i = 0;
00337     int bits = AudioOutputSettings::FormatToBits(format);
00338     float f = (uint)(1<<(bits-1)) - 128;
00339     int shift = 32 - bits;
00340 
00341     if (format == FORMAT_S24LSB)
00342         shift = 0;
00343 
00344 #if ARCH_X86
00345     if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0)
00346     {
00347         float o = 1, mo = -1;
00348         int loops = len >> 4;
00349         i = loops << 4;
00350 
00351         __asm__ volatile (
00352             "movd       %3, %%xmm7          \n\t"
00353             "movss      %4, %%xmm5          \n\t"
00354             "punpckldq  %%xmm7, %%xmm7      \n\t"
00355             "movss      %5, %%xmm6          \n\t"
00356             "punpckldq  %%xmm5, %%xmm5      \n\t"
00357             "punpckldq  %%xmm6, %%xmm6      \n\t"
00358             "movd       %6, %%xmm0          \n\t"
00359             "punpckldq  %%xmm7, %%xmm7      \n\t"
00360             "punpckldq  %%xmm5, %%xmm5      \n\t"
00361             "punpckldq  %%xmm6, %%xmm6      \n\t"
00362             "1:                             \n\t"
00363             "movups     (%1), %%xmm1        \n\t"
00364             "movups     16(%1), %%xmm2      \n\t"
00365             "minps      %%xmm5, %%xmm1      \n\t"
00366             "movups     32(%1), %%xmm3      \n\t"
00367             "maxps      %%xmm6, %%xmm1      \n\t"
00368             "movups     48(%1), %%xmm4      \n\t"
00369             "mulps      %%xmm7, %%xmm1      \n\t"
00370             "minps      %%xmm5, %%xmm2      \n\t"
00371             "cvtps2dq   %%xmm1, %%xmm1      \n\t"
00372             "maxps      %%xmm6, %%xmm2      \n\t"
00373             "pslld      %%xmm0, %%xmm1      \n\t"
00374             "minps      %%xmm5, %%xmm3      \n\t"
00375             "mulps      %%xmm7, %%xmm2      \n\t"
00376             "movdqu     %%xmm1, (%0)        \n\t"
00377             "cvtps2dq   %%xmm2, %%xmm2      \n\t"
00378             "maxps      %%xmm6, %%xmm3      \n\t"
00379             "minps      %%xmm5, %%xmm4      \n\t"
00380             "pslld      %%xmm0, %%xmm2      \n\t"
00381             "mulps      %%xmm7, %%xmm3      \n\t"
00382             "maxps      %%xmm6, %%xmm4      \n\t"
00383             "movdqu     %%xmm2, 16(%0)      \n\t"
00384             "cvtps2dq   %%xmm3, %%xmm3      \n\t"
00385             "mulps      %%xmm7, %%xmm4      \n\t"
00386             "pslld      %%xmm0, %%xmm3      \n\t"
00387             "cvtps2dq   %%xmm4, %%xmm4      \n\t"
00388             "movdqu     %%xmm3, 32(%0)      \n\t"
00389             "pslld      %%xmm0, %%xmm4      \n\t"
00390             "add        $64,    %1          \n\t"
00391             "movdqu     %%xmm4, 48(%0)      \n\t"
00392             "add        $64,    %0          \n\t"
00393             "sub        $1, %%ecx           \n\t"
00394             "jnz        1b                  \n\t"
00395             :"+r"(out), "+r"(in)
00396             :"c"(loops), "r"(f), "m"(o), "m"(mo), "r"(shift)
00397         );
00398     }
00399 #endif //ARCH_x86
00400     for (;i < len;i++)
00401         *out++ = lrintf(clipcheck(*in++) * f) << shift;
00402     return len << 2;
00403 }
00404 
00405 static int fromFloatFLT(float *out, float *in, int len)
00406 {
00407     int i = 0;
00408 
00409 #if ARCH_X86
00410     if (sse_check() && len >= 16 && ((unsigned long)in & 0xf) == 0)
00411     {
00412         int loops = len >> 4;
00413         float o = 1, mo = -1;
00414         i = loops << 4;
00415 
00416         __asm__ volatile (
00417             "movss      %3, %%xmm6          \n\t"
00418             "movss      %4, %%xmm7          \n\t"
00419             "punpckldq  %%xmm6, %%xmm6      \n\t"
00420             "punpckldq  %%xmm7, %%xmm7      \n\t"
00421             "punpckldq  %%xmm6, %%xmm6      \n\t"
00422             "punpckldq  %%xmm7, %%xmm7      \n\t"
00423             "1:                             \n\t"
00424             "movups     (%1), %%xmm1        \n\t"
00425             "movups     16(%1), %%xmm2      \n\t"
00426             "minps      %%xmm6, %%xmm1      \n\t"
00427             "movups     32(%1), %%xmm3      \n\t"
00428             "maxps      %%xmm7, %%xmm1      \n\t"
00429             "minps      %%xmm6, %%xmm2      \n\t"
00430             "movups     48(%1), %%xmm4      \n\t"
00431             "maxps      %%xmm7, %%xmm2      \n\t"
00432             "movups     %%xmm1, (%0)        \n\t"
00433             "minps      %%xmm6, %%xmm3      \n\t"
00434             "movups     %%xmm2, 16(%0)      \n\t"
00435             "maxps      %%xmm7, %%xmm3      \n\t"
00436             "minps      %%xmm6, %%xmm4      \n\t"
00437             "movups     %%xmm3, 32(%0)      \n\t"
00438             "maxps      %%xmm7, %%xmm4      \n\t"
00439             "add        $64,    %1          \n\t"
00440             "movups     %%xmm4, 48(%0)      \n\t"
00441             "add        $64,    %0          \n\t"
00442             "sub        $1, %%ecx           \n\t"
00443             "jnz        1b                  \n\t"
00444             :"+r"(out), "+r"(in)
00445             :"c"(loops), "m"(o), "m"(mo)
00446         );
00447     }
00448 #endif //ARCH_x86
00449     for (;i < len;i++)
00450         *out++ = clipcheck(*in++);
00451     return len << 2;
00452 }
00453 
00458 bool AudioOutputUtil::has_hardware_fpu()
00459 {
00460 #if ARCH_X86
00461     return sse_check();
00462 #else
00463     return false;
00464 #endif
00465 }
00466 
00472 int AudioOutputUtil::toFloat(AudioFormat format, void *out, void *in,
00473                              int bytes)
00474 {
00475     if (bytes <= 0)
00476         return 0;
00477 
00478     switch (format)
00479     {
00480         case FORMAT_U8:
00481             return toFloat8((float *)out,  (uchar *)in, bytes);
00482         case FORMAT_S16:
00483             return toFloat16((float *)out, (short *)in, bytes >> 1);
00484         case FORMAT_S24:
00485         case FORMAT_S24LSB:
00486         case FORMAT_S32:
00487             return toFloat32(format, (float *)out, (int *)in, bytes >> 2);
00488         case FORMAT_FLT:
00489             memcpy(out, in, bytes);
00490             return bytes;
00491     }
00492 
00493     return 0;
00494 }
00495 
00501 int AudioOutputUtil::fromFloat(AudioFormat format, void *out, void *in,
00502                                int bytes)
00503 {
00504     if (bytes <= 0)
00505         return 0;
00506 
00507     switch (format)
00508     {
00509         case FORMAT_U8:
00510             return fromFloat8((uchar *)out, (float *)in, bytes >> 2);
00511         case FORMAT_S16:
00512             return fromFloat16((short *)out, (float *)in, bytes >> 2);
00513         case FORMAT_S24:
00514         case FORMAT_S24LSB:
00515         case FORMAT_S32:
00516             return fromFloat32(format, (int *)out, (float *)in, bytes >> 2);
00517         case FORMAT_FLT:
00518             return fromFloatFLT((float *)out, (float *)in, bytes >> 2);
00519     }
00520 
00521     return 0;
00522 }
00523 
00527 void AudioOutputUtil::MonoToStereo(void *dst, void *src, int samples)
00528 {
00529     float *d = (float *)dst;
00530     float *s = (float *)src;
00531     for (int i = 0; i < samples; i++)
00532     {
00533         *d++ = *s;
00534         *d++ = *s++;
00535     }
00536 }
00537 
00544 void AudioOutputUtil::AdjustVolume(void *buf, int len, int volume,
00545                                    bool music, bool upmix)
00546 {
00547     float g     = volume / 100.0f;
00548     float *fptr = (float *)buf;
00549     int samples = len >> 2;
00550     int i       = 0;
00551 
00552     // Should be exponential - this'll do
00553     g *= g;
00554 
00555     // Try to ~ match stereo volume when upmixing
00556     if (upmix)
00557         g *= 1.5f;
00558 
00559     // Music is relatively loud
00560     if (music)
00561         g *= 0.4f;
00562 
00563     if (g == 1.0f)
00564         return;
00565 
00566 #if ARCH_X86
00567     if (sse_check() && samples >= 16)
00568     {
00569         int loops = samples >> 4;
00570         i = loops << 4;
00571 
00572         __asm__ volatile (
00573             "movss      %2, %%xmm0          \n\t"
00574             "punpckldq  %%xmm0, %%xmm0      \n\t"
00575             "punpckldq  %%xmm0, %%xmm0      \n\t"
00576             "1:                             \n\t"
00577             "movups     (%0), %%xmm1        \n\t"
00578             "movups     16(%0), %%xmm2      \n\t"
00579             "mulps      %%xmm0, %%xmm1      \n\t"
00580             "movups     32(%0), %%xmm3      \n\t"
00581             "mulps      %%xmm0, %%xmm2      \n\t"
00582             "movups     48(%0), %%xmm4      \n\t"
00583             "mulps      %%xmm0, %%xmm3      \n\t"
00584             "movups     %%xmm1, (%0)        \n\t"
00585             "mulps      %%xmm0, %%xmm4      \n\t"
00586             "movups     %%xmm2, 16(%0)      \n\t"
00587             "movups     %%xmm3, 32(%0)      \n\t"
00588             "movups     %%xmm4, 48(%0)      \n\t"
00589             "add        $64,    %0          \n\t"
00590             "sub        $1, %%ecx           \n\t"
00591             "jnz        1b                  \n\t"
00592             :"+r"(fptr)
00593             :"c"(loops),"m"(g)
00594         );
00595     }
00596 #endif //ARCH_X86
00597     for (; i < samples; i++)
00598         *fptr++ *= g;
00599 }
00600 
00601 template <class AudioDataType>
00602 void _MuteChannel(AudioDataType *buffer, int channels, int ch, int frames)
00603 {
00604     AudioDataType *s1 = buffer + ch;
00605     AudioDataType *s2 = buffer - ch + 1;
00606 
00607     for (int i = 0; i < frames; i++)
00608     {
00609         *s1 = *s2;
00610         s1 += channels;
00611         s2 += channels;
00612     }
00613 }
00614 
00621 void AudioOutputUtil::MuteChannel(int obits, int channels, int ch,
00622                                   void *buffer, int bytes)
00623 {
00624     int frames = bytes / ((obits >> 3) * channels);
00625 
00626     if (obits == 8)
00627         _MuteChannel((uchar *)buffer, channels, ch, frames);
00628     else if (obits == 16)
00629         _MuteChannel((short *)buffer, channels, ch, frames);
00630     else
00631         _MuteChannel((int *)buffer, channels, ch, frames);
00632 }
00633 
00634 #if HAVE_BIGENDIAN
00635 #define LE_SHORT(v)      bswap_16(v)
00636 #define LE_INT(v)        bswap_32(v)
00637 #else
00638 #define LE_SHORT(v)      (v)
00639 #define LE_INT(v)        (v)
00640 #endif
00641 
00642 char *AudioOutputUtil::GeneratePinkFrames(char *frames, int channels,
00643                                           int channel, int count, int bits)
00644 {
00645     pink_noise_t pink;
00646 
00647     initialize_pink_noise(&pink, bits);
00648 
00649     double   res;
00650     int32_t  ires;
00651     int16_t *samp16 = (int16_t*) frames;
00652     int32_t *samp32 = (int32_t*) frames;
00653 
00654     while (count-- > 0)
00655     {
00656         for(int chn = 0 ; chn < channels; chn++)
00657         {
00658             if (chn==channel)
00659             {
00660                 res = generate_pink_noise_sample(&pink) * 0x03fffffff; /* Don't use MAX volume */
00661                 ires = res;
00662                 if (bits == 16)
00663                     *samp16++ = LE_SHORT(ires >> 16);
00664                 else
00665                     *samp32++ = LE_INT(ires);
00666             }
00667             else
00668             {
00669                 if (bits == 16)
00670                     *samp16++ = 0;
00671                 else
00672                     *samp32++ = 0;
00673             }
00674         }
00675     }    
00676     return frames;
00677 }
00678   
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends