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