src/audio/SDL_audiocvt.c
changeset 3021 f3dcf04412cf
parent 3012 7e30c2dc7783
child 3032 77c3e67f0740
equal deleted inserted replaced
3020:70d876a0b90e 3021:f3dcf04412cf
    24 /* Functions for audio drivers to perform runtime conversion of audio format */
    24 /* Functions for audio drivers to perform runtime conversion of audio format */
    25 
    25 
    26 #include "SDL_audio.h"
    26 #include "SDL_audio.h"
    27 #include "SDL_audio_c.h"
    27 #include "SDL_audio_c.h"
    28 
    28 
    29 //#define DEBUG_CONVERT
    29 /* #define DEBUG_CONVERT */
    30 
    30 
    31 /* These are fractional multiplication routines. That is, their inputs
    31 /* !!! FIXME */
    32    are two numbers in the range [-1, 1) and the result falls in that
    32 #ifndef assert
    33    same range. The output is the same size as the inputs, i.e.
    33 #define assert(x)
    34    32-bit x 32-bit = 32-bit.
       
    35  */
       
    36 
       
    37 /* We hope here that the right shift includes sign extension */
       
    38 #ifdef SDL_HAS_64BIT_Type
       
    39 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
       
    40 #else
       
    41 /* 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 */
       
    42 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
       
    43 #endif
    34 #endif
    44 #define SDL_FixMpy16(a, b) ((((Sint32)a * (Sint32)b) >> 14) & 0xffff)
       
    45 #define SDL_FixMpy8(a, b) ((((Sint16)a * (Sint16)b) >> 7) & 0xff)
       
    46 /* This macro just makes the floating point filtering code not have to be a special case. */
       
    47 #define SDL_FloatMpy(a, b) (a * b)
       
    48 
       
    49 /* These macros take floating point numbers in the range [-1.0f, 1.0f) and
       
    50    represent them as fixed-point numbers in that same range. There's no
       
    51    checking that the floating point argument is inside the appropriate range.
       
    52  */
       
    53 
       
    54 #define SDL_Make_1_7(a) (Sint8)(a * 128.0f)
       
    55 #define SDL_Make_1_15(a) (Sint16)(a * 32768.0f)
       
    56 #define SDL_Make_1_31(a) (Sint32)(a * 2147483648.0f)
       
    57 #define SDL_Make_2_6(a) (Sint8)(a * 64.0f)
       
    58 #define SDL_Make_2_14(a) (Sint16)(a * 16384.0f)
       
    59 #define SDL_Make_2_30(a) (Sint32)(a * 1073741824.0f)
       
    60 
    35 
    61 /* Effectively mix right and left channels into a single channel */
    36 /* Effectively mix right and left channels into a single channel */
    62 static void SDLCALL
    37 static void SDLCALL
    63 SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    38 SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    64 {
    39 {
   796     if (cvt->filters[++cvt->filter_index]) {
   771     if (cvt->filters[++cvt->filter_index]) {
   797         cvt->filters[cvt->filter_index] (cvt, format);
   772         cvt->filters[cvt->filter_index] (cvt, format);
   798     }
   773     }
   799 }
   774 }
   800 
   775 
   801 /* Convert rate up by multiple of 2 */
       
   802 static void SDLCALL
       
   803 SDL_RateMUL2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
   804 {
       
   805     int i;
       
   806 
       
   807 #ifdef DEBUG_CONVERT
       
   808     fprintf(stderr, "Converting audio rate * 2 (mono)\n");
       
   809 #endif
       
   810 
       
   811 #define mul2_mono(type) { \
       
   812         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
       
   813         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
       
   814         for (i = cvt->len_cvt / sizeof (type); i; --i) { \
       
   815             src--; \
       
   816             dst[-1] = dst[-2] = src[0]; \
       
   817             dst -= 2; \
       
   818         } \
       
   819     }
       
   820 
       
   821     switch (SDL_AUDIO_BITSIZE(format)) {
       
   822     case 8:
       
   823         mul2_mono(Uint8);
       
   824         break;
       
   825     case 16:
       
   826         mul2_mono(Uint16);
       
   827         break;
       
   828     case 32:
       
   829         mul2_mono(Uint32);
       
   830         break;
       
   831     }
       
   832 
       
   833 #undef mul2_mono
       
   834 
       
   835     cvt->len_cvt *= 2;
       
   836     if (cvt->filters[++cvt->filter_index]) {
       
   837         cvt->filters[cvt->filter_index] (cvt, format);
       
   838     }
       
   839 }
       
   840 
       
   841 
       
   842 /* Convert rate up by multiple of 2, for stereo */
       
   843 static void SDLCALL
       
   844 SDL_RateMUL2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
   845 {
       
   846     int i;
       
   847 
       
   848 #ifdef DEBUG_CONVERT
       
   849     fprintf(stderr, "Converting audio rate * 2 (stereo)\n");
       
   850 #endif
       
   851 
       
   852 #define mul2_stereo(type) { \
       
   853         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
       
   854         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
       
   855         for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
       
   856             const type r = src[-1]; \
       
   857             const type l = src[-2]; \
       
   858             src -= 2; \
       
   859             dst[-1] = r; \
       
   860             dst[-2] = l; \
       
   861             dst[-3] = r; \
       
   862             dst[-4] = l; \
       
   863             dst -= 4; \
       
   864         } \
       
   865     }
       
   866 
       
   867     switch (SDL_AUDIO_BITSIZE(format)) {
       
   868     case 8:
       
   869         mul2_stereo(Uint8);
       
   870         break;
       
   871     case 16:
       
   872         mul2_stereo(Uint16);
       
   873         break;
       
   874     case 32:
       
   875         mul2_stereo(Uint32);
       
   876         break;
       
   877     }
       
   878 
       
   879 #undef mul2_stereo
       
   880 
       
   881     cvt->len_cvt *= 2;
       
   882     if (cvt->filters[++cvt->filter_index]) {
       
   883         cvt->filters[cvt->filter_index] (cvt, format);
       
   884     }
       
   885 }
       
   886 
       
   887 /* Convert rate up by multiple of 2, for quad */
       
   888 static void SDLCALL
       
   889 SDL_RateMUL2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
   890 {
       
   891     int i;
       
   892 
       
   893 #ifdef DEBUG_CONVERT
       
   894     fprintf(stderr, "Converting audio rate * 2 (quad)\n");
       
   895 #endif
       
   896 
       
   897 #define mul2_quad(type) { \
       
   898         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
       
   899         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
       
   900         for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
       
   901             const type c1 = src[-1]; \
       
   902             const type c2 = src[-2]; \
       
   903             const type c3 = src[-3]; \
       
   904             const type c4 = src[-4]; \
       
   905             src -= 4; \
       
   906             dst[-1] = c1; \
       
   907             dst[-2] = c2; \
       
   908             dst[-3] = c3; \
       
   909             dst[-4] = c4; \
       
   910             dst[-5] = c1; \
       
   911             dst[-6] = c2; \
       
   912             dst[-7] = c3; \
       
   913             dst[-8] = c4; \
       
   914             dst -= 8; \
       
   915         } \
       
   916     }
       
   917 
       
   918     switch (SDL_AUDIO_BITSIZE(format)) {
       
   919     case 8:
       
   920         mul2_quad(Uint8);
       
   921         break;
       
   922     case 16:
       
   923         mul2_quad(Uint16);
       
   924         break;
       
   925     case 32:
       
   926         mul2_quad(Uint32);
       
   927         break;
       
   928     }
       
   929 
       
   930 #undef mul2_quad
       
   931 
       
   932     cvt->len_cvt *= 2;
       
   933     if (cvt->filters[++cvt->filter_index]) {
       
   934         cvt->filters[cvt->filter_index] (cvt, format);
       
   935     }
       
   936 }
       
   937 
       
   938 
       
   939 /* Convert rate up by multiple of 2, for 5.1 */
       
   940 static void SDLCALL
       
   941 SDL_RateMUL2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
   942 {
       
   943     int i;
       
   944 
       
   945 #ifdef DEBUG_CONVERT
       
   946     fprintf(stderr, "Converting audio rate * 2 (six channels)\n");
       
   947 #endif
       
   948 
       
   949 #define mul2_chansix(type) { \
       
   950         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
       
   951         type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
       
   952         for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
       
   953             const type c1 = src[-1]; \
       
   954             const type c2 = src[-2]; \
       
   955             const type c3 = src[-3]; \
       
   956             const type c4 = src[-4]; \
       
   957             const type c5 = src[-5]; \
       
   958             const type c6 = src[-6]; \
       
   959             src -= 6; \
       
   960             dst[-1] = c1; \
       
   961             dst[-2] = c2; \
       
   962             dst[-3] = c3; \
       
   963             dst[-4] = c4; \
       
   964             dst[-5] = c5; \
       
   965             dst[-6] = c6; \
       
   966             dst[-7] = c1; \
       
   967             dst[-8] = c2; \
       
   968             dst[-9] = c3; \
       
   969             dst[-10] = c4; \
       
   970             dst[-11] = c5; \
       
   971             dst[-12] = c6; \
       
   972             dst -= 12; \
       
   973         } \
       
   974     }
       
   975 
       
   976     switch (SDL_AUDIO_BITSIZE(format)) {
       
   977     case 8:
       
   978         mul2_chansix(Uint8);
       
   979         break;
       
   980     case 16:
       
   981         mul2_chansix(Uint16);
       
   982         break;
       
   983     case 32:
       
   984         mul2_chansix(Uint32);
       
   985         break;
       
   986     }
       
   987 
       
   988 #undef mul2_chansix
       
   989 
       
   990     cvt->len_cvt *= 2;
       
   991     if (cvt->filters[++cvt->filter_index]) {
       
   992         cvt->filters[cvt->filter_index] (cvt, format);
       
   993     }
       
   994 }
       
   995 
       
   996 /* Convert rate down by multiple of 2 */
       
   997 static void SDLCALL
       
   998 SDL_RateDIV2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
   999 {
       
  1000     int i;
       
  1001 
       
  1002 #ifdef DEBUG_CONVERT
       
  1003     fprintf(stderr, "Converting audio rate / 2 (mono)\n");
       
  1004 #endif
       
  1005 
       
  1006 #define div2_mono(type) { \
       
  1007         const type *src = (const type *) cvt->buf; \
       
  1008         type *dst = (type *) cvt->buf; \
       
  1009         for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
       
  1010             dst[0] = src[0]; \
       
  1011             src += 2; \
       
  1012             dst++; \
       
  1013         } \
       
  1014     }
       
  1015 
       
  1016     switch (SDL_AUDIO_BITSIZE(format)) {
       
  1017     case 8:
       
  1018         div2_mono(Uint8);
       
  1019         break;
       
  1020     case 16:
       
  1021         div2_mono(Uint16);
       
  1022         break;
       
  1023     case 32:
       
  1024         div2_mono(Uint32);
       
  1025         break;
       
  1026     }
       
  1027 
       
  1028 #undef div2_mono
       
  1029 
       
  1030     cvt->len_cvt /= 2;
       
  1031     if (cvt->filters[++cvt->filter_index]) {
       
  1032         cvt->filters[cvt->filter_index] (cvt, format);
       
  1033     }
       
  1034 }
       
  1035 
       
  1036 
       
  1037 /* Convert rate down by multiple of 2, for stereo */
       
  1038 static void SDLCALL
       
  1039 SDL_RateDIV2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
  1040 {
       
  1041     int i;
       
  1042 
       
  1043 #ifdef DEBUG_CONVERT
       
  1044     fprintf(stderr, "Converting audio rate / 2 (stereo)\n");
       
  1045 #endif
       
  1046 
       
  1047 #define div2_stereo(type) { \
       
  1048         const type *src = (const type *) cvt->buf; \
       
  1049         type *dst = (type *) cvt->buf; \
       
  1050         for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
       
  1051             dst[0] = src[0]; \
       
  1052             dst[1] = src[1]; \
       
  1053             src += 4; \
       
  1054             dst += 2; \
       
  1055         } \
       
  1056     }
       
  1057 
       
  1058     switch (SDL_AUDIO_BITSIZE(format)) {
       
  1059     case 8:
       
  1060         div2_stereo(Uint8);
       
  1061         break;
       
  1062     case 16:
       
  1063         div2_stereo(Uint16);
       
  1064         break;
       
  1065     case 32:
       
  1066         div2_stereo(Uint32);
       
  1067         break;
       
  1068     }
       
  1069 
       
  1070 #undef div2_stereo
       
  1071 
       
  1072     cvt->len_cvt /= 2;
       
  1073     if (cvt->filters[++cvt->filter_index]) {
       
  1074         cvt->filters[cvt->filter_index] (cvt, format);
       
  1075     }
       
  1076 }
       
  1077 
       
  1078 
       
  1079 /* Convert rate down by multiple of 2, for quad */
       
  1080 static void SDLCALL
       
  1081 SDL_RateDIV2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
  1082 {
       
  1083     int i;
       
  1084 
       
  1085 #ifdef DEBUG_CONVERT
       
  1086     fprintf(stderr, "Converting audio rate / 2 (quad)\n");
       
  1087 #endif
       
  1088 
       
  1089 #define div2_quad(type) { \
       
  1090         const type *src = (const type *) cvt->buf; \
       
  1091         type *dst = (type *) cvt->buf; \
       
  1092         for (i = cvt->len_cvt / (sizeof (type) * 8); i; --i) { \
       
  1093             dst[0] = src[0]; \
       
  1094             dst[1] = src[1]; \
       
  1095             dst[2] = src[2]; \
       
  1096             dst[3] = src[3]; \
       
  1097             src += 8; \
       
  1098             dst += 4; \
       
  1099         } \
       
  1100     }
       
  1101 
       
  1102     switch (SDL_AUDIO_BITSIZE(format)) {
       
  1103     case 8:
       
  1104         div2_quad(Uint8);
       
  1105         break;
       
  1106     case 16:
       
  1107         div2_quad(Uint16);
       
  1108         break;
       
  1109     case 32:
       
  1110         div2_quad(Uint32);
       
  1111         break;
       
  1112     }
       
  1113 
       
  1114 #undef div2_quad
       
  1115 
       
  1116     cvt->len_cvt /= 2;
       
  1117     if (cvt->filters[++cvt->filter_index]) {
       
  1118         cvt->filters[cvt->filter_index] (cvt, format);
       
  1119     }
       
  1120 }
       
  1121 
       
  1122 /* Convert rate down by multiple of 2, for 5.1 */
       
  1123 static void SDLCALL
       
  1124 SDL_RateDIV2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
  1125 {
       
  1126     int i;
       
  1127 
       
  1128 #ifdef DEBUG_CONVERT
       
  1129     fprintf(stderr, "Converting audio rate / 2 (six channels)\n");
       
  1130 #endif
       
  1131 
       
  1132 #define div2_chansix(type) { \
       
  1133         const type *src = (const type *) cvt->buf; \
       
  1134         type *dst = (type *) cvt->buf; \
       
  1135         for (i = cvt->len_cvt / (sizeof (type) * 12); i; --i) { \
       
  1136             dst[0] = src[0]; \
       
  1137             dst[1] = src[1]; \
       
  1138             dst[2] = src[2]; \
       
  1139             dst[3] = src[3]; \
       
  1140             dst[4] = src[4]; \
       
  1141             dst[5] = src[5]; \
       
  1142             src += 12; \
       
  1143             dst += 6; \
       
  1144         } \
       
  1145     }
       
  1146 
       
  1147     switch (SDL_AUDIO_BITSIZE(format)) {
       
  1148     case 8:
       
  1149         div2_chansix(Uint8);
       
  1150         break;
       
  1151     case 16:
       
  1152         div2_chansix(Uint16);
       
  1153         break;
       
  1154     case 32:
       
  1155         div2_chansix(Uint32);
       
  1156         break;
       
  1157     }
       
  1158 
       
  1159 #undef div_chansix
       
  1160 
       
  1161     cvt->len_cvt /= 2;
       
  1162     if (cvt->filters[++cvt->filter_index]) {
       
  1163         cvt->filters[cvt->filter_index] (cvt, format);
       
  1164     }
       
  1165 }
       
  1166 
       
  1167 /* Very slow rate conversion routine */
       
  1168 static void SDLCALL
       
  1169 SDL_RateSLOW(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
  1170 {
       
  1171     double ipos;
       
  1172     int i, clen;
       
  1173 
       
  1174 #ifdef DEBUG_CONVERT
       
  1175     fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0 / cvt->rate_incr);
       
  1176 #endif
       
  1177     clen = (int) ((double) cvt->len_cvt / cvt->rate_incr);
       
  1178     if (cvt->rate_incr > 1.0) {
       
  1179         switch (SDL_AUDIO_BITSIZE(format)) {
       
  1180         case 8:
       
  1181             {
       
  1182                 Uint8 *output;
       
  1183 
       
  1184                 output = cvt->buf;
       
  1185                 ipos = 0.0;
       
  1186                 for (i = clen; i; --i) {
       
  1187                     *output = cvt->buf[(int) ipos];
       
  1188                     ipos += cvt->rate_incr;
       
  1189                     output += 1;
       
  1190                 }
       
  1191             }
       
  1192             break;
       
  1193 
       
  1194         case 16:
       
  1195             {
       
  1196                 Uint16 *output;
       
  1197 
       
  1198                 clen &= ~1;
       
  1199                 output = (Uint16 *) cvt->buf;
       
  1200                 ipos = 0.0;
       
  1201                 for (i = clen / 2; i; --i) {
       
  1202                     *output = ((Uint16 *) cvt->buf)[(int) ipos];
       
  1203                     ipos += cvt->rate_incr;
       
  1204                     output += 1;
       
  1205                 }
       
  1206             }
       
  1207             break;
       
  1208 
       
  1209         case 32:
       
  1210             {
       
  1211                 /* !!! FIXME: need 32-bit converter here! */
       
  1212 #ifdef DEBUG_CONVERT
       
  1213                 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
       
  1214 #endif
       
  1215             }
       
  1216         }
       
  1217     } else {
       
  1218         switch (SDL_AUDIO_BITSIZE(format)) {
       
  1219         case 8:
       
  1220             {
       
  1221                 Uint8 *output;
       
  1222 
       
  1223                 output = cvt->buf + clen;
       
  1224                 ipos = (double) cvt->len_cvt;
       
  1225                 for (i = clen; i; --i) {
       
  1226                     ipos -= cvt->rate_incr;
       
  1227                     output -= 1;
       
  1228                     *output = cvt->buf[(int) ipos];
       
  1229                 }
       
  1230             }
       
  1231             break;
       
  1232 
       
  1233         case 16:
       
  1234             {
       
  1235                 Uint16 *output;
       
  1236 
       
  1237                 clen &= ~1;
       
  1238                 output = (Uint16 *) (cvt->buf + clen);
       
  1239                 ipos = (double) cvt->len_cvt / 2;
       
  1240                 for (i = clen / 2; i; --i) {
       
  1241                     ipos -= cvt->rate_incr;
       
  1242                     output -= 1;
       
  1243                     *output = ((Uint16 *) cvt->buf)[(int) ipos];
       
  1244                 }
       
  1245             }
       
  1246             break;
       
  1247 
       
  1248         case 32:
       
  1249             {
       
  1250                 /* !!! FIXME: need 32-bit converter here! */
       
  1251 #ifdef DEBUG_CONVERT
       
  1252                 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
       
  1253 #endif
       
  1254             }
       
  1255         }
       
  1256     }
       
  1257 
       
  1258     cvt->len_cvt = clen;
       
  1259     if (cvt->filters[++cvt->filter_index]) {
       
  1260         cvt->filters[cvt->filter_index] (cvt, format);
       
  1261     }
       
  1262 }
       
  1263 
   776 
  1264 int
   777 int
  1265 SDL_ConvertAudio(SDL_AudioCVT * cvt)
   778 SDL_ConvertAudio(SDL_AudioCVT * cvt)
  1266 {
   779 {
       
   780     /* !!! FIXME: (cvt) should be const; stack-copy it here. */
       
   781     /* !!! FIXME: (actually, we can't...len_cvt needs to be updated. Grr.) */
       
   782 
  1267     /* Make sure there's data to convert */
   783     /* Make sure there's data to convert */
  1268     if (cvt->buf == NULL) {
   784     if (cvt->buf == NULL) {
  1269         SDL_SetError("No buffer allocated for conversion");
   785         SDL_SetError("No buffer allocated for conversion");
  1270         return (-1);
   786         return (-1);
  1271     }
   787     }
  1339     }
   855     }
  1340 
   856 
  1341     return 0;                   /* no conversion necessary. */
   857     return 0;                   /* no conversion necessary. */
  1342 }
   858 }
  1343 
   859 
  1344 /* Generate the necessary IIR lowpass coefficients for resampling.
   860 
  1345    Assume that the SDL_AudioCVT struct is already set up with
   861 static SDL_AudioFilter
  1346    the correct values for len_mult and len_div, and use the
   862 SDL_HandTunedResampleCVT(SDL_AudioCVT * cvt, int dst_channels,
  1347    type of dst_format. Also assume the buffer is allocated.
   863                          int src_rate, int dst_rate)
  1348    Note the buffer needs to be 6 units long.
   864 {
  1349    For now, use RBJ's cookbook coefficients. It might be more
   865     /*
  1350    optimal to create a Butterworth filter, but this is more difficult.
   866      * Fill in any future conversions that are specialized to a
  1351 */
   867      *  processor, platform, compiler, or library here.
  1352 #if 0
   868      */
  1353 int
   869 
  1354 SDL_BuildIIRLowpass(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   870     return NULL;                /* no specialized converter code available. */
  1355 {
   871 }
  1356     float fc;                   /* cutoff frequency */
   872 
  1357     float coeff[6];             /* floating point iir coefficients b0, b1, b2, a0, a1, a2 */
   873 static int
  1358     float scale;
   874 SDL_FindFrequencyMultiple(const int src_rate, const int dst_rate)
  1359     float w0, alpha, cosw0;
   875 {
  1360     int i;
   876     int retval = 0;
  1361 
   877 
  1362     /* The higher Q is, the higher CUTOFF can be. Need to find a good balance to avoid aliasing */
   878     /* If we only built with the arbitrary resamplers, ignore multiples. */
  1363     static const float Q = 5.0f;
   879 #if !LESS_RESAMPLERS
  1364     static const float CUTOFF = 0.4f;
   880     int lo, hi;
  1365 
   881     int div;
  1366     fc = (cvt->len_mult >
   882 
  1367           cvt->len_div) ? CUTOFF / (float) cvt->len_mult : CUTOFF /
   883     assert(src_rate != 0);
  1368         (float) cvt->len_div;
   884     assert(dst_rate != 0);
  1369 
   885     assert(src_rate != dst_rate);
  1370     w0 = 2.0f * M_PI * fc;
   886 
  1371     cosw0 = cosf(w0);
   887     if (src_rate < dst_rate) {
  1372     alpha = sinf(w0) / (2.0f * Q);
   888         lo = src_rate;
  1373 
   889         hi = dst_rate;
  1374     /* Compute coefficients, normalizing by a0 */
       
  1375     scale = 1.0f / (1.0f + alpha);
       
  1376 
       
  1377     coeff[0] = (1.0f - cosw0) / 2.0f * scale;
       
  1378     coeff[1] = (1.0f - cosw0) * scale;
       
  1379     coeff[2] = coeff[0];
       
  1380 
       
  1381     coeff[3] = 1.0f;            /* a0 is normalized to 1 */
       
  1382     coeff[4] = -2.0f * cosw0 * scale;
       
  1383     coeff[5] = (1.0f - alpha) * scale;
       
  1384 
       
  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]); \
       
  1390             } \
       
  1391         }
       
  1392 
       
  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];
       
  1397         }
       
  1398     } else {
   890     } else {
  1399         switch (SDL_AUDIO_BITSIZE(format)) {
   891         lo = dst_rate;
  1400         case 8:
   892         hi = src_rate;
  1401             convert_fixed(Uint8, SDL_Make_2_6);
   893     }
  1402             break;
   894 
  1403         case 16:
   895     /* zero means "not a supported multiple" ... we only do 2x and 4x. */
  1404             convert_fixed(Uint16, SDL_Make_2_14);
   896     if ((hi % lo) != 0)
  1405             break;
   897         return 0;   /* not a multiple. */
  1406         case 32:
   898 
  1407             convert_fixed(Uint32, SDL_Make_2_30);
   899     div = hi / lo;
  1408             break;
   900     retval = ((div == 2) || (div == 4)) ? div : 0;
  1409         }
       
  1410     }
       
  1411 
       
  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]); \
       
  1417             } \
       
  1418         }
       
  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]);
       
  1423         }
       
  1424     } else {
       
  1425         switch (SDL_AUDIO_BITSIZE(format)) {
       
  1426         case 8:
       
  1427             debug_iir(Uint8);
       
  1428             break;
       
  1429         case 16:
       
  1430             debug_iir(Uint16);
       
  1431             break;
       
  1432         case 32:
       
  1433             debug_iir(Uint32);
       
  1434             break;
       
  1435         }
       
  1436     }
       
  1437 #undef debug_iir
       
  1438 #endif
   901 #endif
  1439 
   902 
  1440     /* Initialize the state buffer to all zeroes, and set initial position */
   903     return retval;
  1441     SDL_memset(cvt->state_buf, 0, 4 * SDL_AUDIO_BITSIZE(format) / 4);
   904 }
  1442     cvt->state_pos = 0;
   905 
  1443 #undef convert_fixed
   906 static int
  1444 
   907 SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, int dst_channels,
  1445     return 0;
   908                           int src_rate, int dst_rate)
  1446 }
   909 {
  1447 #endif
   910     if (src_rate != dst_rate) {
  1448 
   911         SDL_AudioFilter filter = SDL_HandTunedResampleCVT(cvt, dst_channels,
  1449 /* Apply the lowpass IIR filter to the given SDL_AudioCVT struct */
   912                                                           src_rate, dst_rate);
  1450 /* This was implemented because it would be much faster than the fir filter, 
   913 
  1451    but it doesn't seem to have a steep enough cutoff so we'd need several
   914         /* No hand-tuned converter? Try the autogenerated ones. */
  1452    cascaded biquads, which probably isn't a great idea. Therefore, this
   915         if (filter == NULL) {
  1453    function can probably be discarded.
   916             int i;
  1454 */
   917             const int upsample = (src_rate < dst_rate) ? 1 : 0;
  1455 static void
   918             const int multiple = SDL_FindFrequencyMultiple(src_rate, dst_rate);
  1456 SDL_FilterIIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   919 
  1457 {
   920             for (i = 0; sdl_audio_rate_filters[i].filter != NULL; i++) {
  1458     Uint32 i, n;
   921                 const SDL_AudioRateFilters *filt = &sdl_audio_rate_filters[i];
  1459 
   922                 if ((filt->fmt == cvt->dst_format) &&
  1460     /* TODO: Check that n is calculated right */
   923                     (filt->channels == dst_channels) &&
  1461     n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
   924                     (filt->upsample == upsample) &&
  1462 
   925                     (filt->multiple == multiple)) {
  1463     /* 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. */
   926                     filter = filt->filter;
  1464     /* cvt->state_pos = 1: state[0] = x_n-1, state[1] = x_n-2, state[2] = y_n-1, state[3] - y_n-2 */
   927                     break;
  1465 #define iir_fix(type, mult) {\
   928                 }
  1466             type *coeff = (type *)cvt->coeff; \
   929             }
  1467             type *state = (type *)cvt->state_buf; \
   930 
  1468             type *buf = (type *)cvt->buf; \
   931             if (filter == NULL) {
  1469             type temp; \
   932                 return -1;      /* Still no matching converter?! */
  1470             for(i = 0; i < n; ++i) { \
   933             }
  1471                     temp = buf[i] >> 1; \
   934         }
  1472                     if(cvt->state_pos) { \
   935 
  1473                         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]); \
   936         /* Update (cvt) with filter details... */
  1474                         state[1] = temp; \
   937         cvt->filters[cvt->filter_index++] = filter;
  1475                         state[3] = buf[i]; \
   938         if (src_rate < dst_rate) {
  1476                         cvt->state_pos = 0; \
   939             const double mult = ((double) dst_rate) / ((double) src_rate);
  1477                     } else { \
   940             cvt->len_mult *= (int) ceil(mult);  /* !!! FIXME: C runtime dependency. */
  1478                         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]); \
   941             cvt->len_ratio *= mult;
  1479                         state[0] = temp; \
       
  1480                         state[2] = buf[i]; \
       
  1481                         cvt->state_pos = 1; \
       
  1482                     } \
       
  1483                 } \
       
  1484         }
       
  1485 /* Need to test to see if the previous method or this one is faster */
       
  1486 /*#define iir_fix(type, mult) {\
       
  1487             type *coeff = (type *)cvt->coeff; \
       
  1488             type *state = (type *)cvt->state_buf; \
       
  1489             type *buf = (type *)cvt->buf; \
       
  1490             type temp; \
       
  1491             for(i = 0; i < n; ++i) { \
       
  1492                     temp = buf[i] >> 1; \
       
  1493                     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]); \
       
  1494                     state[1] = state[0]; \
       
  1495                     state[0] = temp; \
       
  1496                     state[3] = state[2]; \
       
  1497                     state[2] = buf[i]; \
       
  1498                 } \
       
  1499         }*/
       
  1500 
       
  1501     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
       
  1502         float *coeff = (float *) cvt->coeff;
       
  1503         float *state = (float *) cvt->state_buf;
       
  1504         float *buf = (float *) cvt->buf;
       
  1505         float temp;
       
  1506 
       
  1507         for (i = 0; i < n; ++i) {
       
  1508             /* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a[2] * y[n-2] */
       
  1509             temp = buf[i];
       
  1510             if (cvt->state_pos) {
       
  1511                 buf[i] =
       
  1512                     coeff[0] * buf[n] + coeff[1] * state[0] +
       
  1513                     coeff[2] * state[1] - coeff[4] * state[2] -
       
  1514                     coeff[5] * state[3];
       
  1515                 state[1] = temp;
       
  1516                 state[3] = buf[i];
       
  1517                 cvt->state_pos = 0;
       
  1518             } else {
       
  1519                 buf[i] =
       
  1520                     coeff[0] * buf[n] + coeff[1] * state[1] +
       
  1521                     coeff[2] * state[0] - coeff[4] * state[3] -
       
  1522                     coeff[5] * state[2];
       
  1523                 state[0] = temp;
       
  1524                 state[2] = buf[i];
       
  1525                 cvt->state_pos = 1;
       
  1526             }
       
  1527         }
       
  1528     } else {
       
  1529         /* Treat everything as signed! */
       
  1530         switch (SDL_AUDIO_BITSIZE(format)) {
       
  1531         case 8:
       
  1532             iir_fix(Sint8, SDL_FixMpy8);
       
  1533             break;
       
  1534         case 16:
       
  1535             iir_fix(Sint16, SDL_FixMpy16);
       
  1536             break;
       
  1537         case 32:
       
  1538             iir_fix(Sint32, SDL_FixMpy32);
       
  1539             break;
       
  1540         }
       
  1541     }
       
  1542 #undef iir_fix
       
  1543 }
       
  1544 
       
  1545 /* Apply the windowed sinc FIR filter to the given SDL_AudioCVT struct.
       
  1546 */
       
  1547 static void
       
  1548 SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
  1549 {
       
  1550     /* !!! FIXME: (n) is incorrect, or my allocation of state_buf is wrong. */
       
  1551     const int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
       
  1552     int m = cvt->len_sinc;
       
  1553     int i, j;
       
  1554 
       
  1555     /* 
       
  1556        Note: We can make a big optimization here by taking advantage
       
  1557        of the fact that the signal is zero stuffed, so we can do
       
  1558        significantly fewer multiplications and additions. However, this
       
  1559        depends on the zero stuffing ratio, so it may not pay off. This would
       
  1560        basically be a polyphase filter.
       
  1561      */
       
  1562     /* One other way to do this fast is to look at the fir filter from a different angle:
       
  1563        After we zero stuff, we have input of all zeroes, except for every len_mult
       
  1564        sample. If we choose a sinc length equal to len_mult, then the fir filter becomes
       
  1565        much more simple: we're just taking a windowed sinc, shifting it to start at each
       
  1566        len_mult sample, and scaling it by the value of that sample. If we do this, then
       
  1567        we don't even need to worry about the sample histories, and the inner loop here is
       
  1568        unnecessary. This probably sacrifices some quality but could really speed things up as well.
       
  1569      */
       
  1570     /* We only calculate the values of samples which are 0 (mod len_div) because
       
  1571        those are the only ones used. All the other ones are discarded in the
       
  1572        third step of resampling. This is a huge speedup. As a warning, though,
       
  1573        if for some reason this is used elsewhere where there are no samples discarded,
       
  1574        the output will not be corrrect if len_div is not 1. To make this filter a
       
  1575        generic FIR filter, simply remove the if statement "if(i % cvt->len_div == 0)"
       
  1576        around the inner loop so that every sample is processed.
       
  1577      */
       
  1578     /* This is basically just a FIR filter. i.e. for input x_n and m coefficients,
       
  1579        y_n = x_n*sinc_0 + x_(n-1)*sinc_1 +  x_(n-2)*sinc_2 + ... + x_(n-m+1)*sinc_(m-1)
       
  1580      */
       
  1581 #define filter_sinc(type, mult) { \
       
  1582             type *sinc = (type *)cvt->coeff; \
       
  1583             type *state = (type *)cvt->state_buf; \
       
  1584             type *buf = (type *)cvt->buf; \
       
  1585             for(i = 0; i < n; ++i) { \
       
  1586                 state[cvt->state_pos] = buf[i]; \
       
  1587                 buf[i] = 0; \
       
  1588                 if( i % cvt->len_div == 0 ) { \
       
  1589                     for(j = 0; j < m;  ++j) { \
       
  1590                         buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
       
  1591                     } \
       
  1592                 }\
       
  1593                 cvt->state_pos = (cvt->state_pos + 1) % m; \
       
  1594             } \
       
  1595         }
       
  1596 
       
  1597     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
       
  1598         filter_sinc(float, SDL_FloatMpy);
       
  1599     } else {
       
  1600         switch (SDL_AUDIO_BITSIZE(format)) {
       
  1601         case 8:
       
  1602             filter_sinc(Sint8, SDL_FixMpy8);
       
  1603             break;
       
  1604         case 16:
       
  1605             filter_sinc(Sint16, SDL_FixMpy16);
       
  1606             break;
       
  1607         case 32:
       
  1608             filter_sinc(Sint32, SDL_FixMpy32);
       
  1609             break;
       
  1610         }
       
  1611     }
       
  1612 
       
  1613 #undef filter_sinc
       
  1614 
       
  1615 }
       
  1616 
       
  1617 /* Generate the necessary windowed sinc filter for resampling.
       
  1618    Assume that the SDL_AudioCVT struct is already set up with
       
  1619    the correct values for len_mult and len_div, and use the
       
  1620    type of dst_format. Also assume the buffer is allocated.
       
  1621    Note the buffer needs to be m+1 units long.
       
  1622 */
       
  1623 int
       
  1624 SDL_BuildWindowedSinc(SDL_AudioCVT * cvt, SDL_AudioFormat format,
       
  1625                       unsigned int m)
       
  1626 {
       
  1627     float *fSinc;               /* floating point sinc buffer, to be converted to fixed point */
       
  1628     float fc;                   /* cutoff frequency */
       
  1629     float two_pi_fc, two_pi_over_m, four_pi_over_m, m_over_two;
       
  1630     float norm_sum, norm_fact;
       
  1631     unsigned int i;
       
  1632 
       
  1633     /* Set the length */
       
  1634     cvt->len_sinc = m + 1;
       
  1635 
       
  1636     /* Allocate the floating point windowed sinc. */
       
  1637     fSinc = SDL_stack_alloc(float, (m + 1));
       
  1638     if (fSinc == NULL) {
       
  1639         return -1;
       
  1640     }
       
  1641 
       
  1642     /* Set up the filter parameters */
       
  1643     fc = (cvt->len_mult >
       
  1644           cvt->len_div) ? 0.5f / (float) cvt->len_mult : 0.5f /
       
  1645         (float) cvt->len_div;
       
  1646 #ifdef DEBUG_CONVERT
       
  1647     printf("Lowpass cutoff frequency = %f\n", fc);
       
  1648 #endif
       
  1649     two_pi_fc = 2.0f * M_PI * fc;
       
  1650     two_pi_over_m = 2.0f * M_PI / (float) m;
       
  1651     four_pi_over_m = 2.0f * two_pi_over_m;
       
  1652     m_over_two = (float) m / 2.0f;
       
  1653     norm_sum = 0.0f;
       
  1654 
       
  1655     for (i = 0; i <= m; ++i) {
       
  1656         if (i == m / 2) {
       
  1657             fSinc[i] = two_pi_fc;
       
  1658         } else {
   942         } else {
  1659             fSinc[i] = SDL_sinf(two_pi_fc * ((float) i - m_over_two)) / ((float) i - m_over_two);
   943             cvt->len_ratio /= ((double) src_rate) / ((double) dst_rate);
  1660             /* Apply blackman window */
   944         }
  1661             fSinc[i] *= 0.42f - 0.5f * SDL_cosf(two_pi_over_m * (float) i) + 0.08f * SDL_cosf(four_pi_over_m * (float) i);
   945 
  1662         }
   946         return 1;               /* added a converter. */
  1663         norm_sum += fSinc[i] < 0 ? -fSinc[i] : fSinc[i];        /* fabs(fSinc[i]); */
   947     }
  1664     }
   948 
  1665 
   949     return 0;                   /* no conversion necessary. */
  1666     norm_fact = 1.0f / norm_sum;
       
  1667 
       
  1668 #define convert_fixed(type, fix) { \
       
  1669         type *dst = (type *)cvt->coeff; \
       
  1670         for( i = 0; i <= m; ++i ) { \
       
  1671             dst[i] = fix(fSinc[i] * norm_fact); \
       
  1672         } \
       
  1673     }
       
  1674 
       
  1675     /* !!! FIXME: this memory leaks. */
       
  1676     cvt->coeff =
       
  1677         (Uint8 *) SDL_malloc((SDL_AUDIO_BITSIZE(format) / 8) * (m + 1));
       
  1678     if (cvt->coeff == NULL) {
       
  1679         return -1;
       
  1680     }
       
  1681 
       
  1682     /* If we're using floating point, we only need to normalize */
       
  1683     if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
       
  1684         float *fDest = (float *) cvt->coeff;
       
  1685         for (i = 0; i <= m; ++i) {
       
  1686             fDest[i] = fSinc[i] * norm_fact;
       
  1687         }
       
  1688     } else {
       
  1689         switch (SDL_AUDIO_BITSIZE(format)) {
       
  1690         case 8:
       
  1691             convert_fixed(Uint8, SDL_Make_1_7);
       
  1692             break;
       
  1693         case 16:
       
  1694             convert_fixed(Uint16, SDL_Make_1_15);
       
  1695             break;
       
  1696         case 32:
       
  1697             convert_fixed(Uint32, SDL_Make_1_31);
       
  1698             break;
       
  1699         }
       
  1700     }
       
  1701 
       
  1702     /* Initialize the state buffer to all zeroes, and set initial position */
       
  1703     /* !!! FIXME: this memory leaks. */
       
  1704     cvt->state_buf =
       
  1705         (Uint8 *) SDL_malloc(cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
       
  1706     if (cvt->state_buf == NULL) {
       
  1707         return -1;
       
  1708     }
       
  1709     SDL_memset(cvt->state_buf, 0,
       
  1710                cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
       
  1711     cvt->state_pos = 0;
       
  1712 
       
  1713     /* Clean up */
       
  1714 #undef convert_fixed
       
  1715     SDL_stack_free(fSinc);
       
  1716 
       
  1717     return 0;
       
  1718 }
       
  1719 
       
  1720 /* This is used to reduce the resampling ratio */
       
  1721 static __inline__ int
       
  1722 SDL_GCD(int a, int b)
       
  1723 {
       
  1724     int temp;
       
  1725     while (b != 0) {
       
  1726         temp = a % b;
       
  1727         a = b;
       
  1728         b = temp;
       
  1729     }
       
  1730     return a;
       
  1731 }
       
  1732 
       
  1733 /* Perform proper resampling. This is pretty slow but it's the best-sounding method. */
       
  1734 static void SDLCALL
       
  1735 SDL_Resample(SDL_AudioCVT * cvt, SDL_AudioFormat format)
       
  1736 {
       
  1737     int i;
       
  1738 
       
  1739 #ifdef DEBUG_CONVERT
       
  1740     printf("Converting audio rate via proper resampling (mono)\n");
       
  1741 #endif
       
  1742 
       
  1743 #define zerostuff_mono(type) { \
       
  1744         const type *src = (const type *) (cvt->buf + cvt->len); \
       
  1745         type *dst = (type *) (cvt->buf + (cvt->len * cvt->len_mult)); \
       
  1746         for (i = cvt->len / sizeof (type); i; --i) { \
       
  1747             src--; \
       
  1748             dst[-1] = src[0]; \
       
  1749             if (cvt->len_mult > 1) { \
       
  1750                 SDL_memset(dst-cvt->len_mult, 0, cvt->len_mult-1); \
       
  1751             } \
       
  1752             dst -= cvt->len_mult; \
       
  1753         } \
       
  1754     }
       
  1755 
       
  1756 #define discard_mono(type) { \
       
  1757         const type *src = (const type *) (cvt->buf); \
       
  1758         type *dst = (type *) (cvt->buf); \
       
  1759         for (i = 0; i < (cvt->len_cvt / sizeof(type)) / cvt->len_div; ++i) { \
       
  1760             dst[0] = src[0]; \
       
  1761             src += cvt->len_div; \
       
  1762             ++dst; \
       
  1763         } \
       
  1764     }
       
  1765 
       
  1766     /* Step 1: Zero stuff the conversion buffer. This upsamples by a factor of len_mult,
       
  1767        creating aliasing at frequencies above the original nyquist frequency.
       
  1768      */
       
  1769 #ifdef DEBUG_CONVERT
       
  1770     printf("Zero-stuffing by a factor of %u\n", cvt->len_mult);
       
  1771 #endif
       
  1772     switch (SDL_AUDIO_BITSIZE(format)) {
       
  1773     case 8:
       
  1774         zerostuff_mono(Uint8);
       
  1775         break;
       
  1776     case 16:
       
  1777         zerostuff_mono(Uint16);
       
  1778         break;
       
  1779     case 32:
       
  1780         zerostuff_mono(Uint32);
       
  1781         break;
       
  1782     }
       
  1783 
       
  1784     cvt->len_cvt *= cvt->len_mult;
       
  1785 
       
  1786     /* Step 2: Use a windowed sinc FIR filter (lowpass filter) to remove the alias
       
  1787        frequencies. This is the slow part.
       
  1788      */
       
  1789     SDL_FilterFIR(cvt, format);
       
  1790 
       
  1791     /* Step 3: Now downsample by discarding samples. */
       
  1792 
       
  1793 #ifdef DEBUG_CONVERT
       
  1794     printf("Discarding samples by a factor of %u\n", cvt->len_div);
       
  1795 #endif
       
  1796     switch (SDL_AUDIO_BITSIZE(format)) {
       
  1797     case 8:
       
  1798         discard_mono(Uint8);
       
  1799         break;
       
  1800     case 16:
       
  1801         discard_mono(Uint16);
       
  1802         break;
       
  1803     case 32:
       
  1804         discard_mono(Uint32);
       
  1805         break;
       
  1806     }
       
  1807 
       
  1808 #undef zerostuff_mono
       
  1809 #undef discard_mono
       
  1810 
       
  1811     cvt->len_cvt /= cvt->len_div;
       
  1812 
       
  1813     if (cvt->filters[++cvt->filter_index]) {
       
  1814         cvt->filters[cvt->filter_index] (cvt, format);
       
  1815     }
       
  1816 }
   950 }
  1817 
   951 
  1818 
   952 
  1819 /* Creates a set of audio filters to convert from one format to another.
   953 /* Creates a set of audio filters to convert from one format to another.
  1820    Returns -1 if the format conversion is not supported, 0 if there's
   954    Returns -1 if the format conversion is not supported, 0 if there's
  1824 int
   958 int
  1825 SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
   959 SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
  1826                   SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
   960                   SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
  1827                   SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
   961                   SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
  1828 {
   962 {
       
   963     /*
       
   964      * !!! FIXME: reorder filters based on which grow/shrink the buffer.
       
   965      * !!! FIXME: ideally, we should do everything that shrinks the buffer
       
   966      * !!! FIXME: first, so we don't have to process as many bytes in a given
       
   967      * !!! FIXME: filter and abuse the CPU cache less. This might not be as
       
   968      * !!! FIXME: good in practice as it sounds in theory, though.
       
   969      */
       
   970 
  1829     /* there are no unsigned types over 16 bits, so catch this upfront. */
   971     /* there are no unsigned types over 16 bits, so catch this upfront. */
  1830     if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
   972     if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
  1831         return -1;
   973         return -1;
  1832     }
   974     }
  1833     if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
   975     if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
  1834         return -1;
   976         return -1;
  1835     }
   977     }
       
   978 
       
   979     /* prevent possible divisions by zero, etc. */
       
   980     if ((src_rate == 0) || (dst_rate == 0)) {
       
   981         return -1;
       
   982     }
       
   983 
  1836 #ifdef DEBUG_CONVERT
   984 #ifdef DEBUG_CONVERT
  1837     printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
   985     printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
  1838            src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
   986            src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
  1839 #endif
   987 #endif
  1840 
   988 
  1845     cvt->needed = 0;
   993     cvt->needed = 0;
  1846     cvt->filter_index = 0;
   994     cvt->filter_index = 0;
  1847     cvt->filters[0] = NULL;
   995     cvt->filters[0] = NULL;
  1848     cvt->len_mult = 1;
   996     cvt->len_mult = 1;
  1849     cvt->len_ratio = 1.0;
   997     cvt->len_ratio = 1.0;
       
   998     cvt->rate_incr = ((double) dst_rate) / ((double) src_rate);
  1850 
   999 
  1851     /* Convert data types, if necessary. Updates (cvt). */
  1000     /* Convert data types, if necessary. Updates (cvt). */
  1852     if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1)
  1001     if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1) {
  1853         return -1;              /* shouldn't happen, but just in case... */
  1002         return -1;              /* shouldn't happen, but just in case... */
       
  1003     }
  1854 
  1004 
  1855     /* Channel conversion */
  1005     /* Channel conversion */
  1856     if (src_channels != dst_channels) {
  1006     if (src_channels != dst_channels) {
  1857         if ((src_channels == 1) && (dst_channels > 1)) {
  1007         if ((src_channels == 1) && (dst_channels > 1)) {
  1858             cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
  1008             cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
  1901         if (src_channels != dst_channels) {
  1051         if (src_channels != dst_channels) {
  1902             /* Uh oh.. */ ;
  1052             /* Uh oh.. */ ;
  1903         }
  1053         }
  1904     }
  1054     }
  1905 
  1055 
  1906     /* Do rate conversion */
  1056     /* Do rate conversion, if necessary. Updates (cvt). */
  1907     if (src_rate != dst_rate) {
  1057     if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) == -1) {
  1908         int rate_gcd;
  1058         return -1;              /* shouldn't happen, but just in case... */
  1909         rate_gcd = SDL_GCD(src_rate, dst_rate);
  1059     }
  1910         cvt->len_mult = dst_rate / rate_gcd;
       
  1911         cvt->len_div = src_rate / rate_gcd;
       
  1912         cvt->len_ratio = (double) cvt->len_mult / (double) cvt->len_div;
       
  1913         cvt->filters[cvt->filter_index++] = SDL_Resample;
       
  1914         /* !!! FIXME: check return value. */
       
  1915         SDL_BuildWindowedSinc(cvt, dst_fmt, 768);
       
  1916     }
       
  1917 
       
  1918 /*
       
  1919     cvt->rate_incr = 0.0;
       
  1920     if ((src_rate / 100) != (dst_rate / 100)) {
       
  1921         Uint32 hi_rate, lo_rate;
       
  1922         int len_mult;
       
  1923         double len_ratio;
       
  1924         SDL_AudioFilter rate_cvt = NULL;
       
  1925 
       
  1926         if (src_rate > dst_rate) {
       
  1927             hi_rate = src_rate;
       
  1928             lo_rate = dst_rate;
       
  1929             switch (src_channels) {
       
  1930             case 1:
       
  1931                 rate_cvt = SDL_RateDIV2;
       
  1932                 break;
       
  1933             case 2:
       
  1934                 rate_cvt = SDL_RateDIV2_c2;
       
  1935                 break;
       
  1936             case 4:
       
  1937                 rate_cvt = SDL_RateDIV2_c4;
       
  1938                 break;
       
  1939             case 6:
       
  1940                 rate_cvt = SDL_RateDIV2_c6;
       
  1941                 break;
       
  1942             default:
       
  1943                 return -1;
       
  1944             }
       
  1945             len_mult = 1;
       
  1946             len_ratio = 0.5;
       
  1947         } else {
       
  1948             hi_rate = dst_rate;
       
  1949             lo_rate = src_rate;
       
  1950             switch (src_channels) {
       
  1951             case 1:
       
  1952                 rate_cvt = SDL_RateMUL2;
       
  1953                 break;
       
  1954             case 2:
       
  1955                 rate_cvt = SDL_RateMUL2_c2;
       
  1956                 break;
       
  1957             case 4:
       
  1958                 rate_cvt = SDL_RateMUL2_c4;
       
  1959                 break;
       
  1960             case 6:
       
  1961                 rate_cvt = SDL_RateMUL2_c6;
       
  1962                 break;
       
  1963             default:
       
  1964                 return -1;
       
  1965             }
       
  1966             len_mult = 2;
       
  1967             len_ratio = 2.0;
       
  1968         }*/
       
  1969     /* If hi_rate = lo_rate*2^x then conversion is easy */
       
  1970     /*   while (((lo_rate * 2) / 100) <= (hi_rate / 100)) {
       
  1971        cvt->filters[cvt->filter_index++] = rate_cvt;
       
  1972        cvt->len_mult *= len_mult;
       
  1973        lo_rate *= 2;
       
  1974        cvt->len_ratio *= len_ratio;
       
  1975        } */
       
  1976     /* We may need a slow conversion here to finish up */
       
  1977     /*    if ((lo_rate / 100) != (hi_rate / 100)) {
       
  1978        #if 1 */
       
  1979     /* The problem with this is that if the input buffer is
       
  1980        say 1K, and the conversion rate is say 1.1, then the
       
  1981        output buffer is 1.1K, which may not be an acceptable
       
  1982        buffer size for the audio driver (not a power of 2)
       
  1983      */
       
  1984     /* For now, punt and hope the rate distortion isn't great.
       
  1985      */
       
  1986 /*#else
       
  1987             if (src_rate < dst_rate) {
       
  1988                 cvt->rate_incr = (double) lo_rate / hi_rate;
       
  1989                 cvt->len_mult *= 2;
       
  1990                 cvt->len_ratio /= cvt->rate_incr;
       
  1991             } else {
       
  1992                 cvt->rate_incr = (double) hi_rate / lo_rate;
       
  1993                 cvt->len_ratio *= cvt->rate_incr;
       
  1994             }
       
  1995             cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
       
  1996 #endif
       
  1997         }
       
  1998     }*/
       
  1999 
  1060 
  2000     /* Set up the filter information */
  1061     /* Set up the filter information */
  2001     if (cvt->filter_index != 0) {
  1062     if (cvt->filter_index != 0) {
  2002         cvt->needed = 1;
  1063         cvt->needed = 1;
  2003         cvt->src_format = src_fmt;
  1064         cvt->src_format = src_fmt;
  2007         cvt->filters[cvt->filter_index] = NULL;
  1068         cvt->filters[cvt->filter_index] = NULL;
  2008     }
  1069     }
  2009     return (cvt->needed);
  1070     return (cvt->needed);
  2010 }
  1071 }
  2011 
  1072 
  2012 #undef SDL_FixMpy8
       
  2013 #undef SDL_FixMpy16
       
  2014 #undef SDL_FixMpy32
       
  2015 #undef SDL_FloatMpy
       
  2016 #undef SDL_Make_1_7
       
  2017 #undef SDL_Make_1_15
       
  2018 #undef SDL_Make_1_31
       
  2019 #undef SDL_Make_2_6
       
  2020 #undef SDL_Make_2_14
       
  2021 #undef SDL_Make_2_30
       
  2022 
  1073 
  2023 /* vi: set ts=4 sw=4 expandtab: */
  1074 /* vi: set ts=4 sw=4 expandtab: */