src/audio/SDL_audiocvt.c
changeset 1982 3b4ce57c6215
parent 1895 c121d94672cb
child 1985 8055185ae4ed
     1.1 --- a/src/audio/SDL_audiocvt.c	Thu Aug 10 15:15:06 2006 +0000
     1.2 +++ b/src/audio/SDL_audiocvt.c	Thu Aug 24 12:10:46 2006 +0000
     1.3 @@ -24,11 +24,11 @@
     1.4  /* Functions for audio drivers to perform runtime conversion of audio format */
     1.5  
     1.6  #include "SDL_audio.h"
     1.7 -
     1.8 +#include "SDL_audio_c.h"
     1.9  
    1.10  /* Effectively mix right and left channels into a single channel */
    1.11 -void SDLCALL
    1.12 -SDL_ConvertMono(SDL_AudioCVT * cvt, Uint16 format)
    1.13 +static void SDLCALL
    1.14 +SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.15  {
    1.16      int i;
    1.17      Sint32 sample;
    1.18 @@ -36,8 +36,7 @@
    1.19  #ifdef DEBUG_CONVERT
    1.20      fprintf(stderr, "Converting to mono\n");
    1.21  #endif
    1.22 -    switch (format & 0x8018) {
    1.23 -
    1.24 +    switch (format & (SDL_AUDIO_MASK_SIGNED|SDL_AUDIO_MASK_BITSIZE)) {
    1.25      case AUDIO_U8:
    1.26          {
    1.27              Uint8 *src, *dst;
    1.28 @@ -84,7 +83,7 @@
    1.29  
    1.30              src = cvt->buf;
    1.31              dst = cvt->buf;
    1.32 -            if ((format & 0x1000) == 0x1000) {
    1.33 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
    1.34                  for (i = cvt->len_cvt / 4; i; --i) {
    1.35                      sample = (Uint16) ((src[0] << 8) | src[1]) +
    1.36                          (Uint16) ((src[2] << 8) | src[3]);
    1.37 @@ -124,7 +123,7 @@
    1.38  
    1.39              src = cvt->buf;
    1.40              dst = cvt->buf;
    1.41 -            if ((format & 0x1000) == 0x1000) {
    1.42 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
    1.43                  for (i = cvt->len_cvt / 4; i; --i) {
    1.44                      sample = (Sint16) ((src[0] << 8) | src[1]) +
    1.45                          (Sint16) ((src[2] << 8) | src[3]);
    1.46 @@ -163,127 +162,106 @@
    1.47              }
    1.48          }
    1.49          break;
    1.50 +
    1.51 +    case AUDIO_S32:
    1.52 +        {
    1.53 +            const Uint32 *src = (const Uint32 *) cvt->buf;
    1.54 +            Uint32 *dst = (Uint32 *) cvt->buf;
    1.55 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
    1.56 +                for (i = cvt->len_cvt / 8; i; --i, src += 2) {
    1.57 +                    const Sint64 added =
    1.58 +                                    (((Sint64) (Sint32) SDL_SwapBE32(src[0])) +
    1.59 +                                     ((Sint64) (Sint32) SDL_SwapBE32(src[1])));
    1.60 +                    *(dst++) = SDL_SwapBE32((Uint32) ((Sint32) (added >> 1)));
    1.61 +                }
    1.62 +            } else {
    1.63 +                for (i = cvt->len_cvt / 8; i; --i, src += 2) {
    1.64 +                    const Sint64 added =
    1.65 +                                    (((Sint64) (Sint32) SDL_SwapLE32(src[0])) +
    1.66 +                                     ((Sint64) (Sint32) SDL_SwapLE32(src[1])));
    1.67 +                    *(dst++) = SDL_SwapLE32((Uint32) ((Sint32) (added >> 1)));
    1.68 +                }
    1.69 +            }
    1.70 +        }
    1.71 +        break;
    1.72 +
    1.73 +    case AUDIO_F32:
    1.74 +        {
    1.75 +            /* !!! FIXME: this convert union is nasty. */
    1.76 +            union { float f; Uint32 ui32; } f2i;
    1.77 +            const Uint32 *src = (const Uint32 *) cvt->buf;
    1.78 +            Uint32 *dst = (Uint32 *) cvt->buf;
    1.79 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
    1.80 +                for (i = cvt->len_cvt / 8; i; --i, src += 2) {
    1.81 +                    float src1, src2;
    1.82 +                    f2i.ui32 = SDL_SwapBE32(src[0]);
    1.83 +                    src1 = f2i.f;
    1.84 +                    f2i.ui32 = SDL_SwapBE32(src[1]);
    1.85 +                    src2 = f2i.f;
    1.86 +                    const double added = ((double) src1) + ((double) src2);
    1.87 +                    f2i.f = (float) (added * 0.5);
    1.88 +                    *(dst++) = SDL_SwapBE32(f2i.ui32);
    1.89 +                }
    1.90 +            } else {
    1.91 +                for (i = cvt->len_cvt / 8; i; --i, src += 2) {
    1.92 +                    float src1, src2;
    1.93 +                    f2i.ui32 = SDL_SwapLE32(src[0]);
    1.94 +                    src1 = f2i.f;
    1.95 +                    f2i.ui32 = SDL_SwapLE32(src[1]);
    1.96 +                    src2 = f2i.f;
    1.97 +                    const double added = ((double) src1) + ((double) src2);
    1.98 +                    f2i.f = (float) (added * 0.5);
    1.99 +                    *(dst++) = SDL_SwapLE32(f2i.ui32);
   1.100 +                }
   1.101 +            }
   1.102 +        }
   1.103 +        break;
   1.104      }
   1.105 +
   1.106      cvt->len_cvt /= 2;
   1.107      if (cvt->filters[++cvt->filter_index]) {
   1.108          cvt->filters[cvt->filter_index] (cvt, format);
   1.109      }
   1.110  }
   1.111  
   1.112 +
   1.113  /* Discard top 4 channels */
   1.114 -void SDLCALL
   1.115 -SDL_ConvertStrip(SDL_AudioCVT * cvt, Uint16 format)
   1.116 +static void SDLCALL
   1.117 +SDL_ConvertStrip(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.118  {
   1.119      int i;
   1.120 -    Sint32 lsample, rsample;
   1.121  
   1.122  #ifdef DEBUG_CONVERT
   1.123 -    fprintf(stderr, "Converting down to stereo\n");
   1.124 +    fprintf(stderr, "Converting down from 6 channels to stereo\n");
   1.125  #endif
   1.126 -    switch (format & 0x8018) {
   1.127  
   1.128 -    case AUDIO_U8:
   1.129 -        {
   1.130 -            Uint8 *src, *dst;
   1.131 +    #define strip_chans_6_to_2(type) \
   1.132 +    { \
   1.133 +        const type *src = (const type *) cvt->buf; \
   1.134 +        type *dst = (type *) cvt->buf; \
   1.135 +        for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
   1.136 +            dst[0] = src[0]; \
   1.137 +            dst[1] = src[1]; \
   1.138 +            src += 6; \
   1.139 +            dst += 2; \
   1.140 +        } \
   1.141 +    }
   1.142  
   1.143 -            src = cvt->buf;
   1.144 -            dst = cvt->buf;
   1.145 -            for (i = cvt->len_cvt / 6; i; --i) {
   1.146 -                dst[0] = src[0];
   1.147 -                dst[1] = src[1];
   1.148 -                src += 6;
   1.149 -                dst += 2;
   1.150 -            }
   1.151 -        }
   1.152 -        break;
   1.153 +    /* this function only cares about typesize, and data as a block of bits. */
   1.154 +    switch (SDL_AUDIO_BITSIZE(format)) {
   1.155 +        case 8:
   1.156 +            strip_chans_6_to_2(Uint8);
   1.157 +            break;
   1.158 +        case 16:
   1.159 +            strip_chans_6_to_2(Uint16);
   1.160 +            break;
   1.161 +        case 32:
   1.162 +            strip_chans_6_to_2(Uint32);
   1.163 +            break;
   1.164 +    }
   1.165  
   1.166 -    case AUDIO_S8:
   1.167 -        {
   1.168 -            Sint8 *src, *dst;
   1.169 +    #undef strip_chans_6_to_2
   1.170  
   1.171 -            src = (Sint8 *) cvt->buf;
   1.172 -            dst = (Sint8 *) cvt->buf;
   1.173 -            for (i = cvt->len_cvt / 6; i; --i) {
   1.174 -                dst[0] = src[0];
   1.175 -                dst[1] = src[1];
   1.176 -                src += 6;
   1.177 -                dst += 2;
   1.178 -            }
   1.179 -        }
   1.180 -        break;
   1.181 -
   1.182 -    case AUDIO_U16:
   1.183 -        {
   1.184 -            Uint8 *src, *dst;
   1.185 -
   1.186 -            src = cvt->buf;
   1.187 -            dst = cvt->buf;
   1.188 -            if ((format & 0x1000) == 0x1000) {
   1.189 -                for (i = cvt->len_cvt / 12; i; --i) {
   1.190 -                    lsample = (Uint16) ((src[0] << 8) | src[1]);
   1.191 -                    rsample = (Uint16) ((src[2] << 8) | src[3]);
   1.192 -                    dst[1] = (lsample & 0xFF);
   1.193 -                    lsample >>= 8;
   1.194 -                    dst[0] = (lsample & 0xFF);
   1.195 -                    dst[3] = (rsample & 0xFF);
   1.196 -                    rsample >>= 8;
   1.197 -                    dst[2] = (rsample & 0xFF);
   1.198 -                    src += 12;
   1.199 -                    dst += 4;
   1.200 -                }
   1.201 -            } else {
   1.202 -                for (i = cvt->len_cvt / 12; i; --i) {
   1.203 -                    lsample = (Uint16) ((src[1] << 8) | src[0]);
   1.204 -                    rsample = (Uint16) ((src[3] << 8) | src[2]);
   1.205 -                    dst[0] = (lsample & 0xFF);
   1.206 -                    lsample >>= 8;
   1.207 -                    dst[1] = (lsample & 0xFF);
   1.208 -                    dst[2] = (rsample & 0xFF);
   1.209 -                    rsample >>= 8;
   1.210 -                    dst[3] = (rsample & 0xFF);
   1.211 -                    src += 12;
   1.212 -                    dst += 4;
   1.213 -                }
   1.214 -            }
   1.215 -        }
   1.216 -        break;
   1.217 -
   1.218 -    case AUDIO_S16:
   1.219 -        {
   1.220 -            Uint8 *src, *dst;
   1.221 -
   1.222 -            src = cvt->buf;
   1.223 -            dst = cvt->buf;
   1.224 -            if ((format & 0x1000) == 0x1000) {
   1.225 -                for (i = cvt->len_cvt / 12; i; --i) {
   1.226 -                    lsample = (Sint16) ((src[0] << 8) | src[1]);
   1.227 -                    rsample = (Sint16) ((src[2] << 8) | src[3]);
   1.228 -                    dst[1] = (lsample & 0xFF);
   1.229 -                    lsample >>= 8;
   1.230 -                    dst[0] = (lsample & 0xFF);
   1.231 -                    dst[3] = (rsample & 0xFF);
   1.232 -                    rsample >>= 8;
   1.233 -                    dst[2] = (rsample & 0xFF);
   1.234 -                    src += 12;
   1.235 -                    dst += 4;
   1.236 -                }
   1.237 -            } else {
   1.238 -                for (i = cvt->len_cvt / 12; i; --i) {
   1.239 -                    lsample = (Sint16) ((src[1] << 8) | src[0]);
   1.240 -                    rsample = (Sint16) ((src[3] << 8) | src[2]);
   1.241 -                    dst[0] = (lsample & 0xFF);
   1.242 -                    lsample >>= 8;
   1.243 -                    dst[1] = (lsample & 0xFF);
   1.244 -                    dst[2] = (rsample & 0xFF);
   1.245 -                    rsample >>= 8;
   1.246 -                    dst[3] = (rsample & 0xFF);
   1.247 -                    src += 12;
   1.248 -                    dst += 4;
   1.249 -                }
   1.250 -            }
   1.251 -        }
   1.252 -        break;
   1.253 -    }
   1.254      cvt->len_cvt /= 3;
   1.255      if (cvt->filters[++cvt->filter_index]) {
   1.256          cvt->filters[cvt->filter_index] (cvt, format);
   1.257 @@ -292,157 +270,87 @@
   1.258  
   1.259  
   1.260  /* Discard top 2 channels of 6 */
   1.261 -void SDLCALL
   1.262 -SDL_ConvertStrip_2(SDL_AudioCVT * cvt, Uint16 format)
   1.263 +static void SDLCALL
   1.264 +SDL_ConvertStrip_2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.265  {
   1.266      int i;
   1.267 -    Sint32 lsample, rsample;
   1.268  
   1.269  #ifdef DEBUG_CONVERT
   1.270      fprintf(stderr, "Converting 6 down to quad\n");
   1.271  #endif
   1.272 -    switch (format & 0x8018) {
   1.273  
   1.274 -    case AUDIO_U8:
   1.275 -        {
   1.276 -            Uint8 *src, *dst;
   1.277 +    #define strip_chans_6_to_4(type) \
   1.278 +    { \
   1.279 +        const type *src = (const type *) cvt->buf; \
   1.280 +        type *dst = (type *) cvt->buf; \
   1.281 +        for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
   1.282 +            dst[0] = src[0]; \
   1.283 +            dst[1] = src[1]; \
   1.284 +            dst[2] = src[2]; \
   1.285 +            dst[3] = src[3]; \
   1.286 +            src += 6; \
   1.287 +            dst += 4; \
   1.288 +        } \
   1.289 +    }
   1.290  
   1.291 -            src = cvt->buf;
   1.292 -            dst = cvt->buf;
   1.293 -            for (i = cvt->len_cvt / 4; i; --i) {
   1.294 -                dst[0] = src[0];
   1.295 -                dst[1] = src[1];
   1.296 -                src += 4;
   1.297 -                dst += 2;
   1.298 -            }
   1.299 -        }
   1.300 -        break;
   1.301 +    /* this function only cares about typesize, and data as a block of bits. */
   1.302 +    switch (SDL_AUDIO_BITSIZE(format)) {
   1.303 +        case 8:
   1.304 +            strip_chans_6_to_4(Uint8);
   1.305 +            break;
   1.306 +        case 16:
   1.307 +            strip_chans_6_to_4(Uint16);
   1.308 +            break;
   1.309 +        case 32:
   1.310 +            strip_chans_6_to_4(Uint32);
   1.311 +            break;
   1.312 +    }
   1.313  
   1.314 -    case AUDIO_S8:
   1.315 -        {
   1.316 -            Sint8 *src, *dst;
   1.317 +    #undef strip_chans_6_to_4
   1.318  
   1.319 -            src = (Sint8 *) cvt->buf;
   1.320 -            dst = (Sint8 *) cvt->buf;
   1.321 -            for (i = cvt->len_cvt / 4; i; --i) {
   1.322 -                dst[0] = src[0];
   1.323 -                dst[1] = src[1];
   1.324 -                src += 4;
   1.325 -                dst += 2;
   1.326 -            }
   1.327 -        }
   1.328 -        break;
   1.329 -
   1.330 -    case AUDIO_U16:
   1.331 -        {
   1.332 -            Uint8 *src, *dst;
   1.333 -
   1.334 -            src = cvt->buf;
   1.335 -            dst = cvt->buf;
   1.336 -            if ((format & 0x1000) == 0x1000) {
   1.337 -                for (i = cvt->len_cvt / 8; i; --i) {
   1.338 -                    lsample = (Uint16) ((src[0] << 8) | src[1]);
   1.339 -                    rsample = (Uint16) ((src[2] << 8) | src[3]);
   1.340 -                    dst[1] = (lsample & 0xFF);
   1.341 -                    lsample >>= 8;
   1.342 -                    dst[0] = (lsample & 0xFF);
   1.343 -                    dst[3] = (rsample & 0xFF);
   1.344 -                    rsample >>= 8;
   1.345 -                    dst[2] = (rsample & 0xFF);
   1.346 -                    src += 8;
   1.347 -                    dst += 4;
   1.348 -                }
   1.349 -            } else {
   1.350 -                for (i = cvt->len_cvt / 8; i; --i) {
   1.351 -                    lsample = (Uint16) ((src[1] << 8) | src[0]);
   1.352 -                    rsample = (Uint16) ((src[3] << 8) | src[2]);
   1.353 -                    dst[0] = (lsample & 0xFF);
   1.354 -                    lsample >>= 8;
   1.355 -                    dst[1] = (lsample & 0xFF);
   1.356 -                    dst[2] = (rsample & 0xFF);
   1.357 -                    rsample >>= 8;
   1.358 -                    dst[3] = (rsample & 0xFF);
   1.359 -                    src += 8;
   1.360 -                    dst += 4;
   1.361 -                }
   1.362 -            }
   1.363 -        }
   1.364 -        break;
   1.365 -
   1.366 -    case AUDIO_S16:
   1.367 -        {
   1.368 -            Uint8 *src, *dst;
   1.369 -
   1.370 -            src = cvt->buf;
   1.371 -            dst = cvt->buf;
   1.372 -            if ((format & 0x1000) == 0x1000) {
   1.373 -                for (i = cvt->len_cvt / 8; i; --i) {
   1.374 -                    lsample = (Sint16) ((src[0] << 8) | src[1]);
   1.375 -                    rsample = (Sint16) ((src[2] << 8) | src[3]);
   1.376 -                    dst[1] = (lsample & 0xFF);
   1.377 -                    lsample >>= 8;
   1.378 -                    dst[0] = (lsample & 0xFF);
   1.379 -                    dst[3] = (rsample & 0xFF);
   1.380 -                    rsample >>= 8;
   1.381 -                    dst[2] = (rsample & 0xFF);
   1.382 -                    src += 8;
   1.383 -                    dst += 4;
   1.384 -                }
   1.385 -            } else {
   1.386 -                for (i = cvt->len_cvt / 8; i; --i) {
   1.387 -                    lsample = (Sint16) ((src[1] << 8) | src[0]);
   1.388 -                    rsample = (Sint16) ((src[3] << 8) | src[2]);
   1.389 -                    dst[0] = (lsample & 0xFF);
   1.390 -                    lsample >>= 8;
   1.391 -                    dst[1] = (lsample & 0xFF);
   1.392 -                    dst[2] = (rsample & 0xFF);
   1.393 -                    rsample >>= 8;
   1.394 -                    dst[3] = (rsample & 0xFF);
   1.395 -                    src += 8;
   1.396 -                    dst += 4;
   1.397 -                }
   1.398 -            }
   1.399 -        }
   1.400 -        break;
   1.401 -    }
   1.402 -    cvt->len_cvt /= 2;
   1.403 +    cvt->len_cvt /= 6;
   1.404 +    cvt->len_cvt *= 4;
   1.405      if (cvt->filters[++cvt->filter_index]) {
   1.406          cvt->filters[cvt->filter_index] (cvt, format);
   1.407      }
   1.408  }
   1.409  
   1.410  /* Duplicate a mono channel to both stereo channels */
   1.411 -void SDLCALL
   1.412 -SDL_ConvertStereo(SDL_AudioCVT * cvt, Uint16 format)
   1.413 +static void SDLCALL
   1.414 +SDL_ConvertStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.415  {
   1.416      int i;
   1.417  
   1.418  #ifdef DEBUG_CONVERT
   1.419      fprintf(stderr, "Converting to stereo\n");
   1.420  #endif
   1.421 -    if ((format & 0xFF) == 16) {
   1.422 -        Uint16 *src, *dst;
   1.423  
   1.424 -        src = (Uint16 *) (cvt->buf + cvt->len_cvt);
   1.425 -        dst = (Uint16 *) (cvt->buf + cvt->len_cvt * 2);
   1.426 -        for (i = cvt->len_cvt / 2; i; --i) {
   1.427 -            dst -= 2;
   1.428 -            src -= 1;
   1.429 -            dst[0] = src[0];
   1.430 -            dst[1] = src[0];
   1.431 -        }
   1.432 -    } else {
   1.433 -        Uint8 *src, *dst;
   1.434 +    #define dup_chans_1_to_2(type) \
   1.435 +    { \
   1.436 +        const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   1.437 +        type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
   1.438 +        for (i = cvt->len_cvt / 2; i; --i, --src) { \
   1.439 +            const type val = *src; \
   1.440 +            dst -= 2; \
   1.441 +            dst[0] = dst[1] = val; \
   1.442 +        } \
   1.443 +    }
   1.444  
   1.445 -        src = cvt->buf + cvt->len_cvt;
   1.446 -        dst = cvt->buf + cvt->len_cvt * 2;
   1.447 -        for (i = cvt->len_cvt; i; --i) {
   1.448 -            dst -= 2;
   1.449 -            src -= 1;
   1.450 -            dst[0] = src[0];
   1.451 -            dst[1] = src[0];
   1.452 -        }
   1.453 +    /* this function only cares about typesize, and data as a block of bits. */
   1.454 +    switch (SDL_AUDIO_BITSIZE(format)) {
   1.455 +        case 8:
   1.456 +            dup_chans_1_to_2(Uint8);
   1.457 +            break;
   1.458 +        case 16:
   1.459 +            dup_chans_1_to_2(Uint16);
   1.460 +            break;
   1.461 +        case 32:
   1.462 +            dup_chans_1_to_2(Uint32);
   1.463 +            break;
   1.464      }
   1.465 +
   1.466 +    #undef dup_chans_1_to_2
   1.467 +
   1.468      cvt->len_cvt *= 2;
   1.469      if (cvt->filters[++cvt->filter_index]) {
   1.470          cvt->filters[cvt->filter_index] (cvt, format);
   1.471 @@ -451,16 +359,16 @@
   1.472  
   1.473  
   1.474  /* Duplicate a stereo channel to a pseudo-5.1 stream */
   1.475 -void SDLCALL
   1.476 -SDL_ConvertSurround(SDL_AudioCVT * cvt, Uint16 format)
   1.477 +static void SDLCALL
   1.478 +SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.479  {
   1.480      int i;
   1.481  
   1.482  #ifdef DEBUG_CONVERT
   1.483      fprintf(stderr, "Converting stereo to surround\n");
   1.484  #endif
   1.485 -    switch (format & 0x8018) {
   1.486  
   1.487 +    switch (format & (SDL_AUDIO_MASK_SIGNED|SDL_AUDIO_MASK_BITSIZE)) {
   1.488      case AUDIO_U8:
   1.489          {
   1.490              Uint8 *src, *dst, lf, rf, ce;
   1.491 @@ -513,7 +421,7 @@
   1.492              src = cvt->buf + cvt->len_cvt;
   1.493              dst = cvt->buf + cvt->len_cvt * 3;
   1.494  
   1.495 -            if ((format & 0x1000) == 0x1000) {
   1.496 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
   1.497                  for (i = cvt->len_cvt / 4; i; --i) {
   1.498                      dst -= 12;
   1.499                      src -= 4;
   1.500 @@ -573,7 +481,7 @@
   1.501              src = cvt->buf + cvt->len_cvt;
   1.502              dst = cvt->buf + cvt->len_cvt * 3;
   1.503  
   1.504 -            if ((format & 0x1000) == 0x1000) {
   1.505 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
   1.506                  for (i = cvt->len_cvt / 4; i; --i) {
   1.507                      dst -= 12;
   1.508                      src -= 4;
   1.509 @@ -624,6 +532,96 @@
   1.510              }
   1.511          }
   1.512          break;
   1.513 +
   1.514 +    case AUDIO_S32:
   1.515 +        {
   1.516 +            Sint32 lf, rf, ce;
   1.517 +            const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
   1.518 +            Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
   1.519 +
   1.520 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
   1.521 +                for (i = cvt->len_cvt / 8; i; --i) {
   1.522 +                    dst -= 6;
   1.523 +                    src -= 2;
   1.524 +                    lf = (Sint32) SDL_SwapBE32(src[0]);
   1.525 +                    rf = (Sint32) SDL_SwapBE32(src[1]);
   1.526 +                    ce = (lf / 2) + (rf / 2);
   1.527 +                    dst[0] = SDL_SwapBE32((Uint32) lf);
   1.528 +                    dst[1] = SDL_SwapBE32((Uint32) rf);
   1.529 +                    dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
   1.530 +                    dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
   1.531 +                    dst[4] = SDL_SwapBE32((Uint32) ce);
   1.532 +                    dst[5] = SDL_SwapBE32((Uint32) ce);
   1.533 +                }
   1.534 +            } else {
   1.535 +                for (i = cvt->len_cvt / 8; i; --i) {
   1.536 +                    dst -= 6;
   1.537 +                    src -= 2;
   1.538 +                    lf = (Sint32) SDL_SwapLE32(src[0]);
   1.539 +                    rf = (Sint32) SDL_SwapLE32(src[1]);
   1.540 +                    ce = (lf / 2) + (rf / 2);
   1.541 +                    dst[0] = src[0];
   1.542 +                    dst[1] = src[1];
   1.543 +                    dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
   1.544 +                    dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
   1.545 +                    dst[4] = SDL_SwapLE32((Uint32) ce);
   1.546 +                    dst[5] = SDL_SwapLE32((Uint32) ce);
   1.547 +                }
   1.548 +            }
   1.549 +        }
   1.550 +        break;
   1.551 +
   1.552 +    case AUDIO_F32:
   1.553 +        {
   1.554 +            union { float f; Uint32 ui32; } f2i;  /* !!! FIXME: lame. */
   1.555 +            float lf, rf, ce;
   1.556 +            const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
   1.557 +            Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
   1.558 +
   1.559 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
   1.560 +                for (i = cvt->len_cvt / 8; i; --i) {
   1.561 +                    dst -= 6;
   1.562 +                    src -= 2;
   1.563 +                    f2i.ui32 = SDL_SwapBE32(src[0]);
   1.564 +                    lf = f2i.f;
   1.565 +                    f2i.ui32 = SDL_SwapBE32(src[1]);
   1.566 +                    rf = f2i.f;
   1.567 +                    ce = (lf * 0.5f) + (rf * 0.5f);
   1.568 +                    dst[0] = src[0];
   1.569 +                    dst[1] = src[1];
   1.570 +                    f2i.f = (lf - ce);
   1.571 +                    dst[2] = SDL_SwapBE32(f2i.ui32);
   1.572 +                    f2i.f = (rf - ce);
   1.573 +                    dst[3] = SDL_SwapBE32(f2i.ui32);
   1.574 +                    f2i.f = ce;
   1.575 +                    f2i.ui32 = SDL_SwapBE32(f2i.ui32);
   1.576 +                    dst[4] = f2i.ui32;
   1.577 +                    dst[5] = f2i.ui32;
   1.578 +                }
   1.579 +            } else {
   1.580 +                for (i = cvt->len_cvt / 8; i; --i) {
   1.581 +                    dst -= 6;
   1.582 +                    src -= 2;
   1.583 +                    f2i.ui32 = SDL_SwapLE32(src[0]);
   1.584 +                    lf = f2i.f;
   1.585 +                    f2i.ui32 = SDL_SwapLE32(src[1]);
   1.586 +                    rf = f2i.f;
   1.587 +                    ce = (lf * 0.5f) + (rf * 0.5f);
   1.588 +                    dst[0] = src[0];
   1.589 +                    dst[1] = src[1];
   1.590 +                    f2i.f = (lf - ce);
   1.591 +                    dst[2] = SDL_SwapLE32(f2i.ui32);
   1.592 +                    f2i.f = (rf - ce);
   1.593 +                    dst[3] = SDL_SwapLE32(f2i.ui32);
   1.594 +                    f2i.f = ce;
   1.595 +                    f2i.ui32 = SDL_SwapLE32(f2i.ui32);
   1.596 +                    dst[4] = f2i.ui32;
   1.597 +                    dst[5] = f2i.ui32;
   1.598 +                }
   1.599 +            }
   1.600 +        }
   1.601 +        break;
   1.602 +
   1.603      }
   1.604      cvt->len_cvt *= 3;
   1.605      if (cvt->filters[++cvt->filter_index]) {
   1.606 @@ -633,16 +631,16 @@
   1.607  
   1.608  
   1.609  /* Duplicate a stereo channel to a pseudo-4.0 stream */
   1.610 -void SDLCALL
   1.611 -SDL_ConvertSurround_4(SDL_AudioCVT * cvt, Uint16 format)
   1.612 +static void SDLCALL
   1.613 +SDL_ConvertSurround_4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.614  {
   1.615      int i;
   1.616  
   1.617  #ifdef DEBUG_CONVERT
   1.618      fprintf(stderr, "Converting stereo to quad\n");
   1.619  #endif
   1.620 -    switch (format & 0x8018) {
   1.621  
   1.622 +    switch (format & (SDL_AUDIO_MASK_SIGNED|SDL_AUDIO_MASK_BITSIZE)) {
   1.623      case AUDIO_U8:
   1.624          {
   1.625              Uint8 *src, *dst, lf, rf, ce;
   1.626 @@ -691,7 +689,7 @@
   1.627              src = cvt->buf + cvt->len_cvt;
   1.628              dst = cvt->buf + cvt->len_cvt * 2;
   1.629  
   1.630 -            if ((format & 0x1000) == 0x1000) {
   1.631 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
   1.632                  for (i = cvt->len_cvt / 4; i; --i) {
   1.633                      dst -= 8;
   1.634                      src -= 4;
   1.635 @@ -741,7 +739,7 @@
   1.636              src = cvt->buf + cvt->len_cvt;
   1.637              dst = cvt->buf + cvt->len_cvt * 2;
   1.638  
   1.639 -            if ((format & 0x1000) == 0x1000) {
   1.640 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
   1.641                  for (i = cvt->len_cvt / 4; i; --i) {
   1.642                      dst -= 8;
   1.643                      src -= 4;
   1.644 @@ -782,173 +780,38 @@
   1.645              }
   1.646          }
   1.647          break;
   1.648 -    }
   1.649 -    cvt->len_cvt *= 2;
   1.650 -    if (cvt->filters[++cvt->filter_index]) {
   1.651 -        cvt->filters[cvt->filter_index] (cvt, format);
   1.652 -    }
   1.653 -}
   1.654  
   1.655 +    case AUDIO_S32:
   1.656 +        {
   1.657 +            const Uint32 *src = (const Uint32 *) (cvt->buf + cvt->len_cvt);
   1.658 +            Uint32 *dst = (Uint32 *) (cvt->buf + cvt->len_cvt * 2);
   1.659 +            Sint32 lf, rf, ce;
   1.660  
   1.661 -/* Convert 8-bit to 16-bit - LSB */
   1.662 -void SDLCALL
   1.663 -SDL_Convert16LSB(SDL_AudioCVT * cvt, Uint16 format)
   1.664 -{
   1.665 -    int i;
   1.666 -    Uint8 *src, *dst;
   1.667 -
   1.668 -#ifdef DEBUG_CONVERT
   1.669 -    fprintf(stderr, "Converting to 16-bit LSB\n");
   1.670 -#endif
   1.671 -    src = cvt->buf + cvt->len_cvt;
   1.672 -    dst = cvt->buf + cvt->len_cvt * 2;
   1.673 -    for (i = cvt->len_cvt; i; --i) {
   1.674 -        src -= 1;
   1.675 -        dst -= 2;
   1.676 -        dst[1] = *src;
   1.677 -        dst[0] = 0;
   1.678 -    }
   1.679 -    format = ((format & ~0x0008) | AUDIO_U16LSB);
   1.680 -    cvt->len_cvt *= 2;
   1.681 -    if (cvt->filters[++cvt->filter_index]) {
   1.682 -        cvt->filters[cvt->filter_index] (cvt, format);
   1.683 -    }
   1.684 -}
   1.685 -
   1.686 -/* Convert 8-bit to 16-bit - MSB */
   1.687 -void SDLCALL
   1.688 -SDL_Convert16MSB(SDL_AudioCVT * cvt, Uint16 format)
   1.689 -{
   1.690 -    int i;
   1.691 -    Uint8 *src, *dst;
   1.692 -
   1.693 -#ifdef DEBUG_CONVERT
   1.694 -    fprintf(stderr, "Converting to 16-bit MSB\n");
   1.695 -#endif
   1.696 -    src = cvt->buf + cvt->len_cvt;
   1.697 -    dst = cvt->buf + cvt->len_cvt * 2;
   1.698 -    for (i = cvt->len_cvt; i; --i) {
   1.699 -        src -= 1;
   1.700 -        dst -= 2;
   1.701 -        dst[0] = *src;
   1.702 -        dst[1] = 0;
   1.703 -    }
   1.704 -    format = ((format & ~0x0008) | AUDIO_U16MSB);
   1.705 -    cvt->len_cvt *= 2;
   1.706 -    if (cvt->filters[++cvt->filter_index]) {
   1.707 -        cvt->filters[cvt->filter_index] (cvt, format);
   1.708 -    }
   1.709 -}
   1.710 -
   1.711 -/* Convert 16-bit to 8-bit */
   1.712 -void SDLCALL
   1.713 -SDL_Convert8(SDL_AudioCVT * cvt, Uint16 format)
   1.714 -{
   1.715 -    int i;
   1.716 -    Uint8 *src, *dst;
   1.717 -
   1.718 -#ifdef DEBUG_CONVERT
   1.719 -    fprintf(stderr, "Converting to 8-bit\n");
   1.720 -#endif
   1.721 -    src = cvt->buf;
   1.722 -    dst = cvt->buf;
   1.723 -    if ((format & 0x1000) != 0x1000) {  /* Little endian */
   1.724 -        ++src;
   1.725 -    }
   1.726 -    for (i = cvt->len_cvt / 2; i; --i) {
   1.727 -        *dst = *src;
   1.728 -        src += 2;
   1.729 -        dst += 1;
   1.730 -    }
   1.731 -    format = ((format & ~0x9010) | AUDIO_U8);
   1.732 -    cvt->len_cvt /= 2;
   1.733 -    if (cvt->filters[++cvt->filter_index]) {
   1.734 -        cvt->filters[cvt->filter_index] (cvt, format);
   1.735 -    }
   1.736 -}
   1.737 -
   1.738 -/* Toggle signed/unsigned */
   1.739 -void SDLCALL
   1.740 -SDL_ConvertSign(SDL_AudioCVT * cvt, Uint16 format)
   1.741 -{
   1.742 -    int i;
   1.743 -    Uint8 *data;
   1.744 -
   1.745 -#ifdef DEBUG_CONVERT
   1.746 -    fprintf(stderr, "Converting audio signedness\n");
   1.747 -#endif
   1.748 -    data = cvt->buf;
   1.749 -    if ((format & 0xFF) == 16) {
   1.750 -        if ((format & 0x1000) != 0x1000) {      /* Little endian */
   1.751 -            ++data;
   1.752 -        }
   1.753 -        for (i = cvt->len_cvt / 2; i; --i) {
   1.754 -            *data ^= 0x80;
   1.755 -            data += 2;
   1.756 -        }
   1.757 -    } else {
   1.758 -        for (i = cvt->len_cvt; i; --i) {
   1.759 -            *data++ ^= 0x80;
   1.760 -        }
   1.761 -    }
   1.762 -    format = (format ^ 0x8000);
   1.763 -    if (cvt->filters[++cvt->filter_index]) {
   1.764 -        cvt->filters[cvt->filter_index] (cvt, format);
   1.765 -    }
   1.766 -}
   1.767 -
   1.768 -/* Toggle endianness */
   1.769 -void SDLCALL
   1.770 -SDL_ConvertEndian(SDL_AudioCVT * cvt, Uint16 format)
   1.771 -{
   1.772 -    int i;
   1.773 -    Uint8 *data, tmp;
   1.774 -
   1.775 -#ifdef DEBUG_CONVERT
   1.776 -    fprintf(stderr, "Converting audio endianness\n");
   1.777 -#endif
   1.778 -    data = cvt->buf;
   1.779 -    for (i = cvt->len_cvt / 2; i; --i) {
   1.780 -        tmp = data[0];
   1.781 -        data[0] = data[1];
   1.782 -        data[1] = tmp;
   1.783 -        data += 2;
   1.784 -    }
   1.785 -    format = (format ^ 0x1000);
   1.786 -    if (cvt->filters[++cvt->filter_index]) {
   1.787 -        cvt->filters[cvt->filter_index] (cvt, format);
   1.788 -    }
   1.789 -}
   1.790 -
   1.791 -/* Convert rate up by multiple of 2 */
   1.792 -void SDLCALL
   1.793 -SDL_RateMUL2(SDL_AudioCVT * cvt, Uint16 format)
   1.794 -{
   1.795 -    int i;
   1.796 -    Uint8 *src, *dst;
   1.797 -
   1.798 -#ifdef DEBUG_CONVERT
   1.799 -    fprintf(stderr, "Converting audio rate * 2\n");
   1.800 -#endif
   1.801 -    src = cvt->buf + cvt->len_cvt;
   1.802 -    dst = cvt->buf + cvt->len_cvt * 2;
   1.803 -    switch (format & 0xFF) {
   1.804 -    case 8:
   1.805 -        for (i = cvt->len_cvt; i; --i) {
   1.806 -            src -= 1;
   1.807 -            dst -= 2;
   1.808 -            dst[0] = src[0];
   1.809 -            dst[1] = src[0];
   1.810 -        }
   1.811 -        break;
   1.812 -    case 16:
   1.813 -        for (i = cvt->len_cvt / 2; i; --i) {
   1.814 -            src -= 2;
   1.815 -            dst -= 4;
   1.816 -            dst[0] = src[0];
   1.817 -            dst[1] = src[1];
   1.818 -            dst[2] = src[0];
   1.819 -            dst[3] = src[1];
   1.820 +            if (SDL_AUDIO_ISBIGENDIAN(format)) {
   1.821 +                for (i = cvt->len_cvt / 8; i; --i) {
   1.822 +                    dst -= 4;
   1.823 +                    src -= 2;
   1.824 +                    lf = (Sint32) SDL_SwapBE32(src[0]);
   1.825 +                    rf = (Sint32) SDL_SwapBE32(src[1]);
   1.826 +                    ce = (lf / 2) + (rf / 2);
   1.827 +                    dst[0] = src[0];
   1.828 +                    dst[1] = src[1];
   1.829 +                    dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
   1.830 +                    dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
   1.831 +                }
   1.832 +            } else {
   1.833 +                for (i = cvt->len_cvt / 8; i; --i) {
   1.834 +                    dst -= 4;
   1.835 +                    src -= 2;
   1.836 +                    lf = (Sint32) SDL_SwapLE32(src[0]);
   1.837 +                    rf = (Sint32) SDL_SwapLE32(src[1]);
   1.838 +                    ce = (lf / 2) + (rf / 2);
   1.839 +                    dst[0] = src[0];
   1.840 +                    dst[1] = src[1];
   1.841 +                    dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
   1.842 +                    dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
   1.843 +                }
   1.844 +            }
   1.845          }
   1.846          break;
   1.847      }
   1.848 @@ -958,45 +821,86 @@
   1.849      }
   1.850  }
   1.851  
   1.852 +/* Convert rate up by multiple of 2 */
   1.853 +static void SDLCALL
   1.854 +SDL_RateMUL2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.855 +{
   1.856 +    int i;
   1.857 +
   1.858 +#ifdef DEBUG_CONVERT
   1.859 +    fprintf(stderr, "Converting audio rate * 2 (mono)\n");
   1.860 +#endif
   1.861 +
   1.862 +    #define mul2_mono(type) { \
   1.863 +        const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   1.864 +        type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
   1.865 +        for (i = cvt->len_cvt / sizeof (type); i; --i) { \
   1.866 +            src--; \
   1.867 +            dst[-1] = dst[-2] = src[0]; \
   1.868 +            dst -= 2; \
   1.869 +        } \
   1.870 +    }
   1.871 +
   1.872 +    switch (SDL_AUDIO_BITSIZE(format)) {
   1.873 +    case 8:
   1.874 +        mul2_mono(Uint8);
   1.875 +        break;
   1.876 +    case 16:
   1.877 +        mul2_mono(Uint16);
   1.878 +        break;
   1.879 +    case 32:
   1.880 +        mul2_mono(Uint32);
   1.881 +        break;
   1.882 +    }
   1.883 +
   1.884 +    #undef mul2_mono
   1.885 +
   1.886 +    cvt->len_cvt *= 2;
   1.887 +    if (cvt->filters[++cvt->filter_index]) {
   1.888 +        cvt->filters[cvt->filter_index] (cvt, format);
   1.889 +    }
   1.890 +}
   1.891 +
   1.892  
   1.893  /* Convert rate up by multiple of 2, for stereo */
   1.894 -void SDLCALL
   1.895 -SDL_RateMUL2_c2(SDL_AudioCVT * cvt, Uint16 format)
   1.896 +static void SDLCALL
   1.897 +SDL_RateMUL2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.898  {
   1.899      int i;
   1.900 -    Uint8 *src, *dst;
   1.901  
   1.902  #ifdef DEBUG_CONVERT
   1.903 -    fprintf(stderr, "Converting audio rate * 2\n");
   1.904 +    fprintf(stderr, "Converting audio rate * 2 (stereo)\n");
   1.905  #endif
   1.906 -    src = cvt->buf + cvt->len_cvt;
   1.907 -    dst = cvt->buf + cvt->len_cvt * 2;
   1.908 -    switch (format & 0xFF) {
   1.909 +
   1.910 +    #define mul2_stereo(type) { \
   1.911 +        const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   1.912 +        type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
   1.913 +        for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
   1.914 +            const type r = src[-1]; \
   1.915 +            const type l = src[-2]; \
   1.916 +            src -= 2; \
   1.917 +            dst[-1] = r; \
   1.918 +            dst[-2] = l; \
   1.919 +            dst[-3] = r; \
   1.920 +            dst[-4] = l; \
   1.921 +            dst -= 4; \
   1.922 +        } \
   1.923 +    }
   1.924 +
   1.925 +    switch (SDL_AUDIO_BITSIZE(format)) {
   1.926      case 8:
   1.927 -        for (i = cvt->len_cvt / 2; i; --i) {
   1.928 -            src -= 2;
   1.929 -            dst -= 4;
   1.930 -            dst[0] = src[0];
   1.931 -            dst[1] = src[1];
   1.932 -            dst[2] = src[0];
   1.933 -            dst[3] = src[1];
   1.934 -        }
   1.935 +        mul2_stereo(Uint8);
   1.936          break;
   1.937      case 16:
   1.938 -        for (i = cvt->len_cvt / 4; i; --i) {
   1.939 -            src -= 4;
   1.940 -            dst -= 8;
   1.941 -            dst[0] = src[0];
   1.942 -            dst[1] = src[1];
   1.943 -            dst[2] = src[2];
   1.944 -            dst[3] = src[3];
   1.945 -            dst[4] = src[0];
   1.946 -            dst[5] = src[1];
   1.947 -            dst[6] = src[2];
   1.948 -            dst[7] = src[3];
   1.949 -        }
   1.950 +        mul2_stereo(Uint16);
   1.951 +        break;
   1.952 +    case 32:
   1.953 +        mul2_stereo(Uint32);
   1.954          break;
   1.955      }
   1.956 +
   1.957 +    #undef mul2_stereo
   1.958 +
   1.959      cvt->len_cvt *= 2;
   1.960      if (cvt->filters[++cvt->filter_index]) {
   1.961          cvt->filters[cvt->filter_index] (cvt, format);
   1.962 @@ -1004,55 +908,50 @@
   1.963  }
   1.964  
   1.965  /* Convert rate up by multiple of 2, for quad */
   1.966 -void SDLCALL
   1.967 -SDL_RateMUL2_c4(SDL_AudioCVT * cvt, Uint16 format)
   1.968 +static void SDLCALL
   1.969 +SDL_RateMUL2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.970  {
   1.971      int i;
   1.972 -    Uint8 *src, *dst;
   1.973  
   1.974  #ifdef DEBUG_CONVERT
   1.975 -    fprintf(stderr, "Converting audio rate * 2\n");
   1.976 +    fprintf(stderr, "Converting audio rate * 2 (quad)\n");
   1.977  #endif
   1.978 -    src = cvt->buf + cvt->len_cvt;
   1.979 -    dst = cvt->buf + cvt->len_cvt * 2;
   1.980 -    switch (format & 0xFF) {
   1.981 +
   1.982 +    #define mul2_quad(type) { \
   1.983 +        const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   1.984 +        type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
   1.985 +        for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
   1.986 +            const type c1 = src[-1]; \
   1.987 +            const type c2 = src[-2]; \
   1.988 +            const type c3 = src[-3]; \
   1.989 +            const type c4 = src[-4]; \
   1.990 +            src -= 4; \
   1.991 +            dst[-1] = c1; \
   1.992 +            dst[-2] = c2; \
   1.993 +            dst[-3] = c3; \
   1.994 +            dst[-4] = c4; \
   1.995 +            dst[-5] = c1; \
   1.996 +            dst[-6] = c2; \
   1.997 +            dst[-7] = c3; \
   1.998 +            dst[-8] = c4; \
   1.999 +            dst -= 8; \
  1.1000 +        } \
  1.1001 +    }
  1.1002 +
  1.1003 +    switch (SDL_AUDIO_BITSIZE(format)) {
  1.1004      case 8:
  1.1005 -        for (i = cvt->len_cvt / 4; i; --i) {
  1.1006 -            src -= 4;
  1.1007 -            dst -= 8;
  1.1008 -            dst[0] = src[0];
  1.1009 -            dst[1] = src[1];
  1.1010 -            dst[2] = src[2];
  1.1011 -            dst[3] = src[3];
  1.1012 -            dst[4] = src[0];
  1.1013 -            dst[5] = src[1];
  1.1014 -            dst[6] = src[2];
  1.1015 -            dst[7] = src[3];
  1.1016 -        }
  1.1017 +        mul2_quad(Uint8);
  1.1018          break;
  1.1019      case 16:
  1.1020 -        for (i = cvt->len_cvt / 8; i; --i) {
  1.1021 -            src -= 8;
  1.1022 -            dst -= 16;
  1.1023 -            dst[0] = src[0];
  1.1024 -            dst[1] = src[1];
  1.1025 -            dst[2] = src[2];
  1.1026 -            dst[3] = src[3];
  1.1027 -            dst[4] = src[4];
  1.1028 -            dst[5] = src[5];
  1.1029 -            dst[6] = src[6];
  1.1030 -            dst[7] = src[7];
  1.1031 -            dst[8] = src[0];
  1.1032 -            dst[9] = src[1];
  1.1033 -            dst[10] = src[2];
  1.1034 -            dst[11] = src[3];
  1.1035 -            dst[12] = src[4];
  1.1036 -            dst[13] = src[5];
  1.1037 -            dst[14] = src[6];
  1.1038 -            dst[15] = src[7];
  1.1039 -        }
  1.1040 +        mul2_quad(Uint16);
  1.1041 +        break;
  1.1042 +    case 32:
  1.1043 +        mul2_quad(Uint32);
  1.1044          break;
  1.1045      }
  1.1046 +
  1.1047 +    #undef mul2_quad
  1.1048 +
  1.1049      cvt->len_cvt *= 2;
  1.1050      if (cvt->filters[++cvt->filter_index]) {
  1.1051          cvt->filters[cvt->filter_index] (cvt, format);
  1.1052 @@ -1061,67 +960,56 @@
  1.1053  
  1.1054  
  1.1055  /* Convert rate up by multiple of 2, for 5.1 */
  1.1056 -void SDLCALL
  1.1057 -SDL_RateMUL2_c6(SDL_AudioCVT * cvt, Uint16 format)
  1.1058 +static void SDLCALL
  1.1059 +SDL_RateMUL2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1.1060  {
  1.1061      int i;
  1.1062 -    Uint8 *src, *dst;
  1.1063  
  1.1064  #ifdef DEBUG_CONVERT
  1.1065 -    fprintf(stderr, "Converting audio rate * 2\n");
  1.1066 +    fprintf(stderr, "Converting audio rate * 2 (six channels)\n");
  1.1067  #endif
  1.1068 -    src = cvt->buf + cvt->len_cvt;
  1.1069 -    dst = cvt->buf + cvt->len_cvt * 2;
  1.1070 -    switch (format & 0xFF) {
  1.1071 +
  1.1072 +    #define mul2_chansix(type) { \
  1.1073 +        const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
  1.1074 +        type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
  1.1075 +        for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
  1.1076 +            const type c1 = src[-1]; \
  1.1077 +            const type c2 = src[-2]; \
  1.1078 +            const type c3 = src[-3]; \
  1.1079 +            const type c4 = src[-4]; \
  1.1080 +            const type c5 = src[-5]; \
  1.1081 +            const type c6 = src[-6]; \
  1.1082 +            src -= 6; \
  1.1083 +            dst[-1] = c1; \
  1.1084 +            dst[-2] = c2; \
  1.1085 +            dst[-3] = c3; \
  1.1086 +            dst[-4] = c4; \
  1.1087 +            dst[-5] = c5; \
  1.1088 +            dst[-6] = c6; \
  1.1089 +            dst[-7] = c1; \
  1.1090 +            dst[-8] = c2; \
  1.1091 +            dst[-9] = c3; \
  1.1092 +            dst[-10] = c4; \
  1.1093 +            dst[-11] = c5; \
  1.1094 +            dst[-12] = c6; \
  1.1095 +            dst -= 12; \
  1.1096 +        } \
  1.1097 +    }
  1.1098 +
  1.1099 +    switch (SDL_AUDIO_BITSIZE(format)) {
  1.1100      case 8:
  1.1101 -        for (i = cvt->len_cvt / 6; i; --i) {
  1.1102 -            src -= 6;
  1.1103 -            dst -= 12;
  1.1104 -            dst[0] = src[0];
  1.1105 -            dst[1] = src[1];
  1.1106 -            dst[2] = src[2];
  1.1107 -            dst[3] = src[3];
  1.1108 -            dst[4] = src[4];
  1.1109 -            dst[5] = src[5];
  1.1110 -            dst[6] = src[0];
  1.1111 -            dst[7] = src[1];
  1.1112 -            dst[8] = src[2];
  1.1113 -            dst[9] = src[3];
  1.1114 -            dst[10] = src[4];
  1.1115 -            dst[11] = src[5];
  1.1116 -        }
  1.1117 +        mul2_chansix(Uint8);
  1.1118          break;
  1.1119      case 16:
  1.1120 -        for (i = cvt->len_cvt / 12; i; --i) {
  1.1121 -            src -= 12;
  1.1122 -            dst -= 24;
  1.1123 -            dst[0] = src[0];
  1.1124 -            dst[1] = src[1];
  1.1125 -            dst[2] = src[2];
  1.1126 -            dst[3] = src[3];
  1.1127 -            dst[4] = src[4];
  1.1128 -            dst[5] = src[5];
  1.1129 -            dst[6] = src[6];
  1.1130 -            dst[7] = src[7];
  1.1131 -            dst[8] = src[8];
  1.1132 -            dst[9] = src[9];
  1.1133 -            dst[10] = src[10];
  1.1134 -            dst[11] = src[11];
  1.1135 -            dst[12] = src[0];
  1.1136 -            dst[13] = src[1];
  1.1137 -            dst[14] = src[2];
  1.1138 -            dst[15] = src[3];
  1.1139 -            dst[16] = src[4];
  1.1140 -            dst[17] = src[5];
  1.1141 -            dst[18] = src[6];
  1.1142 -            dst[19] = src[7];
  1.1143 -            dst[20] = src[8];
  1.1144 -            dst[21] = src[9];
  1.1145 -            dst[22] = src[10];
  1.1146 -            dst[23] = src[11];
  1.1147 -        }
  1.1148 +        mul2_chansix(Uint16);
  1.1149 +        break;
  1.1150 +    case 32:
  1.1151 +        mul2_chansix(Uint32);
  1.1152          break;
  1.1153      }
  1.1154 +
  1.1155 +    #undef mul2_chansix
  1.1156 +
  1.1157      cvt->len_cvt *= 2;
  1.1158      if (cvt->filters[++cvt->filter_index]) {
  1.1159          cvt->filters[cvt->filter_index] (cvt, format);
  1.1160 @@ -1129,34 +1017,39 @@
  1.1161  }
  1.1162  
  1.1163  /* Convert rate down by multiple of 2 */
  1.1164 -void SDLCALL
  1.1165 -SDL_RateDIV2(SDL_AudioCVT * cvt, Uint16 format)
  1.1166 +static void SDLCALL
  1.1167 +SDL_RateDIV2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1.1168  {
  1.1169      int i;
  1.1170 -    Uint8 *src, *dst;
  1.1171  
  1.1172  #ifdef DEBUG_CONVERT
  1.1173 -    fprintf(stderr, "Converting audio rate / 2\n");
  1.1174 +    fprintf(stderr, "Converting audio rate / 2 (mono)\n");
  1.1175  #endif
  1.1176 -    src = cvt->buf;
  1.1177 -    dst = cvt->buf;
  1.1178 -    switch (format & 0xFF) {
  1.1179 +
  1.1180 +    #define div2_mono(type) { \
  1.1181 +        const type *src = (const type *) cvt->buf; \
  1.1182 +        type *dst = (type *) cvt->buf; \
  1.1183 +        for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
  1.1184 +            dst[0] = src[0]; \
  1.1185 +            src += 2; \
  1.1186 +            dst++; \
  1.1187 +        } \
  1.1188 +    }
  1.1189 +
  1.1190 +    switch (SDL_AUDIO_BITSIZE(format)) {
  1.1191      case 8:
  1.1192 -        for (i = cvt->len_cvt / 2; i; --i) {
  1.1193 -            dst[0] = src[0];
  1.1194 -            src += 2;
  1.1195 -            dst += 1;
  1.1196 -        }
  1.1197 +        div2_mono(Uint8);
  1.1198          break;
  1.1199      case 16:
  1.1200 -        for (i = cvt->len_cvt / 4; i; --i) {
  1.1201 -            dst[0] = src[0];
  1.1202 -            dst[1] = src[1];
  1.1203 -            src += 4;
  1.1204 -            dst += 2;
  1.1205 -        }
  1.1206 +        div2_mono(Uint16);
  1.1207 +        break;
  1.1208 +    case 32:
  1.1209 +        div2_mono(Uint32);
  1.1210          break;
  1.1211      }
  1.1212 +
  1.1213 +    #undef div2_mono
  1.1214 +
  1.1215      cvt->len_cvt /= 2;
  1.1216      if (cvt->filters[++cvt->filter_index]) {
  1.1217          cvt->filters[cvt->filter_index] (cvt, format);
  1.1218 @@ -1165,37 +1058,40 @@
  1.1219  
  1.1220  
  1.1221  /* Convert rate down by multiple of 2, for stereo */
  1.1222 -void SDLCALL
  1.1223 -SDL_RateDIV2_c2(SDL_AudioCVT * cvt, Uint16 format)
  1.1224 +static void SDLCALL
  1.1225 +SDL_RateDIV2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1.1226  {
  1.1227      int i;
  1.1228 -    Uint8 *src, *dst;
  1.1229  
  1.1230  #ifdef DEBUG_CONVERT
  1.1231 -    fprintf(stderr, "Converting audio rate / 2\n");
  1.1232 +    fprintf(stderr, "Converting audio rate / 2 (stereo)\n");
  1.1233  #endif
  1.1234 -    src = cvt->buf;
  1.1235 -    dst = cvt->buf;
  1.1236 -    switch (format & 0xFF) {
  1.1237 +
  1.1238 +    #define div2_stereo(type) { \
  1.1239 +        const type *src = (const type *) cvt->buf; \
  1.1240 +        type *dst = (type *) cvt->buf; \
  1.1241 +        for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
  1.1242 +            dst[0] = src[0]; \
  1.1243 +            dst[1] = src[1]; \
  1.1244 +            src += 4; \
  1.1245 +            dst += 2; \
  1.1246 +        } \
  1.1247 +    }
  1.1248 +
  1.1249 +    switch (SDL_AUDIO_BITSIZE(format)) {
  1.1250      case 8:
  1.1251 -        for (i = cvt->len_cvt / 4; i; --i) {
  1.1252 -            dst[0] = src[0];
  1.1253 -            dst[1] = src[1];
  1.1254 -            src += 4;
  1.1255 -            dst += 2;
  1.1256 -        }
  1.1257 +        div2_stereo(Uint8);
  1.1258          break;
  1.1259      case 16:
  1.1260 -        for (i = cvt->len_cvt / 8; i; --i) {
  1.1261 -            dst[0] = src[0];
  1.1262 -            dst[1] = src[1];
  1.1263 -            dst[2] = src[2];
  1.1264 -            dst[3] = src[3];
  1.1265 -            src += 8;
  1.1266 -            dst += 4;
  1.1267 -        }
  1.1268 +        div2_stereo(Uint16);
  1.1269 +        break;
  1.1270 +    case 32:
  1.1271 +        div2_stereo(Uint32);
  1.1272          break;
  1.1273      }
  1.1274 +
  1.1275 +    #undef div2_stereo
  1.1276 +
  1.1277      cvt->len_cvt /= 2;
  1.1278      if (cvt->filters[++cvt->filter_index]) {
  1.1279          cvt->filters[cvt->filter_index] (cvt, format);
  1.1280 @@ -1204,43 +1100,42 @@
  1.1281  
  1.1282  
  1.1283  /* Convert rate down by multiple of 2, for quad */
  1.1284 -void SDLCALL
  1.1285 -SDL_RateDIV2_c4(SDL_AudioCVT * cvt, Uint16 format)
  1.1286 +static void SDLCALL
  1.1287 +SDL_RateDIV2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1.1288  {
  1.1289      int i;
  1.1290 -    Uint8 *src, *dst;
  1.1291  
  1.1292  #ifdef DEBUG_CONVERT
  1.1293 -    fprintf(stderr, "Converting audio rate / 2\n");
  1.1294 +    fprintf(stderr, "Converting audio rate / 2 (quad)\n");
  1.1295  #endif
  1.1296 -    src = cvt->buf;
  1.1297 -    dst = cvt->buf;
  1.1298 -    switch (format & 0xFF) {
  1.1299 +
  1.1300 +    #define div2_quad(type) { \
  1.1301 +        const type *src = (const type *) cvt->buf; \
  1.1302 +        type *dst = (type *) cvt->buf; \
  1.1303 +        for (i = cvt->len_cvt / (sizeof (type) * 8); i; --i) { \
  1.1304 +            dst[0] = src[0]; \
  1.1305 +            dst[1] = src[1]; \
  1.1306 +            dst[2] = src[2]; \
  1.1307 +            dst[3] = src[3]; \
  1.1308 +            src += 8; \
  1.1309 +            dst += 4; \
  1.1310 +        } \
  1.1311 +    }
  1.1312 +
  1.1313 +    switch (SDL_AUDIO_BITSIZE(format)) {
  1.1314      case 8:
  1.1315 -        for (i = cvt->len_cvt / 8; i; --i) {
  1.1316 -            dst[0] = src[0];
  1.1317 -            dst[1] = src[1];
  1.1318 -            dst[2] = src[2];
  1.1319 -            dst[3] = src[3];
  1.1320 -            src += 8;
  1.1321 -            dst += 4;
  1.1322 -        }
  1.1323 +        div2_quad(Uint8);
  1.1324          break;
  1.1325      case 16:
  1.1326 -        for (i = cvt->len_cvt / 16; i; --i) {
  1.1327 -            dst[0] = src[0];
  1.1328 -            dst[1] = src[1];
  1.1329 -            dst[2] = src[2];
  1.1330 -            dst[3] = src[3];
  1.1331 -            dst[4] = src[4];
  1.1332 -            dst[5] = src[5];
  1.1333 -            dst[6] = src[6];
  1.1334 -            dst[7] = src[7];
  1.1335 -            src += 16;
  1.1336 -            dst += 8;
  1.1337 -        }
  1.1338 +        div2_quad(Uint16);
  1.1339 +        break;
  1.1340 +    case 32:
  1.1341 +        div2_quad(Uint32);
  1.1342          break;
  1.1343      }
  1.1344 +
  1.1345 +    #undef div2_quad
  1.1346 +
  1.1347      cvt->len_cvt /= 2;
  1.1348      if (cvt->filters[++cvt->filter_index]) {
  1.1349          cvt->filters[cvt->filter_index] (cvt, format);
  1.1350 @@ -1248,49 +1143,44 @@
  1.1351  }
  1.1352  
  1.1353  /* Convert rate down by multiple of 2, for 5.1 */
  1.1354 -void SDLCALL
  1.1355 -SDL_RateDIV2_c6(SDL_AudioCVT * cvt, Uint16 format)
  1.1356 +static void SDLCALL
  1.1357 +SDL_RateDIV2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1.1358  {
  1.1359      int i;
  1.1360 -    Uint8 *src, *dst;
  1.1361  
  1.1362  #ifdef DEBUG_CONVERT
  1.1363 -    fprintf(stderr, "Converting audio rate / 2\n");
  1.1364 +    fprintf(stderr, "Converting audio rate / 2 (six channels)\n");
  1.1365  #endif
  1.1366 -    src = cvt->buf;
  1.1367 -    dst = cvt->buf;
  1.1368 -    switch (format & 0xFF) {
  1.1369 +
  1.1370 +    #define div2_chansix(type) { \
  1.1371 +        const type *src = (const type *) cvt->buf; \
  1.1372 +        type *dst = (type *) cvt->buf; \
  1.1373 +        for (i = cvt->len_cvt / (sizeof (type) * 12); i; --i) { \
  1.1374 +            dst[0] = src[0]; \
  1.1375 +            dst[1] = src[1]; \
  1.1376 +            dst[2] = src[2]; \
  1.1377 +            dst[3] = src[3]; \
  1.1378 +            dst[4] = src[4]; \
  1.1379 +            dst[5] = src[5]; \
  1.1380 +            src += 12; \
  1.1381 +            dst += 6; \
  1.1382 +        } \
  1.1383 +    }
  1.1384 +
  1.1385 +    switch (SDL_AUDIO_BITSIZE(format)) {
  1.1386      case 8:
  1.1387 -        for (i = cvt->len_cvt / 12; i; --i) {
  1.1388 -            dst[0] = src[0];
  1.1389 -            dst[1] = src[1];
  1.1390 -            dst[2] = src[2];
  1.1391 -            dst[3] = src[3];
  1.1392 -            dst[4] = src[4];
  1.1393 -            dst[5] = src[5];
  1.1394 -            src += 12;
  1.1395 -            dst += 6;
  1.1396 -        }
  1.1397 +        div2_chansix(Uint8);
  1.1398          break;
  1.1399      case 16:
  1.1400 -        for (i = cvt->len_cvt / 24; i; --i) {
  1.1401 -            dst[0] = src[0];
  1.1402 -            dst[1] = src[1];
  1.1403 -            dst[2] = src[2];
  1.1404 -            dst[3] = src[3];
  1.1405 -            dst[4] = src[4];
  1.1406 -            dst[5] = src[5];
  1.1407 -            dst[6] = src[6];
  1.1408 -            dst[7] = src[7];
  1.1409 -            dst[8] = src[8];
  1.1410 -            dst[9] = src[9];
  1.1411 -            dst[10] = src[10];
  1.1412 -            dst[11] = src[11];
  1.1413 -            src += 24;
  1.1414 -            dst += 12;
  1.1415 -        }
  1.1416 +        div2_chansix(Uint16);
  1.1417 +        break;
  1.1418 +    case 32:
  1.1419 +        div2_chansix(Uint32);
  1.1420          break;
  1.1421      }
  1.1422 +
  1.1423 +    #undef div_chansix
  1.1424 +
  1.1425      cvt->len_cvt /= 2;
  1.1426      if (cvt->filters[++cvt->filter_index]) {
  1.1427          cvt->filters[cvt->filter_index] (cvt, format);
  1.1428 @@ -1298,8 +1188,8 @@
  1.1429  }
  1.1430  
  1.1431  /* Very slow rate conversion routine */
  1.1432 -void SDLCALL
  1.1433 -SDL_RateSLOW(SDL_AudioCVT * cvt, Uint16 format)
  1.1434 +static void SDLCALL
  1.1435 +SDL_RateSLOW(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1.1436  {
  1.1437      double ipos;
  1.1438      int i, clen;
  1.1439 @@ -1309,7 +1199,7 @@
  1.1440  #endif
  1.1441      clen = (int) ((double) cvt->len_cvt / cvt->rate_incr);
  1.1442      if (cvt->rate_incr > 1.0) {
  1.1443 -        switch (format & 0xFF) {
  1.1444 +        switch (SDL_AUDIO_BITSIZE(format)) {
  1.1445          case 8:
  1.1446              {
  1.1447                  Uint8 *output;
  1.1448 @@ -1338,9 +1228,15 @@
  1.1449                  }
  1.1450              }
  1.1451              break;
  1.1452 +
  1.1453 +        case 32:
  1.1454 +            {
  1.1455 +                /* !!! FIXME: need 32-bit converter here! */
  1.1456 +                fprintf(stderr, "FIXME: need 32-bit converter here!\n");
  1.1457 +            }
  1.1458          }
  1.1459      } else {
  1.1460 -        switch (format & 0xFF) {
  1.1461 +        switch (SDL_AUDIO_BITSIZE(format)) {
  1.1462          case 8:
  1.1463              {
  1.1464                  Uint8 *output;
  1.1465 @@ -1369,8 +1265,15 @@
  1.1466                  }
  1.1467              }
  1.1468              break;
  1.1469 +
  1.1470 +        case 32:
  1.1471 +            {
  1.1472 +                /* !!! FIXME: need 32-bit converter here! */
  1.1473 +                fprintf(stderr, "FIXME: need 32-bit converter here!\n");
  1.1474 +            }
  1.1475          }
  1.1476      }
  1.1477 +
  1.1478      cvt->len_cvt = clen;
  1.1479      if (cvt->filters[++cvt->filter_index]) {
  1.1480          cvt->filters[cvt->filter_index] (cvt, format);
  1.1481 @@ -1397,57 +1300,106 @@
  1.1482      return (0);
  1.1483  }
  1.1484  
  1.1485 -/* Creates a set of audio filters to convert from one format to another. 
  1.1486 -   Returns -1 if the format conversion is not supported, or 1 if the
  1.1487 -   audio filter is set up.
  1.1488 +
  1.1489 +static SDL_AudioFilter
  1.1490 +SDL_HandTunedTypeCVT(SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
  1.1491 +{
  1.1492 +    /*
  1.1493 +     * Fill in any future conversions that are specialized to a
  1.1494 +     *  processor, platform, compiler, or library here.
  1.1495 +     */
  1.1496 +
  1.1497 +    return NULL;  /* no specialized converter code available. */
  1.1498 +}
  1.1499 +
  1.1500 +
  1.1501 +/*
  1.1502 + * Find a converter between two data types. We try to select a hand-tuned
  1.1503 + *  asm/vectorized/optimized function first, and then fallback to an
  1.1504 + *  autogenerated function that is customized to convert between two
  1.1505 + *  specific data types.
  1.1506 + */
  1.1507 +static int
  1.1508 +SDL_BuildAudioTypeCVT(SDL_AudioCVT * cvt,
  1.1509 +                      SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
  1.1510 +{
  1.1511 +    if (src_fmt != dst_fmt) {
  1.1512 +        const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt);
  1.1513 +        const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt);
  1.1514 +        SDL_AudioFilter filter = SDL_HandTunedTypeCVT(src_fmt, dst_fmt);
  1.1515 +
  1.1516 +        /* No hand-tuned converter? Try the autogenerated ones. */
  1.1517 +        if (filter == NULL) {
  1.1518 +            int i;
  1.1519 +            for (i = 0; sdl_audio_type_filters[i].filter != NULL; i++) {
  1.1520 +                const SDL_AudioTypeFilters *filt = &sdl_audio_type_filters[i];
  1.1521 +                if ((filt->src_fmt == src_fmt) && (filt->dst_fmt == dst_fmt)) {
  1.1522 +                    filter = filt->filter;
  1.1523 +                    break;
  1.1524 +                }
  1.1525 +            }
  1.1526 +
  1.1527 +            if (filter == NULL) {
  1.1528 +                return -1;  /* Still no matching converter?! */
  1.1529 +            }
  1.1530 +        }
  1.1531 +
  1.1532 +        /* Update (cvt) with filter details... */
  1.1533 +        cvt->filters[cvt->filter_index++] = filter;
  1.1534 +        if (src_bitsize < dst_bitsize) {
  1.1535 +            const int mult = (dst_bitsize / src_bitsize);
  1.1536 +            cvt->len_mult *= mult;
  1.1537 +            cvt->len_ratio *= mult;
  1.1538 +        } else if (src_bitsize > dst_bitsize) {
  1.1539 +            cvt->len_ratio /= (src_bitsize / dst_bitsize);
  1.1540 +        }
  1.1541 +
  1.1542 +        return 1;  /* added a converter. */
  1.1543 +    }
  1.1544 +
  1.1545 +    return 0;  /* no conversion necessary. */
  1.1546 +}
  1.1547 +
  1.1548 +
  1.1549 +
  1.1550 +/* Creates a set of audio filters to convert from one format to another.
  1.1551 +   Returns -1 if the format conversion is not supported, 0 if there's
  1.1552 +   no conversion needed, or 1 if the audio filter is set up.
  1.1553  */
  1.1554  
  1.1555  int
  1.1556  SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
  1.1557 -                  Uint16 src_format, Uint8 src_channels, int src_rate,
  1.1558 -                  Uint16 dst_format, Uint8 dst_channels, int dst_rate)
  1.1559 +                  SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
  1.1560 +                  SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
  1.1561  {
  1.1562 -/*printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
  1.1563 -		src_format, dst_format, src_channels, dst_channels, src_rate, dst_rate);*/
  1.1564 +    /* there are no unsigned types over 16 bits, so catch this upfront. */
  1.1565 +    if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
  1.1566 +        return -1;
  1.1567 +    }
  1.1568 +    if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
  1.1569 +        return -1;
  1.1570 +    }
  1.1571 +
  1.1572 +    #ifdef DEBUG_CONVERT
  1.1573 +    printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
  1.1574 +		    src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
  1.1575 +    #endif
  1.1576 +
  1.1577      /* Start off with no conversion necessary */
  1.1578 +
  1.1579 +    cvt->src_format = src_fmt;
  1.1580 +    cvt->dst_format = dst_fmt;
  1.1581      cvt->needed = 0;
  1.1582      cvt->filter_index = 0;
  1.1583      cvt->filters[0] = NULL;
  1.1584      cvt->len_mult = 1;
  1.1585      cvt->len_ratio = 1.0;
  1.1586  
  1.1587 -    /* First filter:  Endian conversion from src to dst */
  1.1588 -    if ((src_format & 0x1000) != (dst_format & 0x1000)
  1.1589 -        && ((src_format & 0xff) != 8)) {
  1.1590 -        cvt->filters[cvt->filter_index++] = SDL_ConvertEndian;
  1.1591 -    }
  1.1592 +    /* Convert data types, if necessary. Updates (cvt). */
  1.1593 +    if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1)
  1.1594 +        return -1;  /* shouldn't happen, but just in case... */
  1.1595  
  1.1596 -    /* Second filter: Sign conversion -- signed/unsigned */
  1.1597 -    if ((src_format & 0x8000) != (dst_format & 0x8000)) {
  1.1598 -        cvt->filters[cvt->filter_index++] = SDL_ConvertSign;
  1.1599 -    }
  1.1600 -
  1.1601 -    /* Next filter:  Convert 16 bit <--> 8 bit PCM */
  1.1602 -    if ((src_format & 0xFF) != (dst_format & 0xFF)) {
  1.1603 -        switch (dst_format & 0x10FF) {
  1.1604 -        case AUDIO_U8:
  1.1605 -            cvt->filters[cvt->filter_index++] = SDL_Convert8;
  1.1606 -            cvt->len_ratio /= 2;
  1.1607 -            break;
  1.1608 -        case AUDIO_U16LSB:
  1.1609 -            cvt->filters[cvt->filter_index++] = SDL_Convert16LSB;
  1.1610 -            cvt->len_mult *= 2;
  1.1611 -            cvt->len_ratio *= 2;
  1.1612 -            break;
  1.1613 -        case AUDIO_U16MSB:
  1.1614 -            cvt->filters[cvt->filter_index++] = SDL_Convert16MSB;
  1.1615 -            cvt->len_mult *= 2;
  1.1616 -            cvt->len_ratio *= 2;
  1.1617 -            break;
  1.1618 -        }
  1.1619 -    }
  1.1620 -
  1.1621 -    /* Last filter:  Mono/Stereo conversion */
  1.1622 +    /* Channel conversion */
  1.1623      if (src_channels != dst_channels) {
  1.1624          if ((src_channels == 1) && (dst_channels > 1)) {
  1.1625              cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
  1.1626 @@ -1504,7 +1456,7 @@
  1.1627          Uint32 hi_rate, lo_rate;
  1.1628          int len_mult;
  1.1629          double len_ratio;
  1.1630 -        void (SDLCALL * rate_cvt) (SDL_AudioCVT * cvt, Uint16 format);
  1.1631 +        SDL_AudioFilter rate_cvt = NULL;
  1.1632  
  1.1633          if (src_rate > dst_rate) {
  1.1634              hi_rate = src_rate;
  1.1635 @@ -1583,8 +1535,8 @@
  1.1636      /* Set up the filter information */
  1.1637      if (cvt->filter_index != 0) {
  1.1638          cvt->needed = 1;
  1.1639 -        cvt->src_format = src_format;
  1.1640 -        cvt->dst_format = dst_format;
  1.1641 +        cvt->src_format = src_fmt;
  1.1642 +        cvt->dst_format = dst_fmt;
  1.1643          cvt->len = 0;
  1.1644          cvt->buf = NULL;
  1.1645          cvt->filters[cvt->filter_index] = NULL;