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