2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
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.
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.
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
22 #include "SDL_config.h"
24 /* Functions for audio drivers to perform runtime conversion of audio format */
26 #include "SDL_audio.h"
29 /* Effectively mix right and left channels into a single channel */
30 void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format)
36 fprintf(stderr, "Converting to mono\n");
38 switch (format&0x8018) {
45 for ( i=cvt->len_cvt/2; i; --i ) {
46 sample = src[0] + src[1];
47 *dst = (Uint8)(sample / 2);
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);
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]);
78 dst[1] = (sample&0xFF);
80 dst[0] = (sample&0xFF);
85 for ( i=cvt->len_cvt/4; i; --i ) {
86 sample = (Uint16)((src[1]<<8)|src[0])+
87 (Uint16)((src[3]<<8)|src[2]);
89 dst[0] = (sample&0xFF);
91 dst[1] = (sample&0xFF);
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]);
109 dst[1] = (sample&0xFF);
111 dst[0] = (sample&0xFF);
116 for ( i=cvt->len_cvt/4; i; --i ) {
117 sample = (Sint16)((src[1]<<8)|src[0])+
118 (Sint16)((src[3]<<8)|src[2]);
120 dst[0] = (sample&0xFF);
122 dst[1] = (sample&0xFF);
131 if ( cvt->filters[++cvt->filter_index] ) {
132 cvt->filters[cvt->filter_index](cvt, format);
136 /* Discard top 4 channels */
137 void SDLCALL SDL_ConvertStrip(SDL_AudioCVT *cvt, Uint16 format)
140 Sint32 lsample, rsample;
143 fprintf(stderr, "Converting down to stereo\n");
145 switch (format&0x8018) {
152 for ( i=cvt->len_cvt/6; i; --i ) {
164 src = (Sint8 *)cvt->buf;
165 dst = (Sint8 *)cvt->buf;
166 for ( i=cvt->len_cvt/6; i; --i ) {
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);
186 dst[0] = (lsample&0xFF);
187 dst[3] = (rsample&0xFF);
189 dst[2] = (rsample&0xFF);
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);
199 dst[1] = (lsample&0xFF);
200 dst[2] = (rsample&0xFF);
202 dst[3] = (rsample&0xFF);
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);
221 dst[0] = (lsample&0xFF);
222 dst[3] = (rsample&0xFF);
224 dst[2] = (rsample&0xFF);
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);
234 dst[1] = (lsample&0xFF);
235 dst[2] = (rsample&0xFF);
237 dst[3] = (rsample&0xFF);
246 if ( cvt->filters[++cvt->filter_index] ) {
247 cvt->filters[cvt->filter_index](cvt, format);
252 /* Discard top 2 channels of 6 */
253 void SDLCALL SDL_ConvertStrip_2(SDL_AudioCVT *cvt, Uint16 format)
256 Sint32 lsample, rsample;
259 fprintf(stderr, "Converting 6 down to quad\n");
261 switch (format&0x8018) {
268 for ( i=cvt->len_cvt/4; i; --i ) {
280 src = (Sint8 *)cvt->buf;
281 dst = (Sint8 *)cvt->buf;
282 for ( i=cvt->len_cvt/4; i; --i ) {
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);
302 dst[0] = (lsample&0xFF);
303 dst[3] = (rsample&0xFF);
305 dst[2] = (rsample&0xFF);
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);
315 dst[1] = (lsample&0xFF);
316 dst[2] = (rsample&0xFF);
318 dst[3] = (rsample&0xFF);
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);
337 dst[0] = (lsample&0xFF);
338 dst[3] = (rsample&0xFF);
340 dst[2] = (rsample&0xFF);
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);
350 dst[1] = (lsample&0xFF);
351 dst[2] = (rsample&0xFF);
353 dst[3] = (rsample&0xFF);
362 if ( cvt->filters[++cvt->filter_index] ) {
363 cvt->filters[cvt->filter_index](cvt, format);
367 /* Duplicate a mono channel to both stereo channels */
368 void SDLCALL SDL_ConvertStereo(SDL_AudioCVT *cvt, Uint16 format)
373 fprintf(stderr, "Converting to stereo\n");
375 if ( (format & 0xFF) == 16 ) {
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 ) {
389 src = cvt->buf+cvt->len_cvt;
390 dst = cvt->buf+cvt->len_cvt*2;
391 for ( i=cvt->len_cvt; i; --i ) {
399 if ( cvt->filters[++cvt->filter_index] ) {
400 cvt->filters[cvt->filter_index](cvt, format);
405 /* Duplicate a stereo channel to a pseudo-5.1 stream */
406 void SDLCALL SDL_ConvertSurround(SDL_AudioCVT *cvt, Uint16 format)
411 fprintf(stderr, "Converting stereo to surround\n");
413 switch (format&0x8018) {
416 Uint8 *src, *dst, lf, rf, ce;
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 ) {
425 ce = (lf/2) + (rf/2);
437 Sint8 *src, *dst, lf, rf, ce;
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 ) {
446 ce = (lf/2) + (rf/2);
459 Uint16 lf, rf, ce, lr, rr;
461 src = cvt->buf+cvt->len_cvt;
462 dst = cvt->buf+cvt->len_cvt*3;
464 if ( (format & 0x1000) == 0x1000 ) {
465 for ( i=cvt->len_cvt/4; i; --i ) {
468 lf = (Uint16)((src[0]<<8)|src[1]);
469 rf = (Uint16)((src[2]<<8)|src[3]);
470 ce = (lf/2) + (rf/2);
474 dst[0] = ((lf>>8)&0xFF);
476 dst[2] = ((rf>>8)&0xFF);
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);
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);
489 for ( i=cvt->len_cvt/4; i; --i ) {
492 lf = (Uint16)((src[1]<<8)|src[0]);
493 rf = (Uint16)((src[3]<<8)|src[2]);
494 ce = (lf/2) + (rf/2);
498 dst[1] = ((lf>>8)&0xFF);
500 dst[3] = ((rf>>8)&0xFF);
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);
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);
518 Sint16 lf, rf, ce, lr, rr;
520 src = cvt->buf+cvt->len_cvt;
521 dst = cvt->buf+cvt->len_cvt*3;
523 if ( (format & 0x1000) == 0x1000 ) {
524 for ( i=cvt->len_cvt/4; i; --i ) {
527 lf = (Sint16)((src[0]<<8)|src[1]);
528 rf = (Sint16)((src[2]<<8)|src[3]);
529 ce = (lf/2) + (rf/2);
533 dst[0] = ((lf>>8)&0xFF);
535 dst[2] = ((rf>>8)&0xFF);
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);
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);
548 for ( i=cvt->len_cvt/4; i; --i ) {
551 lf = (Sint16)((src[1]<<8)|src[0]);
552 rf = (Sint16)((src[3]<<8)|src[2]);
553 ce = (lf/2) + (rf/2);
557 dst[1] = ((lf>>8)&0xFF);
559 dst[3] = ((rf>>8)&0xFF);
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);
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);
576 if ( cvt->filters[++cvt->filter_index] ) {
577 cvt->filters[cvt->filter_index](cvt, format);
582 /* Duplicate a stereo channel to a pseudo-4.0 stream */
583 void SDLCALL SDL_ConvertSurround_4(SDL_AudioCVT *cvt, Uint16 format)
588 fprintf(stderr, "Converting stereo to quad\n");
590 switch (format&0x8018) {
593 Uint8 *src, *dst, lf, rf, ce;
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 ) {
602 ce = (lf/2) + (rf/2);
612 Sint8 *src, *dst, lf, rf, ce;
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 ) {
621 ce = (lf/2) + (rf/2);
632 Uint16 lf, rf, ce, lr, rr;
634 src = cvt->buf+cvt->len_cvt;
635 dst = cvt->buf+cvt->len_cvt*2;
637 if ( (format & 0x1000) == 0x1000 ) {
638 for ( i=cvt->len_cvt/4; i; --i ) {
641 lf = (Uint16)((src[0]<<8)|src[1]);
642 rf = (Uint16)((src[2]<<8)|src[3]);
643 ce = (lf/2) + (rf/2);
647 dst[0] = ((lf>>8)&0xFF);
649 dst[2] = ((rf>>8)&0xFF);
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);
657 for ( i=cvt->len_cvt/4; i; --i ) {
660 lf = (Uint16)((src[1]<<8)|src[0]);
661 rf = (Uint16)((src[3]<<8)|src[2]);
662 ce = (lf/2) + (rf/2);
666 dst[1] = ((lf>>8)&0xFF);
668 dst[3] = ((rf>>8)&0xFF);
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);
681 Sint16 lf, rf, ce, lr, rr;
683 src = cvt->buf+cvt->len_cvt;
684 dst = cvt->buf+cvt->len_cvt*2;
686 if ( (format & 0x1000) == 0x1000 ) {
687 for ( i=cvt->len_cvt/4; i; --i ) {
690 lf = (Sint16)((src[0]<<8)|src[1]);
691 rf = (Sint16)((src[2]<<8)|src[3]);
692 ce = (lf/2) + (rf/2);
696 dst[0] = ((lf>>8)&0xFF);
698 dst[2] = ((rf>>8)&0xFF);
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);
706 for ( i=cvt->len_cvt/4; i; --i ) {
709 lf = (Sint16)((src[1]<<8)|src[0]);
710 rf = (Sint16)((src[3]<<8)|src[2]);
711 ce = (lf/2) + (rf/2);
715 dst[1] = ((lf>>8)&0xFF);
717 dst[3] = ((rf>>8)&0xFF);
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);
729 if ( cvt->filters[++cvt->filter_index] ) {
730 cvt->filters[cvt->filter_index](cvt, format);
735 /* Convert 8-bit to 16-bit - LSB */
736 void SDLCALL SDL_Convert16LSB(SDL_AudioCVT *cvt, Uint16 format)
742 fprintf(stderr, "Converting to 16-bit LSB\n");
744 src = cvt->buf+cvt->len_cvt;
745 dst = cvt->buf+cvt->len_cvt*2;
746 for ( i=cvt->len_cvt; i; --i ) {
752 format = ((format & ~0x0008) | AUDIO_U16LSB);
754 if ( cvt->filters[++cvt->filter_index] ) {
755 cvt->filters[cvt->filter_index](cvt, format);
758 /* Convert 8-bit to 16-bit - MSB */
759 void SDLCALL SDL_Convert16MSB(SDL_AudioCVT *cvt, Uint16 format)
765 fprintf(stderr, "Converting to 16-bit MSB\n");
767 src = cvt->buf+cvt->len_cvt;
768 dst = cvt->buf+cvt->len_cvt*2;
769 for ( i=cvt->len_cvt; i; --i ) {
775 format = ((format & ~0x0008) | AUDIO_U16MSB);
777 if ( cvt->filters[++cvt->filter_index] ) {
778 cvt->filters[cvt->filter_index](cvt, format);
782 /* Convert 16-bit to 8-bit */
783 void SDLCALL SDL_Convert8(SDL_AudioCVT *cvt, Uint16 format)
789 fprintf(stderr, "Converting to 8-bit\n");
793 if ( (format & 0x1000) != 0x1000 ) { /* Little endian */
796 for ( i=cvt->len_cvt/2; i; --i ) {
801 format = ((format & ~0x9010) | AUDIO_U8);
803 if ( cvt->filters[++cvt->filter_index] ) {
804 cvt->filters[cvt->filter_index](cvt, format);
808 /* Toggle signed/unsigned */
809 void SDLCALL SDL_ConvertSign(SDL_AudioCVT *cvt, Uint16 format)
815 fprintf(stderr, "Converting audio signedness\n");
818 if ( (format & 0xFF) == 16 ) {
819 if ( (format & 0x1000) != 0x1000 ) { /* Little endian */
822 for ( i=cvt->len_cvt/2; i; --i ) {
827 for ( i=cvt->len_cvt; i; --i ) {
831 format = (format ^ 0x8000);
832 if ( cvt->filters[++cvt->filter_index] ) {
833 cvt->filters[cvt->filter_index](cvt, format);
837 /* Toggle endianness */
838 void SDLCALL SDL_ConvertEndian(SDL_AudioCVT *cvt, Uint16 format)
844 fprintf(stderr, "Converting audio endianness\n");
847 for ( i=cvt->len_cvt/2; i; --i ) {
853 format = (format ^ 0x1000);
854 if ( cvt->filters[++cvt->filter_index] ) {
855 cvt->filters[cvt->filter_index](cvt, format);
859 /* Convert rate up by multiple of 2 */
860 void SDLCALL SDL_RateMUL2(SDL_AudioCVT *cvt, Uint16 format)
866 fprintf(stderr, "Converting audio rate * 2\n");
868 src = cvt->buf+cvt->len_cvt;
869 dst = cvt->buf+cvt->len_cvt*2;
870 switch (format & 0xFF) {
872 for ( i=cvt->len_cvt; i; --i ) {
880 for ( i=cvt->len_cvt/2; i; --i ) {
891 if ( cvt->filters[++cvt->filter_index] ) {
892 cvt->filters[cvt->filter_index](cvt, format);
897 /* Convert rate up by multiple of 2, for stereo */
898 void SDLCALL SDL_RateMUL2_c2(SDL_AudioCVT *cvt, Uint16 format)
904 fprintf(stderr, "Converting audio rate * 2\n");
906 src = cvt->buf+cvt->len_cvt;
907 dst = cvt->buf+cvt->len_cvt*2;
908 switch (format & 0xFF) {
910 for ( i=cvt->len_cvt/2; i; --i ) {
920 for ( i=cvt->len_cvt/4; i; --i ) {
935 if ( cvt->filters[++cvt->filter_index] ) {
936 cvt->filters[cvt->filter_index](cvt, format);
940 /* Convert rate up by multiple of 2, for quad */
941 void SDLCALL SDL_RateMUL2_c4(SDL_AudioCVT *cvt, Uint16 format)
947 fprintf(stderr, "Converting audio rate * 2\n");
949 src = cvt->buf+cvt->len_cvt;
950 dst = cvt->buf+cvt->len_cvt*2;
951 switch (format & 0xFF) {
953 for ( i=cvt->len_cvt/4; i; --i ) {
967 for ( i=cvt->len_cvt/8; i; --i ) {
990 if ( cvt->filters[++cvt->filter_index] ) {
991 cvt->filters[cvt->filter_index](cvt, format);
996 /* Convert rate up by multiple of 2, for 5.1 */
997 void SDLCALL SDL_RateMUL2_c6(SDL_AudioCVT *cvt, Uint16 format)
1002 #ifdef DEBUG_CONVERT
1003 fprintf(stderr, "Converting audio rate * 2\n");
1005 src = cvt->buf+cvt->len_cvt;
1006 dst = cvt->buf+cvt->len_cvt*2;
1007 switch (format & 0xFF) {
1009 for ( i=cvt->len_cvt/6; i; --i ) {
1027 for ( i=cvt->len_cvt/12; i; --i ) {
1058 if ( cvt->filters[++cvt->filter_index] ) {
1059 cvt->filters[cvt->filter_index](cvt, format);
1063 /* Convert rate down by multiple of 2 */
1064 void SDLCALL SDL_RateDIV2(SDL_AudioCVT *cvt, Uint16 format)
1069 #ifdef DEBUG_CONVERT
1070 fprintf(stderr, "Converting audio rate / 2\n");
1074 switch (format & 0xFF) {
1076 for ( i=cvt->len_cvt/2; i; --i ) {
1083 for ( i=cvt->len_cvt/4; i; --i ) {
1092 if ( cvt->filters[++cvt->filter_index] ) {
1093 cvt->filters[cvt->filter_index](cvt, format);
1098 /* Convert rate down by multiple of 2, for stereo */
1099 void SDLCALL SDL_RateDIV2_c2(SDL_AudioCVT *cvt, Uint16 format)
1104 #ifdef DEBUG_CONVERT
1105 fprintf(stderr, "Converting audio rate / 2\n");
1109 switch (format & 0xFF) {
1111 for ( i=cvt->len_cvt/4; i; --i ) {
1119 for ( i=cvt->len_cvt/8; i; --i ) {
1130 if ( cvt->filters[++cvt->filter_index] ) {
1131 cvt->filters[cvt->filter_index](cvt, format);
1136 /* Convert rate down by multiple of 2, for quad */
1137 void SDLCALL SDL_RateDIV2_c4(SDL_AudioCVT *cvt, Uint16 format)
1142 #ifdef DEBUG_CONVERT
1143 fprintf(stderr, "Converting audio rate / 2\n");
1147 switch (format & 0xFF) {
1149 for ( i=cvt->len_cvt/8; i; --i ) {
1159 for ( i=cvt->len_cvt/16; i; --i ) {
1174 if ( cvt->filters[++cvt->filter_index] ) {
1175 cvt->filters[cvt->filter_index](cvt, format);
1179 /* Convert rate down by multiple of 2, for 5.1 */
1180 void SDLCALL SDL_RateDIV2_c6(SDL_AudioCVT *cvt, Uint16 format)
1185 #ifdef DEBUG_CONVERT
1186 fprintf(stderr, "Converting audio rate / 2\n");
1190 switch (format & 0xFF) {
1192 for ( i=cvt->len_cvt/12; i; --i ) {
1204 for ( i=cvt->len_cvt/24; i; --i ) {
1223 if ( cvt->filters[++cvt->filter_index] ) {
1224 cvt->filters[cvt->filter_index](cvt, format);
1228 /* Very slow rate conversion routine */
1229 void SDLCALL SDL_RateSLOW(SDL_AudioCVT *cvt, Uint16 format)
1234 #ifdef DEBUG_CONVERT
1235 fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0/cvt->rate_incr);
1237 clen = (int)((double)cvt->len_cvt / cvt->rate_incr);
1238 if ( cvt->rate_incr > 1.0 ) {
1239 switch (format & 0xFF) {
1245 for ( i=clen; i; --i ) {
1246 *output = cvt->buf[(int)ipos];
1247 ipos += cvt->rate_incr;
1257 output = (Uint16 *)cvt->buf;
1259 for ( i=clen/2; i; --i ) {
1260 *output=((Uint16 *)cvt->buf)[(int)ipos];
1261 ipos += cvt->rate_incr;
1268 switch (format & 0xFF) {
1272 output = cvt->buf+clen;
1273 ipos = (double)cvt->len_cvt;
1274 for ( i=clen; i; --i ) {
1275 ipos -= cvt->rate_incr;
1277 *output = cvt->buf[(int)ipos];
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;
1291 *output=((Uint16 *)cvt->buf)[(int)ipos];
1297 cvt->len_cvt = clen;
1298 if ( cvt->filters[++cvt->filter_index] ) {
1299 cvt->filters[cvt->filter_index](cvt, format);
1303 int SDL_ConvertAudio(SDL_AudioCVT *cvt)
1305 /* Make sure there's data to convert */
1306 if ( cvt->buf == NULL ) {
1307 SDL_SetError("No buffer allocated for conversion");
1310 /* Return okay if no conversion is necessary */
1311 cvt->len_cvt = cvt->len;
1312 if ( cvt->filters[0] == NULL ) {
1316 /* Set up the conversion and go! */
1317 cvt->filter_index = 0;
1318 cvt->filters[0](cvt, cvt->src_format);
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.
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)
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 */
1335 cvt->filter_index = 0;
1336 cvt->filters[0] = NULL;
1338 cvt->len_ratio = 1.0;
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;
1346 /* Second filter: Sign conversion -- signed/unsigned */
1347 if ( (src_format & 0x8000) != (dst_format & 0x8000) ) {
1348 cvt->filters[cvt->filter_index++] = SDL_ConvertSign;
1351 /* Next filter: Convert 16 bit <--> 8 bit PCM */
1352 if ( (src_format & 0xFF) != (dst_format & 0xFF) ) {
1353 switch (dst_format&0x10FF) {
1355 cvt->filters[cvt->filter_index++] =
1357 cvt->len_ratio /= 2;
1360 cvt->filters[cvt->filter_index++] =
1363 cvt->len_ratio *= 2;
1366 cvt->filters[cvt->filter_index++] =
1369 cvt->len_ratio *= 2;
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++] =
1381 cvt->len_ratio *= 2;
1383 if ( (src_channels == 2) &&
1384 (dst_channels == 6) ) {
1385 cvt->filters[cvt->filter_index++] =
1386 SDL_ConvertSurround;
1389 cvt->len_ratio *= 3;
1391 if ( (src_channels == 2) &&
1392 (dst_channels == 4) ) {
1393 cvt->filters[cvt->filter_index++] =
1394 SDL_ConvertSurround_4;
1397 cvt->len_ratio *= 2;
1399 while ( (src_channels*2) <= dst_channels ) {
1400 cvt->filters[cvt->filter_index++] =
1404 cvt->len_ratio *= 2;
1406 if ( (src_channels == 6) &&
1407 (dst_channels <= 2) ) {
1408 cvt->filters[cvt->filter_index++] =
1411 cvt->len_ratio /= 3;
1413 if ( (src_channels == 6) &&
1414 (dst_channels == 4) ) {
1415 cvt->filters[cvt->filter_index++] =
1418 cvt->len_ratio /= 2;
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.
1424 while ( ((src_channels%2) == 0) &&
1425 ((src_channels/2) >= dst_channels) ) {
1426 cvt->filters[cvt->filter_index++] =
1429 cvt->len_ratio /= 2;
1431 if ( src_channels != dst_channels ) {
1436 /* Do rate conversion */
1437 cvt->rate_incr = 0.0;
1438 if ( (src_rate/100) != (dst_rate/100) ) {
1439 Uint32 hi_rate, lo_rate;
1442 void (SDLCALL *rate_cvt)(SDL_AudioCVT *cvt, Uint16 format);
1444 if ( src_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;
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;
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;
1474 cvt->len_ratio *= len_ratio;
1476 /* We may need a slow conversion here to finish up */
1477 if ( (lo_rate/100) != (hi_rate/100) ) {
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)
1484 /* For now, punt and hope the rate distortion isn't great.
1487 if ( src_rate < dst_rate ) {
1488 cvt->rate_incr = (double)lo_rate/hi_rate;
1490 cvt->len_ratio /= cvt->rate_incr;
1492 cvt->rate_incr = (double)hi_rate/lo_rate;
1493 cvt->len_ratio *= cvt->rate_incr;
1495 cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
1500 /* Set up the filter information */
1501 if ( cvt->filter_index != 0 ) {
1503 cvt->src_format = src_format;
1504 cvt->dst_format = dst_format;
1507 cvt->filters[cvt->filter_index] = NULL;
1509 return(cvt->needed);