1 /* DirectSound format conversion and mixing routines 2 * 3 * Copyright 2007 Maarten Lankhorst 4 * Copyright 2011 Owen Rudge for CodeWeavers 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 /* 8 bits is unsigned, the rest is signed. 22 * First I tried to reuse existing stuff from alsa-lib, after that 23 * didn't work, I gave up and just went for individual hacks. 24 * 25 * 24 bit is expensive to do, due to unaligned access. 26 * In dlls/winex11.drv/dib_convert.c convert_888_to_0888_asis there is a way 27 * around it, but I'm happy current code works, maybe something for later. 28 * 29 * The ^ 0x80 flips the signed bit, this is the conversion from 30 * signed (-128.. 0.. 127) to unsigned (0...255) 31 * This is only temporary: All 8 bit data should be converted to signed. 32 * then when fed to the sound card, it should be converted to unsigned again. 33 * 34 * Sound is LITTLE endian 35 */ 36 37 #include "dsound_private.h" 38 39 #ifdef WORDS_BIGENDIAN 40 #define le16(x) RtlUshortByteSwap((x)) 41 #define le32(x) RtlUlongByteSwap((x)) 42 #else 43 #define le16(x) (x) 44 #define le32(x) (x) 45 #endif 46 47 static inline void src_advance(const void **src, UINT stride, INT *count, UINT *freqAcc, UINT adj) 48 { 49 *freqAcc += adj; 50 if (*freqAcc >= (1 << DSOUND_FREQSHIFT)) 51 { 52 ULONG adv = (*freqAcc >> DSOUND_FREQSHIFT); 53 *freqAcc &= (1 << DSOUND_FREQSHIFT) - 1; 54 *(const char **)src += adv * stride; 55 *count -= adv; 56 } 57 } 58 59 static void convert_8_to_8 (const void *src, void *dst, UINT src_stride, 60 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 61 { 62 while (count > 0) 63 { 64 *(BYTE *)dst = *(const BYTE *)src; 65 66 dst = (char *)dst + dst_stride; 67 src_advance(&src, src_stride, &count, &freqAcc, adj); 68 } 69 } 70 71 static void convert_8_to_16 (const void *src, void *dst, UINT src_stride, 72 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 73 { 74 while (count > 0) 75 { 76 WORD dest = *(const BYTE *)src, *dest16 = dst; 77 *dest16 = le16(dest * 257 - 32768); 78 79 dst = (char *)dst + dst_stride; 80 src_advance(&src, src_stride, &count, &freqAcc, adj); 81 } 82 } 83 84 static void convert_8_to_24 (const void *src, void *dst, UINT src_stride, 85 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 86 { 87 while (count > 0) 88 { 89 BYTE dest = *(const BYTE *)src; 90 BYTE *dest24 = dst; 91 dest24[0] = dest; 92 dest24[1] = dest; 93 dest24[2] = dest - 0x80; 94 95 dst = (char *)dst + dst_stride; 96 src_advance(&src, src_stride, &count, &freqAcc, adj); 97 } 98 } 99 100 static void convert_8_to_32 (const void *src, void *dst, UINT src_stride, 101 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 102 { 103 while (count > 0) 104 { 105 DWORD dest = *(const BYTE *)src, *dest32 = dst; 106 *dest32 = le32(dest * 16843009 - 2147483648U); 107 108 dst = (char *)dst + dst_stride; 109 src_advance(&src, src_stride, &count, &freqAcc, adj); 110 } 111 } 112 113 static void convert_16_to_8 (const void *src, void *dst, UINT src_stride, 114 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 115 { 116 while (count > 0) 117 { 118 BYTE *dst8 = dst; 119 *dst8 = (le16(*(const WORD *)src)) / 256; 120 *dst8 -= 0x80; 121 122 dst = (char *)dst + dst_stride; 123 src_advance(&src, src_stride, &count, &freqAcc, adj); 124 } 125 } 126 127 static void convert_16_to_16 (const void *src, void *dst, UINT src_stride, 128 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 129 { 130 while (count > 0) 131 { 132 *(WORD *)dst = *(const WORD *)src; 133 134 dst = (char *)dst + dst_stride; 135 src_advance(&src, src_stride, &count, &freqAcc, adj); 136 } 137 } 138 139 static void convert_16_to_24 (const void *src, void *dst, UINT src_stride, 140 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 141 { 142 while (count > 0) 143 { 144 WORD dest = le16(*(const WORD *)src); 145 BYTE *dest24 = dst; 146 147 dest24[0] = dest / 256; 148 dest24[1] = dest; 149 dest24[2] = dest / 256; 150 151 dst = (char *)dst + dst_stride; 152 src_advance(&src, src_stride, &count, &freqAcc, adj); 153 } 154 } 155 156 static void convert_16_to_32 (const void *src, void *dst, UINT src_stride, 157 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 158 { 159 while (count > 0) 160 { 161 DWORD dest = *(const WORD *)src, *dest32 = dst; 162 *dest32 = dest * 65537; 163 164 dst = (char *)dst + dst_stride; 165 src_advance(&src, src_stride, &count, &freqAcc, adj); 166 } 167 } 168 169 static void convert_24_to_8 (const void *src, void *dst, UINT src_stride, 170 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 171 { 172 while (count > 0) 173 { 174 BYTE *dst8 = dst; 175 *dst8 = ((const BYTE *)src)[2]; 176 177 dst = (char *)dst + dst_stride; 178 src_advance(&src, src_stride, &count, &freqAcc, adj); 179 } 180 } 181 182 static void convert_24_to_16 (const void *src, void *dst, UINT src_stride, 183 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 184 { 185 while (count > 0) 186 { 187 WORD *dest16 = dst; 188 const BYTE *source = src; 189 *dest16 = le16(source[2] * 256 + source[1]); 190 191 dst = (char *)dst + dst_stride; 192 src_advance(&src, src_stride, &count, &freqAcc, adj); 193 } 194 } 195 196 static void convert_24_to_24 (const void *src, void *dst, UINT src_stride, 197 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 198 { 199 while (count > 0) 200 { 201 BYTE *dest24 = dst; 202 const BYTE *src24 = src; 203 204 dest24[0] = src24[0]; 205 dest24[1] = src24[1]; 206 dest24[2] = src24[2]; 207 208 dst = (char *)dst + dst_stride; 209 src_advance(&src, src_stride, &count, &freqAcc, adj); 210 } 211 } 212 213 static void convert_24_to_32 (const void *src, void *dst, UINT src_stride, 214 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 215 { 216 while (count > 0) 217 { 218 DWORD *dest32 = dst; 219 const BYTE *source = src; 220 *dest32 = le32(source[2] * 16777217 + source[1] * 65536 + source[0] * 256); 221 222 dst = (char *)dst + dst_stride; 223 src_advance(&src, src_stride, &count, &freqAcc, adj); 224 } 225 } 226 227 static void convert_32_to_8 (const void *src, void *dst, UINT src_stride, 228 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 229 { 230 while (count > 0) 231 { 232 BYTE *dst8 = dst; 233 *dst8 = (le32(*(const DWORD *)src) / 16777216); 234 *dst8 -= 0x80; 235 236 dst = (char *)dst + dst_stride; 237 src_advance(&src, src_stride, &count, &freqAcc, adj); 238 } 239 } 240 241 static void convert_32_to_16 (const void *src, void *dst, UINT src_stride, 242 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 243 { 244 while (count > 0) 245 { 246 WORD *dest16 = dst; 247 *dest16 = le16(le32(*(const DWORD *)src) / 65536); 248 249 dst = (char *)dst + dst_stride; 250 src_advance(&src, src_stride, &count, &freqAcc, adj); 251 } 252 } 253 254 static void convert_32_to_24 (const void *src, void *dst, UINT src_stride, 255 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 256 { 257 while (count > 0) 258 { 259 DWORD dest = le32(*(const DWORD *)src); 260 BYTE *dest24 = dst; 261 262 dest24[0] = dest / 256; 263 dest24[1] = dest / 65536; 264 dest24[2] = dest / 16777216; 265 266 dst = (char *)dst + dst_stride; 267 src_advance(&src, src_stride, &count, &freqAcc, adj); 268 } 269 } 270 271 static void convert_32_to_32 (const void *src, void *dst, UINT src_stride, 272 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 273 { 274 while (count > 0) 275 { 276 DWORD *dest = dst; 277 *dest = *(const DWORD *)src; 278 279 dst = (char *)dst + dst_stride; 280 src_advance(&src, src_stride, &count, &freqAcc, adj); 281 } 282 } 283 284 static void convert_ieee_32_to_8 (const void *src, void *dst, UINT src_stride, 285 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 286 { 287 while (count > 0) 288 { 289 DWORD src_le = le32(*(DWORD *) src); 290 float v = *((float *) &src_le); 291 INT8 d = 0; 292 293 if (v < -1.0f) 294 d = -128; 295 else if (v > 1.0f) 296 d = 127; 297 else 298 d = v * 127.5f - 0.5f; 299 300 *(BYTE *) dst = d ^ 0x80; 301 302 dst = (char *)dst + dst_stride; 303 src_advance(&src, src_stride, &count, &freqAcc, adj); 304 } 305 } 306 307 static void convert_ieee_32_to_16 (const void *src, void *dst, UINT src_stride, 308 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 309 { 310 while (count > 0) 311 { 312 DWORD src_le = le32(*(DWORD *) src); 313 float v = *((float *) &src_le); 314 315 INT16 *d = (INT16 *) dst; 316 317 if (v < -1.0f) 318 *d = -32768; 319 else if (v > 1.0f) 320 *d = 32767; 321 else 322 *d = v * 32767.5f - 0.5f; 323 324 *d = le16(*d); 325 326 dst = (char *)dst + dst_stride; 327 src_advance(&src, src_stride, &count, &freqAcc, adj); 328 } 329 } 330 331 static void convert_ieee_32_to_24 (const void *src, void *dst, UINT src_stride, 332 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 333 { 334 while (count > 0) 335 { 336 DWORD src_le = le32(*(DWORD *) src); 337 float v = *((float *) &src_le); 338 BYTE *dest24 = dst; 339 340 if (v < -1.0f) 341 { 342 dest24[0] = 0; 343 dest24[1] = 0; 344 dest24[2] = 0x80; 345 } 346 else if (v > 1.0f) 347 { 348 dest24[0] = 0xff; 349 dest24[1] = 0xff; 350 dest24[2] = 0x7f; 351 } 352 else if (v < 0.0f) 353 { 354 dest24[0] = v * 8388608.0f; 355 dest24[1] = v * 32768.0f; 356 dest24[2] = v * 128.0f; 357 } 358 else if (v >= 0.0f) 359 { 360 dest24[0] = v * 8388608.0f; 361 dest24[1] = v * 32768.0f; 362 dest24[2] = v * 127.0f; 363 } 364 365 dst = (char *)dst + dst_stride; 366 src_advance(&src, src_stride, &count, &freqAcc, adj); 367 } 368 } 369 370 static void convert_ieee_32_to_32 (const void *src, void *dst, UINT src_stride, 371 UINT dst_stride, INT count, UINT freqAcc, UINT adj) 372 { 373 while (count > 0) 374 { 375 DWORD src_le = le32(*(DWORD *) src); 376 float v = *((float *) &src_le); 377 INT32 *d = (INT32 *) dst; 378 379 if (v < -1.0f) 380 *d = -2147483647 - 1; /* silence warning */ 381 else if (v > 1.0f) 382 *d = 2147483647; 383 else 384 *d = v * 2147483647.5f - 0.5f; 385 386 *d = le32(*d); 387 388 dst = (char *)dst + dst_stride; 389 src_advance(&src, src_stride, &count, &freqAcc, adj); 390 } 391 } 392 393 const bitsconvertfunc convertbpp[5][4] = { 394 { convert_8_to_8, convert_8_to_16, convert_8_to_24, convert_8_to_32 }, 395 { convert_16_to_8, convert_16_to_16, convert_16_to_24, convert_16_to_32 }, 396 { convert_24_to_8, convert_24_to_16, convert_24_to_24, convert_24_to_32 }, 397 { convert_32_to_8, convert_32_to_16, convert_32_to_24, convert_32_to_32 }, 398 { convert_ieee_32_to_8, convert_ieee_32_to_16, convert_ieee_32_to_24, convert_ieee_32_to_32 }, 399 }; 400 401 static void mix8(signed char *src, INT *dst, unsigned len) 402 { 403 TRACE("%p - %p %d\n", src, dst, len); 404 while (len--) 405 /* 8-bit WAV is unsigned, it's here converted to signed, normalize function will convert it back again */ 406 *(dst++) += (signed char)((BYTE)*(src++) - (BYTE)0x80); 407 } 408 409 static void mix16(SHORT *src, INT *dst, unsigned len) 410 { 411 TRACE("%p - %p %d\n", src, dst, len); 412 len /= 2; 413 while (len--) 414 { 415 *dst += le16(*src); 416 ++dst; ++src; 417 } 418 } 419 420 static void mix24(BYTE *src, INT *dst, unsigned len) 421 { 422 TRACE("%p - %p %d\n", src, dst, len); 423 len /= 3; 424 while (len--) 425 { 426 DWORD field; 427 field = ((DWORD)src[2] << 16) + ((DWORD)src[1] << 8) + (DWORD)src[0]; 428 if (src[2] & 0x80) 429 field |= 0xFF000000U; 430 *(dst++) += field; 431 ++src; 432 } 433 } 434 435 static void mix32(INT *src, LONGLONG *dst, unsigned len) 436 { 437 TRACE("%p - %p %d\n", src, dst, len); 438 len /= 4; 439 while (len--) 440 *(dst++) += le32(*(src++)); 441 } 442 443 const mixfunc mixfunctions[4] = { 444 (mixfunc)mix8, 445 (mixfunc)mix16, 446 (mixfunc)mix24, 447 (mixfunc)mix32 448 }; 449 450 static void norm8(INT *src, signed char *dst, unsigned len) 451 { 452 TRACE("%p - %p %d\n", src, dst, len); 453 while (len--) 454 { 455 *dst = (*src) + 0x80; 456 if (*src < -0x80) 457 *dst = 0; 458 else if (*src > 0x7f) 459 *dst = 0xff; 460 ++dst; 461 ++src; 462 } 463 } 464 465 static void norm16(INT *src, SHORT *dst, unsigned len) 466 { 467 TRACE("%p - %p %d\n", src, dst, len); 468 len /= 2; 469 while (len--) 470 { 471 *dst = le16(*src); 472 if (*src <= -0x8000) 473 *dst = le16(0x8000); 474 else if (*src > 0x7fff) 475 *dst = le16(0x7fff); 476 ++dst; 477 ++src; 478 } 479 } 480 481 static void norm24(INT *src, BYTE *dst, unsigned len) 482 { 483 TRACE("%p - %p %d\n", src, dst, len); 484 len /= 3; 485 while (len--) 486 { 487 if (*src <= -0x800000) 488 { 489 dst[0] = 0; 490 dst[1] = 0; 491 dst[2] = 0x80; 492 } 493 else if (*src > 0x7fffff) 494 { 495 dst[0] = 0xff; 496 dst[1] = 0xff; 497 dst[2] = 0x7f; 498 } 499 else 500 { 501 dst[0] = *src; 502 dst[1] = *src >> 8; 503 dst[2] = *src >> 16; 504 } 505 ++dst; 506 ++src; 507 } 508 } 509 510 static void norm32(LONGLONG *src, INT *dst, unsigned len) 511 { 512 TRACE("%p - %p %d\n", src, dst, len); 513 len /= 4; 514 while (len--) 515 { 516 *dst = le32(*src); 517 if (*src <= -(LONGLONG)0x80000000) 518 *dst = le32(0x80000000); 519 else if (*src > 0x7fffffff) 520 *dst = le32(0x7fffffff); 521 ++dst; 522 ++src; 523 } 524 } 525 526 const normfunc normfunctions[4] = { 527 (normfunc)norm8, 528 (normfunc)norm16, 529 (normfunc)norm24, 530 (normfunc)norm32, 531 }; 532