Final merge of Google Summer of Code 2008 work...
Audio Ideas - Resampling and Pitch Shifting
by Aaron Wishnick, mentored by Ryan C. Gordon
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 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"
25 /* Functions for audio drivers to perform runtime conversion of audio format */
27 #include "SDL_audio.h"
28 #include "SDL_audio_c.h"
32 /* These are fractional multiplication routines. That is, their inputs
33 are two numbers in the range [-1, 1) and the result falls in that
34 same range. The output is the same size as the inputs, i.e.
35 32-bit x 32-bit = 32-bit.
38 /* We hope here that the right shift includes sign extension */
39 #ifdef SDL_HAS_64BIT_Type
40 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
42 /* If we don't have the 64-bit type, do something more complicated. See http://www.8052.com/mul16.phtml or http://www.cs.uaf.edu/~cs301/notes/Chapter5/node5.html */
43 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
45 #define SDL_FixMpy16(a, b) ((((Sint32)a * (Sint32)b) >> 14) & 0xffff)
46 #define SDL_FixMpy8(a, b) ((((Sint16)a * (Sint16)b) >> 7) & 0xff)
47 /* This macro just makes the floating point filtering code not have to be a special case. */
48 #define SDL_FloatMpy(a, b) (a * b)
50 /* These macros take floating point numbers in the range [-1.0f, 1.0f) and
51 represent them as fixed-point numbers in that same range. There's no
52 checking that the floating point argument is inside the appropriate range.
55 #define SDL_Make_1_7(a) (Sint8)(a * 128.0f)
56 #define SDL_Make_1_15(a) (Sint16)(a * 32768.0f)
57 #define SDL_Make_1_31(a) (Sint32)(a * 2147483648.0f)
58 #define SDL_Make_2_6(a) (Sint8)(a * 64.0f)
59 #define SDL_Make_2_14(a) (Sint16)(a * 16384.0f)
60 #define SDL_Make_2_30(a) (Sint32)(a * 1073741824.0f)
62 /* Effectively mix right and left channels into a single channel */
64 SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
70 fprintf(stderr, "Converting to mono\n");
72 switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
79 for (i = cvt->len_cvt / 2; i; --i) {
80 sample = src[0] + src[1];
81 *dst = (Uint8) (sample / 2);
92 src = (Sint8 *) cvt->buf;
93 dst = (Sint8 *) cvt->buf;
94 for (i = cvt->len_cvt / 2; i; --i) {
95 sample = src[0] + src[1];
96 *dst = (Sint8) (sample / 2);
109 if (SDL_AUDIO_ISBIGENDIAN(format)) {
110 for (i = cvt->len_cvt / 4; i; --i) {
111 sample = (Uint16) ((src[0] << 8) | src[1]) +
112 (Uint16) ((src[2] << 8) | src[3]);
114 dst[1] = (sample & 0xFF);
116 dst[0] = (sample & 0xFF);
121 for (i = cvt->len_cvt / 4; i; --i) {
122 sample = (Uint16) ((src[1] << 8) | src[0]) +
123 (Uint16) ((src[3] << 8) | src[2]);
125 dst[0] = (sample & 0xFF);
127 dst[1] = (sample & 0xFF);
141 if (SDL_AUDIO_ISBIGENDIAN(format)) {
142 for (i = cvt->len_cvt / 4; i; --i) {
143 sample = (Sint16) ((src[0] << 8) | src[1]) +
144 (Sint16) ((src[2] << 8) | src[3]);
146 dst[1] = (sample & 0xFF);
148 dst[0] = (sample & 0xFF);
153 for (i = cvt->len_cvt / 4; i; --i) {
154 sample = (Sint16) ((src[1] << 8) | src[0]) +
155 (Sint16) ((src[3] << 8) | src[2]);
157 dst[0] = (sample & 0xFF);
159 dst[1] = (sample & 0xFF);
169 const Uint32 *src = (const Uint32 *) cvt->buf;
170 Uint32 *dst = (Uint32 *) cvt->buf;
171 if (SDL_AUDIO_ISBIGENDIAN(format)) {
172 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
174 (((Sint64) (Sint32) SDL_SwapBE32(src[0])) +
175 ((Sint64) (Sint32) SDL_SwapBE32(src[1])));
176 *(dst++) = SDL_SwapBE32((Uint32) ((Sint32) (added / 2)));
179 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
181 (((Sint64) (Sint32) SDL_SwapLE32(src[0])) +
182 ((Sint64) (Sint32) SDL_SwapLE32(src[1])));
183 *(dst++) = SDL_SwapLE32((Uint32) ((Sint32) (added / 2)));
191 const float *src = (const float *) cvt->buf;
192 float *dst = (float *) cvt->buf;
193 if (SDL_AUDIO_ISBIGENDIAN(format)) {
194 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
195 const float src1 = SDL_SwapFloatBE(src[0]);
196 const float src2 = SDL_SwapFloatBE(src[1]);
197 const double added = ((double) src1) + ((double) src2);
198 const float halved = (float) (added * 0.5);
199 *(dst++) = SDL_SwapFloatBE(halved);
202 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
203 const float src1 = SDL_SwapFloatLE(src[0]);
204 const float src2 = SDL_SwapFloatLE(src[1]);
205 const double added = ((double) src1) + ((double) src2);
206 const float halved = (float) (added * 0.5);
207 *(dst++) = SDL_SwapFloatLE(halved);
215 if (cvt->filters[++cvt->filter_index]) {
216 cvt->filters[cvt->filter_index] (cvt, format);
221 /* Discard top 4 channels */
223 SDL_ConvertStrip(SDL_AudioCVT * cvt, SDL_AudioFormat format)
228 fprintf(stderr, "Converting down from 6 channels to stereo\n");
231 #define strip_chans_6_to_2(type) \
233 const type *src = (const type *) cvt->buf; \
234 type *dst = (type *) cvt->buf; \
235 for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
243 /* this function only cares about typesize, and data as a block of bits. */
244 switch (SDL_AUDIO_BITSIZE(format)) {
246 strip_chans_6_to_2(Uint8);
249 strip_chans_6_to_2(Uint16);
252 strip_chans_6_to_2(Uint32);
256 #undef strip_chans_6_to_2
259 if (cvt->filters[++cvt->filter_index]) {
260 cvt->filters[cvt->filter_index] (cvt, format);
265 /* Discard top 2 channels of 6 */
267 SDL_ConvertStrip_2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
272 fprintf(stderr, "Converting 6 down to quad\n");
275 #define strip_chans_6_to_4(type) \
277 const type *src = (const type *) cvt->buf; \
278 type *dst = (type *) cvt->buf; \
279 for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
289 /* this function only cares about typesize, and data as a block of bits. */
290 switch (SDL_AUDIO_BITSIZE(format)) {
292 strip_chans_6_to_4(Uint8);
295 strip_chans_6_to_4(Uint16);
298 strip_chans_6_to_4(Uint32);
302 #undef strip_chans_6_to_4
306 if (cvt->filters[++cvt->filter_index]) {
307 cvt->filters[cvt->filter_index] (cvt, format);
311 /* Duplicate a mono channel to both stereo channels */
313 SDL_ConvertStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
318 fprintf(stderr, "Converting to stereo\n");
321 #define dup_chans_1_to_2(type) \
323 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
324 type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
325 for (i = cvt->len_cvt / 2; i; --i, --src) { \
326 const type val = *src; \
328 dst[0] = dst[1] = val; \
332 /* this function only cares about typesize, and data as a block of bits. */
333 switch (SDL_AUDIO_BITSIZE(format)) {
335 dup_chans_1_to_2(Uint8);
338 dup_chans_1_to_2(Uint16);
341 dup_chans_1_to_2(Uint32);
345 #undef dup_chans_1_to_2
348 if (cvt->filters[++cvt->filter_index]) {
349 cvt->filters[cvt->filter_index] (cvt, format);
354 /* Duplicate a stereo channel to a pseudo-5.1 stream */
356 SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
361 fprintf(stderr, "Converting stereo to surround\n");
364 switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
367 Uint8 *src, *dst, lf, rf, ce;
369 src = (Uint8 *) (cvt->buf + cvt->len_cvt);
370 dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 3);
371 for (i = cvt->len_cvt; i; --i) {
376 ce = (lf / 2) + (rf / 2);
389 Sint8 *src, *dst, lf, rf, ce;
391 src = (Sint8 *) cvt->buf + cvt->len_cvt;
392 dst = (Sint8 *) cvt->buf + cvt->len_cvt * 3;
393 for (i = cvt->len_cvt; i; --i) {
398 ce = (lf / 2) + (rf / 2);
412 Uint16 lf, rf, ce, lr, rr;
414 src = cvt->buf + cvt->len_cvt;
415 dst = cvt->buf + cvt->len_cvt * 3;
417 if (SDL_AUDIO_ISBIGENDIAN(format)) {
418 for (i = cvt->len_cvt / 4; i; --i) {
421 lf = (Uint16) ((src[0] << 8) | src[1]);
422 rf = (Uint16) ((src[2] << 8) | src[3]);
423 ce = (lf / 2) + (rf / 2);
426 dst[1] = (lf & 0xFF);
427 dst[0] = ((lf >> 8) & 0xFF);
428 dst[3] = (rf & 0xFF);
429 dst[2] = ((rf >> 8) & 0xFF);
431 dst[1 + 4] = (lr & 0xFF);
432 dst[0 + 4] = ((lr >> 8) & 0xFF);
433 dst[3 + 4] = (rr & 0xFF);
434 dst[2 + 4] = ((rr >> 8) & 0xFF);
436 dst[1 + 8] = (ce & 0xFF);
437 dst[0 + 8] = ((ce >> 8) & 0xFF);
438 dst[3 + 8] = (ce & 0xFF);
439 dst[2 + 8] = ((ce >> 8) & 0xFF);
442 for (i = cvt->len_cvt / 4; i; --i) {
445 lf = (Uint16) ((src[1] << 8) | src[0]);
446 rf = (Uint16) ((src[3] << 8) | src[2]);
447 ce = (lf / 2) + (rf / 2);
450 dst[0] = (lf & 0xFF);
451 dst[1] = ((lf >> 8) & 0xFF);
452 dst[2] = (rf & 0xFF);
453 dst[3] = ((rf >> 8) & 0xFF);
455 dst[0 + 4] = (lr & 0xFF);
456 dst[1 + 4] = ((lr >> 8) & 0xFF);
457 dst[2 + 4] = (rr & 0xFF);
458 dst[3 + 4] = ((rr >> 8) & 0xFF);
460 dst[0 + 8] = (ce & 0xFF);
461 dst[1 + 8] = ((ce >> 8) & 0xFF);
462 dst[2 + 8] = (ce & 0xFF);
463 dst[3 + 8] = ((ce >> 8) & 0xFF);
472 Sint16 lf, rf, ce, lr, rr;
474 src = cvt->buf + cvt->len_cvt;
475 dst = cvt->buf + cvt->len_cvt * 3;
477 if (SDL_AUDIO_ISBIGENDIAN(format)) {
478 for (i = cvt->len_cvt / 4; i; --i) {
481 lf = (Sint16) ((src[0] << 8) | src[1]);
482 rf = (Sint16) ((src[2] << 8) | src[3]);
483 ce = (lf / 2) + (rf / 2);
486 dst[1] = (lf & 0xFF);
487 dst[0] = ((lf >> 8) & 0xFF);
488 dst[3] = (rf & 0xFF);
489 dst[2] = ((rf >> 8) & 0xFF);
491 dst[1 + 4] = (lr & 0xFF);
492 dst[0 + 4] = ((lr >> 8) & 0xFF);
493 dst[3 + 4] = (rr & 0xFF);
494 dst[2 + 4] = ((rr >> 8) & 0xFF);
496 dst[1 + 8] = (ce & 0xFF);
497 dst[0 + 8] = ((ce >> 8) & 0xFF);
498 dst[3 + 8] = (ce & 0xFF);
499 dst[2 + 8] = ((ce >> 8) & 0xFF);
502 for (i = cvt->len_cvt / 4; i; --i) {
505 lf = (Sint16) ((src[1] << 8) | src[0]);
506 rf = (Sint16) ((src[3] << 8) | src[2]);
507 ce = (lf / 2) + (rf / 2);
510 dst[0] = (lf & 0xFF);
511 dst[1] = ((lf >> 8) & 0xFF);
512 dst[2] = (rf & 0xFF);
513 dst[3] = ((rf >> 8) & 0xFF);
515 dst[0 + 4] = (lr & 0xFF);
516 dst[1 + 4] = ((lr >> 8) & 0xFF);
517 dst[2 + 4] = (rr & 0xFF);
518 dst[3 + 4] = ((rr >> 8) & 0xFF);
520 dst[0 + 8] = (ce & 0xFF);
521 dst[1 + 8] = ((ce >> 8) & 0xFF);
522 dst[2 + 8] = (ce & 0xFF);
523 dst[3 + 8] = ((ce >> 8) & 0xFF);
532 const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
533 Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
535 if (SDL_AUDIO_ISBIGENDIAN(format)) {
536 for (i = cvt->len_cvt / 8; i; --i) {
539 lf = (Sint32) SDL_SwapBE32(src[0]);
540 rf = (Sint32) SDL_SwapBE32(src[1]);
541 ce = (lf / 2) + (rf / 2);
542 dst[0] = SDL_SwapBE32((Uint32) lf);
543 dst[1] = SDL_SwapBE32((Uint32) rf);
544 dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
545 dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
546 dst[4] = SDL_SwapBE32((Uint32) ce);
547 dst[5] = SDL_SwapBE32((Uint32) ce);
550 for (i = cvt->len_cvt / 8; i; --i) {
553 lf = (Sint32) SDL_SwapLE32(src[0]);
554 rf = (Sint32) SDL_SwapLE32(src[1]);
555 ce = (lf / 2) + (rf / 2);
558 dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
559 dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
560 dst[4] = SDL_SwapLE32((Uint32) ce);
561 dst[5] = SDL_SwapLE32((Uint32) ce);
570 const float *src = (const float *) cvt->buf + cvt->len_cvt;
571 float *dst = (float *) cvt->buf + cvt->len_cvt * 3;
573 if (SDL_AUDIO_ISBIGENDIAN(format)) {
574 for (i = cvt->len_cvt / 8; i; --i) {
577 lf = SDL_SwapFloatBE(src[0]);
578 rf = SDL_SwapFloatBE(src[1]);
579 ce = (lf * 0.5f) + (rf * 0.5f);
582 dst[2] = SDL_SwapFloatBE(lf - ce);
583 dst[3] = SDL_SwapFloatBE(rf - ce);
584 dst[4] = dst[5] = SDL_SwapFloatBE(ce);
587 for (i = cvt->len_cvt / 8; i; --i) {
590 lf = SDL_SwapFloatLE(src[0]);
591 rf = SDL_SwapFloatLE(src[1]);
592 ce = (lf * 0.5f) + (rf * 0.5f);
595 dst[2] = SDL_SwapFloatLE(lf - ce);
596 dst[3] = SDL_SwapFloatLE(rf - ce);
597 dst[4] = dst[5] = SDL_SwapFloatLE(ce);
605 if (cvt->filters[++cvt->filter_index]) {
606 cvt->filters[cvt->filter_index] (cvt, format);
611 /* Duplicate a stereo channel to a pseudo-4.0 stream */
613 SDL_ConvertSurround_4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
618 fprintf(stderr, "Converting stereo to quad\n");
621 switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
624 Uint8 *src, *dst, lf, rf, ce;
626 src = (Uint8 *) (cvt->buf + cvt->len_cvt);
627 dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 2);
628 for (i = cvt->len_cvt; i; --i) {
633 ce = (lf / 2) + (rf / 2);
644 Sint8 *src, *dst, lf, rf, ce;
646 src = (Sint8 *) cvt->buf + cvt->len_cvt;
647 dst = (Sint8 *) cvt->buf + cvt->len_cvt * 2;
648 for (i = cvt->len_cvt; i; --i) {
653 ce = (lf / 2) + (rf / 2);
665 Uint16 lf, rf, ce, lr, rr;
667 src = cvt->buf + cvt->len_cvt;
668 dst = cvt->buf + cvt->len_cvt * 2;
670 if (SDL_AUDIO_ISBIGENDIAN(format)) {
671 for (i = cvt->len_cvt / 4; i; --i) {
674 lf = (Uint16) ((src[0] << 8) | src[1]);
675 rf = (Uint16) ((src[2] << 8) | src[3]);
676 ce = (lf / 2) + (rf / 2);
679 dst[1] = (lf & 0xFF);
680 dst[0] = ((lf >> 8) & 0xFF);
681 dst[3] = (rf & 0xFF);
682 dst[2] = ((rf >> 8) & 0xFF);
684 dst[1 + 4] = (lr & 0xFF);
685 dst[0 + 4] = ((lr >> 8) & 0xFF);
686 dst[3 + 4] = (rr & 0xFF);
687 dst[2 + 4] = ((rr >> 8) & 0xFF);
690 for (i = cvt->len_cvt / 4; i; --i) {
693 lf = (Uint16) ((src[1] << 8) | src[0]);
694 rf = (Uint16) ((src[3] << 8) | src[2]);
695 ce = (lf / 2) + (rf / 2);
698 dst[0] = (lf & 0xFF);
699 dst[1] = ((lf >> 8) & 0xFF);
700 dst[2] = (rf & 0xFF);
701 dst[3] = ((rf >> 8) & 0xFF);
703 dst[0 + 4] = (lr & 0xFF);
704 dst[1 + 4] = ((lr >> 8) & 0xFF);
705 dst[2 + 4] = (rr & 0xFF);
706 dst[3 + 4] = ((rr >> 8) & 0xFF);
715 Sint16 lf, rf, ce, lr, rr;
717 src = cvt->buf + cvt->len_cvt;
718 dst = cvt->buf + cvt->len_cvt * 2;
720 if (SDL_AUDIO_ISBIGENDIAN(format)) {
721 for (i = cvt->len_cvt / 4; i; --i) {
724 lf = (Sint16) ((src[0] << 8) | src[1]);
725 rf = (Sint16) ((src[2] << 8) | src[3]);
726 ce = (lf / 2) + (rf / 2);
729 dst[1] = (lf & 0xFF);
730 dst[0] = ((lf >> 8) & 0xFF);
731 dst[3] = (rf & 0xFF);
732 dst[2] = ((rf >> 8) & 0xFF);
734 dst[1 + 4] = (lr & 0xFF);
735 dst[0 + 4] = ((lr >> 8) & 0xFF);
736 dst[3 + 4] = (rr & 0xFF);
737 dst[2 + 4] = ((rr >> 8) & 0xFF);
740 for (i = cvt->len_cvt / 4; i; --i) {
743 lf = (Sint16) ((src[1] << 8) | src[0]);
744 rf = (Sint16) ((src[3] << 8) | src[2]);
745 ce = (lf / 2) + (rf / 2);
748 dst[0] = (lf & 0xFF);
749 dst[1] = ((lf >> 8) & 0xFF);
750 dst[2] = (rf & 0xFF);
751 dst[3] = ((rf >> 8) & 0xFF);
753 dst[0 + 4] = (lr & 0xFF);
754 dst[1 + 4] = ((lr >> 8) & 0xFF);
755 dst[2 + 4] = (rr & 0xFF);
756 dst[3 + 4] = ((rr >> 8) & 0xFF);
764 const Uint32 *src = (const Uint32 *) (cvt->buf + cvt->len_cvt);
765 Uint32 *dst = (Uint32 *) (cvt->buf + cvt->len_cvt * 2);
768 if (SDL_AUDIO_ISBIGENDIAN(format)) {
769 for (i = cvt->len_cvt / 8; i; --i) {
772 lf = (Sint32) SDL_SwapBE32(src[0]);
773 rf = (Sint32) SDL_SwapBE32(src[1]);
774 ce = (lf / 2) + (rf / 2);
777 dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
778 dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
781 for (i = cvt->len_cvt / 8; i; --i) {
784 lf = (Sint32) SDL_SwapLE32(src[0]);
785 rf = (Sint32) SDL_SwapLE32(src[1]);
786 ce = (lf / 2) + (rf / 2);
789 dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
790 dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
797 if (cvt->filters[++cvt->filter_index]) {
798 cvt->filters[cvt->filter_index] (cvt, format);
802 /* Convert rate up by multiple of 2 */
804 SDL_RateMUL2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
809 fprintf(stderr, "Converting audio rate * 2 (mono)\n");
812 #define mul2_mono(type) { \
813 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
814 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
815 for (i = cvt->len_cvt / sizeof (type); i; --i) { \
817 dst[-1] = dst[-2] = src[0]; \
822 switch (SDL_AUDIO_BITSIZE(format)) {
837 if (cvt->filters[++cvt->filter_index]) {
838 cvt->filters[cvt->filter_index] (cvt, format);
843 /* Convert rate up by multiple of 2, for stereo */
845 SDL_RateMUL2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
850 fprintf(stderr, "Converting audio rate * 2 (stereo)\n");
853 #define mul2_stereo(type) { \
854 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
855 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
856 for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
857 const type r = src[-1]; \
858 const type l = src[-2]; \
868 switch (SDL_AUDIO_BITSIZE(format)) {
883 if (cvt->filters[++cvt->filter_index]) {
884 cvt->filters[cvt->filter_index] (cvt, format);
888 /* Convert rate up by multiple of 2, for quad */
890 SDL_RateMUL2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
895 fprintf(stderr, "Converting audio rate * 2 (quad)\n");
898 #define mul2_quad(type) { \
899 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
900 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
901 for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
902 const type c1 = src[-1]; \
903 const type c2 = src[-2]; \
904 const type c3 = src[-3]; \
905 const type c4 = src[-4]; \
919 switch (SDL_AUDIO_BITSIZE(format)) {
934 if (cvt->filters[++cvt->filter_index]) {
935 cvt->filters[cvt->filter_index] (cvt, format);
940 /* Convert rate up by multiple of 2, for 5.1 */
942 SDL_RateMUL2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
947 fprintf(stderr, "Converting audio rate * 2 (six channels)\n");
950 #define mul2_chansix(type) { \
951 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
952 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
953 for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
954 const type c1 = src[-1]; \
955 const type c2 = src[-2]; \
956 const type c3 = src[-3]; \
957 const type c4 = src[-4]; \
958 const type c5 = src[-5]; \
959 const type c6 = src[-6]; \
977 switch (SDL_AUDIO_BITSIZE(format)) {
982 mul2_chansix(Uint16);
985 mul2_chansix(Uint32);
992 if (cvt->filters[++cvt->filter_index]) {
993 cvt->filters[cvt->filter_index] (cvt, format);
997 /* Convert rate down by multiple of 2 */
999 SDL_RateDIV2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1003 #ifdef DEBUG_CONVERT
1004 fprintf(stderr, "Converting audio rate / 2 (mono)\n");
1007 #define div2_mono(type) { \
1008 const type *src = (const type *) cvt->buf; \
1009 type *dst = (type *) cvt->buf; \
1010 for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
1017 switch (SDL_AUDIO_BITSIZE(format)) {
1032 if (cvt->filters[++cvt->filter_index]) {
1033 cvt->filters[cvt->filter_index] (cvt, format);
1038 /* Convert rate down by multiple of 2, for stereo */
1040 SDL_RateDIV2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1044 #ifdef DEBUG_CONVERT
1045 fprintf(stderr, "Converting audio rate / 2 (stereo)\n");
1048 #define div2_stereo(type) { \
1049 const type *src = (const type *) cvt->buf; \
1050 type *dst = (type *) cvt->buf; \
1051 for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
1059 switch (SDL_AUDIO_BITSIZE(format)) {
1064 div2_stereo(Uint16);
1067 div2_stereo(Uint32);
1074 if (cvt->filters[++cvt->filter_index]) {
1075 cvt->filters[cvt->filter_index] (cvt, format);
1080 /* Convert rate down by multiple of 2, for quad */
1082 SDL_RateDIV2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1086 #ifdef DEBUG_CONVERT
1087 fprintf(stderr, "Converting audio rate / 2 (quad)\n");
1090 #define div2_quad(type) { \
1091 const type *src = (const type *) cvt->buf; \
1092 type *dst = (type *) cvt->buf; \
1093 for (i = cvt->len_cvt / (sizeof (type) * 8); i; --i) { \
1103 switch (SDL_AUDIO_BITSIZE(format)) {
1118 if (cvt->filters[++cvt->filter_index]) {
1119 cvt->filters[cvt->filter_index] (cvt, format);
1123 /* Convert rate down by multiple of 2, for 5.1 */
1125 SDL_RateDIV2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1129 #ifdef DEBUG_CONVERT
1130 fprintf(stderr, "Converting audio rate / 2 (six channels)\n");
1133 #define div2_chansix(type) { \
1134 const type *src = (const type *) cvt->buf; \
1135 type *dst = (type *) cvt->buf; \
1136 for (i = cvt->len_cvt / (sizeof (type) * 12); i; --i) { \
1148 switch (SDL_AUDIO_BITSIZE(format)) {
1150 div2_chansix(Uint8);
1153 div2_chansix(Uint16);
1156 div2_chansix(Uint32);
1163 if (cvt->filters[++cvt->filter_index]) {
1164 cvt->filters[cvt->filter_index] (cvt, format);
1168 /* Very slow rate conversion routine */
1170 SDL_RateSLOW(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1175 #ifdef DEBUG_CONVERT
1176 fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0 / cvt->rate_incr);
1178 clen = (int) ((double) cvt->len_cvt / cvt->rate_incr);
1179 if (cvt->rate_incr > 1.0) {
1180 switch (SDL_AUDIO_BITSIZE(format)) {
1187 for (i = clen; i; --i) {
1188 *output = cvt->buf[(int) ipos];
1189 ipos += cvt->rate_incr;
1200 output = (Uint16 *) cvt->buf;
1202 for (i = clen / 2; i; --i) {
1203 *output = ((Uint16 *) cvt->buf)[(int) ipos];
1204 ipos += cvt->rate_incr;
1212 /* !!! FIXME: need 32-bit converter here! */
1213 #ifdef DEBUG_CONVERT
1214 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
1219 switch (SDL_AUDIO_BITSIZE(format)) {
1224 output = cvt->buf + clen;
1225 ipos = (double) cvt->len_cvt;
1226 for (i = clen; i; --i) {
1227 ipos -= cvt->rate_incr;
1229 *output = cvt->buf[(int) ipos];
1239 output = (Uint16 *) (cvt->buf + clen);
1240 ipos = (double) cvt->len_cvt / 2;
1241 for (i = clen / 2; i; --i) {
1242 ipos -= cvt->rate_incr;
1244 *output = ((Uint16 *) cvt->buf)[(int) ipos];
1251 /* !!! FIXME: need 32-bit converter here! */
1252 #ifdef DEBUG_CONVERT
1253 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
1259 cvt->len_cvt = clen;
1260 if (cvt->filters[++cvt->filter_index]) {
1261 cvt->filters[cvt->filter_index] (cvt, format);
1266 SDL_ConvertAudio(SDL_AudioCVT * cvt)
1268 /* Make sure there's data to convert */
1269 if (cvt->buf == NULL) {
1270 SDL_SetError("No buffer allocated for conversion");
1273 /* Return okay if no conversion is necessary */
1274 cvt->len_cvt = cvt->len;
1275 if (cvt->filters[0] == NULL) {
1279 /* Set up the conversion and go! */
1280 cvt->filter_index = 0;
1281 cvt->filters[0] (cvt, cvt->src_format);
1286 static SDL_AudioFilter
1287 SDL_HandTunedTypeCVT(SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
1290 * Fill in any future conversions that are specialized to a
1291 * processor, platform, compiler, or library here.
1294 return NULL; /* no specialized converter code available. */
1299 * Find a converter between two data types. We try to select a hand-tuned
1300 * asm/vectorized/optimized function first, and then fallback to an
1301 * autogenerated function that is customized to convert between two
1302 * specific data types.
1305 SDL_BuildAudioTypeCVT(SDL_AudioCVT * cvt,
1306 SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
1308 if (src_fmt != dst_fmt) {
1309 const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt);
1310 const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt);
1311 SDL_AudioFilter filter = SDL_HandTunedTypeCVT(src_fmt, dst_fmt);
1313 /* No hand-tuned converter? Try the autogenerated ones. */
1314 if (filter == NULL) {
1316 for (i = 0; sdl_audio_type_filters[i].filter != NULL; i++) {
1317 const SDL_AudioTypeFilters *filt = &sdl_audio_type_filters[i];
1318 if ((filt->src_fmt == src_fmt) && (filt->dst_fmt == dst_fmt)) {
1319 filter = filt->filter;
1324 if (filter == NULL) {
1325 return -1; /* Still no matching converter?! */
1329 /* Update (cvt) with filter details... */
1330 cvt->filters[cvt->filter_index++] = filter;
1331 if (src_bitsize < dst_bitsize) {
1332 const int mult = (dst_bitsize / src_bitsize);
1333 cvt->len_mult *= mult;
1334 cvt->len_ratio *= mult;
1335 } else if (src_bitsize > dst_bitsize) {
1336 cvt->len_ratio /= (src_bitsize / dst_bitsize);
1339 return 1; /* added a converter. */
1342 return 0; /* no conversion necessary. */
1345 /* Generate the necessary IIR lowpass coefficients for resampling.
1346 Assume that the SDL_AudioCVT struct is already set up with
1347 the correct values for len_mult and len_div, and use the
1348 type of dst_format. Also assume the buffer is allocated.
1349 Note the buffer needs to be 6 units long.
1350 For now, use RBJ's cookbook coefficients. It might be more
1351 optimal to create a Butterworth filter, but this is more difficult.
1354 SDL_BuildIIRLowpass(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1356 float fc; /* cutoff frequency */
1357 float coeff[6]; /* floating point iir coefficients b0, b1, b2, a0, a1, a2 */
1359 float w0, alpha, cosw0;
1362 /* The higher Q is, the higher CUTOFF can be. Need to find a good balance to avoid aliasing */
1363 static const float Q = 5.0f;
1364 static const float CUTOFF = 0.4f;
1366 fc = (cvt->len_mult >
1367 cvt->len_div) ? CUTOFF / (float) cvt->len_mult : CUTOFF /
1368 (float) cvt->len_div;
1370 w0 = 2.0f * M_PI * fc;
1372 alpha = sin(w0) / (2.0f * Q);
1374 /* Compute coefficients, normalizing by a0 */
1375 scale = 1.0f / (1.0f + alpha);
1377 coeff[0] = (1.0f - cosw0) / 2.0f * scale;
1378 coeff[1] = (1.0f - cosw0) * scale;
1379 coeff[2] = coeff[0];
1381 coeff[3] = 1.0f; /* a0 is normalized to 1 */
1382 coeff[4] = -2.0f * cosw0 * scale;
1383 coeff[5] = (1.0f - alpha) * scale;
1385 /* Copy the coefficients to the struct. If necessary, convert coefficients to fixed point, using the range (-2.0, 2.0) */
1386 #define convert_fixed(type, fix) { \
1387 type *cvt_coeff = (type *)cvt->coeff; \
1388 for(i = 0; i < 6; ++i) { \
1389 cvt_coeff[i] = fix(coeff[i]); \
1393 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1394 float *cvt_coeff = (float *) cvt->coeff;
1395 for (i = 0; i < 6; ++i) {
1396 cvt_coeff[i] = coeff[i];
1399 switch (SDL_AUDIO_BITSIZE(format)) {
1401 convert_fixed(Uint8, SDL_Make_2_6);
1404 convert_fixed(Uint16, SDL_Make_2_14);
1407 convert_fixed(Uint32, SDL_Make_2_30);
1412 #ifdef DEBUG_CONVERT
1413 #define debug_iir(type) { \
1414 type *cvt_coeff = (type *)cvt->coeff; \
1415 for(i = 0; i < 6; ++i) { \
1416 printf("coeff[%u] = %f = 0x%x\n", i, coeff[i], cvt_coeff[i]); \
1419 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1420 float *cvt_coeff = (float *) cvt->coeff;
1421 for (i = 0; i < 6; ++i) {
1422 printf("coeff[%u] = %f = %f\n", i, coeff[i], cvt_coeff[i]);
1425 switch (SDL_AUDIO_BITSIZE(format)) {
1440 /* Initialize the state buffer to all zeroes, and set initial position */
1441 memset(cvt->state_buf, 0, 4 * SDL_AUDIO_BITSIZE(format) / 4);
1443 #undef convert_fixed
1446 /* Apply the lowpass IIR filter to the given SDL_AudioCVT struct */
1447 /* This was implemented because it would be much faster than the fir filter,
1448 but it doesn't seem to have a steep enough cutoff so we'd need several
1449 cascaded biquads, which probably isn't a great idea. Therefore, this
1450 function can probably be discarded.
1453 SDL_FilterIIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1457 /* TODO: Check that n is calculated right */
1458 n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
1460 /* Note that the coefficients are 2_x and the input is 1_x. Do we need to shift left at the end here? The right shift temp = buf[n] >> 1 needs to depend on whether the type is signed or not for sign extension. */
1461 /* cvt->state_pos = 1: state[0] = x_n-1, state[1] = x_n-2, state[2] = y_n-1, state[3] - y_n-2 */
1462 #define iir_fix(type, mult) {\
1463 type *coeff = (type *)cvt->coeff; \
1464 type *state = (type *)cvt->state_buf; \
1465 type *buf = (type *)cvt->buf; \
1467 for(i = 0; i < n; ++i) { \
1468 temp = buf[i] >> 1; \
1469 if(cvt->state_pos) { \
1470 buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[0]) + mult(coeff[2], state[1]) - mult(coeff[4], state[2]) - mult(coeff[5], state[3]); \
1472 state[3] = buf[i]; \
1473 cvt->state_pos = 0; \
1475 buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[1]) + mult(coeff[2], state[0]) - mult(coeff[4], state[3]) - mult(coeff[5], state[2]); \
1477 state[2] = buf[i]; \
1478 cvt->state_pos = 1; \
1482 /* Need to test to see if the previous method or this one is faster */
1483 /*#define iir_fix(type, mult) {\
1484 type *coeff = (type *)cvt->coeff; \
1485 type *state = (type *)cvt->state_buf; \
1486 type *buf = (type *)cvt->buf; \
1488 for(i = 0; i < n; ++i) { \
1489 temp = buf[i] >> 1; \
1490 buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[0]) + mult(coeff[2], state[1]) - mult(coeff[4], state[2]) - mult(coeff[5], state[3]); \
1491 state[1] = state[0]; \
1493 state[3] = state[2]; \
1494 state[2] = buf[i]; \
1498 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1499 float *coeff = (float *) cvt->coeff;
1500 float *state = (float *) cvt->state_buf;
1501 float *buf = (float *) cvt->buf;
1504 for (i = 0; i < n; ++i) {
1505 /* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a[2] * y[n-2] */
1507 if (cvt->state_pos) {
1509 coeff[0] * buf[n] + coeff[1] * state[0] +
1510 coeff[2] * state[1] - coeff[4] * state[2] -
1511 coeff[5] * state[3];
1517 coeff[0] * buf[n] + coeff[1] * state[1] +
1518 coeff[2] * state[0] - coeff[4] * state[3] -
1519 coeff[5] * state[2];
1526 /* Treat everything as signed! */
1527 switch (SDL_AUDIO_BITSIZE(format)) {
1529 iir_fix(Sint8, SDL_FixMpy8);
1532 iir_fix(Sint16, SDL_FixMpy16);
1535 iir_fix(Sint32, SDL_FixMpy32);
1542 /* Apply the windowed sinc FIR filter to the given SDL_AudioCVT struct.
1545 SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1547 int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
1548 int m = cvt->len_sinc;
1552 Note: We can make a big optimization here by taking advantage
1553 of the fact that the signal is zero stuffed, so we can do
1554 significantly fewer multiplications and additions. However, this
1555 depends on the zero stuffing ratio, so it may not pay off. This would
1556 basically be a polyphase filter.
1558 /* One other way to do this fast is to look at the fir filter from a different angle:
1559 After we zero stuff, we have input of all zeroes, except for every len_mult
1560 sample. If we choose a sinc length equal to len_mult, then the fir filter becomes
1561 much more simple: we're just taking a windowed sinc, shifting it to start at each
1562 len_mult sample, and scaling it by the value of that sample. If we do this, then
1563 we don't even need to worry about the sample histories, and the inner loop here is
1564 unnecessary. This probably sacrifices some quality but could really speed things up as well.
1566 /* We only calculate the values of samples which are 0 (mod len_div) because
1567 those are the only ones used. All the other ones are discarded in the
1568 third step of resampling. This is a huge speedup. As a warning, though,
1569 if for some reason this is used elsewhere where there are no samples discarded,
1570 the output will not be corrrect if len_div is not 1. To make this filter a
1571 generic FIR filter, simply remove the if statement "if(i % cvt->len_div == 0)"
1572 around the inner loop so that every sample is processed.
1574 /* This is basically just a FIR filter. i.e. for input x_n and m coefficients,
1575 y_n = x_n*sinc_0 + x_(n-1)*sinc_1 + x_(n-2)*sinc_2 + ... + x_(n-m+1)*sinc_(m-1)
1577 #define filter_sinc(type, mult) { \
1578 type *sinc = (type *)cvt->coeff; \
1579 type *state = (type *)cvt->state_buf; \
1580 type *buf = (type *)cvt->buf; \
1581 for(i = 0; i < n; ++i) { \
1582 state[cvt->state_pos] = buf[i]; \
1584 if( i % cvt->len_div == 0 ) { \
1585 for(j = 0; j < m; ++j) { \
1586 buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
1589 cvt->state_pos = (cvt->state_pos + 1) % m; \
1593 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1594 filter_sinc(float, SDL_FloatMpy);
1596 switch (SDL_AUDIO_BITSIZE(format)) {
1598 filter_sinc(Sint8, SDL_FixMpy8);
1601 filter_sinc(Sint16, SDL_FixMpy16);
1604 filter_sinc(Sint32, SDL_FixMpy32);
1613 /* Generate the necessary windowed sinc filter for resampling.
1614 Assume that the SDL_AudioCVT struct is already set up with
1615 the correct values for len_mult and len_div, and use the
1616 type of dst_format. Also assume the buffer is allocated.
1617 Note the buffer needs to be m+1 units long.
1620 SDL_BuildWindowedSinc(SDL_AudioCVT * cvt, SDL_AudioFormat format,
1623 float fScale; /* scale factor for fixed point */
1624 float *fSinc; /* floating point sinc buffer, to be converted to fixed point */
1625 float fc; /* cutoff frequency */
1626 float two_pi_fc, two_pi_over_m, four_pi_over_m, m_over_two;
1627 float norm_sum, norm_fact;
1630 /* Check that the buffer is allocated */
1631 if (cvt->coeff == NULL) {
1635 /* Set the length */
1636 cvt->len_sinc = m + 1;
1638 /* Allocate the floating point windowed sinc. */
1639 fSinc = (float *) malloc((m + 1) * sizeof(float));
1640 if (fSinc == NULL) {
1644 /* Set up the filter parameters */
1645 fc = (cvt->len_mult >
1646 cvt->len_div) ? 0.5f / (float) cvt->len_mult : 0.5f /
1647 (float) cvt->len_div;
1648 #ifdef DEBUG_CONVERT
1649 printf("Lowpass cutoff frequency = %f\n", fc);
1651 two_pi_fc = 2.0f * M_PI * fc;
1652 two_pi_over_m = 2.0f * M_PI / (float) m;
1653 four_pi_over_m = 2.0f * two_pi_over_m;
1654 m_over_two = (float) m / 2.0f;
1657 for (i = 0; i <= m; ++i) {
1659 fSinc[i] = two_pi_fc;
1662 sinf(two_pi_fc * ((float) i - m_over_two)) / ((float) i -
1664 /* Apply blackman window */
1666 0.42f - 0.5f * cosf(two_pi_over_m * (float) i) +
1667 0.08f * cosf(four_pi_over_m * (float) i);
1669 norm_sum += fabs(fSinc[i]);
1672 norm_fact = 1.0f / norm_sum;
1674 #define convert_fixed(type, fix) { \
1675 type *dst = (type *)cvt->coeff; \
1676 for( i = 0; i <= m; ++i ) { \
1677 dst[i] = fix(fSinc[i] * norm_fact); \
1681 /* If we're using floating point, we only need to normalize */
1682 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1683 float *fDest = (float *) cvt->coeff;
1684 for (i = 0; i <= m; ++i) {
1685 fDest[i] = fSinc[i] * norm_fact;
1688 switch (SDL_AUDIO_BITSIZE(format)) {
1690 convert_fixed(Uint8, SDL_Make_1_7);
1693 convert_fixed(Uint16, SDL_Make_1_15);
1696 convert_fixed(Uint32, SDL_Make_1_31);
1701 /* Initialize the state buffer to all zeroes, and set initial position */
1702 memset(cvt->state_buf, 0, cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
1706 #undef convert_fixed
1710 /* This is used to reduce the resampling ratio */
1712 SDL_GCD(int a, int b)
1723 /* Perform proper resampling. This is pretty slow but it's the best-sounding method. */
1725 SDL_Resample(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1729 #ifdef DEBUG_CONVERT
1730 printf("Converting audio rate via proper resampling (mono)\n");
1733 #define zerostuff_mono(type) { \
1734 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
1735 type *dst = (type *) (cvt->buf + (cvt->len_cvt * cvt->len_mult)); \
1736 for (i = cvt->len_cvt / sizeof (type); i; --i) { \
1739 for( j = -cvt->len_mult; j < -1; ++j ) { \
1742 dst -= cvt->len_mult; \
1746 #define discard_mono(type) { \
1747 const type *src = (const type *) (cvt->buf); \
1748 type *dst = (type *) (cvt->buf); \
1749 for (i = 0; i < (cvt->len_cvt / sizeof(type)) / cvt->len_div; ++i) { \
1751 src += cvt->len_div; \
1756 /* Step 1: Zero stuff the conversion buffer. This upsamples by a factor of len_mult,
1757 creating aliasing at frequencies above the original nyquist frequency.
1759 #ifdef DEBUG_CONVERT
1760 printf("Zero-stuffing by a factor of %u\n", cvt->len_mult);
1762 switch (SDL_AUDIO_BITSIZE(format)) {
1764 zerostuff_mono(Uint8);
1767 zerostuff_mono(Uint16);
1770 zerostuff_mono(Uint32);
1774 cvt->len_cvt *= cvt->len_mult;
1776 /* Step 2: Use a windowed sinc FIR filter (lowpass filter) to remove the alias
1777 frequencies. This is the slow part.
1779 SDL_FilterFIR(cvt, format);
1781 /* Step 3: Now downsample by discarding samples. */
1783 #ifdef DEBUG_CONVERT
1784 printf("Discarding samples by a factor of %u\n", cvt->len_div);
1786 switch (SDL_AUDIO_BITSIZE(format)) {
1788 discard_mono(Uint8);
1791 discard_mono(Uint16);
1794 discard_mono(Uint32);
1798 #undef zerostuff_mono
1801 cvt->len_cvt /= cvt->len_div;
1803 if (cvt->filters[++cvt->filter_index]) {
1804 cvt->filters[cvt->filter_index] (cvt, format);
1809 /* Creates a set of audio filters to convert from one format to another.
1810 Returns -1 if the format conversion is not supported, 0 if there's
1811 no conversion needed, or 1 if the audio filter is set up.
1815 SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
1816 SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
1817 SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
1819 /* there are no unsigned types over 16 bits, so catch this upfront. */
1820 if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
1823 if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
1826 #ifdef DEBUG_CONVERT
1827 printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
1828 src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
1831 /* Start off with no conversion necessary */
1833 cvt->src_format = src_fmt;
1834 cvt->dst_format = dst_fmt;
1836 cvt->filter_index = 0;
1837 cvt->filters[0] = NULL;
1839 cvt->len_ratio = 1.0;
1841 /* Convert data types, if necessary. Updates (cvt). */
1842 if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1)
1843 return -1; /* shouldn't happen, but just in case... */
1845 /* Channel conversion */
1846 if (src_channels != dst_channels) {
1847 if ((src_channels == 1) && (dst_channels > 1)) {
1848 cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
1851 cvt->len_ratio *= 2;
1853 if ((src_channels == 2) && (dst_channels == 6)) {
1854 cvt->filters[cvt->filter_index++] = SDL_ConvertSurround;
1857 cvt->len_ratio *= 3;
1859 if ((src_channels == 2) && (dst_channels == 4)) {
1860 cvt->filters[cvt->filter_index++] = SDL_ConvertSurround_4;
1863 cvt->len_ratio *= 2;
1865 while ((src_channels * 2) <= dst_channels) {
1866 cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
1869 cvt->len_ratio *= 2;
1871 if ((src_channels == 6) && (dst_channels <= 2)) {
1872 cvt->filters[cvt->filter_index++] = SDL_ConvertStrip;
1874 cvt->len_ratio /= 3;
1876 if ((src_channels == 6) && (dst_channels == 4)) {
1877 cvt->filters[cvt->filter_index++] = SDL_ConvertStrip_2;
1879 cvt->len_ratio /= 2;
1881 /* This assumes that 4 channel audio is in the format:
1882 Left {front/back} + Right {front/back}
1883 so converting to L/R stereo works properly.
1885 while (((src_channels % 2) == 0) &&
1886 ((src_channels / 2) >= dst_channels)) {
1887 cvt->filters[cvt->filter_index++] = SDL_ConvertMono;
1889 cvt->len_ratio /= 2;
1891 if (src_channels != dst_channels) {
1896 /* Do rate conversion */
1897 if (src_rate != dst_rate) {
1899 rate_gcd = SDL_GCD(src_rate, dst_rate);
1900 cvt->len_mult = dst_rate / rate_gcd;
1901 cvt->len_div = src_rate / rate_gcd;
1902 cvt->len_ratio = (double) cvt->len_mult / (double) cvt->len_div;
1903 cvt->filters[cvt->filter_index++] = SDL_Resample;
1904 SDL_BuildWindowedSinc(cvt, dst_fmt, 768);
1908 cvt->rate_incr = 0.0;
1909 if ((src_rate / 100) != (dst_rate / 100)) {
1910 Uint32 hi_rate, lo_rate;
1913 SDL_AudioFilter rate_cvt = NULL;
1915 if (src_rate > dst_rate) {
1918 switch (src_channels) {
1920 rate_cvt = SDL_RateDIV2;
1923 rate_cvt = SDL_RateDIV2_c2;
1926 rate_cvt = SDL_RateDIV2_c4;
1929 rate_cvt = SDL_RateDIV2_c6;
1939 switch (src_channels) {
1941 rate_cvt = SDL_RateMUL2;
1944 rate_cvt = SDL_RateMUL2_c2;
1947 rate_cvt = SDL_RateMUL2_c4;
1950 rate_cvt = SDL_RateMUL2_c6;
1958 /* If hi_rate = lo_rate*2^x then conversion is easy */
1959 /* while (((lo_rate * 2) / 100) <= (hi_rate / 100)) {
1960 cvt->filters[cvt->filter_index++] = rate_cvt;
1961 cvt->len_mult *= len_mult;
1963 cvt->len_ratio *= len_ratio;
1965 /* We may need a slow conversion here to finish up */
1966 /* if ((lo_rate / 100) != (hi_rate / 100)) {
1968 /* The problem with this is that if the input buffer is
1969 say 1K, and the conversion rate is say 1.1, then the
1970 output buffer is 1.1K, which may not be an acceptable
1971 buffer size for the audio driver (not a power of 2)
1973 /* For now, punt and hope the rate distortion isn't great.
1976 if (src_rate < dst_rate) {
1977 cvt->rate_incr = (double) lo_rate / hi_rate;
1979 cvt->len_ratio /= cvt->rate_incr;
1981 cvt->rate_incr = (double) hi_rate / lo_rate;
1982 cvt->len_ratio *= cvt->rate_incr;
1984 cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
1989 /* Set up the filter information */
1990 if (cvt->filter_index != 0) {
1992 cvt->src_format = src_fmt;
1993 cvt->dst_format = dst_fmt;
1996 cvt->filters[cvt->filter_index] = NULL;
1998 return (cvt->needed);
2006 #undef SDL_Make_1_15
2007 #undef SDL_Make_1_31
2009 #undef SDL_Make_2_14
2010 #undef SDL_Make_2_30
2012 /* vi: set ts=4 sw=4 expandtab: */