src/audio/SDL_audiocvt.c
author Ryan C. Gordon <icculus@icculus.org>
Fri, 19 Dec 2008 08:30:26 +0000
changeset 2880 3c2f56e433a8
parent 2879 3ff86c46d324
child 2881 c8d203ef4335
permissions -rw-r--r--
Allocate SDL_AudioCVT::coeff before using it.

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