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