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