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"
49 #include "dsound_private.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(dsound
);
53 #ifdef WORDS_BIGENDIAN
54 #define le16(x) RtlUshortByteSwap((x))
55 #define le32(x) RtlUlongByteSwap((x))
61 static inline void src_advance(const void **src
, UINT stride
, INT
*count
, UINT
*freqAcc
, UINT adj
)
64 if (*freqAcc
>= (1 << DSOUND_FREQSHIFT
))
66 ULONG adv
= (*freqAcc
>> DSOUND_FREQSHIFT
);
67 *freqAcc
&= (1 << DSOUND_FREQSHIFT
) - 1;
68 *(const char **)src
+= adv
* stride
;
73 static void convert_8_to_8 (const void *src
, void *dst
, UINT src_stride
,
74 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
78 *(BYTE
*)dst
= *(const BYTE
*)src
;
80 dst
= (char *)dst
+ dst_stride
;
81 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
85 static void convert_8_to_16 (const void *src
, void *dst
, UINT src_stride
,
86 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
90 WORD dest
= *(const BYTE
*)src
, *dest16
= dst
;
91 *dest16
= le16(dest
* 257 - 32768);
93 dst
= (char *)dst
+ dst_stride
;
94 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
98 static void convert_8_to_24 (const void *src
, void *dst
, UINT src_stride
,
99 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
103 BYTE dest
= *(const BYTE
*)src
;
107 dest24
[2] = dest
- 0x80;
109 dst
= (char *)dst
+ dst_stride
;
110 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
114 static void convert_8_to_32 (const void *src
, void *dst
, UINT src_stride
,
115 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
119 DWORD dest
= *(const BYTE
*)src
, *dest32
= dst
;
120 *dest32
= le32(dest
* 16843009 - 2147483648U);
122 dst
= (char *)dst
+ dst_stride
;
123 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
127 static void convert_16_to_8 (const void *src
, void *dst
, UINT src_stride
,
128 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
133 *dst8
= (le16(*(const WORD
*)src
)) / 256;
136 dst
= (char *)dst
+ dst_stride
;
137 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
141 static void convert_16_to_16 (const void *src
, void *dst
, UINT src_stride
,
142 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
146 *(WORD
*)dst
= *(const WORD
*)src
;
148 dst
= (char *)dst
+ dst_stride
;
149 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
153 static void convert_16_to_24 (const void *src
, void *dst
, UINT src_stride
,
154 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
158 WORD dest
= le16(*(const WORD
*)src
);
161 dest24
[0] = dest
/ 256;
163 dest24
[2] = dest
/ 256;
165 dst
= (char *)dst
+ dst_stride
;
166 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
170 static void convert_16_to_32 (const void *src
, void *dst
, UINT src_stride
,
171 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
175 DWORD dest
= *(const WORD
*)src
, *dest32
= dst
;
176 *dest32
= dest
* 65537;
178 dst
= (char *)dst
+ dst_stride
;
179 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
183 static void convert_24_to_8 (const void *src
, void *dst
, UINT src_stride
,
184 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
189 *dst8
= ((const BYTE
*)src
)[2];
191 dst
= (char *)dst
+ dst_stride
;
192 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
196 static void convert_24_to_16 (const void *src
, void *dst
, UINT src_stride
,
197 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
202 const BYTE
*source
= src
;
203 *dest16
= le16(source
[2] * 256 + source
[1]);
205 dst
= (char *)dst
+ dst_stride
;
206 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
210 static void convert_24_to_24 (const void *src
, void *dst
, UINT src_stride
,
211 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
216 const BYTE
*src24
= src
;
218 dest24
[0] = src24
[0];
219 dest24
[1] = src24
[1];
220 dest24
[2] = src24
[2];
222 dst
= (char *)dst
+ dst_stride
;
223 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
227 static void convert_24_to_32 (const void *src
, void *dst
, UINT src_stride
,
228 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
233 const BYTE
*source
= src
;
234 *dest32
= le32(source
[2] * 16777217 + source
[1] * 65536 + source
[0] * 256);
236 dst
= (char *)dst
+ dst_stride
;
237 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
241 static void convert_32_to_8 (const void *src
, void *dst
, UINT src_stride
,
242 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
247 *dst8
= (le32(*(const DWORD
*)src
) / 16777216);
250 dst
= (char *)dst
+ dst_stride
;
251 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
255 static void convert_32_to_16 (const void *src
, void *dst
, UINT src_stride
,
256 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
261 *dest16
= le16(le32(*(const DWORD
*)src
) / 65536);
263 dst
= (char *)dst
+ dst_stride
;
264 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
268 static void convert_32_to_24 (const void *src
, void *dst
, UINT src_stride
,
269 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
273 DWORD dest
= le32(*(const DWORD
*)src
);
276 dest24
[0] = dest
/ 256;
277 dest24
[1] = dest
/ 65536;
278 dest24
[2] = dest
/ 16777216;
280 dst
= (char *)dst
+ dst_stride
;
281 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
285 static void convert_32_to_32 (const void *src
, void *dst
, UINT src_stride
,
286 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
291 *dest
= *(const DWORD
*)src
;
293 dst
= (char *)dst
+ dst_stride
;
294 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
298 static void convert_ieee_32_to_8 (const void *src
, void *dst
, UINT src_stride
,
299 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
303 DWORD src_le
= le32(*(DWORD
*) src
);
304 float v
= *((float *) &src_le
);
312 d
= v
* 127.5f
- 0.5f
;
314 *(BYTE
*) dst
= d
^ 0x80;
316 dst
= (char *)dst
+ dst_stride
;
317 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
321 static void convert_ieee_32_to_16 (const void *src
, void *dst
, UINT src_stride
,
322 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
326 DWORD src_le
= le32(*(DWORD
*) src
);
327 float v
= *((float *) &src_le
);
329 INT16
*d
= (INT16
*) dst
;
336 *d
= v
* 32767.5f
- 0.5f
;
340 dst
= (char *)dst
+ dst_stride
;
341 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
345 static void convert_ieee_32_to_24 (const void *src
, void *dst
, UINT src_stride
,
346 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
350 DWORD src_le
= le32(*(DWORD
*) src
);
351 float v
= *((float *) &src_le
);
368 dest24
[0] = v
* 8388608.0f
;
369 dest24
[1] = v
* 32768.0f
;
370 dest24
[2] = v
* 128.0f
;
374 dest24
[0] = v
* 8388608.0f
;
375 dest24
[1] = v
* 32768.0f
;
376 dest24
[2] = v
* 127.0f
;
379 dst
= (char *)dst
+ dst_stride
;
380 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
384 static void convert_ieee_32_to_32 (const void *src
, void *dst
, UINT src_stride
,
385 UINT dst_stride
, INT count
, UINT freqAcc
, UINT adj
)
389 DWORD src_le
= le32(*(DWORD
*) src
);
390 float v
= *((float *) &src_le
);
391 INT32
*d
= (INT32
*) dst
;
394 *d
= -2147483647 - 1; /* silence warning */
398 *d
= v
* 2147483647.5f
- 0.5f
;
402 dst
= (char *)dst
+ dst_stride
;
403 src_advance(&src
, src_stride
, &count
, &freqAcc
, adj
);
407 const bitsconvertfunc convertbpp
[5][4] = {
408 { convert_8_to_8
, convert_8_to_16
, convert_8_to_24
, convert_8_to_32
},
409 { convert_16_to_8
, convert_16_to_16
, convert_16_to_24
, convert_16_to_32
},
410 { convert_24_to_8
, convert_24_to_16
, convert_24_to_24
, convert_24_to_32
},
411 { convert_32_to_8
, convert_32_to_16
, convert_32_to_24
, convert_32_to_32
},
412 { convert_ieee_32_to_8
, convert_ieee_32_to_16
, convert_ieee_32_to_24
, convert_ieee_32_to_32
},
415 static void mix8(signed char *src
, INT
*dst
, unsigned len
)
417 TRACE("%p - %p %d\n", src
, dst
, len
);
419 /* 8-bit WAV is unsigned, it's here converted to signed, normalize function will convert it back again */
420 *(dst
++) += (signed char)((BYTE
)*(src
++) - (BYTE
)0x80);
423 static void mix16(SHORT
*src
, INT
*dst
, unsigned len
)
425 TRACE("%p - %p %d\n", src
, dst
, len
);
434 static void mix24(BYTE
*src
, INT
*dst
, unsigned len
)
436 TRACE("%p - %p %d\n", src
, dst
, len
);
441 field
= ((DWORD
)src
[2] << 16) + ((DWORD
)src
[1] << 8) + (DWORD
)src
[0];
443 field
|= 0xFF000000U
;
449 static void mix32(INT
*src
, LONGLONG
*dst
, unsigned len
)
451 TRACE("%p - %p %d\n", src
, dst
, len
);
454 *(dst
++) += le32(*(src
++));
457 const mixfunc mixfunctions
[4] = {
464 static void norm8(INT
*src
, signed char *dst
, unsigned len
)
466 TRACE("%p - %p %d\n", src
, dst
, len
);
469 *dst
= (*src
) + 0x80;
472 else if (*src
> 0x7f)
479 static void norm16(INT
*src
, SHORT
*dst
, unsigned len
)
481 TRACE("%p - %p %d\n", src
, dst
, len
);
488 else if (*src
> 0x7fff)
495 static void norm24(INT
*src
, BYTE
*dst
, unsigned len
)
497 TRACE("%p - %p %d\n", src
, dst
, len
);
501 if (*src
<= -0x800000)
507 else if (*src
> 0x7fffff)
524 static void norm32(LONGLONG
*src
, INT
*dst
, unsigned len
)
526 TRACE("%p - %p %d\n", src
, dst
, len
);
531 if (*src
<= -(LONGLONG
)0x80000000)
532 *dst
= le32(0x80000000);
533 else if (*src
> 0x7fffffff)
534 *dst
= le32(0x7fffffff);
540 const normfunc normfunctions
[4] = {