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