Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendsound_convert.c
Go to the documentation of this file.
00001 /* DirectSound format conversion and mixing routines 00002 * 00003 * Copyright 2007 Maarten Lankhorst 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 /* 8 bits is unsigned, the rest is signed. 00021 * First I tried to reuse existing stuff from alsa-lib, after that 00022 * didn't work, I gave up and just went for individual hacks. 00023 * 00024 * 24 bit is expensive to do, due to unaligned access. 00025 * In dlls/winex11.drv/dib_convert.c convert_888_to_0888_asis there is a way 00026 * around it, but I'm happy current code works, maybe something for later. 00027 * 00028 * The ^ 0x80 flips the signed bit, this is the conversion from 00029 * signed (-128.. 0.. 127) to unsigned (0...255) 00030 * This is only temporary: All 8 bit data should be converted to signed. 00031 * then when fed to the sound card, it should be converted to unsigned again. 00032 * 00033 * Sound is LITTLE endian 00034 */ 00035 00036 #include "config.h" 00037 00038 #include <stdarg.h> 00039 00040 #define NONAMELESSSTRUCT 00041 #define NONAMELESSUNION 00042 #include "windef.h" 00043 #include "winbase.h" 00044 #include "mmsystem.h" 00045 #include "winternl.h" 00046 #include "wine/debug.h" 00047 #include "dsound.h" 00048 #include "dsdriver.h" 00049 #include "dsound_private.h" 00050 00051 WINE_DEFAULT_DEBUG_CHANNEL(dsound); 00052 00053 #ifdef WORDS_BIGENDIAN 00054 #define le16(x) RtlUshortByteSwap((x)) 00055 #define le32(x) RtlUlongByteSwap((x)) 00056 #else 00057 #define le16(x) (x) 00058 #define le32(x) (x) 00059 #endif 00060 00061 static inline void src_advance(const void **src, UINT stride, INT *count, UINT *freqAcc, UINT adj) 00062 { 00063 *freqAcc += adj; 00064 if (*freqAcc >= (1 << DSOUND_FREQSHIFT)) 00065 { 00066 ULONG adv = (*freqAcc >> DSOUND_FREQSHIFT); 00067 *freqAcc &= (1 << DSOUND_FREQSHIFT) - 1; 00068 *(const char **)src += adv * stride; 00069 *count -= adv; 00070 } 00071 } 00072 00073 static void convert_8_to_8 (const void *src, void *dst, UINT src_stride, 00074 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00075 { 00076 while (count > 0) 00077 { 00078 *(BYTE *)dst = *(const BYTE *)src; 00079 00080 dst = (char *)dst + dst_stride; 00081 src_advance(&src, src_stride, &count, &freqAcc, adj); 00082 } 00083 } 00084 00085 static void convert_8_to_16 (const void *src, void *dst, UINT src_stride, 00086 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00087 { 00088 while (count > 0) 00089 { 00090 WORD dest = *(const BYTE *)src, *dest16 = dst; 00091 *dest16 = le16(dest * 257 - 32768); 00092 00093 dst = (char *)dst + dst_stride; 00094 src_advance(&src, src_stride, &count, &freqAcc, adj); 00095 } 00096 } 00097 00098 static void convert_8_to_24 (const void *src, void *dst, UINT src_stride, 00099 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00100 { 00101 while (count > 0) 00102 { 00103 BYTE dest = *(const BYTE *)src; 00104 BYTE *dest24 = dst; 00105 dest24[0] = dest; 00106 dest24[1] = dest; 00107 dest24[2] = dest - 0x80; 00108 00109 dst = (char *)dst + dst_stride; 00110 src_advance(&src, src_stride, &count, &freqAcc, adj); 00111 } 00112 } 00113 00114 static void convert_8_to_32 (const void *src, void *dst, UINT src_stride, 00115 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00116 { 00117 while (count > 0) 00118 { 00119 DWORD dest = *(const BYTE *)src, *dest32 = dst; 00120 *dest32 = le32(dest * 16843009 - 2147483648U); 00121 00122 dst = (char *)dst + dst_stride; 00123 src_advance(&src, src_stride, &count, &freqAcc, adj); 00124 } 00125 } 00126 00127 static void convert_16_to_8 (const void *src, void *dst, UINT src_stride, 00128 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00129 { 00130 while (count > 0) 00131 { 00132 BYTE *dst8 = dst; 00133 *dst8 = (le16(*(const WORD *)src)) / 256; 00134 *dst8 -= 0x80; 00135 00136 dst = (char *)dst + dst_stride; 00137 src_advance(&src, src_stride, &count, &freqAcc, adj); 00138 } 00139 } 00140 00141 static void convert_16_to_16 (const void *src, void *dst, UINT src_stride, 00142 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00143 { 00144 while (count > 0) 00145 { 00146 *(WORD *)dst = *(const WORD *)src; 00147 00148 dst = (char *)dst + dst_stride; 00149 src_advance(&src, src_stride, &count, &freqAcc, adj); 00150 } 00151 } 00152 00153 static void convert_16_to_24 (const void *src, void *dst, UINT src_stride, 00154 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00155 { 00156 while (count > 0) 00157 { 00158 WORD dest = le16(*(const WORD *)src); 00159 BYTE *dest24 = dst; 00160 00161 dest24[0] = dest / 256; 00162 dest24[1] = dest; 00163 dest24[2] = dest / 256; 00164 00165 dst = (char *)dst + dst_stride; 00166 src_advance(&src, src_stride, &count, &freqAcc, adj); 00167 } 00168 } 00169 00170 static void convert_16_to_32 (const void *src, void *dst, UINT src_stride, 00171 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00172 { 00173 while (count > 0) 00174 { 00175 DWORD dest = *(const WORD *)src, *dest32 = dst; 00176 *dest32 = dest * 65537; 00177 00178 dst = (char *)dst + dst_stride; 00179 src_advance(&src, src_stride, &count, &freqAcc, adj); 00180 } 00181 } 00182 00183 static void convert_24_to_8 (const void *src, void *dst, UINT src_stride, 00184 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00185 { 00186 while (count > 0) 00187 { 00188 BYTE *dst8 = dst; 00189 *dst8 = ((const BYTE *)src)[2]; 00190 00191 dst = (char *)dst + dst_stride; 00192 src_advance(&src, src_stride, &count, &freqAcc, adj); 00193 } 00194 } 00195 00196 static void convert_24_to_16 (const void *src, void *dst, UINT src_stride, 00197 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00198 { 00199 while (count > 0) 00200 { 00201 WORD *dest16 = dst; 00202 const BYTE *source = src; 00203 *dest16 = le16(source[2] * 256 + source[1]); 00204 00205 dst = (char *)dst + dst_stride; 00206 src_advance(&src, src_stride, &count, &freqAcc, adj); 00207 } 00208 } 00209 00210 static void convert_24_to_24 (const void *src, void *dst, UINT src_stride, 00211 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00212 { 00213 while (count > 0) 00214 { 00215 BYTE *dest24 = dst; 00216 const BYTE *src24 = src; 00217 00218 dest24[0] = src24[0]; 00219 dest24[1] = src24[1]; 00220 dest24[2] = src24[2]; 00221 00222 dst = (char *)dst + dst_stride; 00223 src_advance(&src, src_stride, &count, &freqAcc, adj); 00224 } 00225 } 00226 00227 static void convert_24_to_32 (const void *src, void *dst, UINT src_stride, 00228 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00229 { 00230 while (count > 0) 00231 { 00232 DWORD *dest32 = dst; 00233 const BYTE *source = src; 00234 *dest32 = le32(source[2] * 16777217 + source[1] * 65536 + source[0] * 256); 00235 00236 dst = (char *)dst + dst_stride; 00237 src_advance(&src, src_stride, &count, &freqAcc, adj); 00238 } 00239 } 00240 00241 static void convert_32_to_8 (const void *src, void *dst, UINT src_stride, 00242 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00243 { 00244 while (count > 0) 00245 { 00246 BYTE *dst8 = dst; 00247 *dst8 = (le32(*(const DWORD *)src) / 16777216); 00248 *dst8 -= 0x80; 00249 00250 dst = (char *)dst + dst_stride; 00251 src_advance(&src, src_stride, &count, &freqAcc, adj); 00252 } 00253 } 00254 00255 static void convert_32_to_16 (const void *src, void *dst, UINT src_stride, 00256 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00257 { 00258 while (count > 0) 00259 { 00260 WORD *dest16 = dst; 00261 *dest16 = le16(le32(*(const DWORD *)src) / 65536); 00262 00263 dst = (char *)dst + dst_stride; 00264 src_advance(&src, src_stride, &count, &freqAcc, adj); 00265 } 00266 } 00267 00268 static void convert_32_to_24 (const void *src, void *dst, UINT src_stride, 00269 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00270 { 00271 while (count > 0) 00272 { 00273 DWORD dest = le32(*(const DWORD *)src); 00274 BYTE *dest24 = dst; 00275 00276 dest24[0] = dest / 256; 00277 dest24[1] = dest / 65536; 00278 dest24[2] = dest / 16777216; 00279 00280 dst = (char *)dst + dst_stride; 00281 src_advance(&src, src_stride, &count, &freqAcc, adj); 00282 } 00283 } 00284 00285 static void convert_32_to_32 (const void *src, void *dst, UINT src_stride, 00286 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 00287 { 00288 while (count > 0) 00289 { 00290 DWORD *dest = dst; 00291 *dest = *(const DWORD *)src; 00292 00293 dst = (char *)dst + dst_stride; 00294 src_advance(&src, src_stride, &count, &freqAcc, adj); 00295 } 00296 } 00297 00298 const bitsconvertfunc convertbpp[4][4] = { 00299 { convert_8_to_8, convert_8_to_16, convert_8_to_24, convert_8_to_32 }, 00300 { convert_16_to_8, convert_16_to_16, convert_16_to_24, convert_16_to_32 }, 00301 { convert_24_to_8, convert_24_to_16, convert_24_to_24, convert_24_to_32 }, 00302 { convert_32_to_8, convert_32_to_16, convert_32_to_24, convert_32_to_32 }, 00303 }; 00304 00305 static void mix8(signed char *src, INT *dst, unsigned len) 00306 { 00307 TRACE("%p - %p %d\n", src, dst, len); 00308 while (len--) 00309 /* 8-bit WAV is unsigned, it's here converted to signed, normalize function will convert it back again */ 00310 *(dst++) += (signed char)((BYTE)*(src++) - (BYTE)0x80); 00311 } 00312 00313 static void mix16(SHORT *src, INT *dst, unsigned len) 00314 { 00315 TRACE("%p - %p %d\n", src, dst, len); 00316 len /= 2; 00317 while (len--) 00318 { 00319 *dst += le16(*src); 00320 ++dst; ++src; 00321 } 00322 } 00323 00324 static void mix24(BYTE *src, INT *dst, unsigned len) 00325 { 00326 TRACE("%p - %p %d\n", src, dst, len); 00327 len /= 3; 00328 while (len--) 00329 { 00330 DWORD field; 00331 field = ((DWORD)src[2] << 16) + ((DWORD)src[1] << 8) + (DWORD)src[0]; 00332 if (src[2] & 0x80) 00333 field |= 0xFF000000U; 00334 *(dst++) += field; 00335 ++src; 00336 } 00337 } 00338 00339 static void mix32(INT *src, LONGLONG *dst, unsigned len) 00340 { 00341 TRACE("%p - %p %d\n", src, dst, len); 00342 len /= 4; 00343 while (len--) 00344 *(dst++) += le32(*(src++)); 00345 } 00346 00347 const mixfunc mixfunctions[4] = { 00348 (mixfunc)mix8, 00349 (mixfunc)mix16, 00350 (mixfunc)mix24, 00351 (mixfunc)mix32 00352 }; 00353 00354 static void norm8(INT *src, signed char *dst, unsigned len) 00355 { 00356 TRACE("%p - %p %d\n", src, dst, len); 00357 while (len--) 00358 { 00359 *dst = (*src) + 0x80; 00360 if (*src < -0x80) 00361 *dst = 0; 00362 else if (*src > 0x7f) 00363 *dst = 0xff; 00364 ++dst; 00365 ++src; 00366 } 00367 } 00368 00369 static void norm16(INT *src, SHORT *dst, unsigned len) 00370 { 00371 TRACE("%p - %p %d\n", src, dst, len); 00372 len /= 2; 00373 while (len--) 00374 { 00375 *dst = le16(*src); 00376 if (*src <= -0x8000) 00377 *dst = le16(0x8000); 00378 else if (*src > 0x7fff) 00379 *dst = le16(0x7fff); 00380 ++dst; 00381 ++src; 00382 } 00383 } 00384 00385 static void norm24(INT *src, BYTE *dst, unsigned len) 00386 { 00387 TRACE("%p - %p %d\n", src, dst, len); 00388 len /= 3; 00389 while (len--) 00390 { 00391 if (*src <= -0x800000) 00392 { 00393 dst[0] = 0; 00394 dst[1] = 0; 00395 dst[2] = 0x80; 00396 } 00397 else if (*src > 0x7fffff) 00398 { 00399 dst[0] = 0xff; 00400 dst[1] = 0xff; 00401 dst[2] = 0x7f; 00402 } 00403 else 00404 { 00405 dst[0] = *src; 00406 dst[1] = *src >> 8; 00407 dst[2] = *src >> 16; 00408 } 00409 ++dst; 00410 ++src; 00411 } 00412 } 00413 00414 static void norm32(LONGLONG *src, INT *dst, unsigned len) 00415 { 00416 TRACE("%p - %p %d\n", src, dst, len); 00417 len /= 4; 00418 while (len--) 00419 { 00420 *dst = le32(*src); 00421 if (*src <= -(LONGLONG)0x80000000) 00422 *dst = le32(0x80000000); 00423 else if (*src > 0x7fffffff) 00424 *dst = le32(0x7fffffff); 00425 ++dst; 00426 ++src; 00427 } 00428 } 00429 00430 const normfunc normfunctions[4] = { 00431 (normfunc)norm8, 00432 (normfunc)norm16, 00433 (normfunc)norm24, 00434 (normfunc)norm32, 00435 }; Generated on Mon May 28 2012 04:21:09 for ReactOS by
1.7.6.1
|