1 /* DirectSound format conversion and mixing routines
3 * Copyright 2007 Maarten Lankhorst
4 * Copyright 2011 Owen Rudge for CodeWeavers
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.
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.
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
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.
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.
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.
34 * Sound is LITTLE endian
41 #define NONAMELESSSTRUCT
42 #define NONAMELESSUNION
47 #include "wine/debug.h"
50 #include "dsound_private.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(dsound
);
54 #ifdef WORDS_BIGENDIAN
55 #define le16(x) RtlUshortByteSwap((x))
56 #define le32(x) RtlUlongByteSwap((x))
62 static inline void src_advance(const void **src
, UINT stride
, INT
*count
, UINT
*freqAcc
, UINT adj
)
65 if (*freqAcc
>= (1 << DSOUND_FREQSHIFT
))
67 ULONG adv
= (*freqAcc
>> DSOUND_FREQSHIFT
);
68 *freqAcc
&= (1 << DSOUND_FREQSHIFT
) - 1;
69 *(const char **)src
+= adv
* stride
;
74 static void convert_8_to_8 (const void *src
, void *dst
, UINT src_stride
,
75 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
79 *(BYTE
*)dst
= *(const BYTE
*)src
;
81 dst
= (char *)dst
+ dst_stride
;
82 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
86 static void convert_8_to_16 (const void *src
, void *dst
, UINT src_stride
,
87 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
91 WORD dest
= *(const BYTE
*)src
, *dest16
= dst
;
92 *dest16
= le16(dest
* 257 - 32768);
94 dst
= (char *)dst
+ dst_stride
;
95 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
99 static void convert_8_to_24 (const void *src
, void *dst
, UINT src_stride
,
100 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
104 BYTE dest
= *(const BYTE
*)src
;
108 dest24
[2] = dest
- 0x80;
110 dst
= (char *)dst
+ dst_stride
;
111 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
115 static void convert_8_to_32 (const void *src
, void *dst
, UINT src_stride
,
116 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
120 DWORD dest
= *(const BYTE
*)src
, *dest32
= dst
;
121 *dest32
= le32(dest
* 16843009 - 2147483648U);
123 dst
= (char *)dst
+ dst_stride
;
124 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
128 static void convert_16_to_8 (const void *src
, void *dst
, UINT src_stride
,
129 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
134 *dst8
= (le16(*(const WORD
*)src
)) / 256;
137 dst
= (char *)dst
+ dst_stride
;
138 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
142 static void convert_16_to_16 (const void *src
, void *dst
, UINT src_stride
,
143 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
147 *(WORD
*)dst
= *(const WORD
*)src
;
149 dst
= (char *)dst
+ dst_stride
;
150 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
154 static void convert_16_to_24 (const void *src
, void *dst
, UINT src_stride
,
155 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
159 WORD dest
= le16(*(const WORD
*)src
);
162 dest24
[0] = dest
/ 256;
164 dest24
[2] = dest
/ 256;
166 dst
= (char *)dst
+ dst_stride
;
167 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
171 static void convert_16_to_32 (const void *src
, void *dst
, UINT src_stride
,
172 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
176 DWORD dest
= *(const WORD
*)src
, *dest32
= dst
;
177 *dest32
= dest
* 65537;
179 dst
= (char *)dst
+ dst_stride
;
180 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
184 static void convert_24_to_8 (const void *src
, void *dst
, UINT src_stride
,
185 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
190 *dst8
= ((const BYTE
*)src
)[2];
192 dst
= (char *)dst
+ dst_stride
;
193 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
197 static void convert_24_to_16 (const void *src
, void *dst
, UINT src_stride
,
198 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
203 const BYTE
*source
= src
;
204 *dest16
= le16(source
[2] * 256 + source
[1]);
206 dst
= (char *)dst
+ dst_stride
;
207 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
211 static void convert_24_to_24 (const void *src
, void *dst
, UINT src_stride
,
212 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
217 const BYTE
*src24
= src
;
219 dest24
[0] = src24
[0];
220 dest24
[1] = src24
[1];
221 dest24
[2] = src24
[2];
223 dst
= (char *)dst
+ dst_stride
;
224 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
228 static void convert_24_to_32 (const void *src
, void *dst
, UINT src_stride
,
229 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
234 const BYTE
*source
= src
;
235 *dest32
= le32(source
[2] * 16777217 + source
[1] * 65536 + source
[0] * 256);
237 dst
= (char *)dst
+ dst_stride
;
238 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
242 static void convert_32_to_8 (const void *src
, void *dst
, UINT src_stride
,
243 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
248 *dst8
= (le32(*(const DWORD
*)src
) / 16777216);
251 dst
= (char *)dst
+ dst_stride
;
252 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
256 static void convert_32_to_16 (const void *src
, void *dst
, UINT src_stride
,
257 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
262 *dest16
= le16(le32(*(const DWORD
*)src
) / 65536);
264 dst
= (char *)dst
+ dst_stride
;
265 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
269 static void convert_32_to_24 (const void *src
, void *dst
, UINT src_stride
,
270 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
274 DWORD dest
= le32(*(const DWORD
*)src
);
277 dest24
[0] = dest
/ 256;
278 dest24
[1] = dest
/ 65536;
279 dest24
[2] = dest
/ 16777216;
281 dst
= (char *)dst
+ dst_stride
;
282 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
286 static void convert_32_to_32 (const void *src
, void *dst
, UINT src_stride
,
287 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
292 *dest
= *(const DWORD
*)src
;
294 dst
= (char *)dst
+ dst_stride
;
295 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
299 static void convert_ieee_32_to_8 (const void *src
, void *dst
, UINT src_stride
,
300 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
304 DWORD src_le
= le32(*(DWORD
*) src
);
305 float v
= *((float *) &src_le
);
313 d
= v
* 127.5f
- 0.5f
;
315 *(BYTE
*) dst
= d
^ 0x80;
317 dst
= (char *)dst
+ dst_stride
;
318 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
322 static void convert_ieee_32_to_16 (const void *src
, void *dst
, UINT src_stride
,
323 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
327 DWORD src_le
= le32(*(DWORD
*) src
);
328 float v
= *((float *) &src_le
);
330 INT16
*d
= (INT16
*) dst
;
337 *d
= v
* 32767.5f
- 0.5f
;
341 dst
= (char *)dst
+ dst_stride
;
342 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
346 static void convert_ieee_32_to_24 (const void *src
, void *dst
, UINT src_stride
,
347 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
351 DWORD src_le
= le32(*(DWORD
*) src
);
352 float v
= *((float *) &src_le
);
369 dest24
[0] = v
* 8388608.0f
;
370 dest24
[1] = v
* 32768.0f
;
371 dest24
[2] = v
* 128.0f
;
375 dest24
[0] = v
* 8388608.0f
;
376 dest24
[1] = v
* 32768.0f
;
377 dest24
[2] = v
* 127.0f
;
380 dst
= (char *)dst
+ dst_stride
;
381 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
385 static void convert_ieee_32_to_32 (const void *src
, void *dst
, UINT src_stride
,
386 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
390 DWORD src_le
= le32(*(DWORD
*) src
);
391 float v
= *((float *) &src_le
);
392 INT32
*d
= (INT32
*) dst
;
395 *d
= -2147483647 - 1; /* silence warning */
399 *d
= v
* 2147483647.5f
- 0.5f
;
403 dst
= (char *)dst
+ dst_stride
;
404 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
408 const bitsconvertfunc convertbpp
[5][4] = {
409 { convert_8_to_8
, convert_8_to_16
, convert_8_to_24
, convert_8_to_32
},
410 { convert_16_to_8
, convert_16_to_16
, convert_16_to_24
, convert_16_to_32
},
411 { convert_24_to_8
, convert_24_to_16
, convert_24_to_24
, convert_24_to_32
},
412 { convert_32_to_8
, convert_32_to_16
, convert_32_to_24
, convert_32_to_32
},
413 { convert_ieee_32_to_8
, convert_ieee_32_to_16
, convert_ieee_32_to_24
, convert_ieee_32_to_32
},
416 static void mix8(signed char *src
, INT
*dst
, unsigned len
)
418 TRACE("%p - %p %d\n", src
, dst
, len
);
420 /* 8-bit WAV is unsigned, it's here converted to signed, normalize function will convert it back again */
421 *(dst
++) += (signed char)((BYTE
)*(src
++) - (BYTE
)0x80);
424 static void mix16(SHORT
*src
, INT
*dst
, unsigned len
)
426 TRACE("%p - %p %d\n", src
, dst
, len
);
435 static void mix24(BYTE
*src
, INT
*dst
, unsigned len
)
437 TRACE("%p - %p %d\n", src
, dst
, len
);
442 field
= ((DWORD
)src
[2] << 16) + ((DWORD
)src
[1] << 8) + (DWORD
)src
[0];
444 field
|= 0xFF000000U
;
450 static void mix32(INT
*src
, LONGLONG
*dst
, unsigned len
)
452 TRACE("%p - %p %d\n", src
, dst
, len
);
455 *(dst
++) += le32(*(src
++));
458 const mixfunc mixfunctions
[4] = {
465 static void norm8(INT
*src
, signed char *dst
, unsigned len
)
467 TRACE("%p - %p %d\n", src
, dst
, len
);
470 *dst
= (*src
) + 0x80;
473 else if (*src
> 0x7f)
480 static void norm16(INT
*src
, SHORT
*dst
, unsigned len
)
482 TRACE("%p - %p %d\n", src
, dst
, len
);
489 else if (*src
> 0x7fff)
496 static void norm24(INT
*src
, BYTE
*dst
, unsigned len
)
498 TRACE("%p - %p %d\n", src
, dst
, len
);
502 if (*src
<= -0x800000)
508 else if (*src
> 0x7fffff)
525 static void norm32(LONGLONG
*src
, INT
*dst
, unsigned len
)
527 TRACE("%p - %p %d\n", src
, dst
, len
);
532 if (*src
<= -(LONGLONG
)0x80000000)
533 *dst
= le32(0x80000000);
534 else if (*src
> 0x7fffffff)
535 *dst
= le32(0x7fffffff);
541 const normfunc normfunctions
[4] = {