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
00015 static inline bool sse_check()
00016 {
00017 if (has_sse2 != -1)
00018 return (bool)has_sse2;
00019 __asm__(
00020
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
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
00057
00058
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
00125
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
00553 g *= g;
00554
00555
00556 if (upmix)
00557 g *= 1.5f;
00558
00559
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;
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