src/audio/SDL_audiocvt.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 10 Jul 2006 21:04:37 +0000
changeset 1895 c121d94672cb
parent 1769 290b5baf2fca
child 1982 3b4ce57c6215
permissions -rw-r--r--
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
     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 
    24 /* Functions for audio drivers to perform runtime conversion of audio format */
    25 
    26 #include "SDL_audio.h"
    27 
    28 
    29 /* Effectively mix right and left channels into a single channel */
    30 void SDLCALL
    31 SDL_ConvertMono(SDL_AudioCVT * cvt, Uint16 format)
    32 {
    33     int i;
    34     Sint32 sample;
    35 
    36 #ifdef DEBUG_CONVERT
    37     fprintf(stderr, "Converting to mono\n");
    38 #endif
    39     switch (format & 0x8018) {
    40 
    41     case AUDIO_U8:
    42         {
    43             Uint8 *src, *dst;
    44 
    45             src = cvt->buf;
    46             dst = cvt->buf;
    47             for (i = cvt->len_cvt / 2; i; --i) {
    48                 sample = src[0] + src[1];
    49                 if (sample > 255) {
    50                     *dst = 255;
    51                 } else {
    52                     *dst = (Uint8) sample;
    53                 }
    54                 src += 2;
    55                 dst += 1;
    56             }
    57         }
    58         break;
    59 
    60     case AUDIO_S8:
    61         {
    62             Sint8 *src, *dst;
    63 
    64             src = (Sint8 *) cvt->buf;
    65             dst = (Sint8 *) cvt->buf;
    66             for (i = cvt->len_cvt / 2; i; --i) {
    67                 sample = src[0] + src[1];
    68                 if (sample > 127) {
    69                     *dst = 127;
    70                 } else if (sample < -128) {
    71                     *dst = -128;
    72                 } else {
    73                     *dst = (Sint8) sample;
    74                 }
    75                 src += 2;
    76                 dst += 1;
    77             }
    78         }
    79         break;
    80 
    81     case AUDIO_U16:
    82         {
    83             Uint8 *src, *dst;
    84 
    85             src = cvt->buf;
    86             dst = cvt->buf;
    87             if ((format & 0x1000) == 0x1000) {
    88                 for (i = cvt->len_cvt / 4; i; --i) {
    89                     sample = (Uint16) ((src[0] << 8) | src[1]) +
    90                         (Uint16) ((src[2] << 8) | src[3]);
    91                     if (sample > 65535) {
    92                         dst[0] = 0xFF;
    93                         dst[1] = 0xFF;
    94                     } else {
    95                         dst[1] = (sample & 0xFF);
    96                         sample >>= 8;
    97                         dst[0] = (sample & 0xFF);
    98                     }
    99                     src += 4;
   100                     dst += 2;
   101                 }
   102             } else {
   103                 for (i = cvt->len_cvt / 4; i; --i) {
   104                     sample = (Uint16) ((src[1] << 8) | src[0]) +
   105                         (Uint16) ((src[3] << 8) | src[2]);
   106                     if (sample > 65535) {
   107                         dst[0] = 0xFF;
   108                         dst[1] = 0xFF;
   109                     } else {
   110                         dst[0] = (sample & 0xFF);
   111                         sample >>= 8;
   112                         dst[1] = (sample & 0xFF);
   113                     }
   114                     src += 4;
   115                     dst += 2;
   116                 }
   117             }
   118         }
   119         break;
   120 
   121     case AUDIO_S16:
   122         {
   123             Uint8 *src, *dst;
   124 
   125             src = cvt->buf;
   126             dst = cvt->buf;
   127             if ((format & 0x1000) == 0x1000) {
   128                 for (i = cvt->len_cvt / 4; i; --i) {
   129                     sample = (Sint16) ((src[0] << 8) | src[1]) +
   130                         (Sint16) ((src[2] << 8) | src[3]);
   131                     if (sample > 32767) {
   132                         dst[0] = 0x7F;
   133                         dst[1] = 0xFF;
   134                     } else if (sample < -32768) {
   135                         dst[0] = 0x80;
   136                         dst[1] = 0x00;
   137                     } else {
   138                         dst[1] = (sample & 0xFF);
   139                         sample >>= 8;
   140                         dst[0] = (sample & 0xFF);
   141                     }
   142                     src += 4;
   143                     dst += 2;
   144                 }
   145             } else {
   146                 for (i = cvt->len_cvt / 4; i; --i) {
   147                     sample = (Sint16) ((src[1] << 8) | src[0]) +
   148                         (Sint16) ((src[3] << 8) | src[2]);
   149                     if (sample > 32767) {
   150                         dst[1] = 0x7F;
   151                         dst[0] = 0xFF;
   152                     } else if (sample < -32768) {
   153                         dst[1] = 0x80;
   154                         dst[0] = 0x00;
   155                     } else {
   156                         dst[0] = (sample & 0xFF);
   157                         sample >>= 8;
   158                         dst[1] = (sample & 0xFF);
   159                     }
   160                     src += 4;
   161                     dst += 2;
   162                 }
   163             }
   164         }
   165         break;
   166     }
   167     cvt->len_cvt /= 2;
   168     if (cvt->filters[++cvt->filter_index]) {
   169         cvt->filters[cvt->filter_index] (cvt, format);
   170     }
   171 }
   172 
   173 /* Discard top 4 channels */
   174 void SDLCALL
   175 SDL_ConvertStrip(SDL_AudioCVT * cvt, Uint16 format)
   176 {
   177     int i;
   178     Sint32 lsample, rsample;
   179 
   180 #ifdef DEBUG_CONVERT
   181     fprintf(stderr, "Converting down to stereo\n");
   182 #endif
   183     switch (format & 0x8018) {
   184 
   185     case AUDIO_U8:
   186         {
   187             Uint8 *src, *dst;
   188 
   189             src = cvt->buf;
   190             dst = cvt->buf;
   191             for (i = cvt->len_cvt / 6; i; --i) {
   192                 dst[0] = src[0];
   193                 dst[1] = src[1];
   194                 src += 6;
   195                 dst += 2;
   196             }
   197         }
   198         break;
   199 
   200     case AUDIO_S8:
   201         {
   202             Sint8 *src, *dst;
   203 
   204             src = (Sint8 *) cvt->buf;
   205             dst = (Sint8 *) cvt->buf;
   206             for (i = cvt->len_cvt / 6; i; --i) {
   207                 dst[0] = src[0];
   208                 dst[1] = src[1];
   209                 src += 6;
   210                 dst += 2;
   211             }
   212         }
   213         break;
   214 
   215     case AUDIO_U16:
   216         {
   217             Uint8 *src, *dst;
   218 
   219             src = cvt->buf;
   220             dst = cvt->buf;
   221             if ((format & 0x1000) == 0x1000) {
   222                 for (i = cvt->len_cvt / 12; i; --i) {
   223                     lsample = (Uint16) ((src[0] << 8) | src[1]);
   224                     rsample = (Uint16) ((src[2] << 8) | src[3]);
   225                     dst[1] = (lsample & 0xFF);
   226                     lsample >>= 8;
   227                     dst[0] = (lsample & 0xFF);
   228                     dst[3] = (rsample & 0xFF);
   229                     rsample >>= 8;
   230                     dst[2] = (rsample & 0xFF);
   231                     src += 12;
   232                     dst += 4;
   233                 }
   234             } else {
   235                 for (i = cvt->len_cvt / 12; i; --i) {
   236                     lsample = (Uint16) ((src[1] << 8) | src[0]);
   237                     rsample = (Uint16) ((src[3] << 8) | src[2]);
   238                     dst[0] = (lsample & 0xFF);
   239                     lsample >>= 8;
   240                     dst[1] = (lsample & 0xFF);
   241                     dst[2] = (rsample & 0xFF);
   242                     rsample >>= 8;
   243                     dst[3] = (rsample & 0xFF);
   244                     src += 12;
   245                     dst += 4;
   246                 }
   247             }
   248         }
   249         break;
   250 
   251     case AUDIO_S16:
   252         {
   253             Uint8 *src, *dst;
   254 
   255             src = cvt->buf;
   256             dst = cvt->buf;
   257             if ((format & 0x1000) == 0x1000) {
   258                 for (i = cvt->len_cvt / 12; i; --i) {
   259                     lsample = (Sint16) ((src[0] << 8) | src[1]);
   260                     rsample = (Sint16) ((src[2] << 8) | src[3]);
   261                     dst[1] = (lsample & 0xFF);
   262                     lsample >>= 8;
   263                     dst[0] = (lsample & 0xFF);
   264                     dst[3] = (rsample & 0xFF);
   265                     rsample >>= 8;
   266                     dst[2] = (rsample & 0xFF);
   267                     src += 12;
   268                     dst += 4;
   269                 }
   270             } else {
   271                 for (i = cvt->len_cvt / 12; i; --i) {
   272                     lsample = (Sint16) ((src[1] << 8) | src[0]);
   273                     rsample = (Sint16) ((src[3] << 8) | src[2]);
   274                     dst[0] = (lsample & 0xFF);
   275                     lsample >>= 8;
   276                     dst[1] = (lsample & 0xFF);
   277                     dst[2] = (rsample & 0xFF);
   278                     rsample >>= 8;
   279                     dst[3] = (rsample & 0xFF);
   280                     src += 12;
   281                     dst += 4;
   282                 }
   283             }
   284         }
   285         break;
   286     }
   287     cvt->len_cvt /= 3;
   288     if (cvt->filters[++cvt->filter_index]) {
   289         cvt->filters[cvt->filter_index] (cvt, format);
   290     }
   291 }
   292 
   293 
   294 /* Discard top 2 channels of 6 */
   295 void SDLCALL
   296 SDL_ConvertStrip_2(SDL_AudioCVT * cvt, Uint16 format)
   297 {
   298     int i;
   299     Sint32 lsample, rsample;
   300 
   301 #ifdef DEBUG_CONVERT
   302     fprintf(stderr, "Converting 6 down to quad\n");
   303 #endif
   304     switch (format & 0x8018) {
   305 
   306     case AUDIO_U8:
   307         {
   308             Uint8 *src, *dst;
   309 
   310             src = cvt->buf;
   311             dst = cvt->buf;
   312             for (i = cvt->len_cvt / 4; i; --i) {
   313                 dst[0] = src[0];
   314                 dst[1] = src[1];
   315                 src += 4;
   316                 dst += 2;
   317             }
   318         }
   319         break;
   320 
   321     case AUDIO_S8:
   322         {
   323             Sint8 *src, *dst;
   324 
   325             src = (Sint8 *) cvt->buf;
   326             dst = (Sint8 *) cvt->buf;
   327             for (i = cvt->len_cvt / 4; i; --i) {
   328                 dst[0] = src[0];
   329                 dst[1] = src[1];
   330                 src += 4;
   331                 dst += 2;
   332             }
   333         }
   334         break;
   335 
   336     case AUDIO_U16:
   337         {
   338             Uint8 *src, *dst;
   339 
   340             src = cvt->buf;
   341             dst = cvt->buf;
   342             if ((format & 0x1000) == 0x1000) {
   343                 for (i = cvt->len_cvt / 8; i; --i) {
   344                     lsample = (Uint16) ((src[0] << 8) | src[1]);
   345                     rsample = (Uint16) ((src[2] << 8) | src[3]);
   346                     dst[1] = (lsample & 0xFF);
   347                     lsample >>= 8;
   348                     dst[0] = (lsample & 0xFF);
   349                     dst[3] = (rsample & 0xFF);
   350                     rsample >>= 8;
   351                     dst[2] = (rsample & 0xFF);
   352                     src += 8;
   353                     dst += 4;
   354                 }
   355             } else {
   356                 for (i = cvt->len_cvt / 8; i; --i) {
   357                     lsample = (Uint16) ((src[1] << 8) | src[0]);
   358                     rsample = (Uint16) ((src[3] << 8) | src[2]);
   359                     dst[0] = (lsample & 0xFF);
   360                     lsample >>= 8;
   361                     dst[1] = (lsample & 0xFF);
   362                     dst[2] = (rsample & 0xFF);
   363                     rsample >>= 8;
   364                     dst[3] = (rsample & 0xFF);
   365                     src += 8;
   366                     dst += 4;
   367                 }
   368             }
   369         }
   370         break;
   371 
   372     case AUDIO_S16:
   373         {
   374             Uint8 *src, *dst;
   375 
   376             src = cvt->buf;
   377             dst = cvt->buf;
   378             if ((format & 0x1000) == 0x1000) {
   379                 for (i = cvt->len_cvt / 8; i; --i) {
   380                     lsample = (Sint16) ((src[0] << 8) | src[1]);
   381                     rsample = (Sint16) ((src[2] << 8) | src[3]);
   382                     dst[1] = (lsample & 0xFF);
   383                     lsample >>= 8;
   384                     dst[0] = (lsample & 0xFF);
   385                     dst[3] = (rsample & 0xFF);
   386                     rsample >>= 8;
   387                     dst[2] = (rsample & 0xFF);
   388                     src += 8;
   389                     dst += 4;
   390                 }
   391             } else {
   392                 for (i = cvt->len_cvt / 8; i; --i) {
   393                     lsample = (Sint16) ((src[1] << 8) | src[0]);
   394                     rsample = (Sint16) ((src[3] << 8) | src[2]);
   395                     dst[0] = (lsample & 0xFF);
   396                     lsample >>= 8;
   397                     dst[1] = (lsample & 0xFF);
   398                     dst[2] = (rsample & 0xFF);
   399                     rsample >>= 8;
   400                     dst[3] = (rsample & 0xFF);
   401                     src += 8;
   402                     dst += 4;
   403                 }
   404             }
   405         }
   406         break;
   407     }
   408     cvt->len_cvt /= 2;
   409     if (cvt->filters[++cvt->filter_index]) {
   410         cvt->filters[cvt->filter_index] (cvt, format);
   411     }
   412 }
   413 
   414 /* Duplicate a mono channel to both stereo channels */
   415 void SDLCALL
   416 SDL_ConvertStereo(SDL_AudioCVT * cvt, Uint16 format)
   417 {
   418     int i;
   419 
   420 #ifdef DEBUG_CONVERT
   421     fprintf(stderr, "Converting to stereo\n");
   422 #endif
   423     if ((format & 0xFF) == 16) {
   424         Uint16 *src, *dst;
   425 
   426         src = (Uint16 *) (cvt->buf + cvt->len_cvt);
   427         dst = (Uint16 *) (cvt->buf + cvt->len_cvt * 2);
   428         for (i = cvt->len_cvt / 2; i; --i) {
   429             dst -= 2;
   430             src -= 1;
   431             dst[0] = src[0];
   432             dst[1] = src[0];
   433         }
   434     } else {
   435         Uint8 *src, *dst;
   436 
   437         src = cvt->buf + cvt->len_cvt;
   438         dst = cvt->buf + cvt->len_cvt * 2;
   439         for (i = cvt->len_cvt; i; --i) {
   440             dst -= 2;
   441             src -= 1;
   442             dst[0] = src[0];
   443             dst[1] = src[0];
   444         }
   445     }
   446     cvt->len_cvt *= 2;
   447     if (cvt->filters[++cvt->filter_index]) {
   448         cvt->filters[cvt->filter_index] (cvt, format);
   449     }
   450 }
   451 
   452 
   453 /* Duplicate a stereo channel to a pseudo-5.1 stream */
   454 void SDLCALL
   455 SDL_ConvertSurround(SDL_AudioCVT * cvt, Uint16 format)
   456 {
   457     int i;
   458 
   459 #ifdef DEBUG_CONVERT
   460     fprintf(stderr, "Converting stereo to surround\n");
   461 #endif
   462     switch (format & 0x8018) {
   463 
   464     case AUDIO_U8:
   465         {
   466             Uint8 *src, *dst, lf, rf, ce;
   467 
   468             src = (Uint8 *) (cvt->buf + cvt->len_cvt);
   469             dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 3);
   470             for (i = cvt->len_cvt; i; --i) {
   471                 dst -= 6;
   472                 src -= 2;
   473                 lf = src[0];
   474                 rf = src[1];
   475                 ce = (lf / 2) + (rf / 2);
   476                 dst[0] = lf;
   477                 dst[1] = rf;
   478                 dst[2] = lf - ce;
   479                 dst[3] = rf - ce;
   480                 dst[4] = ce;
   481                 dst[5] = ce;
   482             }
   483         }
   484         break;
   485 
   486     case AUDIO_S8:
   487         {
   488             Sint8 *src, *dst, lf, rf, ce;
   489 
   490             src = (Sint8 *) cvt->buf + cvt->len_cvt;
   491             dst = (Sint8 *) cvt->buf + cvt->len_cvt * 3;
   492             for (i = cvt->len_cvt; i; --i) {
   493                 dst -= 6;
   494                 src -= 2;
   495                 lf = src[0];
   496                 rf = src[1];
   497                 ce = (lf / 2) + (rf / 2);
   498                 dst[0] = lf;
   499                 dst[1] = rf;
   500                 dst[2] = lf - ce;
   501                 dst[3] = rf - ce;
   502                 dst[4] = ce;
   503                 dst[5] = ce;
   504             }
   505         }
   506         break;
   507 
   508     case AUDIO_U16:
   509         {
   510             Uint8 *src, *dst;
   511             Uint16 lf, rf, ce, lr, rr;
   512 
   513             src = cvt->buf + cvt->len_cvt;
   514             dst = cvt->buf + cvt->len_cvt * 3;
   515 
   516             if ((format & 0x1000) == 0x1000) {
   517                 for (i = cvt->len_cvt / 4; i; --i) {
   518                     dst -= 12;
   519                     src -= 4;
   520                     lf = (Uint16) ((src[0] << 8) | src[1]);
   521                     rf = (Uint16) ((src[2] << 8) | src[3]);
   522                     ce = (lf / 2) + (rf / 2);
   523                     rr = lf - ce;
   524                     lr = rf - ce;
   525                     dst[1] = (lf & 0xFF);
   526                     dst[0] = ((lf >> 8) & 0xFF);
   527                     dst[3] = (rf & 0xFF);
   528                     dst[2] = ((rf >> 8) & 0xFF);
   529 
   530                     dst[1 + 4] = (lr & 0xFF);
   531                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   532                     dst[3 + 4] = (rr & 0xFF);
   533                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   534 
   535                     dst[1 + 8] = (ce & 0xFF);
   536                     dst[0 + 8] = ((ce >> 8) & 0xFF);
   537                     dst[3 + 8] = (ce & 0xFF);
   538                     dst[2 + 8] = ((ce >> 8) & 0xFF);
   539                 }
   540             } else {
   541                 for (i = cvt->len_cvt / 4; i; --i) {
   542                     dst -= 12;
   543                     src -= 4;
   544                     lf = (Uint16) ((src[1] << 8) | src[0]);
   545                     rf = (Uint16) ((src[3] << 8) | src[2]);
   546                     ce = (lf / 2) + (rf / 2);
   547                     rr = lf - ce;
   548                     lr = rf - ce;
   549                     dst[0] = (lf & 0xFF);
   550                     dst[1] = ((lf >> 8) & 0xFF);
   551                     dst[2] = (rf & 0xFF);
   552                     dst[3] = ((rf >> 8) & 0xFF);
   553 
   554                     dst[0 + 4] = (lr & 0xFF);
   555                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   556                     dst[2 + 4] = (rr & 0xFF);
   557                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   558 
   559                     dst[0 + 8] = (ce & 0xFF);
   560                     dst[1 + 8] = ((ce >> 8) & 0xFF);
   561                     dst[2 + 8] = (ce & 0xFF);
   562                     dst[3 + 8] = ((ce >> 8) & 0xFF);
   563                 }
   564             }
   565         }
   566         break;
   567 
   568     case AUDIO_S16:
   569         {
   570             Uint8 *src, *dst;
   571             Sint16 lf, rf, ce, lr, rr;
   572 
   573             src = cvt->buf + cvt->len_cvt;
   574             dst = cvt->buf + cvt->len_cvt * 3;
   575 
   576             if ((format & 0x1000) == 0x1000) {
   577                 for (i = cvt->len_cvt / 4; i; --i) {
   578                     dst -= 12;
   579                     src -= 4;
   580                     lf = (Sint16) ((src[0] << 8) | src[1]);
   581                     rf = (Sint16) ((src[2] << 8) | src[3]);
   582                     ce = (lf / 2) + (rf / 2);
   583                     rr = lf - ce;
   584                     lr = rf - ce;
   585                     dst[1] = (lf & 0xFF);
   586                     dst[0] = ((lf >> 8) & 0xFF);
   587                     dst[3] = (rf & 0xFF);
   588                     dst[2] = ((rf >> 8) & 0xFF);
   589 
   590                     dst[1 + 4] = (lr & 0xFF);
   591                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   592                     dst[3 + 4] = (rr & 0xFF);
   593                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   594 
   595                     dst[1 + 8] = (ce & 0xFF);
   596                     dst[0 + 8] = ((ce >> 8) & 0xFF);
   597                     dst[3 + 8] = (ce & 0xFF);
   598                     dst[2 + 8] = ((ce >> 8) & 0xFF);
   599                 }
   600             } else {
   601                 for (i = cvt->len_cvt / 4; i; --i) {
   602                     dst -= 12;
   603                     src -= 4;
   604                     lf = (Sint16) ((src[1] << 8) | src[0]);
   605                     rf = (Sint16) ((src[3] << 8) | src[2]);
   606                     ce = (lf / 2) + (rf / 2);
   607                     rr = lf - ce;
   608                     lr = rf - ce;
   609                     dst[0] = (lf & 0xFF);
   610                     dst[1] = ((lf >> 8) & 0xFF);
   611                     dst[2] = (rf & 0xFF);
   612                     dst[3] = ((rf >> 8) & 0xFF);
   613 
   614                     dst[0 + 4] = (lr & 0xFF);
   615                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   616                     dst[2 + 4] = (rr & 0xFF);
   617                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   618 
   619                     dst[0 + 8] = (ce & 0xFF);
   620                     dst[1 + 8] = ((ce >> 8) & 0xFF);
   621                     dst[2 + 8] = (ce & 0xFF);
   622                     dst[3 + 8] = ((ce >> 8) & 0xFF);
   623                 }
   624             }
   625         }
   626         break;
   627     }
   628     cvt->len_cvt *= 3;
   629     if (cvt->filters[++cvt->filter_index]) {
   630         cvt->filters[cvt->filter_index] (cvt, format);
   631     }
   632 }
   633 
   634 
   635 /* Duplicate a stereo channel to a pseudo-4.0 stream */
   636 void SDLCALL
   637 SDL_ConvertSurround_4(SDL_AudioCVT * cvt, Uint16 format)
   638 {
   639     int i;
   640 
   641 #ifdef DEBUG_CONVERT
   642     fprintf(stderr, "Converting stereo to quad\n");
   643 #endif
   644     switch (format & 0x8018) {
   645 
   646     case AUDIO_U8:
   647         {
   648             Uint8 *src, *dst, lf, rf, ce;
   649 
   650             src = (Uint8 *) (cvt->buf + cvt->len_cvt);
   651             dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 2);
   652             for (i = cvt->len_cvt; i; --i) {
   653                 dst -= 4;
   654                 src -= 2;
   655                 lf = src[0];
   656                 rf = src[1];
   657                 ce = (lf / 2) + (rf / 2);
   658                 dst[0] = lf;
   659                 dst[1] = rf;
   660                 dst[2] = lf - ce;
   661                 dst[3] = rf - ce;
   662             }
   663         }
   664         break;
   665 
   666     case AUDIO_S8:
   667         {
   668             Sint8 *src, *dst, lf, rf, ce;
   669 
   670             src = (Sint8 *) cvt->buf + cvt->len_cvt;
   671             dst = (Sint8 *) cvt->buf + cvt->len_cvt * 2;
   672             for (i = cvt->len_cvt; i; --i) {
   673                 dst -= 4;
   674                 src -= 2;
   675                 lf = src[0];
   676                 rf = src[1];
   677                 ce = (lf / 2) + (rf / 2);
   678                 dst[0] = lf;
   679                 dst[1] = rf;
   680                 dst[2] = lf - ce;
   681                 dst[3] = rf - ce;
   682             }
   683         }
   684         break;
   685 
   686     case AUDIO_U16:
   687         {
   688             Uint8 *src, *dst;
   689             Uint16 lf, rf, ce, lr, rr;
   690 
   691             src = cvt->buf + cvt->len_cvt;
   692             dst = cvt->buf + cvt->len_cvt * 2;
   693 
   694             if ((format & 0x1000) == 0x1000) {
   695                 for (i = cvt->len_cvt / 4; i; --i) {
   696                     dst -= 8;
   697                     src -= 4;
   698                     lf = (Uint16) ((src[0] << 8) | src[1]);
   699                     rf = (Uint16) ((src[2] << 8) | src[3]);
   700                     ce = (lf / 2) + (rf / 2);
   701                     rr = lf - ce;
   702                     lr = rf - ce;
   703                     dst[1] = (lf & 0xFF);
   704                     dst[0] = ((lf >> 8) & 0xFF);
   705                     dst[3] = (rf & 0xFF);
   706                     dst[2] = ((rf >> 8) & 0xFF);
   707 
   708                     dst[1 + 4] = (lr & 0xFF);
   709                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   710                     dst[3 + 4] = (rr & 0xFF);
   711                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   712                 }
   713             } else {
   714                 for (i = cvt->len_cvt / 4; i; --i) {
   715                     dst -= 8;
   716                     src -= 4;
   717                     lf = (Uint16) ((src[1] << 8) | src[0]);
   718                     rf = (Uint16) ((src[3] << 8) | src[2]);
   719                     ce = (lf / 2) + (rf / 2);
   720                     rr = lf - ce;
   721                     lr = rf - ce;
   722                     dst[0] = (lf & 0xFF);
   723                     dst[1] = ((lf >> 8) & 0xFF);
   724                     dst[2] = (rf & 0xFF);
   725                     dst[3] = ((rf >> 8) & 0xFF);
   726 
   727                     dst[0 + 4] = (lr & 0xFF);
   728                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   729                     dst[2 + 4] = (rr & 0xFF);
   730                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   731                 }
   732             }
   733         }
   734         break;
   735 
   736     case AUDIO_S16:
   737         {
   738             Uint8 *src, *dst;
   739             Sint16 lf, rf, ce, lr, rr;
   740 
   741             src = cvt->buf + cvt->len_cvt;
   742             dst = cvt->buf + cvt->len_cvt * 2;
   743 
   744             if ((format & 0x1000) == 0x1000) {
   745                 for (i = cvt->len_cvt / 4; i; --i) {
   746                     dst -= 8;
   747                     src -= 4;
   748                     lf = (Sint16) ((src[0] << 8) | src[1]);
   749                     rf = (Sint16) ((src[2] << 8) | src[3]);
   750                     ce = (lf / 2) + (rf / 2);
   751                     rr = lf - ce;
   752                     lr = rf - ce;
   753                     dst[1] = (lf & 0xFF);
   754                     dst[0] = ((lf >> 8) & 0xFF);
   755                     dst[3] = (rf & 0xFF);
   756                     dst[2] = ((rf >> 8) & 0xFF);
   757 
   758                     dst[1 + 4] = (lr & 0xFF);
   759                     dst[0 + 4] = ((lr >> 8) & 0xFF);
   760                     dst[3 + 4] = (rr & 0xFF);
   761                     dst[2 + 4] = ((rr >> 8) & 0xFF);
   762                 }
   763             } else {
   764                 for (i = cvt->len_cvt / 4; i; --i) {
   765                     dst -= 8;
   766                     src -= 4;
   767                     lf = (Sint16) ((src[1] << 8) | src[0]);
   768                     rf = (Sint16) ((src[3] << 8) | src[2]);
   769                     ce = (lf / 2) + (rf / 2);
   770                     rr = lf - ce;
   771                     lr = rf - ce;
   772                     dst[0] = (lf & 0xFF);
   773                     dst[1] = ((lf >> 8) & 0xFF);
   774                     dst[2] = (rf & 0xFF);
   775                     dst[3] = ((rf >> 8) & 0xFF);
   776 
   777                     dst[0 + 4] = (lr & 0xFF);
   778                     dst[1 + 4] = ((lr >> 8) & 0xFF);
   779                     dst[2 + 4] = (rr & 0xFF);
   780                     dst[3 + 4] = ((rr >> 8) & 0xFF);
   781                 }
   782             }
   783         }
   784         break;
   785     }
   786     cvt->len_cvt *= 2;
   787     if (cvt->filters[++cvt->filter_index]) {
   788         cvt->filters[cvt->filter_index] (cvt, format);
   789     }
   790 }
   791 
   792 
   793 /* Convert 8-bit to 16-bit - LSB */
   794 void SDLCALL
   795 SDL_Convert16LSB(SDL_AudioCVT * cvt, Uint16 format)
   796 {
   797     int i;
   798     Uint8 *src, *dst;
   799 
   800 #ifdef DEBUG_CONVERT
   801     fprintf(stderr, "Converting to 16-bit LSB\n");
   802 #endif
   803     src = cvt->buf + cvt->len_cvt;
   804     dst = cvt->buf + cvt->len_cvt * 2;
   805     for (i = cvt->len_cvt; i; --i) {
   806         src -= 1;
   807         dst -= 2;
   808         dst[1] = *src;
   809         dst[0] = 0;
   810     }
   811     format = ((format & ~0x0008) | AUDIO_U16LSB);
   812     cvt->len_cvt *= 2;
   813     if (cvt->filters[++cvt->filter_index]) {
   814         cvt->filters[cvt->filter_index] (cvt, format);
   815     }
   816 }
   817 
   818 /* Convert 8-bit to 16-bit - MSB */
   819 void SDLCALL
   820 SDL_Convert16MSB(SDL_AudioCVT * cvt, Uint16 format)
   821 {
   822     int i;
   823     Uint8 *src, *dst;
   824 
   825 #ifdef DEBUG_CONVERT
   826     fprintf(stderr, "Converting to 16-bit MSB\n");
   827 #endif
   828     src = cvt->buf + cvt->len_cvt;
   829     dst = cvt->buf + cvt->len_cvt * 2;
   830     for (i = cvt->len_cvt; i; --i) {
   831         src -= 1;
   832         dst -= 2;
   833         dst[0] = *src;
   834         dst[1] = 0;
   835     }
   836     format = ((format & ~0x0008) | AUDIO_U16MSB);
   837     cvt->len_cvt *= 2;
   838     if (cvt->filters[++cvt->filter_index]) {
   839         cvt->filters[cvt->filter_index] (cvt, format);
   840     }
   841 }
   842 
   843 /* Convert 16-bit to 8-bit */
   844 void SDLCALL
   845 SDL_Convert8(SDL_AudioCVT * cvt, Uint16 format)
   846 {
   847     int i;
   848     Uint8 *src, *dst;
   849 
   850 #ifdef DEBUG_CONVERT
   851     fprintf(stderr, "Converting to 8-bit\n");
   852 #endif
   853     src = cvt->buf;
   854     dst = cvt->buf;
   855     if ((format & 0x1000) != 0x1000) {  /* Little endian */
   856         ++src;
   857     }
   858     for (i = cvt->len_cvt / 2; i; --i) {
   859         *dst = *src;
   860         src += 2;
   861         dst += 1;
   862     }
   863     format = ((format & ~0x9010) | AUDIO_U8);
   864     cvt->len_cvt /= 2;
   865     if (cvt->filters[++cvt->filter_index]) {
   866         cvt->filters[cvt->filter_index] (cvt, format);
   867     }
   868 }
   869 
   870 /* Toggle signed/unsigned */
   871 void SDLCALL
   872 SDL_ConvertSign(SDL_AudioCVT * cvt, Uint16 format)
   873 {
   874     int i;
   875     Uint8 *data;
   876 
   877 #ifdef DEBUG_CONVERT
   878     fprintf(stderr, "Converting audio signedness\n");
   879 #endif
   880     data = cvt->buf;
   881     if ((format & 0xFF) == 16) {
   882         if ((format & 0x1000) != 0x1000) {      /* Little endian */
   883             ++data;
   884         }
   885         for (i = cvt->len_cvt / 2; i; --i) {
   886             *data ^= 0x80;
   887             data += 2;
   888         }
   889     } else {
   890         for (i = cvt->len_cvt; i; --i) {
   891             *data++ ^= 0x80;
   892         }
   893     }
   894     format = (format ^ 0x8000);
   895     if (cvt->filters[++cvt->filter_index]) {
   896         cvt->filters[cvt->filter_index] (cvt, format);
   897     }
   898 }
   899 
   900 /* Toggle endianness */
   901 void SDLCALL
   902 SDL_ConvertEndian(SDL_AudioCVT * cvt, Uint16 format)
   903 {
   904     int i;
   905     Uint8 *data, tmp;
   906 
   907 #ifdef DEBUG_CONVERT
   908     fprintf(stderr, "Converting audio endianness\n");
   909 #endif
   910     data = cvt->buf;
   911     for (i = cvt->len_cvt / 2; i; --i) {
   912         tmp = data[0];
   913         data[0] = data[1];
   914         data[1] = tmp;
   915         data += 2;
   916     }
   917     format = (format ^ 0x1000);
   918     if (cvt->filters[++cvt->filter_index]) {
   919         cvt->filters[cvt->filter_index] (cvt, format);
   920     }
   921 }
   922 
   923 /* Convert rate up by multiple of 2 */
   924 void SDLCALL
   925 SDL_RateMUL2(SDL_AudioCVT * cvt, Uint16 format)
   926 {
   927     int i;
   928     Uint8 *src, *dst;
   929 
   930 #ifdef DEBUG_CONVERT
   931     fprintf(stderr, "Converting audio rate * 2\n");
   932 #endif
   933     src = cvt->buf + cvt->len_cvt;
   934     dst = cvt->buf + cvt->len_cvt * 2;
   935     switch (format & 0xFF) {
   936     case 8:
   937         for (i = cvt->len_cvt; i; --i) {
   938             src -= 1;
   939             dst -= 2;
   940             dst[0] = src[0];
   941             dst[1] = src[0];
   942         }
   943         break;
   944     case 16:
   945         for (i = cvt->len_cvt / 2; i; --i) {
   946             src -= 2;
   947             dst -= 4;
   948             dst[0] = src[0];
   949             dst[1] = src[1];
   950             dst[2] = src[0];
   951             dst[3] = src[1];
   952         }
   953         break;
   954     }
   955     cvt->len_cvt *= 2;
   956     if (cvt->filters[++cvt->filter_index]) {
   957         cvt->filters[cvt->filter_index] (cvt, format);
   958     }
   959 }
   960 
   961 
   962 /* Convert rate up by multiple of 2, for stereo */
   963 void SDLCALL
   964 SDL_RateMUL2_c2(SDL_AudioCVT * cvt, Uint16 format)
   965 {
   966     int i;
   967     Uint8 *src, *dst;
   968 
   969 #ifdef DEBUG_CONVERT
   970     fprintf(stderr, "Converting audio rate * 2\n");
   971 #endif
   972     src = cvt->buf + cvt->len_cvt;
   973     dst = cvt->buf + cvt->len_cvt * 2;
   974     switch (format & 0xFF) {
   975     case 8:
   976         for (i = cvt->len_cvt / 2; i; --i) {
   977             src -= 2;
   978             dst -= 4;
   979             dst[0] = src[0];
   980             dst[1] = src[1];
   981             dst[2] = src[0];
   982             dst[3] = src[1];
   983         }
   984         break;
   985     case 16:
   986         for (i = cvt->len_cvt / 4; i; --i) {
   987             src -= 4;
   988             dst -= 8;
   989             dst[0] = src[0];
   990             dst[1] = src[1];
   991             dst[2] = src[2];
   992             dst[3] = src[3];
   993             dst[4] = src[0];
   994             dst[5] = src[1];
   995             dst[6] = src[2];
   996             dst[7] = src[3];
   997         }
   998         break;
   999     }
  1000     cvt->len_cvt *= 2;
  1001     if (cvt->filters[++cvt->filter_index]) {
  1002         cvt->filters[cvt->filter_index] (cvt, format);
  1003     }
  1004 }
  1005 
  1006 /* Convert rate up by multiple of 2, for quad */
  1007 void SDLCALL
  1008 SDL_RateMUL2_c4(SDL_AudioCVT * cvt, Uint16 format)
  1009 {
  1010     int i;
  1011     Uint8 *src, *dst;
  1012 
  1013 #ifdef DEBUG_CONVERT
  1014     fprintf(stderr, "Converting audio rate * 2\n");
  1015 #endif
  1016     src = cvt->buf + cvt->len_cvt;
  1017     dst = cvt->buf + cvt->len_cvt * 2;
  1018     switch (format & 0xFF) {
  1019     case 8:
  1020         for (i = cvt->len_cvt / 4; i; --i) {
  1021             src -= 4;
  1022             dst -= 8;
  1023             dst[0] = src[0];
  1024             dst[1] = src[1];
  1025             dst[2] = src[2];
  1026             dst[3] = src[3];
  1027             dst[4] = src[0];
  1028             dst[5] = src[1];
  1029             dst[6] = src[2];
  1030             dst[7] = src[3];
  1031         }
  1032         break;
  1033     case 16:
  1034         for (i = cvt->len_cvt / 8; i; --i) {
  1035             src -= 8;
  1036             dst -= 16;
  1037             dst[0] = src[0];
  1038             dst[1] = src[1];
  1039             dst[2] = src[2];
  1040             dst[3] = src[3];
  1041             dst[4] = src[4];
  1042             dst[5] = src[5];
  1043             dst[6] = src[6];
  1044             dst[7] = src[7];
  1045             dst[8] = src[0];
  1046             dst[9] = src[1];
  1047             dst[10] = src[2];
  1048             dst[11] = src[3];
  1049             dst[12] = src[4];
  1050             dst[13] = src[5];
  1051             dst[14] = src[6];
  1052             dst[15] = src[7];
  1053         }
  1054         break;
  1055     }
  1056     cvt->len_cvt *= 2;
  1057     if (cvt->filters[++cvt->filter_index]) {
  1058         cvt->filters[cvt->filter_index] (cvt, format);
  1059     }
  1060 }
  1061 
  1062 
  1063 /* Convert rate up by multiple of 2, for 5.1 */
  1064 void SDLCALL
  1065 SDL_RateMUL2_c6(SDL_AudioCVT * cvt, Uint16 format)
  1066 {
  1067     int i;
  1068     Uint8 *src, *dst;
  1069 
  1070 #ifdef DEBUG_CONVERT
  1071     fprintf(stderr, "Converting audio rate * 2\n");
  1072 #endif
  1073     src = cvt->buf + cvt->len_cvt;
  1074     dst = cvt->buf + cvt->len_cvt * 2;
  1075     switch (format & 0xFF) {
  1076     case 8:
  1077         for (i = cvt->len_cvt / 6; i; --i) {
  1078             src -= 6;
  1079             dst -= 12;
  1080             dst[0] = src[0];
  1081             dst[1] = src[1];
  1082             dst[2] = src[2];
  1083             dst[3] = src[3];
  1084             dst[4] = src[4];
  1085             dst[5] = src[5];
  1086             dst[6] = src[0];
  1087             dst[7] = src[1];
  1088             dst[8] = src[2];
  1089             dst[9] = src[3];
  1090             dst[10] = src[4];
  1091             dst[11] = src[5];
  1092         }
  1093         break;
  1094     case 16:
  1095         for (i = cvt->len_cvt / 12; i; --i) {
  1096             src -= 12;
  1097             dst -= 24;
  1098             dst[0] = src[0];
  1099             dst[1] = src[1];
  1100             dst[2] = src[2];
  1101             dst[3] = src[3];
  1102             dst[4] = src[4];
  1103             dst[5] = src[5];
  1104             dst[6] = src[6];
  1105             dst[7] = src[7];
  1106             dst[8] = src[8];
  1107             dst[9] = src[9];
  1108             dst[10] = src[10];
  1109             dst[11] = src[11];
  1110             dst[12] = src[0];
  1111             dst[13] = src[1];
  1112             dst[14] = src[2];
  1113             dst[15] = src[3];
  1114             dst[16] = src[4];
  1115             dst[17] = src[5];
  1116             dst[18] = src[6];
  1117             dst[19] = src[7];
  1118             dst[20] = src[8];
  1119             dst[21] = src[9];
  1120             dst[22] = src[10];
  1121             dst[23] = src[11];
  1122         }
  1123         break;
  1124     }
  1125     cvt->len_cvt *= 2;
  1126     if (cvt->filters[++cvt->filter_index]) {
  1127         cvt->filters[cvt->filter_index] (cvt, format);
  1128     }
  1129 }
  1130 
  1131 /* Convert rate down by multiple of 2 */
  1132 void SDLCALL
  1133 SDL_RateDIV2(SDL_AudioCVT * cvt, Uint16 format)
  1134 {
  1135     int i;
  1136     Uint8 *src, *dst;
  1137 
  1138 #ifdef DEBUG_CONVERT
  1139     fprintf(stderr, "Converting audio rate / 2\n");
  1140 #endif
  1141     src = cvt->buf;
  1142     dst = cvt->buf;
  1143     switch (format & 0xFF) {
  1144     case 8:
  1145         for (i = cvt->len_cvt / 2; i; --i) {
  1146             dst[0] = src[0];
  1147             src += 2;
  1148             dst += 1;
  1149         }
  1150         break;
  1151     case 16:
  1152         for (i = cvt->len_cvt / 4; i; --i) {
  1153             dst[0] = src[0];
  1154             dst[1] = src[1];
  1155             src += 4;
  1156             dst += 2;
  1157         }
  1158         break;
  1159     }
  1160     cvt->len_cvt /= 2;
  1161     if (cvt->filters[++cvt->filter_index]) {
  1162         cvt->filters[cvt->filter_index] (cvt, format);
  1163     }
  1164 }
  1165 
  1166 
  1167 /* Convert rate down by multiple of 2, for stereo */
  1168 void SDLCALL
  1169 SDL_RateDIV2_c2(SDL_AudioCVT * cvt, Uint16 format)
  1170 {
  1171     int i;
  1172     Uint8 *src, *dst;
  1173 
  1174 #ifdef DEBUG_CONVERT
  1175     fprintf(stderr, "Converting audio rate / 2\n");
  1176 #endif
  1177     src = cvt->buf;
  1178     dst = cvt->buf;
  1179     switch (format & 0xFF) {
  1180     case 8:
  1181         for (i = cvt->len_cvt / 4; i; --i) {
  1182             dst[0] = src[0];
  1183             dst[1] = src[1];
  1184             src += 4;
  1185             dst += 2;
  1186         }
  1187         break;
  1188     case 16:
  1189         for (i = cvt->len_cvt / 8; i; --i) {
  1190             dst[0] = src[0];
  1191             dst[1] = src[1];
  1192             dst[2] = src[2];
  1193             dst[3] = src[3];
  1194             src += 8;
  1195             dst += 4;
  1196         }
  1197         break;
  1198     }
  1199     cvt->len_cvt /= 2;
  1200     if (cvt->filters[++cvt->filter_index]) {
  1201         cvt->filters[cvt->filter_index] (cvt, format);
  1202     }
  1203 }
  1204 
  1205 
  1206 /* Convert rate down by multiple of 2, for quad */
  1207 void SDLCALL
  1208 SDL_RateDIV2_c4(SDL_AudioCVT * cvt, Uint16 format)
  1209 {
  1210     int i;
  1211     Uint8 *src, *dst;
  1212 
  1213 #ifdef DEBUG_CONVERT
  1214     fprintf(stderr, "Converting audio rate / 2\n");
  1215 #endif
  1216     src = cvt->buf;
  1217     dst = cvt->buf;
  1218     switch (format & 0xFF) {
  1219     case 8:
  1220         for (i = cvt->len_cvt / 8; i; --i) {
  1221             dst[0] = src[0];
  1222             dst[1] = src[1];
  1223             dst[2] = src[2];
  1224             dst[3] = src[3];
  1225             src += 8;
  1226             dst += 4;
  1227         }
  1228         break;
  1229     case 16:
  1230         for (i = cvt->len_cvt / 16; i; --i) {
  1231             dst[0] = src[0];
  1232             dst[1] = src[1];
  1233             dst[2] = src[2];
  1234             dst[3] = src[3];
  1235             dst[4] = src[4];
  1236             dst[5] = src[5];
  1237             dst[6] = src[6];
  1238             dst[7] = src[7];
  1239             src += 16;
  1240             dst += 8;
  1241         }
  1242         break;
  1243     }
  1244     cvt->len_cvt /= 2;
  1245     if (cvt->filters[++cvt->filter_index]) {
  1246         cvt->filters[cvt->filter_index] (cvt, format);
  1247     }
  1248 }
  1249 
  1250 /* Convert rate down by multiple of 2, for 5.1 */
  1251 void SDLCALL
  1252 SDL_RateDIV2_c6(SDL_AudioCVT * cvt, Uint16 format)
  1253 {
  1254     int i;
  1255     Uint8 *src, *dst;
  1256 
  1257 #ifdef DEBUG_CONVERT
  1258     fprintf(stderr, "Converting audio rate / 2\n");
  1259 #endif
  1260     src = cvt->buf;
  1261     dst = cvt->buf;
  1262     switch (format & 0xFF) {
  1263     case 8:
  1264         for (i = cvt->len_cvt / 12; i; --i) {
  1265             dst[0] = src[0];
  1266             dst[1] = src[1];
  1267             dst[2] = src[2];
  1268             dst[3] = src[3];
  1269             dst[4] = src[4];
  1270             dst[5] = src[5];
  1271             src += 12;
  1272             dst += 6;
  1273         }
  1274         break;
  1275     case 16:
  1276         for (i = cvt->len_cvt / 24; i; --i) {
  1277             dst[0] = src[0];
  1278             dst[1] = src[1];
  1279             dst[2] = src[2];
  1280             dst[3] = src[3];
  1281             dst[4] = src[4];
  1282             dst[5] = src[5];
  1283             dst[6] = src[6];
  1284             dst[7] = src[7];
  1285             dst[8] = src[8];
  1286             dst[9] = src[9];
  1287             dst[10] = src[10];
  1288             dst[11] = src[11];
  1289             src += 24;
  1290             dst += 12;
  1291         }
  1292         break;
  1293     }
  1294     cvt->len_cvt /= 2;
  1295     if (cvt->filters[++cvt->filter_index]) {
  1296         cvt->filters[cvt->filter_index] (cvt, format);
  1297     }
  1298 }
  1299 
  1300 /* Very slow rate conversion routine */
  1301 void SDLCALL
  1302 SDL_RateSLOW(SDL_AudioCVT * cvt, Uint16 format)
  1303 {
  1304     double ipos;
  1305     int i, clen;
  1306 
  1307 #ifdef DEBUG_CONVERT
  1308     fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0 / cvt->rate_incr);
  1309 #endif
  1310     clen = (int) ((double) cvt->len_cvt / cvt->rate_incr);
  1311     if (cvt->rate_incr > 1.0) {
  1312         switch (format & 0xFF) {
  1313         case 8:
  1314             {
  1315                 Uint8 *output;
  1316 
  1317                 output = cvt->buf;
  1318                 ipos = 0.0;
  1319                 for (i = clen; i; --i) {
  1320                     *output = cvt->buf[(int) ipos];
  1321                     ipos += cvt->rate_incr;
  1322                     output += 1;
  1323                 }
  1324             }
  1325             break;
  1326 
  1327         case 16:
  1328             {
  1329                 Uint16 *output;
  1330 
  1331                 clen &= ~1;
  1332                 output = (Uint16 *) cvt->buf;
  1333                 ipos = 0.0;
  1334                 for (i = clen / 2; i; --i) {
  1335                     *output = ((Uint16 *) cvt->buf)[(int) ipos];
  1336                     ipos += cvt->rate_incr;
  1337                     output += 1;
  1338                 }
  1339             }
  1340             break;
  1341         }
  1342     } else {
  1343         switch (format & 0xFF) {
  1344         case 8:
  1345             {
  1346                 Uint8 *output;
  1347 
  1348                 output = cvt->buf + clen;
  1349                 ipos = (double) cvt->len_cvt;
  1350                 for (i = clen; i; --i) {
  1351                     ipos -= cvt->rate_incr;
  1352                     output -= 1;
  1353                     *output = cvt->buf[(int) ipos];
  1354                 }
  1355             }
  1356             break;
  1357 
  1358         case 16:
  1359             {
  1360                 Uint16 *output;
  1361 
  1362                 clen &= ~1;
  1363                 output = (Uint16 *) (cvt->buf + clen);
  1364                 ipos = (double) cvt->len_cvt / 2;
  1365                 for (i = clen / 2; i; --i) {
  1366                     ipos -= cvt->rate_incr;
  1367                     output -= 1;
  1368                     *output = ((Uint16 *) cvt->buf)[(int) ipos];
  1369                 }
  1370             }
  1371             break;
  1372         }
  1373     }
  1374     cvt->len_cvt = clen;
  1375     if (cvt->filters[++cvt->filter_index]) {
  1376         cvt->filters[cvt->filter_index] (cvt, format);
  1377     }
  1378 }
  1379 
  1380 int
  1381 SDL_ConvertAudio(SDL_AudioCVT * cvt)
  1382 {
  1383     /* Make sure there's data to convert */
  1384     if (cvt->buf == NULL) {
  1385         SDL_SetError("No buffer allocated for conversion");
  1386         return (-1);
  1387     }
  1388     /* Return okay if no conversion is necessary */
  1389     cvt->len_cvt = cvt->len;
  1390     if (cvt->filters[0] == NULL) {
  1391         return (0);
  1392     }
  1393 
  1394     /* Set up the conversion and go! */
  1395     cvt->filter_index = 0;
  1396     cvt->filters[0] (cvt, cvt->src_format);
  1397     return (0);
  1398 }
  1399 
  1400 /* Creates a set of audio filters to convert from one format to another. 
  1401    Returns -1 if the format conversion is not supported, or 1 if the
  1402    audio filter is set up.
  1403 */
  1404 
  1405 int
  1406 SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
  1407                   Uint16 src_format, Uint8 src_channels, int src_rate,
  1408                   Uint16 dst_format, Uint8 dst_channels, int dst_rate)
  1409 {
  1410 /*printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
  1411 		src_format, dst_format, src_channels, dst_channels, src_rate, dst_rate);*/
  1412     /* Start off with no conversion necessary */
  1413     cvt->needed = 0;
  1414     cvt->filter_index = 0;
  1415     cvt->filters[0] = NULL;
  1416     cvt->len_mult = 1;
  1417     cvt->len_ratio = 1.0;
  1418 
  1419     /* First filter:  Endian conversion from src to dst */
  1420     if ((src_format & 0x1000) != (dst_format & 0x1000)
  1421         && ((src_format & 0xff) != 8)) {
  1422         cvt->filters[cvt->filter_index++] = SDL_ConvertEndian;
  1423     }
  1424 
  1425     /* Second filter: Sign conversion -- signed/unsigned */
  1426     if ((src_format & 0x8000) != (dst_format & 0x8000)) {
  1427         cvt->filters[cvt->filter_index++] = SDL_ConvertSign;
  1428     }
  1429 
  1430     /* Next filter:  Convert 16 bit <--> 8 bit PCM */
  1431     if ((src_format & 0xFF) != (dst_format & 0xFF)) {
  1432         switch (dst_format & 0x10FF) {
  1433         case AUDIO_U8:
  1434             cvt->filters[cvt->filter_index++] = SDL_Convert8;
  1435             cvt->len_ratio /= 2;
  1436             break;
  1437         case AUDIO_U16LSB:
  1438             cvt->filters[cvt->filter_index++] = SDL_Convert16LSB;
  1439             cvt->len_mult *= 2;
  1440             cvt->len_ratio *= 2;
  1441             break;
  1442         case AUDIO_U16MSB:
  1443             cvt->filters[cvt->filter_index++] = SDL_Convert16MSB;
  1444             cvt->len_mult *= 2;
  1445             cvt->len_ratio *= 2;
  1446             break;
  1447         }
  1448     }
  1449 
  1450     /* Last filter:  Mono/Stereo conversion */
  1451     if (src_channels != dst_channels) {
  1452         if ((src_channels == 1) && (dst_channels > 1)) {
  1453             cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
  1454             cvt->len_mult *= 2;
  1455             src_channels = 2;
  1456             cvt->len_ratio *= 2;
  1457         }
  1458         if ((src_channels == 2) && (dst_channels == 6)) {
  1459             cvt->filters[cvt->filter_index++] = SDL_ConvertSurround;
  1460             src_channels = 6;
  1461             cvt->len_mult *= 3;
  1462             cvt->len_ratio *= 3;
  1463         }
  1464         if ((src_channels == 2) && (dst_channels == 4)) {
  1465             cvt->filters[cvt->filter_index++] = SDL_ConvertSurround_4;
  1466             src_channels = 4;
  1467             cvt->len_mult *= 2;
  1468             cvt->len_ratio *= 2;
  1469         }
  1470         while ((src_channels * 2) <= dst_channels) {
  1471             cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
  1472             cvt->len_mult *= 2;
  1473             src_channels *= 2;
  1474             cvt->len_ratio *= 2;
  1475         }
  1476         if ((src_channels == 6) && (dst_channels <= 2)) {
  1477             cvt->filters[cvt->filter_index++] = SDL_ConvertStrip;
  1478             src_channels = 2;
  1479             cvt->len_ratio /= 3;
  1480         }
  1481         if ((src_channels == 6) && (dst_channels == 4)) {
  1482             cvt->filters[cvt->filter_index++] = SDL_ConvertStrip_2;
  1483             src_channels = 4;
  1484             cvt->len_ratio /= 2;
  1485         }
  1486         /* This assumes that 4 channel audio is in the format:
  1487            Left {front/back} + Right {front/back}
  1488            so converting to L/R stereo works properly.
  1489          */
  1490         while (((src_channels % 2) == 0) &&
  1491                ((src_channels / 2) >= dst_channels)) {
  1492             cvt->filters[cvt->filter_index++] = SDL_ConvertMono;
  1493             src_channels /= 2;
  1494             cvt->len_ratio /= 2;
  1495         }
  1496         if (src_channels != dst_channels) {
  1497             /* Uh oh.. */ ;
  1498         }
  1499     }
  1500 
  1501     /* Do rate conversion */
  1502     cvt->rate_incr = 0.0;
  1503     if ((src_rate / 100) != (dst_rate / 100)) {
  1504         Uint32 hi_rate, lo_rate;
  1505         int len_mult;
  1506         double len_ratio;
  1507         void (SDLCALL * rate_cvt) (SDL_AudioCVT * cvt, Uint16 format);
  1508 
  1509         if (src_rate > dst_rate) {
  1510             hi_rate = src_rate;
  1511             lo_rate = dst_rate;
  1512             switch (src_channels) {
  1513             case 1:
  1514                 rate_cvt = SDL_RateDIV2;
  1515                 break;
  1516             case 2:
  1517                 rate_cvt = SDL_RateDIV2_c2;
  1518                 break;
  1519             case 4:
  1520                 rate_cvt = SDL_RateDIV2_c4;
  1521                 break;
  1522             case 6:
  1523                 rate_cvt = SDL_RateDIV2_c6;
  1524                 break;
  1525             default:
  1526                 return -1;
  1527             }
  1528             len_mult = 1;
  1529             len_ratio = 0.5;
  1530         } else {
  1531             hi_rate = dst_rate;
  1532             lo_rate = src_rate;
  1533             switch (src_channels) {
  1534             case 1:
  1535                 rate_cvt = SDL_RateMUL2;
  1536                 break;
  1537             case 2:
  1538                 rate_cvt = SDL_RateMUL2_c2;
  1539                 break;
  1540             case 4:
  1541                 rate_cvt = SDL_RateMUL2_c4;
  1542                 break;
  1543             case 6:
  1544                 rate_cvt = SDL_RateMUL2_c6;
  1545                 break;
  1546             default:
  1547                 return -1;
  1548             }
  1549             len_mult = 2;
  1550             len_ratio = 2.0;
  1551         }
  1552         /* If hi_rate = lo_rate*2^x then conversion is easy */
  1553         while (((lo_rate * 2) / 100) <= (hi_rate / 100)) {
  1554             cvt->filters[cvt->filter_index++] = rate_cvt;
  1555             cvt->len_mult *= len_mult;
  1556             lo_rate *= 2;
  1557             cvt->len_ratio *= len_ratio;
  1558         }
  1559         /* We may need a slow conversion here to finish up */
  1560         if ((lo_rate / 100) != (hi_rate / 100)) {
  1561 #if 1
  1562             /* The problem with this is that if the input buffer is
  1563                say 1K, and the conversion rate is say 1.1, then the
  1564                output buffer is 1.1K, which may not be an acceptable
  1565                buffer size for the audio driver (not a power of 2)
  1566              */
  1567             /* For now, punt and hope the rate distortion isn't great.
  1568              */
  1569 #else
  1570             if (src_rate < dst_rate) {
  1571                 cvt->rate_incr = (double) lo_rate / hi_rate;
  1572                 cvt->len_mult *= 2;
  1573                 cvt->len_ratio /= cvt->rate_incr;
  1574             } else {
  1575                 cvt->rate_incr = (double) hi_rate / lo_rate;
  1576                 cvt->len_ratio *= cvt->rate_incr;
  1577             }
  1578             cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
  1579 #endif
  1580         }
  1581     }
  1582 
  1583     /* Set up the filter information */
  1584     if (cvt->filter_index != 0) {
  1585         cvt->needed = 1;
  1586         cvt->src_format = src_format;
  1587         cvt->dst_format = dst_format;
  1588         cvt->len = 0;
  1589         cvt->buf = NULL;
  1590         cvt->filters[cvt->filter_index] = NULL;
  1591     }
  1592     return (cvt->needed);
  1593 }
  1594 
  1595 /* vi: set ts=4 sw=4 expandtab: */