ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dsound_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.