src/audio/SDL_audiocvt.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 10 Jan 2009 18:32:24 +0000
changeset 3012 7e30c2dc7783
parent 2883 11626a53e7bc
child 3021 f3dcf04412cf
permissions -rw-r--r--
Fixed Visual C++ release build for Visual C++ 2005
* Some math functions become intrinsic in release mode, so we need to
convert all the math functions into SDL math functions, like we did
with the stdlib functions.
* Constant initializers of 8-bit values become calls to memset() in
release mode, but memset() itself is an intrinsic when explicitly
called. So we'll just explicitly call memset() in those cases.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     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.
     9 
    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.
    14 
    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
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* Functions for audio drivers to perform runtime conversion of audio format */
    25 
    26 #include "SDL_audio.h"
    27 #include "SDL_audio_c.h"
    28 
    29 //#define DEBUG_CONVERT
    30 
    31 /* These are fractional multiplication routines. That is, their inputs
    32    are two numbers in the range [-1, 1) and the result falls in that
    33    same range. The output is the same size as the inputs, i.e.
    34    32-bit x 32-bit = 32-bit.
    35  */
    36 
    37 /* We hope here that the right shift includes sign extension */
    38 #ifdef SDL_HAS_64BIT_Type
    39 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
    40 #else
    41 /* If we don't have the 64-bit type, do something more complicated. See http://www.8052.com/mul16.phtml or http://www.cs.uaf.edu/~cs301/notes/Chapter5/node5.html */
    42 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
    43 #endif
    44 #define SDL_FixMpy16(a, b) ((((Sint32)a * (Sint32)b) >> 14) & 0xffff)
    45 #define SDL_FixMpy8(a, b) ((((Sint16)a * (Sint16)b) >> 7) & 0xff)
    46 /* This macro just makes the floating point filtering code not have to be a special case. */
    47 #define SDL_FloatMpy(a, b) (a * b)
    48 
    49 /* These macros take floating point numbers in the range [-1.0f, 1.0f) and
    50    represent them as fixed-point numbers in that same range. There's no
    51    checking that the floating point argument is inside the appropriate range.
    52  */
    53 
    54 #define SDL_Make_1_7(a) (Sint8)(a * 128.0f)
    55 #define SDL_Make_1_15(a) (Sint16)(a * 32768.0f)
    56 #define SDL_Make_1_31(a) (Sint32)(a * 2147483648.0f)
    57 #define SDL_Make_2_6(a) (Sint8)(a * 64.0f)
    58 #define SDL_Make_2_14(a) (Sint16)(a * 16384.0f)
    59 #define SDL_Make_2_30(a) (Sint32)(a * 1073741824.0f)
    60 
    61 /* Effectively mix right and left channels into a single channel */
    62 static void SDLCALL
    63 SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    64 {
    65     int i;
    66     Sint32 sample;
    67 
    68 #ifdef DEBUG_CONVERT
    69     fprintf(stderr, "Converting to mono\n");
    70 #endif
    71     switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
    72     case AUDIO_U8:
    73         {
    74             Uint8 *src, *dst;
    75 
    76             src = cvt->buf;
    77             dst = cvt->buf;
    78             for (i = cvt->len_cvt / 2; i; --i) {
    79                 sample = src[0] + src[1];
    80                 *dst = (Uint8) (sample / 2);
    81                 src += 2;
    82                 dst += 1;
    83             }
    84         }
    85         break;
    86 
    87     case AUDIO_S8:
    88         {
    89             Sint8 *src, *dst;
    90 
    91             src = (Sint8 *) cvt->buf;
    92             dst = (Sint8 *) cvt->buf;
    93             for (i = cvt->len_cvt / 2; i; --i) {
    94                 sample = src[0] + src[1];
    95                 *dst = (Sint8) (sample / 2);
    96                 src += 2;
    97                 dst += 1;
    98             }
    99         }
   100         break;
   101 
   102     case AUDIO_U16:
   103         {
   104             Uint8 *src, *dst;
   105 
   106             src = cvt->buf;
   107             dst = cvt->buf;
   108             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   109                 for (i = cvt->len_cvt / 4; i; --i) {
   110                     sample = (Uint16) ((src[0] << 8) | src[1]) +
   111                         (Uint16) ((src[2] << 8) | src[3]);
   112                     sample /= 2;
   113                     dst[1] = (sample & 0xFF);
   114                     sample >>= 8;
   115                     dst[0] = (sample & 0xFF);
   116                     src += 4;
   117                     dst += 2;
   118                 }
   119             } else {
   120                 for (i = cvt->len_cvt / 4; i; --i) {
   121                     sample = (Uint16) ((src[1] << 8) | src[0]) +
   122                         (Uint16) ((src[3] << 8) | src[2]);
   123                     sample /= 2;
   124                     dst[0] = (sample & 0xFF);
   125                     sample >>= 8;
   126                     dst[1] = (sample & 0xFF);
   127                     src += 4;
   128                     dst += 2;
   129                 }
   130             }
   131         }
   132         break;
   133 
   134     case AUDIO_S16:
   135         {
   136             Uint8 *src, *dst;
   137 
   138             src = cvt->buf;
   139             dst = cvt->buf;
   140             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   141                 for (i = cvt->len_cvt / 4; i; --i) {
   142                     sample = (Sint16) ((src[0] << 8) | src[1]) +
   143                         (Sint16) ((src[2] << 8) | src[3]);
   144                     sample /= 2;
   145                     dst[1] = (sample & 0xFF);
   146                     sample >>= 8;
   147                     dst[0] = (sample & 0xFF);
   148                     src += 4;
   149                     dst += 2;
   150                 }
   151             } else {
   152                 for (i = cvt->len_cvt / 4; i; --i) {
   153                     sample = (Sint16) ((src[1] << 8) | src[0]) +
   154                         (Sint16) ((src[3] << 8) | src[2]);
   155                     sample /= 2;
   156                     dst[0] = (sample & 0xFF);
   157                     sample >>= 8;
   158                     dst[1] = (sample & 0xFF);
   159                     src += 4;
   160                     dst += 2;
   161                 }
   162             }
   163         }
   164         break;
   165 
   166     case AUDIO_S32:
   167         {
   168             const Uint32 *src = (const Uint32 *) cvt->buf;
   169             Uint32 *dst = (Uint32 *) cvt->buf;
   170             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   171                 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
   172                     const Sint64 added =
   173                         (((Sint64) (Sint32) SDL_SwapBE32(src[0])) +
   174                          ((Sint64) (Sint32) SDL_SwapBE32(src[1])));
   175                     *(dst++) = SDL_SwapBE32((Uint32) ((Sint32) (added / 2)));
   176                 }
   177             } else {
   178                 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
   179                     const Sint64 added =
   180                         (((Sint64) (Sint32) SDL_SwapLE32(src[0])) +
   181                          ((Sint64) (Sint32) SDL_SwapLE32(src[1])));
   182                     *(dst++) = SDL_SwapLE32((Uint32) ((Sint32) (added / 2)));
   183                 }
   184             }
   185         }
   186         break;
   187 
   188     case AUDIO_F32:
   189         {
   190             const float *src = (const float *) cvt->buf;
   191             float *dst = (float *) cvt->buf;
   192             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   193                 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
   194                     const float src1 = SDL_SwapFloatBE(src[0]);
   195                     const float src2 = SDL_SwapFloatBE(src[1]);
   196                     const double added = ((double) src1) + ((double) src2);
   197                     const float halved = (float) (added * 0.5);
   198                     *(dst++) = SDL_SwapFloatBE(halved);
   199                 }
   200             } else {
   201                 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
   202                     const float src1 = SDL_SwapFloatLE(src[0]);
   203                     const float src2 = SDL_SwapFloatLE(src[1]);
   204                     const double added = ((double) src1) + ((double) src2);
   205                     const float halved = (float) (added * 0.5);
   206                     *(dst++) = SDL_SwapFloatLE(halved);
   207                 }
   208             }
   209         }
   210         break;
   211     }
   212 
   213     cvt->len_cvt /= 2;
   214     if (cvt->filters[++cvt->filter_index]) {
   215         cvt->filters[cvt->filter_index] (cvt, format);
   216     }
   217 }
   218 
   219 
   220 /* Discard top 4 channels */
   221 static void SDLCALL
   222 SDL_ConvertStrip(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   223 {
   224     int i;
   225 
   226 #ifdef DEBUG_CONVERT
   227     fprintf(stderr, "Converting down from 6 channels to stereo\n");
   228 #endif
   229 
   230 #define strip_chans_6_to_2(type) \
   231     { \
   232         const type *src = (const type *) cvt->buf; \
   233         type *dst = (type *) cvt->buf; \
   234         for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
   235             dst[0] = src[0]; \
   236             dst[1] = src[1]; \
   237             src += 6; \
   238             dst += 2; \
   239         } \
   240     }
   241 
   242     /* this function only cares about typesize, and data as a block of bits. */
   243     switch (SDL_AUDIO_BITSIZE(format)) {
   244     case 8:
   245         strip_chans_6_to_2(Uint8);
   246         break;
   247     case 16:
   248         strip_chans_6_to_2(Uint16);
   249         break;
   250     case 32:
   251         strip_chans_6_to_2(Uint32);
   252         break;
   253     }
   254 
   255 #undef strip_chans_6_to_2
   256 
   257     cvt->len_cvt /= 3;
   258     if (cvt->filters[++cvt->filter_index]) {
   259         cvt->filters[cvt->filter_index] (cvt, format);
   260     }
   261 }
   262 
   263 
   264 /* Discard top 2 channels of 6 */
   265 static void SDLCALL
   266 SDL_ConvertStrip_2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   267 {
   268     int i;
   269 
   270 #ifdef DEBUG_CONVERT
   271     fprintf(stderr, "Converting 6 down to quad\n");
   272 #endif
   273 
   274 #define strip_chans_6_to_4(type) \
   275     { \
   276         const type *src = (const type *) cvt->buf; \
   277         type *dst = (type *) cvt->buf; \
   278         for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
   279             dst[0] = src[0]; \
   280             dst[1] = src[1]; \
   281             dst[2] = src[2]; \
   282             dst[3] = src[3]; \
   283             src += 6; \
   284             dst += 4; \
   285         } \
   286     }
   287 
   288     /* this function only cares about typesize, and data as a block of bits. */
   289     switch (SDL_AUDIO_BITSIZE(format)) {
   290     case 8:
   291         strip_chans_6_to_4(Uint8);
   292         break;
   293     case 16:
   294         strip_chans_6_to_4(Uint16);
   295         break;
   296     case 32:
   297         strip_chans_6_to_4(Uint32);
   298         break;
   299     }
   300 
   301 #undef strip_chans_6_to_4
   302 
   303     cvt->len_cvt /= 6;
   304     cvt->len_cvt *= 4;
   305     if (cvt->filters[++cvt->filter_index]) {
   306         cvt->filters[cvt->filter_index] (cvt, format);
   307     }
   308 }
   309 
   310 /* Duplicate a mono channel to both stereo channels */
   311 static void SDLCALL
   312 SDL_ConvertStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   313 {
   314     int i;
   315 
   316 #ifdef DEBUG_CONVERT
   317     fprintf(stderr, "Converting to stereo\n");
   318 #endif
   319 
   320 #define dup_chans_1_to_2(type) \
   321     { \
   322         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   323         type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
   324         for (i = cvt->len_cvt / 2; i; --i, --src) { \
   325             const type val = *src; \
   326             dst -= 2; \
   327             dst[0] = dst[1] = val; \
   328         } \
   329     }
   330 
   331     /* this function only cares about typesize, and data as a block of bits. */
   332     switch (SDL_AUDIO_BITSIZE(format)) {
   333     case 8:
   334         dup_chans_1_to_2(Uint8);
   335         break;
   336     case 16:
   337         dup_chans_1_to_2(Uint16);
   338         break;
   339     case 32:
   340         dup_chans_1_to_2(Uint32);
   341         break;
   342     }
   343 
   344 #undef dup_chans_1_to_2
   345 
   346     cvt->len_cvt *= 2;
   347     if (cvt->filters[++cvt->filter_index]) {
   348         cvt->filters[cvt->filter_index] (cvt, format);
   349     }
   350 }
   351 
   352 
   353 /* Duplicate a stereo channel to a pseudo-5.1 stream */
   354 static void SDLCALL
   355 SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   356 {
   357     int i;
   358 
   359 #ifdef DEBUG_CONVERT
   360     fprintf(stderr, "Converting stereo to surround\n");
   361 #endif
   362 
   363     switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
   364     case AUDIO_U8:
   365         {
   366             Uint8 *src, *dst, lf, rf, ce;
   367 
   368             src = (Uint8 *) (cvt->buf + cvt->len_cvt);
   369             dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 3);
   370             for (i = cvt->len_cvt; i; --i) {
   371                 dst -= 6;
   372                 src -= 2;
   373                 lf = src[0];
   374                 rf = src[1];
   375                 ce = (lf / 2) + (rf / 2);
   376                 dst[0] = lf;
   377                 dst[1] = rf;
   378                 dst[2] = lf - ce;
   379                 dst[3] = rf - ce;
   380                 dst[4] = ce;
   381                 dst[5] = ce;
   382             }
   383         }
   384         break;
   385 
   386     case AUDIO_S8:
   387         {
   388             Sint8 *src, *dst, lf, rf, ce;
   389 
   390             src = (Sint8 *) cvt->buf + cvt->len_cvt;
   391             dst = (Sint8 *) cvt->buf + cvt->len_cvt * 3;
   392             for (i = cvt->len_cvt; i; --i) {
   393                 dst -= 6;
   394                 src -= 2;
   395                 lf = src[0];
   396                 rf = src[1];
   397                 ce = (lf / 2) + (rf / 2);
   398                 dst[0] = lf;
   399                 dst[1] = rf;
   400                 dst[2] = lf - ce;
   401                 dst[3] = rf - ce;
   402                 dst[4] = ce;
   403                 dst[5] = ce;
   404             }
   405         }
   406         break;
   407 
   408     case AUDIO_U16:
   409         {
   410             Uint8 *src, *dst;
   411             Uint16 lf, rf, ce, lr, rr;
   412 
   413             src = cvt->buf + cvt->len_cvt;
   414             dst = cvt->buf + cvt->len_cvt * 3;
   415 
   416             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   417                 for (i = cvt->len_cvt / 4; i; --i) {
   418                     dst -= 12;
   419                     src -= 4;
   420                     lf = (Uint16) ((src[0] << 8) | src[1]);
   421                     rf = (Uint16) ((src[2] << 8) | src[3]);
   422                     ce = (lf / 2) + (rf / 2);
   423                     rr = lf - ce;
   424                     lr = rf - ce;
   425                     dst[1] = (lf & 0xFF);
   426                     dst[0] = ((lf >> 8) & 0xFF);
   427                     dst[3] = (rf & 0xFF);
   428                     dst[2] = ((rf >> 8) & 0xFF);
   429 
   430                     dst[1 + 4] = (lr & 0xFF);
   431                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   432                     dst[3 + 4] = (rr & 0xFF);
   433                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   434 
   435                     dst[1 + 8] = (ce & 0xFF);
   436                     dst[0 + 8] = ((ce >> 8) & 0xFF);
   437                     dst[3 + 8] = (ce & 0xFF);
   438                     dst[2 + 8] = ((ce >> 8) & 0xFF);
   439                 }
   440             } else {
   441                 for (i = cvt->len_cvt / 4; i; --i) {
   442                     dst -= 12;
   443                     src -= 4;
   444                     lf = (Uint16) ((src[1] << 8) | src[0]);
   445                     rf = (Uint16) ((src[3] << 8) | src[2]);
   446                     ce = (lf / 2) + (rf / 2);
   447                     rr = lf - ce;
   448                     lr = rf - ce;
   449                     dst[0] = (lf & 0xFF);
   450                     dst[1] = ((lf >> 8) & 0xFF);
   451                     dst[2] = (rf & 0xFF);
   452                     dst[3] = ((rf >> 8) & 0xFF);
   453 
   454                     dst[0 + 4] = (lr & 0xFF);
   455                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   456                     dst[2 + 4] = (rr & 0xFF);
   457                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   458 
   459                     dst[0 + 8] = (ce & 0xFF);
   460                     dst[1 + 8] = ((ce >> 8) & 0xFF);
   461                     dst[2 + 8] = (ce & 0xFF);
   462                     dst[3 + 8] = ((ce >> 8) & 0xFF);
   463                 }
   464             }
   465         }
   466         break;
   467 
   468     case AUDIO_S16:
   469         {
   470             Uint8 *src, *dst;
   471             Sint16 lf, rf, ce, lr, rr;
   472 
   473             src = cvt->buf + cvt->len_cvt;
   474             dst = cvt->buf + cvt->len_cvt * 3;
   475 
   476             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   477                 for (i = cvt->len_cvt / 4; i; --i) {
   478                     dst -= 12;
   479                     src -= 4;
   480                     lf = (Sint16) ((src[0] << 8) | src[1]);
   481                     rf = (Sint16) ((src[2] << 8) | src[3]);
   482                     ce = (lf / 2) + (rf / 2);
   483                     rr = lf - ce;
   484                     lr = rf - ce;
   485                     dst[1] = (lf & 0xFF);
   486                     dst[0] = ((lf >> 8) & 0xFF);
   487                     dst[3] = (rf & 0xFF);
   488                     dst[2] = ((rf >> 8) & 0xFF);
   489 
   490                     dst[1 + 4] = (lr & 0xFF);
   491                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   492                     dst[3 + 4] = (rr & 0xFF);
   493                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   494 
   495                     dst[1 + 8] = (ce & 0xFF);
   496                     dst[0 + 8] = ((ce >> 8) & 0xFF);
   497                     dst[3 + 8] = (ce & 0xFF);
   498                     dst[2 + 8] = ((ce >> 8) & 0xFF);
   499                 }
   500             } else {
   501                 for (i = cvt->len_cvt / 4; i; --i) {
   502                     dst -= 12;
   503                     src -= 4;
   504                     lf = (Sint16) ((src[1] << 8) | src[0]);
   505                     rf = (Sint16) ((src[3] << 8) | src[2]);
   506                     ce = (lf / 2) + (rf / 2);
   507                     rr = lf - ce;
   508                     lr = rf - ce;
   509                     dst[0] = (lf & 0xFF);
   510                     dst[1] = ((lf >> 8) & 0xFF);
   511                     dst[2] = (rf & 0xFF);
   512                     dst[3] = ((rf >> 8) & 0xFF);
   513 
   514                     dst[0 + 4] = (lr & 0xFF);
   515                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   516                     dst[2 + 4] = (rr & 0xFF);
   517                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   518 
   519                     dst[0 + 8] = (ce & 0xFF);
   520                     dst[1 + 8] = ((ce >> 8) & 0xFF);
   521                     dst[2 + 8] = (ce & 0xFF);
   522                     dst[3 + 8] = ((ce >> 8) & 0xFF);
   523                 }
   524             }
   525         }
   526         break;
   527 
   528     case AUDIO_S32:
   529         {
   530             Sint32 lf, rf, ce;
   531             const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
   532             Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
   533 
   534             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   535                 for (i = cvt->len_cvt / 8; i; --i) {
   536                     dst -= 6;
   537                     src -= 2;
   538                     lf = (Sint32) SDL_SwapBE32(src[0]);
   539                     rf = (Sint32) SDL_SwapBE32(src[1]);
   540                     ce = (lf / 2) + (rf / 2);
   541                     dst[0] = SDL_SwapBE32((Uint32) lf);
   542                     dst[1] = SDL_SwapBE32((Uint32) rf);
   543                     dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
   544                     dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
   545                     dst[4] = SDL_SwapBE32((Uint32) ce);
   546                     dst[5] = SDL_SwapBE32((Uint32) ce);
   547                 }
   548             } else {
   549                 for (i = cvt->len_cvt / 8; i; --i) {
   550                     dst -= 6;
   551                     src -= 2;
   552                     lf = (Sint32) SDL_SwapLE32(src[0]);
   553                     rf = (Sint32) SDL_SwapLE32(src[1]);
   554                     ce = (lf / 2) + (rf / 2);
   555                     dst[0] = src[0];
   556                     dst[1] = src[1];
   557                     dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
   558                     dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
   559                     dst[4] = SDL_SwapLE32((Uint32) ce);
   560                     dst[5] = SDL_SwapLE32((Uint32) ce);
   561                 }
   562             }
   563         }
   564         break;
   565 
   566     case AUDIO_F32:
   567         {
   568             float lf, rf, ce;
   569             const float *src = (const float *) cvt->buf + cvt->len_cvt;
   570             float *dst = (float *) cvt->buf + cvt->len_cvt * 3;
   571 
   572             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   573                 for (i = cvt->len_cvt / 8; i; --i) {
   574                     dst -= 6;
   575                     src -= 2;
   576                     lf = SDL_SwapFloatBE(src[0]);
   577                     rf = SDL_SwapFloatBE(src[1]);
   578                     ce = (lf * 0.5f) + (rf * 0.5f);
   579                     dst[0] = src[0];
   580                     dst[1] = src[1];
   581                     dst[2] = SDL_SwapFloatBE(lf - ce);
   582                     dst[3] = SDL_SwapFloatBE(rf - ce);
   583                     dst[4] = dst[5] = SDL_SwapFloatBE(ce);
   584                 }
   585             } else {
   586                 for (i = cvt->len_cvt / 8; i; --i) {
   587                     dst -= 6;
   588                     src -= 2;
   589                     lf = SDL_SwapFloatLE(src[0]);
   590                     rf = SDL_SwapFloatLE(src[1]);
   591                     ce = (lf * 0.5f) + (rf * 0.5f);
   592                     dst[0] = src[0];
   593                     dst[1] = src[1];
   594                     dst[2] = SDL_SwapFloatLE(lf - ce);
   595                     dst[3] = SDL_SwapFloatLE(rf - ce);
   596                     dst[4] = dst[5] = SDL_SwapFloatLE(ce);
   597                 }
   598             }
   599         }
   600         break;
   601 
   602     }
   603     cvt->len_cvt *= 3;
   604     if (cvt->filters[++cvt->filter_index]) {
   605         cvt->filters[cvt->filter_index] (cvt, format);
   606     }
   607 }
   608 
   609 
   610 /* Duplicate a stereo channel to a pseudo-4.0 stream */
   611 static void SDLCALL
   612 SDL_ConvertSurround_4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   613 {
   614     int i;
   615 
   616 #ifdef DEBUG_CONVERT
   617     fprintf(stderr, "Converting stereo to quad\n");
   618 #endif
   619 
   620     switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
   621     case AUDIO_U8:
   622         {
   623             Uint8 *src, *dst, lf, rf, ce;
   624 
   625             src = (Uint8 *) (cvt->buf + cvt->len_cvt);
   626             dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 2);
   627             for (i = cvt->len_cvt; i; --i) {
   628                 dst -= 4;
   629                 src -= 2;
   630                 lf = src[0];
   631                 rf = src[1];
   632                 ce = (lf / 2) + (rf / 2);
   633                 dst[0] = lf;
   634                 dst[1] = rf;
   635                 dst[2] = lf - ce;
   636                 dst[3] = rf - ce;
   637             }
   638         }
   639         break;
   640 
   641     case AUDIO_S8:
   642         {
   643             Sint8 *src, *dst, lf, rf, ce;
   644 
   645             src = (Sint8 *) cvt->buf + cvt->len_cvt;
   646             dst = (Sint8 *) cvt->buf + cvt->len_cvt * 2;
   647             for (i = cvt->len_cvt; i; --i) {
   648                 dst -= 4;
   649                 src -= 2;
   650                 lf = src[0];
   651                 rf = src[1];
   652                 ce = (lf / 2) + (rf / 2);
   653                 dst[0] = lf;
   654                 dst[1] = rf;
   655                 dst[2] = lf - ce;
   656                 dst[3] = rf - ce;
   657             }
   658         }
   659         break;
   660 
   661     case AUDIO_U16:
   662         {
   663             Uint8 *src, *dst;
   664             Uint16 lf, rf, ce, lr, rr;
   665 
   666             src = cvt->buf + cvt->len_cvt;
   667             dst = cvt->buf + cvt->len_cvt * 2;
   668 
   669             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   670                 for (i = cvt->len_cvt / 4; i; --i) {
   671                     dst -= 8;
   672                     src -= 4;
   673                     lf = (Uint16) ((src[0] << 8) | src[1]);
   674                     rf = (Uint16) ((src[2] << 8) | src[3]);
   675                     ce = (lf / 2) + (rf / 2);
   676                     rr = lf - ce;
   677                     lr = rf - ce;
   678                     dst[1] = (lf & 0xFF);
   679                     dst[0] = ((lf >> 8) & 0xFF);
   680                     dst[3] = (rf & 0xFF);
   681                     dst[2] = ((rf >> 8) & 0xFF);
   682 
   683                     dst[1 + 4] = (lr & 0xFF);
   684                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   685                     dst[3 + 4] = (rr & 0xFF);
   686                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   687                 }
   688             } else {
   689                 for (i = cvt->len_cvt / 4; i; --i) {
   690                     dst -= 8;
   691                     src -= 4;
   692                     lf = (Uint16) ((src[1] << 8) | src[0]);
   693                     rf = (Uint16) ((src[3] << 8) | src[2]);
   694                     ce = (lf / 2) + (rf / 2);
   695                     rr = lf - ce;
   696                     lr = rf - ce;
   697                     dst[0] = (lf & 0xFF);
   698                     dst[1] = ((lf >> 8) & 0xFF);
   699                     dst[2] = (rf & 0xFF);
   700                     dst[3] = ((rf >> 8) & 0xFF);
   701 
   702                     dst[0 + 4] = (lr & 0xFF);
   703                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   704                     dst[2 + 4] = (rr & 0xFF);
   705                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   706                 }
   707             }
   708         }
   709         break;
   710 
   711     case AUDIO_S16:
   712         {
   713             Uint8 *src, *dst;
   714             Sint16 lf, rf, ce, lr, rr;
   715 
   716             src = cvt->buf + cvt->len_cvt;
   717             dst = cvt->buf + cvt->len_cvt * 2;
   718 
   719             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   720                 for (i = cvt->len_cvt / 4; i; --i) {
   721                     dst -= 8;
   722                     src -= 4;
   723                     lf = (Sint16) ((src[0] << 8) | src[1]);
   724                     rf = (Sint16) ((src[2] << 8) | src[3]);
   725                     ce = (lf / 2) + (rf / 2);
   726                     rr = lf - ce;
   727                     lr = rf - ce;
   728                     dst[1] = (lf & 0xFF);
   729                     dst[0] = ((lf >> 8) & 0xFF);
   730                     dst[3] = (rf & 0xFF);
   731                     dst[2] = ((rf >> 8) & 0xFF);
   732 
   733                     dst[1 + 4] = (lr & 0xFF);
   734                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   735                     dst[3 + 4] = (rr & 0xFF);
   736                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   737                 }
   738             } else {
   739                 for (i = cvt->len_cvt / 4; i; --i) {
   740                     dst -= 8;
   741                     src -= 4;
   742                     lf = (Sint16) ((src[1] << 8) | src[0]);
   743                     rf = (Sint16) ((src[3] << 8) | src[2]);
   744                     ce = (lf / 2) + (rf / 2);
   745                     rr = lf - ce;
   746                     lr = rf - ce;
   747                     dst[0] = (lf & 0xFF);
   748                     dst[1] = ((lf >> 8) & 0xFF);
   749                     dst[2] = (rf & 0xFF);
   750                     dst[3] = ((rf >> 8) & 0xFF);
   751 
   752                     dst[0 + 4] = (lr & 0xFF);
   753                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   754                     dst[2 + 4] = (rr & 0xFF);
   755                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   756                 }
   757             }
   758         }
   759         break;
   760 
   761     case AUDIO_S32:
   762         {
   763             const Uint32 *src = (const Uint32 *) (cvt->buf + cvt->len_cvt);
   764             Uint32 *dst = (Uint32 *) (cvt->buf + cvt->len_cvt * 2);
   765             Sint32 lf, rf, ce;
   766 
   767             if (SDL_AUDIO_ISBIGENDIAN(format)) {
   768                 for (i = cvt->len_cvt / 8; i; --i) {
   769                     dst -= 4;
   770                     src -= 2;
   771                     lf = (Sint32) SDL_SwapBE32(src[0]);
   772                     rf = (Sint32) SDL_SwapBE32(src[1]);
   773                     ce = (lf / 2) + (rf / 2);
   774                     dst[0] = src[0];
   775                     dst[1] = src[1];
   776                     dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
   777                     dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
   778                 }
   779             } else {
   780                 for (i = cvt->len_cvt / 8; i; --i) {
   781                     dst -= 4;
   782                     src -= 2;
   783                     lf = (Sint32) SDL_SwapLE32(src[0]);
   784                     rf = (Sint32) SDL_SwapLE32(src[1]);
   785                     ce = (lf / 2) + (rf / 2);
   786                     dst[0] = src[0];
   787                     dst[1] = src[1];
   788                     dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
   789                     dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
   790                 }
   791             }
   792         }
   793         break;
   794     }
   795     cvt->len_cvt *= 2;
   796     if (cvt->filters[++cvt->filter_index]) {
   797         cvt->filters[cvt->filter_index] (cvt, format);
   798     }
   799 }
   800 
   801 /* Convert rate up by multiple of 2 */
   802 static void SDLCALL
   803 SDL_RateMUL2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   804 {
   805     int i;
   806 
   807 #ifdef DEBUG_CONVERT
   808     fprintf(stderr, "Converting audio rate * 2 (mono)\n");
   809 #endif
   810 
   811 #define mul2_mono(type) { \
   812         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   813         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
   814         for (i = cvt->len_cvt / sizeof (type); i; --i) { \
   815             src--; \
   816             dst[-1] = dst[-2] = src[0]; \
   817             dst -= 2; \
   818         } \
   819     }
   820 
   821     switch (SDL_AUDIO_BITSIZE(format)) {
   822     case 8:
   823         mul2_mono(Uint8);
   824         break;
   825     case 16:
   826         mul2_mono(Uint16);
   827         break;
   828     case 32:
   829         mul2_mono(Uint32);
   830         break;
   831     }
   832 
   833 #undef mul2_mono
   834 
   835     cvt->len_cvt *= 2;
   836     if (cvt->filters[++cvt->filter_index]) {
   837         cvt->filters[cvt->filter_index] (cvt, format);
   838     }
   839 }
   840 
   841 
   842 /* Convert rate up by multiple of 2, for stereo */
   843 static void SDLCALL
   844 SDL_RateMUL2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   845 {
   846     int i;
   847 
   848 #ifdef DEBUG_CONVERT
   849     fprintf(stderr, "Converting audio rate * 2 (stereo)\n");
   850 #endif
   851 
   852 #define mul2_stereo(type) { \
   853         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   854         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
   855         for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
   856             const type r = src[-1]; \
   857             const type l = src[-2]; \
   858             src -= 2; \
   859             dst[-1] = r; \
   860             dst[-2] = l; \
   861             dst[-3] = r; \
   862             dst[-4] = l; \
   863             dst -= 4; \
   864         } \
   865     }
   866 
   867     switch (SDL_AUDIO_BITSIZE(format)) {
   868     case 8:
   869         mul2_stereo(Uint8);
   870         break;
   871     case 16:
   872         mul2_stereo(Uint16);
   873         break;
   874     case 32:
   875         mul2_stereo(Uint32);
   876         break;
   877     }
   878 
   879 #undef mul2_stereo
   880 
   881     cvt->len_cvt *= 2;
   882     if (cvt->filters[++cvt->filter_index]) {
   883         cvt->filters[cvt->filter_index] (cvt, format);
   884     }
   885 }
   886 
   887 /* Convert rate up by multiple of 2, for quad */
   888 static void SDLCALL
   889 SDL_RateMUL2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   890 {
   891     int i;
   892 
   893 #ifdef DEBUG_CONVERT
   894     fprintf(stderr, "Converting audio rate * 2 (quad)\n");
   895 #endif
   896 
   897 #define mul2_quad(type) { \
   898         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   899         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
   900         for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
   901             const type c1 = src[-1]; \
   902             const type c2 = src[-2]; \
   903             const type c3 = src[-3]; \
   904             const type c4 = src[-4]; \
   905             src -= 4; \
   906             dst[-1] = c1; \
   907             dst[-2] = c2; \
   908             dst[-3] = c3; \
   909             dst[-4] = c4; \
   910             dst[-5] = c1; \
   911             dst[-6] = c2; \
   912             dst[-7] = c3; \
   913             dst[-8] = c4; \
   914             dst -= 8; \
   915         } \
   916     }
   917 
   918     switch (SDL_AUDIO_BITSIZE(format)) {
   919     case 8:
   920         mul2_quad(Uint8);
   921         break;
   922     case 16:
   923         mul2_quad(Uint16);
   924         break;
   925     case 32:
   926         mul2_quad(Uint32);
   927         break;
   928     }
   929 
   930 #undef mul2_quad
   931 
   932     cvt->len_cvt *= 2;
   933     if (cvt->filters[++cvt->filter_index]) {
   934         cvt->filters[cvt->filter_index] (cvt, format);
   935     }
   936 }
   937 
   938 
   939 /* Convert rate up by multiple of 2, for 5.1 */
   940 static void SDLCALL
   941 SDL_RateMUL2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   942 {
   943     int i;
   944 
   945 #ifdef DEBUG_CONVERT
   946     fprintf(stderr, "Converting audio rate * 2 (six channels)\n");
   947 #endif
   948 
   949 #define mul2_chansix(type) { \
   950         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
   951         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
   952         for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
   953             const type c1 = src[-1]; \
   954             const type c2 = src[-2]; \
   955             const type c3 = src[-3]; \
   956             const type c4 = src[-4]; \
   957             const type c5 = src[-5]; \
   958             const type c6 = src[-6]; \
   959             src -= 6; \
   960             dst[-1] = c1; \
   961             dst[-2] = c2; \
   962             dst[-3] = c3; \
   963             dst[-4] = c4; \
   964             dst[-5] = c5; \
   965             dst[-6] = c6; \
   966             dst[-7] = c1; \
   967             dst[-8] = c2; \
   968             dst[-9] = c3; \
   969             dst[-10] = c4; \
   970             dst[-11] = c5; \
   971             dst[-12] = c6; \
   972             dst -= 12; \
   973         } \
   974     }
   975 
   976     switch (SDL_AUDIO_BITSIZE(format)) {
   977     case 8:
   978         mul2_chansix(Uint8);
   979         break;
   980     case 16:
   981         mul2_chansix(Uint16);
   982         break;
   983     case 32:
   984         mul2_chansix(Uint32);
   985         break;
   986     }
   987 
   988 #undef mul2_chansix
   989 
   990     cvt->len_cvt *= 2;
   991     if (cvt->filters[++cvt->filter_index]) {
   992         cvt->filters[cvt->filter_index] (cvt, format);
   993     }
   994 }
   995 
   996 /* Convert rate down by multiple of 2 */
   997 static void SDLCALL
   998 SDL_RateDIV2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   999 {
  1000     int i;
  1001 
  1002 #ifdef DEBUG_CONVERT
  1003     fprintf(stderr, "Converting audio rate / 2 (mono)\n");
  1004 #endif
  1005 
  1006 #define div2_mono(type) { \
  1007         const type *src = (const type *) cvt->buf; \
  1008         type *dst = (type *) cvt->buf; \
  1009         for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
  1010             dst[0] = src[0]; \
  1011             src += 2; \
  1012             dst++; \
  1013         } \
  1014     }
  1015 
  1016     switch (SDL_AUDIO_BITSIZE(format)) {
  1017     case 8:
  1018         div2_mono(Uint8);
  1019         break;
  1020     case 16:
  1021         div2_mono(Uint16);
  1022         break;
  1023     case 32:
  1024         div2_mono(Uint32);
  1025         break;
  1026     }
  1027 
  1028 #undef div2_mono
  1029 
  1030     cvt->len_cvt /= 2;
  1031     if (cvt->filters[++cvt->filter_index]) {
  1032         cvt->filters[cvt->filter_index] (cvt, format);
  1033     }
  1034 }
  1035 
  1036 
  1037 /* Convert rate down by multiple of 2, for stereo */
  1038 static void SDLCALL
  1039 SDL_RateDIV2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1040 {
  1041     int i;
  1042 
  1043 #ifdef DEBUG_CONVERT
  1044     fprintf(stderr, "Converting audio rate / 2 (stereo)\n");
  1045 #endif
  1046 
  1047 #define div2_stereo(type) { \
  1048         const type *src = (const type *) cvt->buf; \
  1049         type *dst = (type *) cvt->buf; \
  1050         for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
  1051             dst[0] = src[0]; \
  1052             dst[1] = src[1]; \
  1053             src += 4; \
  1054             dst += 2; \
  1055         } \
  1056     }
  1057 
  1058     switch (SDL_AUDIO_BITSIZE(format)) {
  1059     case 8:
  1060         div2_stereo(Uint8);
  1061         break;
  1062     case 16:
  1063         div2_stereo(Uint16);
  1064         break;
  1065     case 32:
  1066         div2_stereo(Uint32);
  1067         break;
  1068     }
  1069 
  1070 #undef div2_stereo
  1071 
  1072     cvt->len_cvt /= 2;
  1073     if (cvt->filters[++cvt->filter_index]) {
  1074         cvt->filters[cvt->filter_index] (cvt, format);
  1075     }
  1076 }
  1077 
  1078 
  1079 /* Convert rate down by multiple of 2, for quad */
  1080 static void SDLCALL
  1081 SDL_RateDIV2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1082 {
  1083     int i;
  1084 
  1085 #ifdef DEBUG_CONVERT
  1086     fprintf(stderr, "Converting audio rate / 2 (quad)\n");
  1087 #endif
  1088 
  1089 #define div2_quad(type) { \
  1090         const type *src = (const type *) cvt->buf; \
  1091         type *dst = (type *) cvt->buf; \
  1092         for (i = cvt->len_cvt / (sizeof (type) * 8); i; --i) { \
  1093             dst[0] = src[0]; \
  1094             dst[1] = src[1]; \
  1095             dst[2] = src[2]; \
  1096             dst[3] = src[3]; \
  1097             src += 8; \
  1098             dst += 4; \
  1099         } \
  1100     }
  1101 
  1102     switch (SDL_AUDIO_BITSIZE(format)) {
  1103     case 8:
  1104         div2_quad(Uint8);
  1105         break;
  1106     case 16:
  1107         div2_quad(Uint16);
  1108         break;
  1109     case 32:
  1110         div2_quad(Uint32);
  1111         break;
  1112     }
  1113 
  1114 #undef div2_quad
  1115 
  1116     cvt->len_cvt /= 2;
  1117     if (cvt->filters[++cvt->filter_index]) {
  1118         cvt->filters[cvt->filter_index] (cvt, format);
  1119     }
  1120 }
  1121 
  1122 /* Convert rate down by multiple of 2, for 5.1 */
  1123 static void SDLCALL
  1124 SDL_RateDIV2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1125 {
  1126     int i;
  1127 
  1128 #ifdef DEBUG_CONVERT
  1129     fprintf(stderr, "Converting audio rate / 2 (six channels)\n");
  1130 #endif
  1131 
  1132 #define div2_chansix(type) { \
  1133         const type *src = (const type *) cvt->buf; \
  1134         type *dst = (type *) cvt->buf; \
  1135         for (i = cvt->len_cvt / (sizeof (type) * 12); i; --i) { \
  1136             dst[0] = src[0]; \
  1137             dst[1] = src[1]; \
  1138             dst[2] = src[2]; \
  1139             dst[3] = src[3]; \
  1140             dst[4] = src[4]; \
  1141             dst[5] = src[5]; \
  1142             src += 12; \
  1143             dst += 6; \
  1144         } \
  1145     }
  1146 
  1147     switch (SDL_AUDIO_BITSIZE(format)) {
  1148     case 8:
  1149         div2_chansix(Uint8);
  1150         break;
  1151     case 16:
  1152         div2_chansix(Uint16);
  1153         break;
  1154     case 32:
  1155         div2_chansix(Uint32);
  1156         break;
  1157     }
  1158 
  1159 #undef div_chansix
  1160 
  1161     cvt->len_cvt /= 2;
  1162     if (cvt->filters[++cvt->filter_index]) {
  1163         cvt->filters[cvt->filter_index] (cvt, format);
  1164     }
  1165 }
  1166 
  1167 /* Very slow rate conversion routine */
  1168 static void SDLCALL
  1169 SDL_RateSLOW(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1170 {
  1171     double ipos;
  1172     int i, clen;
  1173 
  1174 #ifdef DEBUG_CONVERT
  1175     fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0 / cvt->rate_incr);
  1176 #endif
  1177     clen = (int) ((double) cvt->len_cvt / cvt->rate_incr);
  1178     if (cvt->rate_incr > 1.0) {
  1179         switch (SDL_AUDIO_BITSIZE(format)) {
  1180         case 8:
  1181             {
  1182                 Uint8 *output;
  1183 
  1184                 output = cvt->buf;
  1185                 ipos = 0.0;
  1186                 for (i = clen; i; --i) {
  1187                     *output = cvt->buf[(int) ipos];
  1188                     ipos += cvt->rate_incr;
  1189                     output += 1;
  1190                 }
  1191             }
  1192             break;
  1193 
  1194         case 16:
  1195             {
  1196                 Uint16 *output;
  1197 
  1198                 clen &= ~1;
  1199                 output = (Uint16 *) cvt->buf;
  1200                 ipos = 0.0;
  1201                 for (i = clen / 2; i; --i) {
  1202                     *output = ((Uint16 *) cvt->buf)[(int) ipos];
  1203                     ipos += cvt->rate_incr;
  1204                     output += 1;
  1205                 }
  1206             }
  1207             break;
  1208 
  1209         case 32:
  1210             {
  1211                 /* !!! FIXME: need 32-bit converter here! */
  1212 #ifdef DEBUG_CONVERT
  1213                 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
  1214 #endif
  1215             }
  1216         }
  1217     } else {
  1218         switch (SDL_AUDIO_BITSIZE(format)) {
  1219         case 8:
  1220             {
  1221                 Uint8 *output;
  1222 
  1223                 output = cvt->buf + clen;
  1224                 ipos = (double) cvt->len_cvt;
  1225                 for (i = clen; i; --i) {
  1226                     ipos -= cvt->rate_incr;
  1227                     output -= 1;
  1228                     *output = cvt->buf[(int) ipos];
  1229                 }
  1230             }
  1231             break;
  1232 
  1233         case 16:
  1234             {
  1235                 Uint16 *output;
  1236 
  1237                 clen &= ~1;
  1238                 output = (Uint16 *) (cvt->buf + clen);
  1239                 ipos = (double) cvt->len_cvt / 2;
  1240                 for (i = clen / 2; i; --i) {
  1241                     ipos -= cvt->rate_incr;
  1242                     output -= 1;
  1243                     *output = ((Uint16 *) cvt->buf)[(int) ipos];
  1244                 }
  1245             }
  1246             break;
  1247 
  1248         case 32:
  1249             {
  1250                 /* !!! FIXME: need 32-bit converter here! */
  1251 #ifdef DEBUG_CONVERT
  1252                 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
  1253 #endif
  1254             }
  1255         }
  1256     }
  1257 
  1258     cvt->len_cvt = clen;
  1259     if (cvt->filters[++cvt->filter_index]) {
  1260         cvt->filters[cvt->filter_index] (cvt, format);
  1261     }
  1262 }
  1263 
  1264 int
  1265 SDL_ConvertAudio(SDL_AudioCVT * cvt)
  1266 {
  1267     /* Make sure there's data to convert */
  1268     if (cvt->buf == NULL) {
  1269         SDL_SetError("No buffer allocated for conversion");
  1270         return (-1);
  1271     }
  1272     /* Return okay if no conversion is necessary */
  1273     cvt->len_cvt = cvt->len;
  1274     if (cvt->filters[0] == NULL) {
  1275         return (0);
  1276     }
  1277 
  1278     /* Set up the conversion and go! */
  1279     cvt->filter_index = 0;
  1280     cvt->filters[0] (cvt, cvt->src_format);
  1281     return (0);
  1282 }
  1283 
  1284 
  1285 static SDL_AudioFilter
  1286 SDL_HandTunedTypeCVT(SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
  1287 {
  1288     /*
  1289      * Fill in any future conversions that are specialized to a
  1290      *  processor, platform, compiler, or library here.
  1291      */
  1292 
  1293     return NULL;                /* no specialized converter code available. */
  1294 }
  1295 
  1296 
  1297 /*
  1298  * Find a converter between two data types. We try to select a hand-tuned
  1299  *  asm/vectorized/optimized function first, and then fallback to an
  1300  *  autogenerated function that is customized to convert between two
  1301  *  specific data types.
  1302  */
  1303 static int
  1304 SDL_BuildAudioTypeCVT(SDL_AudioCVT * cvt,
  1305                       SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
  1306 {
  1307     if (src_fmt != dst_fmt) {
  1308         const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt);
  1309         const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt);
  1310         SDL_AudioFilter filter = SDL_HandTunedTypeCVT(src_fmt, dst_fmt);
  1311 
  1312         /* No hand-tuned converter? Try the autogenerated ones. */
  1313         if (filter == NULL) {
  1314             int i;
  1315             for (i = 0; sdl_audio_type_filters[i].filter != NULL; i++) {
  1316                 const SDL_AudioTypeFilters *filt = &sdl_audio_type_filters[i];
  1317                 if ((filt->src_fmt == src_fmt) && (filt->dst_fmt == dst_fmt)) {
  1318                     filter = filt->filter;
  1319                     break;
  1320                 }
  1321             }
  1322 
  1323             if (filter == NULL) {
  1324                 return -1;      /* Still no matching converter?! */
  1325             }
  1326         }
  1327 
  1328         /* Update (cvt) with filter details... */
  1329         cvt->filters[cvt->filter_index++] = filter;
  1330         if (src_bitsize < dst_bitsize) {
  1331             const int mult = (dst_bitsize / src_bitsize);
  1332             cvt->len_mult *= mult;
  1333             cvt->len_ratio *= mult;
  1334         } else if (src_bitsize > dst_bitsize) {
  1335             cvt->len_ratio /= (src_bitsize / dst_bitsize);
  1336         }
  1337 
  1338         return 1;               /* added a converter. */
  1339     }
  1340 
  1341     return 0;                   /* no conversion necessary. */
  1342 }
  1343 
  1344 /* Generate the necessary IIR lowpass coefficients for resampling.
  1345    Assume that the SDL_AudioCVT struct is already set up with
  1346    the correct values for len_mult and len_div, and use the
  1347    type of dst_format. Also assume the buffer is allocated.
  1348    Note the buffer needs to be 6 units long.
  1349    For now, use RBJ's cookbook coefficients. It might be more
  1350    optimal to create a Butterworth filter, but this is more difficult.
  1351 */
  1352 #if 0
  1353 int
  1354 SDL_BuildIIRLowpass(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1355 {
  1356     float fc;                   /* cutoff frequency */
  1357     float coeff[6];             /* floating point iir coefficients b0, b1, b2, a0, a1, a2 */
  1358     float scale;
  1359     float w0, alpha, cosw0;
  1360     int i;
  1361 
  1362     /* The higher Q is, the higher CUTOFF can be. Need to find a good balance to avoid aliasing */
  1363     static const float Q = 5.0f;
  1364     static const float CUTOFF = 0.4f;
  1365 
  1366     fc = (cvt->len_mult >
  1367           cvt->len_div) ? CUTOFF / (float) cvt->len_mult : CUTOFF /
  1368         (float) cvt->len_div;
  1369 
  1370     w0 = 2.0f * M_PI * fc;
  1371     cosw0 = cosf(w0);
  1372     alpha = sinf(w0) / (2.0f * Q);
  1373 
  1374     /* Compute coefficients, normalizing by a0 */
  1375     scale = 1.0f / (1.0f + alpha);
  1376 
  1377     coeff[0] = (1.0f - cosw0) / 2.0f * scale;
  1378     coeff[1] = (1.0f - cosw0) * scale;
  1379     coeff[2] = coeff[0];
  1380 
  1381     coeff[3] = 1.0f;            /* a0 is normalized to 1 */
  1382     coeff[4] = -2.0f * cosw0 * scale;
  1383     coeff[5] = (1.0f - alpha) * scale;
  1384 
  1385     /* Copy the coefficients to the struct. If necessary, convert coefficients to fixed point, using the range (-2.0, 2.0) */
  1386 #define convert_fixed(type, fix) { \
  1387             type *cvt_coeff = (type *)cvt->coeff; \
  1388             for(i = 0; i < 6; ++i) { \
  1389                 cvt_coeff[i] = fix(coeff[i]); \
  1390             } \
  1391         }
  1392 
  1393     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
  1394         float *cvt_coeff = (float *) cvt->coeff;
  1395         for (i = 0; i < 6; ++i) {
  1396             cvt_coeff[i] = coeff[i];
  1397         }
  1398     } else {
  1399         switch (SDL_AUDIO_BITSIZE(format)) {
  1400         case 8:
  1401             convert_fixed(Uint8, SDL_Make_2_6);
  1402             break;
  1403         case 16:
  1404             convert_fixed(Uint16, SDL_Make_2_14);
  1405             break;
  1406         case 32:
  1407             convert_fixed(Uint32, SDL_Make_2_30);
  1408             break;
  1409         }
  1410     }
  1411 
  1412 #ifdef DEBUG_CONVERT
  1413 #define debug_iir(type) { \
  1414             type *cvt_coeff = (type *)cvt->coeff; \
  1415             for(i = 0; i < 6; ++i) { \
  1416                 printf("coeff[%u] = %f = 0x%x\n", i, coeff[i], cvt_coeff[i]); \
  1417             } \
  1418         }
  1419     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
  1420         float *cvt_coeff = (float *) cvt->coeff;
  1421         for (i = 0; i < 6; ++i) {
  1422             printf("coeff[%u] = %f = %f\n", i, coeff[i], cvt_coeff[i]);
  1423         }
  1424     } else {
  1425         switch (SDL_AUDIO_BITSIZE(format)) {
  1426         case 8:
  1427             debug_iir(Uint8);
  1428             break;
  1429         case 16:
  1430             debug_iir(Uint16);
  1431             break;
  1432         case 32:
  1433             debug_iir(Uint32);
  1434             break;
  1435         }
  1436     }
  1437 #undef debug_iir
  1438 #endif
  1439 
  1440     /* Initialize the state buffer to all zeroes, and set initial position */
  1441     SDL_memset(cvt->state_buf, 0, 4 * SDL_AUDIO_BITSIZE(format) / 4);
  1442     cvt->state_pos = 0;
  1443 #undef convert_fixed
  1444 
  1445     return 0;
  1446 }
  1447 #endif
  1448 
  1449 /* Apply the lowpass IIR filter to the given SDL_AudioCVT struct */
  1450 /* This was implemented because it would be much faster than the fir filter, 
  1451    but it doesn't seem to have a steep enough cutoff so we'd need several
  1452    cascaded biquads, which probably isn't a great idea. Therefore, this
  1453    function can probably be discarded.
  1454 */
  1455 static void
  1456 SDL_FilterIIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1457 {
  1458     Uint32 i, n;
  1459 
  1460     /* TODO: Check that n is calculated right */
  1461     n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
  1462 
  1463     /* Note that the coefficients are 2_x and the input is 1_x. Do we need to shift left at the end here? The right shift temp = buf[n] >> 1 needs to depend on whether the type is signed or not for sign extension. */
  1464     /* cvt->state_pos = 1: state[0] = x_n-1, state[1] = x_n-2, state[2] = y_n-1, state[3] - y_n-2 */
  1465 #define iir_fix(type, mult) {\
  1466             type *coeff = (type *)cvt->coeff; \
  1467             type *state = (type *)cvt->state_buf; \
  1468             type *buf = (type *)cvt->buf; \
  1469             type temp; \
  1470             for(i = 0; i < n; ++i) { \
  1471                     temp = buf[i] >> 1; \
  1472                     if(cvt->state_pos) { \
  1473                         buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[0]) + mult(coeff[2], state[1]) - mult(coeff[4], state[2]) - mult(coeff[5], state[3]); \
  1474                         state[1] = temp; \
  1475                         state[3] = buf[i]; \
  1476                         cvt->state_pos = 0; \
  1477                     } else { \
  1478                         buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[1]) + mult(coeff[2], state[0]) - mult(coeff[4], state[3]) - mult(coeff[5], state[2]); \
  1479                         state[0] = temp; \
  1480                         state[2] = buf[i]; \
  1481                         cvt->state_pos = 1; \
  1482                     } \
  1483                 } \
  1484         }
  1485 /* Need to test to see if the previous method or this one is faster */
  1486 /*#define iir_fix(type, mult) {\
  1487             type *coeff = (type *)cvt->coeff; \
  1488             type *state = (type *)cvt->state_buf; \
  1489             type *buf = (type *)cvt->buf; \
  1490             type temp; \
  1491             for(i = 0; i < n; ++i) { \
  1492                     temp = buf[i] >> 1; \
  1493                     buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[0]) + mult(coeff[2], state[1]) - mult(coeff[4], state[2]) - mult(coeff[5], state[3]); \
  1494                     state[1] = state[0]; \
  1495                     state[0] = temp; \
  1496                     state[3] = state[2]; \
  1497                     state[2] = buf[i]; \
  1498                 } \
  1499         }*/
  1500 
  1501     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
  1502         float *coeff = (float *) cvt->coeff;
  1503         float *state = (float *) cvt->state_buf;
  1504         float *buf = (float *) cvt->buf;
  1505         float temp;
  1506 
  1507         for (i = 0; i < n; ++i) {
  1508             /* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a[2] * y[n-2] */
  1509             temp = buf[i];
  1510             if (cvt->state_pos) {
  1511                 buf[i] =
  1512                     coeff[0] * buf[n] + coeff[1] * state[0] +
  1513                     coeff[2] * state[1] - coeff[4] * state[2] -
  1514                     coeff[5] * state[3];
  1515                 state[1] = temp;
  1516                 state[3] = buf[i];
  1517                 cvt->state_pos = 0;
  1518             } else {
  1519                 buf[i] =
  1520                     coeff[0] * buf[n] + coeff[1] * state[1] +
  1521                     coeff[2] * state[0] - coeff[4] * state[3] -
  1522                     coeff[5] * state[2];
  1523                 state[0] = temp;
  1524                 state[2] = buf[i];
  1525                 cvt->state_pos = 1;
  1526             }
  1527         }
  1528     } else {
  1529         /* Treat everything as signed! */
  1530         switch (SDL_AUDIO_BITSIZE(format)) {
  1531         case 8:
  1532             iir_fix(Sint8, SDL_FixMpy8);
  1533             break;
  1534         case 16:
  1535             iir_fix(Sint16, SDL_FixMpy16);
  1536             break;
  1537         case 32:
  1538             iir_fix(Sint32, SDL_FixMpy32);
  1539             break;
  1540         }
  1541     }
  1542 #undef iir_fix
  1543 }
  1544 
  1545 /* Apply the windowed sinc FIR filter to the given SDL_AudioCVT struct.
  1546 */
  1547 static void
  1548 SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1549 {
  1550     /* !!! FIXME: (n) is incorrect, or my allocation of state_buf is wrong. */
  1551     const int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
  1552     int m = cvt->len_sinc;
  1553     int i, j;
  1554 
  1555     /* 
  1556        Note: We can make a big optimization here by taking advantage
  1557        of the fact that the signal is zero stuffed, so we can do
  1558        significantly fewer multiplications and additions. However, this
  1559        depends on the zero stuffing ratio, so it may not pay off. This would
  1560        basically be a polyphase filter.
  1561      */
  1562     /* One other way to do this fast is to look at the fir filter from a different angle:
  1563        After we zero stuff, we have input of all zeroes, except for every len_mult
  1564        sample. If we choose a sinc length equal to len_mult, then the fir filter becomes
  1565        much more simple: we're just taking a windowed sinc, shifting it to start at each
  1566        len_mult sample, and scaling it by the value of that sample. If we do this, then
  1567        we don't even need to worry about the sample histories, and the inner loop here is
  1568        unnecessary. This probably sacrifices some quality but could really speed things up as well.
  1569      */
  1570     /* We only calculate the values of samples which are 0 (mod len_div) because
  1571        those are the only ones used. All the other ones are discarded in the
  1572        third step of resampling. This is a huge speedup. As a warning, though,
  1573        if for some reason this is used elsewhere where there are no samples discarded,
  1574        the output will not be corrrect if len_div is not 1. To make this filter a
  1575        generic FIR filter, simply remove the if statement "if(i % cvt->len_div == 0)"
  1576        around the inner loop so that every sample is processed.
  1577      */
  1578     /* This is basically just a FIR filter. i.e. for input x_n and m coefficients,
  1579        y_n = x_n*sinc_0 + x_(n-1)*sinc_1 +  x_(n-2)*sinc_2 + ... + x_(n-m+1)*sinc_(m-1)
  1580      */
  1581 #define filter_sinc(type, mult) { \
  1582             type *sinc = (type *)cvt->coeff; \
  1583             type *state = (type *)cvt->state_buf; \
  1584             type *buf = (type *)cvt->buf; \
  1585             for(i = 0; i < n; ++i) { \
  1586                 state[cvt->state_pos] = buf[i]; \
  1587                 buf[i] = 0; \
  1588                 if( i % cvt->len_div == 0 ) { \
  1589                     for(j = 0; j < m;  ++j) { \
  1590                         buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
  1591                     } \
  1592                 }\
  1593                 cvt->state_pos = (cvt->state_pos + 1) % m; \
  1594             } \
  1595         }
  1596 
  1597     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
  1598         filter_sinc(float, SDL_FloatMpy);
  1599     } else {
  1600         switch (SDL_AUDIO_BITSIZE(format)) {
  1601         case 8:
  1602             filter_sinc(Sint8, SDL_FixMpy8);
  1603             break;
  1604         case 16:
  1605             filter_sinc(Sint16, SDL_FixMpy16);
  1606             break;
  1607         case 32:
  1608             filter_sinc(Sint32, SDL_FixMpy32);
  1609             break;
  1610         }
  1611     }
  1612 
  1613 #undef filter_sinc
  1614 
  1615 }
  1616 
  1617 /* Generate the necessary windowed sinc filter for resampling.
  1618    Assume that the SDL_AudioCVT struct is already set up with
  1619    the correct values for len_mult and len_div, and use the
  1620    type of dst_format. Also assume the buffer is allocated.
  1621    Note the buffer needs to be m+1 units long.
  1622 */
  1623 int
  1624 SDL_BuildWindowedSinc(SDL_AudioCVT * cvt, SDL_AudioFormat format,
  1625                       unsigned int m)
  1626 {
  1627     float *fSinc;               /* floating point sinc buffer, to be converted to fixed point */
  1628     float fc;                   /* cutoff frequency */
  1629     float two_pi_fc, two_pi_over_m, four_pi_over_m, m_over_two;
  1630     float norm_sum, norm_fact;
  1631     unsigned int i;
  1632 
  1633     /* Set the length */
  1634     cvt->len_sinc = m + 1;
  1635 
  1636     /* Allocate the floating point windowed sinc. */
  1637     fSinc = SDL_stack_alloc(float, (m + 1));
  1638     if (fSinc == NULL) {
  1639         return -1;
  1640     }
  1641 
  1642     /* Set up the filter parameters */
  1643     fc = (cvt->len_mult >
  1644           cvt->len_div) ? 0.5f / (float) cvt->len_mult : 0.5f /
  1645         (float) cvt->len_div;
  1646 #ifdef DEBUG_CONVERT
  1647     printf("Lowpass cutoff frequency = %f\n", fc);
  1648 #endif
  1649     two_pi_fc = 2.0f * M_PI * fc;
  1650     two_pi_over_m = 2.0f * M_PI / (float) m;
  1651     four_pi_over_m = 2.0f * two_pi_over_m;
  1652     m_over_two = (float) m / 2.0f;
  1653     norm_sum = 0.0f;
  1654 
  1655     for (i = 0; i <= m; ++i) {
  1656         if (i == m / 2) {
  1657             fSinc[i] = two_pi_fc;
  1658         } else {
  1659             fSinc[i] = SDL_sinf(two_pi_fc * ((float) i - m_over_two)) / ((float) i - m_over_two);
  1660             /* Apply blackman window */
  1661             fSinc[i] *= 0.42f - 0.5f * SDL_cosf(two_pi_over_m * (float) i) + 0.08f * SDL_cosf(four_pi_over_m * (float) i);
  1662         }
  1663         norm_sum += fSinc[i] < 0 ? -fSinc[i] : fSinc[i];        /* fabs(fSinc[i]); */
  1664     }
  1665 
  1666     norm_fact = 1.0f / norm_sum;
  1667 
  1668 #define convert_fixed(type, fix) { \
  1669         type *dst = (type *)cvt->coeff; \
  1670         for( i = 0; i <= m; ++i ) { \
  1671             dst[i] = fix(fSinc[i] * norm_fact); \
  1672         } \
  1673     }
  1674 
  1675     /* !!! FIXME: this memory leaks. */
  1676     cvt->coeff =
  1677         (Uint8 *) SDL_malloc((SDL_AUDIO_BITSIZE(format) / 8) * (m + 1));
  1678     if (cvt->coeff == NULL) {
  1679         return -1;
  1680     }
  1681 
  1682     /* If we're using floating point, we only need to normalize */
  1683     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
  1684         float *fDest = (float *) cvt->coeff;
  1685         for (i = 0; i <= m; ++i) {
  1686             fDest[i] = fSinc[i] * norm_fact;
  1687         }
  1688     } else {
  1689         switch (SDL_AUDIO_BITSIZE(format)) {
  1690         case 8:
  1691             convert_fixed(Uint8, SDL_Make_1_7);
  1692             break;
  1693         case 16:
  1694             convert_fixed(Uint16, SDL_Make_1_15);
  1695             break;
  1696         case 32:
  1697             convert_fixed(Uint32, SDL_Make_1_31);
  1698             break;
  1699         }
  1700     }
  1701 
  1702     /* Initialize the state buffer to all zeroes, and set initial position */
  1703     /* !!! FIXME: this memory leaks. */
  1704     cvt->state_buf =
  1705         (Uint8 *) SDL_malloc(cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
  1706     if (cvt->state_buf == NULL) {
  1707         return -1;
  1708     }
  1709     SDL_memset(cvt->state_buf, 0,
  1710                cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
  1711     cvt->state_pos = 0;
  1712 
  1713     /* Clean up */
  1714 #undef convert_fixed
  1715     SDL_stack_free(fSinc);
  1716 
  1717     return 0;
  1718 }
  1719 
  1720 /* This is used to reduce the resampling ratio */
  1721 static __inline__ int
  1722 SDL_GCD(int a, int b)
  1723 {
  1724     int temp;
  1725     while (b != 0) {
  1726         temp = a % b;
  1727         a = b;
  1728         b = temp;
  1729     }
  1730     return a;
  1731 }
  1732 
  1733 /* Perform proper resampling. This is pretty slow but it's the best-sounding method. */
  1734 static void SDLCALL
  1735 SDL_Resample(SDL_AudioCVT * cvt, SDL_AudioFormat format)
  1736 {
  1737     int i;
  1738 
  1739 #ifdef DEBUG_CONVERT
  1740     printf("Converting audio rate via proper resampling (mono)\n");
  1741 #endif
  1742 
  1743 #define zerostuff_mono(type) { \
  1744         const type *src = (const type *) (cvt->buf + cvt->len); \
  1745         type *dst = (type *) (cvt->buf + (cvt->len * cvt->len_mult)); \
  1746         for (i = cvt->len / sizeof (type); i; --i) { \
  1747             src--; \
  1748             dst[-1] = src[0]; \
  1749             if (cvt->len_mult > 1) { \
  1750                 SDL_memset(dst-cvt->len_mult, 0, cvt->len_mult-1); \
  1751             } \
  1752             dst -= cvt->len_mult; \
  1753         } \
  1754     }
  1755 
  1756 #define discard_mono(type) { \
  1757         const type *src = (const type *) (cvt->buf); \
  1758         type *dst = (type *) (cvt->buf); \
  1759         for (i = 0; i < (cvt->len_cvt / sizeof(type)) / cvt->len_div; ++i) { \
  1760             dst[0] = src[0]; \
  1761             src += cvt->len_div; \
  1762             ++dst; \
  1763         } \
  1764     }
  1765 
  1766     /* Step 1: Zero stuff the conversion buffer. This upsamples by a factor of len_mult,
  1767        creating aliasing at frequencies above the original nyquist frequency.
  1768      */
  1769 #ifdef DEBUG_CONVERT
  1770     printf("Zero-stuffing by a factor of %u\n", cvt->len_mult);
  1771 #endif
  1772     switch (SDL_AUDIO_BITSIZE(format)) {
  1773     case 8:
  1774         zerostuff_mono(Uint8);
  1775         break;
  1776     case 16:
  1777         zerostuff_mono(Uint16);
  1778         break;
  1779     case 32:
  1780         zerostuff_mono(Uint32);
  1781         break;
  1782     }
  1783 
  1784     cvt->len_cvt *= cvt->len_mult;
  1785 
  1786     /* Step 2: Use a windowed sinc FIR filter (lowpass filter) to remove the alias
  1787        frequencies. This is the slow part.
  1788      */
  1789     SDL_FilterFIR(cvt, format);
  1790 
  1791     /* Step 3: Now downsample by discarding samples. */
  1792 
  1793 #ifdef DEBUG_CONVERT
  1794     printf("Discarding samples by a factor of %u\n", cvt->len_div);
  1795 #endif
  1796     switch (SDL_AUDIO_BITSIZE(format)) {
  1797     case 8:
  1798         discard_mono(Uint8);
  1799         break;
  1800     case 16:
  1801         discard_mono(Uint16);
  1802         break;
  1803     case 32:
  1804         discard_mono(Uint32);
  1805         break;
  1806     }
  1807 
  1808 #undef zerostuff_mono
  1809 #undef discard_mono
  1810 
  1811     cvt->len_cvt /= cvt->len_div;
  1812 
  1813     if (cvt->filters[++cvt->filter_index]) {
  1814         cvt->filters[cvt->filter_index] (cvt, format);
  1815     }
  1816 }
  1817 
  1818 
  1819 /* Creates a set of audio filters to convert from one format to another.
  1820    Returns -1 if the format conversion is not supported, 0 if there's
  1821    no conversion needed, or 1 if the audio filter is set up.
  1822 */
  1823 
  1824 int
  1825 SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
  1826                   SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
  1827                   SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
  1828 {
  1829     /* there are no unsigned types over 16 bits, so catch this upfront. */
  1830     if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
  1831         return -1;
  1832     }
  1833     if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
  1834         return -1;
  1835     }
  1836 #ifdef DEBUG_CONVERT
  1837     printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
  1838            src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
  1839 #endif
  1840 
  1841     /* Start off with no conversion necessary */
  1842     SDL_zerop(cvt);
  1843     cvt->src_format = src_fmt;
  1844     cvt->dst_format = dst_fmt;
  1845     cvt->needed = 0;
  1846     cvt->filter_index = 0;
  1847     cvt->filters[0] = NULL;
  1848     cvt->len_mult = 1;
  1849     cvt->len_ratio = 1.0;
  1850 
  1851     /* Convert data types, if necessary. Updates (cvt). */
  1852     if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1)
  1853         return -1;              /* shouldn't happen, but just in case... */
  1854 
  1855     /* Channel conversion */
  1856     if (src_channels != dst_channels) {
  1857         if ((src_channels == 1) && (dst_channels > 1)) {
  1858             cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
  1859             cvt->len_mult *= 2;
  1860             src_channels = 2;
  1861             cvt->len_ratio *= 2;
  1862         }
  1863         if ((src_channels == 2) && (dst_channels == 6)) {
  1864             cvt->filters[cvt->filter_index++] = SDL_ConvertSurround;
  1865             src_channels = 6;
  1866             cvt->len_mult *= 3;
  1867             cvt->len_ratio *= 3;
  1868         }
  1869         if ((src_channels == 2) && (dst_channels == 4)) {
  1870             cvt->filters[cvt->filter_index++] = SDL_ConvertSurround_4;
  1871             src_channels = 4;
  1872             cvt->len_mult *= 2;
  1873             cvt->len_ratio *= 2;
  1874         }
  1875         while ((src_channels * 2) <= dst_channels) {
  1876             cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
  1877             cvt->len_mult *= 2;
  1878             src_channels *= 2;
  1879             cvt->len_ratio *= 2;
  1880         }
  1881         if ((src_channels == 6) && (dst_channels <= 2)) {
  1882             cvt->filters[cvt->filter_index++] = SDL_ConvertStrip;
  1883             src_channels = 2;
  1884             cvt->len_ratio /= 3;
  1885         }
  1886         if ((src_channels == 6) && (dst_channels == 4)) {
  1887             cvt->filters[cvt->filter_index++] = SDL_ConvertStrip_2;
  1888             src_channels = 4;
  1889             cvt->len_ratio /= 2;
  1890         }
  1891         /* This assumes that 4 channel audio is in the format:
  1892            Left {front/back} + Right {front/back}
  1893            so converting to L/R stereo works properly.
  1894          */
  1895         while (((src_channels % 2) == 0) &&
  1896                ((src_channels / 2) >= dst_channels)) {
  1897             cvt->filters[cvt->filter_index++] = SDL_ConvertMono;
  1898             src_channels /= 2;
  1899             cvt->len_ratio /= 2;
  1900         }
  1901         if (src_channels != dst_channels) {
  1902             /* Uh oh.. */ ;
  1903         }
  1904     }
  1905 
  1906     /* Do rate conversion */
  1907     if (src_rate != dst_rate) {
  1908         int rate_gcd;
  1909         rate_gcd = SDL_GCD(src_rate, dst_rate);
  1910         cvt->len_mult = dst_rate / rate_gcd;
  1911         cvt->len_div = src_rate / rate_gcd;
  1912         cvt->len_ratio = (double) cvt->len_mult / (double) cvt->len_div;
  1913         cvt->filters[cvt->filter_index++] = SDL_Resample;
  1914         /* !!! FIXME: check return value. */
  1915         SDL_BuildWindowedSinc(cvt, dst_fmt, 768);
  1916     }
  1917 
  1918 /*
  1919     cvt->rate_incr = 0.0;
  1920     if ((src_rate / 100) != (dst_rate / 100)) {
  1921         Uint32 hi_rate, lo_rate;
  1922         int len_mult;
  1923         double len_ratio;
  1924         SDL_AudioFilter rate_cvt = NULL;
  1925 
  1926         if (src_rate > dst_rate) {
  1927             hi_rate = src_rate;
  1928             lo_rate = dst_rate;
  1929             switch (src_channels) {
  1930             case 1:
  1931                 rate_cvt = SDL_RateDIV2;
  1932                 break;
  1933             case 2:
  1934                 rate_cvt = SDL_RateDIV2_c2;
  1935                 break;
  1936             case 4:
  1937                 rate_cvt = SDL_RateDIV2_c4;
  1938                 break;
  1939             case 6:
  1940                 rate_cvt = SDL_RateDIV2_c6;
  1941                 break;
  1942             default:
  1943                 return -1;
  1944             }
  1945             len_mult = 1;
  1946             len_ratio = 0.5;
  1947         } else {
  1948             hi_rate = dst_rate;
  1949             lo_rate = src_rate;
  1950             switch (src_channels) {
  1951             case 1:
  1952                 rate_cvt = SDL_RateMUL2;
  1953                 break;
  1954             case 2:
  1955                 rate_cvt = SDL_RateMUL2_c2;
  1956                 break;
  1957             case 4:
  1958                 rate_cvt = SDL_RateMUL2_c4;
  1959                 break;
  1960             case 6:
  1961                 rate_cvt = SDL_RateMUL2_c6;
  1962                 break;
  1963             default:
  1964                 return -1;
  1965             }
  1966             len_mult = 2;
  1967             len_ratio = 2.0;
  1968         }*/
  1969     /* If hi_rate = lo_rate*2^x then conversion is easy */
  1970     /*   while (((lo_rate * 2) / 100) <= (hi_rate / 100)) {
  1971        cvt->filters[cvt->filter_index++] = rate_cvt;
  1972        cvt->len_mult *= len_mult;
  1973        lo_rate *= 2;
  1974        cvt->len_ratio *= len_ratio;
  1975        } */
  1976     /* We may need a slow conversion here to finish up */
  1977     /*    if ((lo_rate / 100) != (hi_rate / 100)) {
  1978        #if 1 */
  1979     /* The problem with this is that if the input buffer is
  1980        say 1K, and the conversion rate is say 1.1, then the
  1981        output buffer is 1.1K, which may not be an acceptable
  1982        buffer size for the audio driver (not a power of 2)
  1983      */
  1984     /* For now, punt and hope the rate distortion isn't great.
  1985      */
  1986 /*#else
  1987             if (src_rate < dst_rate) {
  1988                 cvt->rate_incr = (double) lo_rate / hi_rate;
  1989                 cvt->len_mult *= 2;
  1990                 cvt->len_ratio /= cvt->rate_incr;
  1991             } else {
  1992                 cvt->rate_incr = (double) hi_rate / lo_rate;
  1993                 cvt->len_ratio *= cvt->rate_incr;
  1994             }
  1995             cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
  1996 #endif
  1997         }
  1998     }*/
  1999 
  2000     /* Set up the filter information */
  2001     if (cvt->filter_index != 0) {
  2002         cvt->needed = 1;
  2003         cvt->src_format = src_fmt;
  2004         cvt->dst_format = dst_fmt;
  2005         cvt->len = 0;
  2006         cvt->buf = NULL;
  2007         cvt->filters[cvt->filter_index] = NULL;
  2008     }
  2009     return (cvt->needed);
  2010 }
  2011 
  2012 #undef SDL_FixMpy8
  2013 #undef SDL_FixMpy16
  2014 #undef SDL_FixMpy32
  2015 #undef SDL_FloatMpy
  2016 #undef SDL_Make_1_7
  2017 #undef SDL_Make_1_15
  2018 #undef SDL_Make_1_31
  2019 #undef SDL_Make_2_6
  2020 #undef SDL_Make_2_14
  2021 #undef SDL_Make_2_30
  2022 
  2023 /* vi: set ts=4 sw=4 expandtab: */