• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2006 Sam Lantinga
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23 
24 /* Functions for audio drivers to perform runtime conversion of audio format */
25 
26 #include "SDL_audio.h"
27 
28 
29 /* Effectively mix right and left channels into a single channel */
SDL_ConvertMono(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_ConvertStrip(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_ConvertStrip_2(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_ConvertStereo(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_ConvertSurround(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_ConvertSurround_4(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_Convert16LSB(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_Convert16MSB(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_Convert8(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_ConvertSign(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_ConvertEndian(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateMUL2(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateMUL2_c2(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateMUL2_c4(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateMUL2_c6(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateDIV2(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateDIV2_c2(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateDIV2_c4(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateDIV2_c6(SDL_AudioCVT * cvt,Uint16 format)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 */
SDL_RateSLOW(SDL_AudioCVT * cvt,Uint16 format)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 
SDL_ConvertAudio(SDL_AudioCVT * cvt)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 
SDL_BuildAudioCVT(SDL_AudioCVT * cvt,Uint16 src_format,Uint8 src_channels,int src_rate,Uint16 dst_format,Uint8 dst_channels,int dst_rate)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