|
MythTV
0.26-pre
|
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
1.7.6.1