1 /* DirectSound format conversion and mixing routines
3 * Copyright 2007 Maarten Lankhorst
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* 8 bits is unsigned, the rest is signed.
21 * First I tried to reuse existing stuff from alsa-lib, after that
22 * didn't work, I gave up and just went for individual hacks.
24 * 24 bit is expensive to do, due to unaligned access.
25 * In dlls/winex11.drv/dib_convert.c convert_888_to_0888_asis there is a way
26 * around it, but I'm happy current code works, maybe something for later.
28 * The ^ 0x80 flips the signed bit, this is the conversion from
29 * signed (-128.. 0.. 127) to unsigned (0...255)
30 * This is only temporary: All 8 bit data should be converted to signed.
31 * then when fed to the sound card, it should be converted to unsigned again.
33 * Sound is LITTLE endian
40 #define NONAMELESSSTRUCT
41 #define NONAMELESSUNION
46 #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 const bitsconvertfunc convertbpp
[4][4] = {
299 { convert_8_to_8
, convert_8_to_16
, convert_8_to_24
, convert_8_to_32
},
300 { convert_16_to_8
, convert_16_to_16
, convert_16_to_24
, convert_16_to_32
},
301 { convert_24_to_8
, convert_24_to_16
, convert_24_to_24
, convert_24_to_32
},
302 { convert_32_to_8
, convert_32_to_16
, convert_32_to_24
, convert_32_to_32
},
305 static void mix8(signed char *src
, INT
*dst
, unsigned len
)
307 TRACE("%p - %p %d\n", src
, dst
, len
);
309 /* 8-bit WAV is unsigned, it's here converted to signed, normalize function will convert it back again */
310 *(dst
++) += (signed char)((BYTE
)*(src
++) - (BYTE
)0x80);
313 static void mix16(SHORT
*src
, INT
*dst
, unsigned len
)
315 TRACE("%p - %p %d\n", src
, dst
, len
);
324 static void mix24(BYTE
*src
, INT
*dst
, unsigned len
)
326 TRACE("%p - %p %d\n", src
, dst
, len
);
331 field
= ((DWORD
)src
[2] << 16) + ((DWORD
)src
[1] << 8) + (DWORD
)src
[0];
333 field
|= 0xFF000000U
;
339 static void mix32(INT
*src
, LONGLONG
*dst
, unsigned len
)
341 TRACE("%p - %p %d\n", src
, dst
, len
);
344 *(dst
++) += le32(*(src
++));
347 const mixfunc mixfunctions
[4] = {
354 static void norm8(INT
*src
, signed char *dst
, unsigned len
)
356 TRACE("%p - %p %d\n", src
, dst
, len
);
359 *dst
= (*src
) + 0x80;
362 else if (*src
> 0x7f)
369 static void norm16(INT
*src
, SHORT
*dst
, unsigned len
)
371 TRACE("%p - %p %d\n", src
, dst
, len
);
378 else if (*src
> 0x7fff)
385 static void norm24(INT
*src
, BYTE
*dst
, unsigned len
)
387 TRACE("%p - %p %d\n", src
, dst
, len
);
391 if (*src
<= -0x800000)
397 else if (*src
> 0x7fffff)
414 static void norm32(LONGLONG
*src
, INT
*dst
, unsigned len
)
416 TRACE("%p - %p %d\n", src
, dst
, len
);
421 if (*src
<= -(LONGLONG
)0x80000000)
422 *dst
= le32(0x80000000);
423 else if (*src
> 0x7fffffff)
424 *dst
= le32(0x7fffffff);
430 const normfunc normfunctions
[4] = {