comparison src/audio/SDL_audiocvt.c @ 1982:3b4ce57c6215

First shot at new audio data types (int32 and float32). Notable changes: - Converters between types are autogenerated. Instead of making multiple passes over the data with seperate filters for endianess, size, signedness, etc, converting between data types is always one specialized filter. This simplifies SDL_BuildAudioCVT(), which otherwise had a million edge cases with the new types, and makes the actually conversions more CPU cache friendly. Left a stub for adding specific optimized versions of these routines (SSE/MMX/Altivec, assembler, etc) - Autogenerated converters are built by SDL/src/audio/sdlgenaudiocvt.pl. This does not need to be run unless tweaking the code, and thus doesn't need integration into the build system. - Went through all the drivers and tried to weed out all the "Uint16" references that are better specified with the new SDL_AudioFormat typedef. - Cleaned out a bunch of hardcoded bitwise magic numbers and replaced them with new SDL_AUDIO_* macros. - Added initial float32 and int32 support code. Theoretically, existing drivers will push these through converters to get the data they want to feed to the hardware. Still TODO: - Optimize and debug new converters. - Update the CoreAudio backend to accept float32 data directly. - Other backends, too? - SDL_LoadWAV() needs to be updated to support int32 and float32 .wav files (both of which exist and can be generated by 'sox' for testing purposes). - Update the mixer to handle new datatypes. - Optionally update SDL_sound and SDL_mixer, etc.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 24 Aug 2006 12:10:46 +0000
parents c121d94672cb
children 8055185ae4ed
comparison
equal deleted inserted replaced
1981:3f21778e7433 1982:3b4ce57c6215
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
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 27 #include "SDL_audio_c.h"
28 28
29 /* Effectively mix right and left channels into a single channel */ 29 /* Effectively mix right and left channels into a single channel */
30 void SDLCALL 30 static void SDLCALL
31 SDL_ConvertMono(SDL_AudioCVT * cvt, Uint16 format) 31 SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
32 { 32 {
33 int i; 33 int i;
34 Sint32 sample; 34 Sint32 sample;
35 35
36 #ifdef DEBUG_CONVERT 36 #ifdef DEBUG_CONVERT
37 fprintf(stderr, "Converting to mono\n"); 37 fprintf(stderr, "Converting to mono\n");
38 #endif 38 #endif
39 switch (format & 0x8018) { 39 switch (format & (SDL_AUDIO_MASK_SIGNED|SDL_AUDIO_MASK_BITSIZE)) {
40
41 case AUDIO_U8: 40 case AUDIO_U8:
42 { 41 {
43 Uint8 *src, *dst; 42 Uint8 *src, *dst;
44 43
45 src = cvt->buf; 44 src = cvt->buf;
82 { 81 {
83 Uint8 *src, *dst; 82 Uint8 *src, *dst;
84 83
85 src = cvt->buf; 84 src = cvt->buf;
86 dst = cvt->buf; 85 dst = cvt->buf;
87 if ((format & 0x1000) == 0x1000) { 86 if (SDL_AUDIO_ISBIGENDIAN(format)) {
88 for (i = cvt->len_cvt / 4; i; --i) { 87 for (i = cvt->len_cvt / 4; i; --i) {
89 sample = (Uint16) ((src[0] << 8) | src[1]) + 88 sample = (Uint16) ((src[0] << 8) | src[1]) +
90 (Uint16) ((src[2] << 8) | src[3]); 89 (Uint16) ((src[2] << 8) | src[3]);
91 if (sample > 65535) { 90 if (sample > 65535) {
92 dst[0] = 0xFF; 91 dst[0] = 0xFF;
122 { 121 {
123 Uint8 *src, *dst; 122 Uint8 *src, *dst;
124 123
125 src = cvt->buf; 124 src = cvt->buf;
126 dst = cvt->buf; 125 dst = cvt->buf;
127 if ((format & 0x1000) == 0x1000) { 126 if (SDL_AUDIO_ISBIGENDIAN(format)) {
128 for (i = cvt->len_cvt / 4; i; --i) { 127 for (i = cvt->len_cvt / 4; i; --i) {
129 sample = (Sint16) ((src[0] << 8) | src[1]) + 128 sample = (Sint16) ((src[0] << 8) | src[1]) +
130 (Sint16) ((src[2] << 8) | src[3]); 129 (Sint16) ((src[2] << 8) | src[3]);
131 if (sample > 32767) { 130 if (sample > 32767) {
132 dst[0] = 0x7F; 131 dst[0] = 0x7F;
161 dst += 2; 160 dst += 2;
162 } 161 }
163 } 162 }
164 } 163 }
165 break; 164 break;
166 } 165
166 case AUDIO_S32:
167 {
168 const Uint32 *src = (const Uint32 *) cvt->buf;
169 Uint32 *dst = (Uint32 *) cvt->buf;
170 if (SDL_AUDIO_ISBIGENDIAN(format)) {
171 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
172 const Sint64 added =
173 (((Sint64) (Sint32) SDL_SwapBE32(src[0])) +
174 ((Sint64) (Sint32) SDL_SwapBE32(src[1])));
175 *(dst++) = SDL_SwapBE32((Uint32) ((Sint32) (added >> 1)));
176 }
177 } else {
178 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
179 const Sint64 added =
180 (((Sint64) (Sint32) SDL_SwapLE32(src[0])) +
181 ((Sint64) (Sint32) SDL_SwapLE32(src[1])));
182 *(dst++) = SDL_SwapLE32((Uint32) ((Sint32) (added >> 1)));
183 }
184 }
185 }
186 break;
187
188 case AUDIO_F32:
189 {
190 /* !!! FIXME: this convert union is nasty. */
191 union { float f; Uint32 ui32; } f2i;
192 const Uint32 *src = (const Uint32 *) cvt->buf;
193 Uint32 *dst = (Uint32 *) cvt->buf;
194 if (SDL_AUDIO_ISBIGENDIAN(format)) {
195 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
196 float src1, src2;
197 f2i.ui32 = SDL_SwapBE32(src[0]);
198 src1 = f2i.f;
199 f2i.ui32 = SDL_SwapBE32(src[1]);
200 src2 = f2i.f;
201 const double added = ((double) src1) + ((double) src2);
202 f2i.f = (float) (added * 0.5);
203 *(dst++) = SDL_SwapBE32(f2i.ui32);
204 }
205 } else {
206 for (i = cvt->len_cvt / 8; i; --i, src += 2) {
207 float src1, src2;
208 f2i.ui32 = SDL_SwapLE32(src[0]);
209 src1 = f2i.f;
210 f2i.ui32 = SDL_SwapLE32(src[1]);
211 src2 = f2i.f;
212 const double added = ((double) src1) + ((double) src2);
213 f2i.f = (float) (added * 0.5);
214 *(dst++) = SDL_SwapLE32(f2i.ui32);
215 }
216 }
217 }
218 break;
219 }
220
167 cvt->len_cvt /= 2; 221 cvt->len_cvt /= 2;
168 if (cvt->filters[++cvt->filter_index]) { 222 if (cvt->filters[++cvt->filter_index]) {
169 cvt->filters[cvt->filter_index] (cvt, format); 223 cvt->filters[cvt->filter_index] (cvt, format);
170 } 224 }
171 } 225 }
172 226
227
173 /* Discard top 4 channels */ 228 /* Discard top 4 channels */
174 void SDLCALL 229 static void SDLCALL
175 SDL_ConvertStrip(SDL_AudioCVT * cvt, Uint16 format) 230 SDL_ConvertStrip(SDL_AudioCVT * cvt, SDL_AudioFormat format)
176 { 231 {
177 int i; 232 int i;
178 Sint32 lsample, rsample;
179 233
180 #ifdef DEBUG_CONVERT 234 #ifdef DEBUG_CONVERT
181 fprintf(stderr, "Converting down to stereo\n"); 235 fprintf(stderr, "Converting down from 6 channels to stereo\n");
182 #endif 236 #endif
183 switch (format & 0x8018) { 237
184 238 #define strip_chans_6_to_2(type) \
185 case AUDIO_U8: 239 { \
186 { 240 const type *src = (const type *) cvt->buf; \
187 Uint8 *src, *dst; 241 type *dst = (type *) cvt->buf; \
188 242 for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
189 src = cvt->buf; 243 dst[0] = src[0]; \
190 dst = cvt->buf; 244 dst[1] = src[1]; \
191 for (i = cvt->len_cvt / 6; i; --i) { 245 src += 6; \
192 dst[0] = src[0]; 246 dst += 2; \
193 dst[1] = src[1]; 247 } \
194 src += 6; 248 }
195 dst += 2; 249
196 } 250 /* this function only cares about typesize, and data as a block of bits. */
197 } 251 switch (SDL_AUDIO_BITSIZE(format)) {
198 break; 252 case 8:
199 253 strip_chans_6_to_2(Uint8);
200 case AUDIO_S8: 254 break;
201 { 255 case 16:
202 Sint8 *src, *dst; 256 strip_chans_6_to_2(Uint16);
203 257 break;
204 src = (Sint8 *) cvt->buf; 258 case 32:
205 dst = (Sint8 *) cvt->buf; 259 strip_chans_6_to_2(Uint32);
206 for (i = cvt->len_cvt / 6; i; --i) { 260 break;
207 dst[0] = src[0]; 261 }
208 dst[1] = src[1]; 262
209 src += 6; 263 #undef strip_chans_6_to_2
210 dst += 2; 264
211 }
212 }
213 break;
214
215 case AUDIO_U16:
216 {
217 Uint8 *src, *dst;
218
219 src = cvt->buf;
220 dst = cvt->buf;
221 if ((format & 0x1000) == 0x1000) {
222 for (i = cvt->len_cvt / 12; i; --i) {
223 lsample = (Uint16) ((src[0] << 8) | src[1]);
224 rsample = (Uint16) ((src[2] << 8) | src[3]);
225 dst[1] = (lsample & 0xFF);
226 lsample >>= 8;
227 dst[0] = (lsample & 0xFF);
228 dst[3] = (rsample & 0xFF);
229 rsample >>= 8;
230 dst[2] = (rsample & 0xFF);
231 src += 12;
232 dst += 4;
233 }
234 } else {
235 for (i = cvt->len_cvt / 12; i; --i) {
236 lsample = (Uint16) ((src[1] << 8) | src[0]);
237 rsample = (Uint16) ((src[3] << 8) | src[2]);
238 dst[0] = (lsample & 0xFF);
239 lsample >>= 8;
240 dst[1] = (lsample & 0xFF);
241 dst[2] = (rsample & 0xFF);
242 rsample >>= 8;
243 dst[3] = (rsample & 0xFF);
244 src += 12;
245 dst += 4;
246 }
247 }
248 }
249 break;
250
251 case AUDIO_S16:
252 {
253 Uint8 *src, *dst;
254
255 src = cvt->buf;
256 dst = cvt->buf;
257 if ((format & 0x1000) == 0x1000) {
258 for (i = cvt->len_cvt / 12; i; --i) {
259 lsample = (Sint16) ((src[0] << 8) | src[1]);
260 rsample = (Sint16) ((src[2] << 8) | src[3]);
261 dst[1] = (lsample & 0xFF);
262 lsample >>= 8;
263 dst[0] = (lsample & 0xFF);
264 dst[3] = (rsample & 0xFF);
265 rsample >>= 8;
266 dst[2] = (rsample & 0xFF);
267 src += 12;
268 dst += 4;
269 }
270 } else {
271 for (i = cvt->len_cvt / 12; i; --i) {
272 lsample = (Sint16) ((src[1] << 8) | src[0]);
273 rsample = (Sint16) ((src[3] << 8) | src[2]);
274 dst[0] = (lsample & 0xFF);
275 lsample >>= 8;
276 dst[1] = (lsample & 0xFF);
277 dst[2] = (rsample & 0xFF);
278 rsample >>= 8;
279 dst[3] = (rsample & 0xFF);
280 src += 12;
281 dst += 4;
282 }
283 }
284 }
285 break;
286 }
287 cvt->len_cvt /= 3; 265 cvt->len_cvt /= 3;
288 if (cvt->filters[++cvt->filter_index]) { 266 if (cvt->filters[++cvt->filter_index]) {
289 cvt->filters[cvt->filter_index] (cvt, format); 267 cvt->filters[cvt->filter_index] (cvt, format);
290 } 268 }
291 } 269 }
292 270
293 271
294 /* Discard top 2 channels of 6 */ 272 /* Discard top 2 channels of 6 */
295 void SDLCALL 273 static void SDLCALL
296 SDL_ConvertStrip_2(SDL_AudioCVT * cvt, Uint16 format) 274 SDL_ConvertStrip_2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
297 { 275 {
298 int i; 276 int i;
299 Sint32 lsample, rsample;
300 277
301 #ifdef DEBUG_CONVERT 278 #ifdef DEBUG_CONVERT
302 fprintf(stderr, "Converting 6 down to quad\n"); 279 fprintf(stderr, "Converting 6 down to quad\n");
303 #endif 280 #endif
304 switch (format & 0x8018) { 281
305 282 #define strip_chans_6_to_4(type) \
306 case AUDIO_U8: 283 { \
307 { 284 const type *src = (const type *) cvt->buf; \
308 Uint8 *src, *dst; 285 type *dst = (type *) cvt->buf; \
309 286 for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
310 src = cvt->buf; 287 dst[0] = src[0]; \
311 dst = cvt->buf; 288 dst[1] = src[1]; \
312 for (i = cvt->len_cvt / 4; i; --i) { 289 dst[2] = src[2]; \
313 dst[0] = src[0]; 290 dst[3] = src[3]; \
314 dst[1] = src[1]; 291 src += 6; \
315 src += 4; 292 dst += 4; \
316 dst += 2; 293 } \
317 } 294 }
318 } 295
319 break; 296 /* this function only cares about typesize, and data as a block of bits. */
320 297 switch (SDL_AUDIO_BITSIZE(format)) {
321 case AUDIO_S8: 298 case 8:
322 { 299 strip_chans_6_to_4(Uint8);
323 Sint8 *src, *dst; 300 break;
324 301 case 16:
325 src = (Sint8 *) cvt->buf; 302 strip_chans_6_to_4(Uint16);
326 dst = (Sint8 *) cvt->buf; 303 break;
327 for (i = cvt->len_cvt / 4; i; --i) { 304 case 32:
328 dst[0] = src[0]; 305 strip_chans_6_to_4(Uint32);
329 dst[1] = src[1]; 306 break;
330 src += 4; 307 }
331 dst += 2; 308
332 } 309 #undef strip_chans_6_to_4
333 } 310
334 break; 311 cvt->len_cvt /= 6;
335 312 cvt->len_cvt *= 4;
336 case AUDIO_U16:
337 {
338 Uint8 *src, *dst;
339
340 src = cvt->buf;
341 dst = cvt->buf;
342 if ((format & 0x1000) == 0x1000) {
343 for (i = cvt->len_cvt / 8; i; --i) {
344 lsample = (Uint16) ((src[0] << 8) | src[1]);
345 rsample = (Uint16) ((src[2] << 8) | src[3]);
346 dst[1] = (lsample & 0xFF);
347 lsample >>= 8;
348 dst[0] = (lsample & 0xFF);
349 dst[3] = (rsample & 0xFF);
350 rsample >>= 8;
351 dst[2] = (rsample & 0xFF);
352 src += 8;
353 dst += 4;
354 }
355 } else {
356 for (i = cvt->len_cvt / 8; i; --i) {
357 lsample = (Uint16) ((src[1] << 8) | src[0]);
358 rsample = (Uint16) ((src[3] << 8) | src[2]);
359 dst[0] = (lsample & 0xFF);
360 lsample >>= 8;
361 dst[1] = (lsample & 0xFF);
362 dst[2] = (rsample & 0xFF);
363 rsample >>= 8;
364 dst[3] = (rsample & 0xFF);
365 src += 8;
366 dst += 4;
367 }
368 }
369 }
370 break;
371
372 case AUDIO_S16:
373 {
374 Uint8 *src, *dst;
375
376 src = cvt->buf;
377 dst = cvt->buf;
378 if ((format & 0x1000) == 0x1000) {
379 for (i = cvt->len_cvt / 8; i; --i) {
380 lsample = (Sint16) ((src[0] << 8) | src[1]);
381 rsample = (Sint16) ((src[2] << 8) | src[3]);
382 dst[1] = (lsample & 0xFF);
383 lsample >>= 8;
384 dst[0] = (lsample & 0xFF);
385 dst[3] = (rsample & 0xFF);
386 rsample >>= 8;
387 dst[2] = (rsample & 0xFF);
388 src += 8;
389 dst += 4;
390 }
391 } else {
392 for (i = cvt->len_cvt / 8; i; --i) {
393 lsample = (Sint16) ((src[1] << 8) | src[0]);
394 rsample = (Sint16) ((src[3] << 8) | src[2]);
395 dst[0] = (lsample & 0xFF);
396 lsample >>= 8;
397 dst[1] = (lsample & 0xFF);
398 dst[2] = (rsample & 0xFF);
399 rsample >>= 8;
400 dst[3] = (rsample & 0xFF);
401 src += 8;
402 dst += 4;
403 }
404 }
405 }
406 break;
407 }
408 cvt->len_cvt /= 2;
409 if (cvt->filters[++cvt->filter_index]) { 313 if (cvt->filters[++cvt->filter_index]) {
410 cvt->filters[cvt->filter_index] (cvt, format); 314 cvt->filters[cvt->filter_index] (cvt, format);
411 } 315 }
412 } 316 }
413 317
414 /* Duplicate a mono channel to both stereo channels */ 318 /* Duplicate a mono channel to both stereo channels */
415 void SDLCALL 319 static void SDLCALL
416 SDL_ConvertStereo(SDL_AudioCVT * cvt, Uint16 format) 320 SDL_ConvertStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
417 { 321 {
418 int i; 322 int i;
419 323
420 #ifdef DEBUG_CONVERT 324 #ifdef DEBUG_CONVERT
421 fprintf(stderr, "Converting to stereo\n"); 325 fprintf(stderr, "Converting to stereo\n");
422 #endif 326 #endif
423 if ((format & 0xFF) == 16) { 327
424 Uint16 *src, *dst; 328 #define dup_chans_1_to_2(type) \
425 329 { \
426 src = (Uint16 *) (cvt->buf + cvt->len_cvt); 330 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
427 dst = (Uint16 *) (cvt->buf + cvt->len_cvt * 2); 331 type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
428 for (i = cvt->len_cvt / 2; i; --i) { 332 for (i = cvt->len_cvt / 2; i; --i, --src) { \
429 dst -= 2; 333 const type val = *src; \
430 src -= 1; 334 dst -= 2; \
431 dst[0] = src[0]; 335 dst[0] = dst[1] = val; \
432 dst[1] = src[0]; 336 } \
433 } 337 }
434 } else { 338
435 Uint8 *src, *dst; 339 /* this function only cares about typesize, and data as a block of bits. */
436 340 switch (SDL_AUDIO_BITSIZE(format)) {
437 src = cvt->buf + cvt->len_cvt; 341 case 8:
438 dst = cvt->buf + cvt->len_cvt * 2; 342 dup_chans_1_to_2(Uint8);
439 for (i = cvt->len_cvt; i; --i) { 343 break;
440 dst -= 2; 344 case 16:
441 src -= 1; 345 dup_chans_1_to_2(Uint16);
442 dst[0] = src[0]; 346 break;
443 dst[1] = src[0]; 347 case 32:
444 } 348 dup_chans_1_to_2(Uint32);
445 } 349 break;
350 }
351
352 #undef dup_chans_1_to_2
353
446 cvt->len_cvt *= 2; 354 cvt->len_cvt *= 2;
447 if (cvt->filters[++cvt->filter_index]) { 355 if (cvt->filters[++cvt->filter_index]) {
448 cvt->filters[cvt->filter_index] (cvt, format); 356 cvt->filters[cvt->filter_index] (cvt, format);
449 } 357 }
450 } 358 }
451 359
452 360
453 /* Duplicate a stereo channel to a pseudo-5.1 stream */ 361 /* Duplicate a stereo channel to a pseudo-5.1 stream */
454 void SDLCALL 362 static void SDLCALL
455 SDL_ConvertSurround(SDL_AudioCVT * cvt, Uint16 format) 363 SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
456 { 364 {
457 int i; 365 int i;
458 366
459 #ifdef DEBUG_CONVERT 367 #ifdef DEBUG_CONVERT
460 fprintf(stderr, "Converting stereo to surround\n"); 368 fprintf(stderr, "Converting stereo to surround\n");
461 #endif 369 #endif
462 switch (format & 0x8018) { 370
463 371 switch (format & (SDL_AUDIO_MASK_SIGNED|SDL_AUDIO_MASK_BITSIZE)) {
464 case AUDIO_U8: 372 case AUDIO_U8:
465 { 373 {
466 Uint8 *src, *dst, lf, rf, ce; 374 Uint8 *src, *dst, lf, rf, ce;
467 375
468 src = (Uint8 *) (cvt->buf + cvt->len_cvt); 376 src = (Uint8 *) (cvt->buf + cvt->len_cvt);
511 Uint16 lf, rf, ce, lr, rr; 419 Uint16 lf, rf, ce, lr, rr;
512 420
513 src = cvt->buf + cvt->len_cvt; 421 src = cvt->buf + cvt->len_cvt;
514 dst = cvt->buf + cvt->len_cvt * 3; 422 dst = cvt->buf + cvt->len_cvt * 3;
515 423
516 if ((format & 0x1000) == 0x1000) { 424 if (SDL_AUDIO_ISBIGENDIAN(format)) {
517 for (i = cvt->len_cvt / 4; i; --i) { 425 for (i = cvt->len_cvt / 4; i; --i) {
518 dst -= 12; 426 dst -= 12;
519 src -= 4; 427 src -= 4;
520 lf = (Uint16) ((src[0] << 8) | src[1]); 428 lf = (Uint16) ((src[0] << 8) | src[1]);
521 rf = (Uint16) ((src[2] << 8) | src[3]); 429 rf = (Uint16) ((src[2] << 8) | src[3]);
571 Sint16 lf, rf, ce, lr, rr; 479 Sint16 lf, rf, ce, lr, rr;
572 480
573 src = cvt->buf + cvt->len_cvt; 481 src = cvt->buf + cvt->len_cvt;
574 dst = cvt->buf + cvt->len_cvt * 3; 482 dst = cvt->buf + cvt->len_cvt * 3;
575 483
576 if ((format & 0x1000) == 0x1000) { 484 if (SDL_AUDIO_ISBIGENDIAN(format)) {
577 for (i = cvt->len_cvt / 4; i; --i) { 485 for (i = cvt->len_cvt / 4; i; --i) {
578 dst -= 12; 486 dst -= 12;
579 src -= 4; 487 src -= 4;
580 lf = (Sint16) ((src[0] << 8) | src[1]); 488 lf = (Sint16) ((src[0] << 8) | src[1]);
581 rf = (Sint16) ((src[2] << 8) | src[3]); 489 rf = (Sint16) ((src[2] << 8) | src[3]);
622 dst[3 + 8] = ((ce >> 8) & 0xFF); 530 dst[3 + 8] = ((ce >> 8) & 0xFF);
623 } 531 }
624 } 532 }
625 } 533 }
626 break; 534 break;
535
536 case AUDIO_S32:
537 {
538 Sint32 lf, rf, ce;
539 const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
540 Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
541
542 if (SDL_AUDIO_ISBIGENDIAN(format)) {
543 for (i = cvt->len_cvt / 8; i; --i) {
544 dst -= 6;
545 src -= 2;
546 lf = (Sint32) SDL_SwapBE32(src[0]);
547 rf = (Sint32) SDL_SwapBE32(src[1]);
548 ce = (lf / 2) + (rf / 2);
549 dst[0] = SDL_SwapBE32((Uint32) lf);
550 dst[1] = SDL_SwapBE32((Uint32) rf);
551 dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
552 dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
553 dst[4] = SDL_SwapBE32((Uint32) ce);
554 dst[5] = SDL_SwapBE32((Uint32) ce);
555 }
556 } else {
557 for (i = cvt->len_cvt / 8; i; --i) {
558 dst -= 6;
559 src -= 2;
560 lf = (Sint32) SDL_SwapLE32(src[0]);
561 rf = (Sint32) SDL_SwapLE32(src[1]);
562 ce = (lf / 2) + (rf / 2);
563 dst[0] = src[0];
564 dst[1] = src[1];
565 dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
566 dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
567 dst[4] = SDL_SwapLE32((Uint32) ce);
568 dst[5] = SDL_SwapLE32((Uint32) ce);
569 }
570 }
571 }
572 break;
573
574 case AUDIO_F32:
575 {
576 union { float f; Uint32 ui32; } f2i; /* !!! FIXME: lame. */
577 float lf, rf, ce;
578 const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
579 Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
580
581 if (SDL_AUDIO_ISBIGENDIAN(format)) {
582 for (i = cvt->len_cvt / 8; i; --i) {
583 dst -= 6;
584 src -= 2;
585 f2i.ui32 = SDL_SwapBE32(src[0]);
586 lf = f2i.f;
587 f2i.ui32 = SDL_SwapBE32(src[1]);
588 rf = f2i.f;
589 ce = (lf * 0.5f) + (rf * 0.5f);
590 dst[0] = src[0];
591 dst[1] = src[1];
592 f2i.f = (lf - ce);
593 dst[2] = SDL_SwapBE32(f2i.ui32);
594 f2i.f = (rf - ce);
595 dst[3] = SDL_SwapBE32(f2i.ui32);
596 f2i.f = ce;
597 f2i.ui32 = SDL_SwapBE32(f2i.ui32);
598 dst[4] = f2i.ui32;
599 dst[5] = f2i.ui32;
600 }
601 } else {
602 for (i = cvt->len_cvt / 8; i; --i) {
603 dst -= 6;
604 src -= 2;
605 f2i.ui32 = SDL_SwapLE32(src[0]);
606 lf = f2i.f;
607 f2i.ui32 = SDL_SwapLE32(src[1]);
608 rf = f2i.f;
609 ce = (lf * 0.5f) + (rf * 0.5f);
610 dst[0] = src[0];
611 dst[1] = src[1];
612 f2i.f = (lf - ce);
613 dst[2] = SDL_SwapLE32(f2i.ui32);
614 f2i.f = (rf - ce);
615 dst[3] = SDL_SwapLE32(f2i.ui32);
616 f2i.f = ce;
617 f2i.ui32 = SDL_SwapLE32(f2i.ui32);
618 dst[4] = f2i.ui32;
619 dst[5] = f2i.ui32;
620 }
621 }
622 }
623 break;
624
627 } 625 }
628 cvt->len_cvt *= 3; 626 cvt->len_cvt *= 3;
629 if (cvt->filters[++cvt->filter_index]) { 627 if (cvt->filters[++cvt->filter_index]) {
630 cvt->filters[cvt->filter_index] (cvt, format); 628 cvt->filters[cvt->filter_index] (cvt, format);
631 } 629 }
632 } 630 }
633 631
634 632
635 /* Duplicate a stereo channel to a pseudo-4.0 stream */ 633 /* Duplicate a stereo channel to a pseudo-4.0 stream */
636 void SDLCALL 634 static void SDLCALL
637 SDL_ConvertSurround_4(SDL_AudioCVT * cvt, Uint16 format) 635 SDL_ConvertSurround_4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
638 { 636 {
639 int i; 637 int i;
640 638
641 #ifdef DEBUG_CONVERT 639 #ifdef DEBUG_CONVERT
642 fprintf(stderr, "Converting stereo to quad\n"); 640 fprintf(stderr, "Converting stereo to quad\n");
643 #endif 641 #endif
644 switch (format & 0x8018) { 642
645 643 switch (format & (SDL_AUDIO_MASK_SIGNED|SDL_AUDIO_MASK_BITSIZE)) {
646 case AUDIO_U8: 644 case AUDIO_U8:
647 { 645 {
648 Uint8 *src, *dst, lf, rf, ce; 646 Uint8 *src, *dst, lf, rf, ce;
649 647
650 src = (Uint8 *) (cvt->buf + cvt->len_cvt); 648 src = (Uint8 *) (cvt->buf + cvt->len_cvt);
689 Uint16 lf, rf, ce, lr, rr; 687 Uint16 lf, rf, ce, lr, rr;
690 688
691 src = cvt->buf + cvt->len_cvt; 689 src = cvt->buf + cvt->len_cvt;
692 dst = cvt->buf + cvt->len_cvt * 2; 690 dst = cvt->buf + cvt->len_cvt * 2;
693 691
694 if ((format & 0x1000) == 0x1000) { 692 if (SDL_AUDIO_ISBIGENDIAN(format)) {
695 for (i = cvt->len_cvt / 4; i; --i) { 693 for (i = cvt->len_cvt / 4; i; --i) {
696 dst -= 8; 694 dst -= 8;
697 src -= 4; 695 src -= 4;
698 lf = (Uint16) ((src[0] << 8) | src[1]); 696 lf = (Uint16) ((src[0] << 8) | src[1]);
699 rf = (Uint16) ((src[2] << 8) | src[3]); 697 rf = (Uint16) ((src[2] << 8) | src[3]);
739 Sint16 lf, rf, ce, lr, rr; 737 Sint16 lf, rf, ce, lr, rr;
740 738
741 src = cvt->buf + cvt->len_cvt; 739 src = cvt->buf + cvt->len_cvt;
742 dst = cvt->buf + cvt->len_cvt * 2; 740 dst = cvt->buf + cvt->len_cvt * 2;
743 741
744 if ((format & 0x1000) == 0x1000) { 742 if (SDL_AUDIO_ISBIGENDIAN(format)) {
745 for (i = cvt->len_cvt / 4; i; --i) { 743 for (i = cvt->len_cvt / 4; i; --i) {
746 dst -= 8; 744 dst -= 8;
747 src -= 4; 745 src -= 4;
748 lf = (Sint16) ((src[0] << 8) | src[1]); 746 lf = (Sint16) ((src[0] << 8) | src[1]);
749 rf = (Sint16) ((src[2] << 8) | src[3]); 747 rf = (Sint16) ((src[2] << 8) | src[3]);
780 dst[3 + 4] = ((rr >> 8) & 0xFF); 778 dst[3 + 4] = ((rr >> 8) & 0xFF);
781 } 779 }
782 } 780 }
783 } 781 }
784 break; 782 break;
783
784 case AUDIO_S32:
785 {
786 const Uint32 *src = (const Uint32 *) (cvt->buf + cvt->len_cvt);
787 Uint32 *dst = (Uint32 *) (cvt->buf + cvt->len_cvt * 2);
788 Sint32 lf, rf, ce;
789
790 if (SDL_AUDIO_ISBIGENDIAN(format)) {
791 for (i = cvt->len_cvt / 8; i; --i) {
792 dst -= 4;
793 src -= 2;
794 lf = (Sint32) SDL_SwapBE32(src[0]);
795 rf = (Sint32) SDL_SwapBE32(src[1]);
796 ce = (lf / 2) + (rf / 2);
797 dst[0] = src[0];
798 dst[1] = src[1];
799 dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
800 dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
801 }
802 } else {
803 for (i = cvt->len_cvt / 8; i; --i) {
804 dst -= 4;
805 src -= 2;
806 lf = (Sint32) SDL_SwapLE32(src[0]);
807 rf = (Sint32) SDL_SwapLE32(src[1]);
808 ce = (lf / 2) + (rf / 2);
809 dst[0] = src[0];
810 dst[1] = src[1];
811 dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
812 dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
813 }
814 }
815 }
816 break;
785 } 817 }
786 cvt->len_cvt *= 2; 818 cvt->len_cvt *= 2;
787 if (cvt->filters[++cvt->filter_index]) { 819 if (cvt->filters[++cvt->filter_index]) {
788 cvt->filters[cvt->filter_index] (cvt, format); 820 cvt->filters[cvt->filter_index] (cvt, format);
789 } 821 }
790 } 822 }
791 823
792 824 /* Convert rate up by multiple of 2 */
793 /* Convert 8-bit to 16-bit - LSB */ 825 static void SDLCALL
794 void SDLCALL 826 SDL_RateMUL2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
795 SDL_Convert16LSB(SDL_AudioCVT * cvt, Uint16 format)
796 { 827 {
797 int i; 828 int i;
798 Uint8 *src, *dst;
799 829
800 #ifdef DEBUG_CONVERT 830 #ifdef DEBUG_CONVERT
801 fprintf(stderr, "Converting to 16-bit LSB\n"); 831 fprintf(stderr, "Converting audio rate * 2 (mono)\n");
802 #endif 832 #endif
803 src = cvt->buf + cvt->len_cvt; 833
804 dst = cvt->buf + cvt->len_cvt * 2; 834 #define mul2_mono(type) { \
805 for (i = cvt->len_cvt; i; --i) { 835 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
806 src -= 1; 836 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
807 dst -= 2; 837 for (i = cvt->len_cvt / sizeof (type); i; --i) { \
808 dst[1] = *src; 838 src--; \
809 dst[0] = 0; 839 dst[-1] = dst[-2] = src[0]; \
810 } 840 dst -= 2; \
811 format = ((format & ~0x0008) | AUDIO_U16LSB); 841 } \
842 }
843
844 switch (SDL_AUDIO_BITSIZE(format)) {
845 case 8:
846 mul2_mono(Uint8);
847 break;
848 case 16:
849 mul2_mono(Uint16);
850 break;
851 case 32:
852 mul2_mono(Uint32);
853 break;
854 }
855
856 #undef mul2_mono
857
812 cvt->len_cvt *= 2; 858 cvt->len_cvt *= 2;
813 if (cvt->filters[++cvt->filter_index]) { 859 if (cvt->filters[++cvt->filter_index]) {
814 cvt->filters[cvt->filter_index] (cvt, format); 860 cvt->filters[cvt->filter_index] (cvt, format);
815 } 861 }
816 } 862 }
817 863
818 /* Convert 8-bit to 16-bit - MSB */ 864
819 void SDLCALL 865 /* Convert rate up by multiple of 2, for stereo */
820 SDL_Convert16MSB(SDL_AudioCVT * cvt, Uint16 format) 866 static void SDLCALL
867 SDL_RateMUL2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
821 { 868 {
822 int i; 869 int i;
823 Uint8 *src, *dst;
824 870
825 #ifdef DEBUG_CONVERT 871 #ifdef DEBUG_CONVERT
826 fprintf(stderr, "Converting to 16-bit MSB\n"); 872 fprintf(stderr, "Converting audio rate * 2 (stereo)\n");
827 #endif 873 #endif
828 src = cvt->buf + cvt->len_cvt; 874
829 dst = cvt->buf + cvt->len_cvt * 2; 875 #define mul2_stereo(type) { \
830 for (i = cvt->len_cvt; i; --i) { 876 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
831 src -= 1; 877 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
832 dst -= 2; 878 for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
833 dst[0] = *src; 879 const type r = src[-1]; \
834 dst[1] = 0; 880 const type l = src[-2]; \
835 } 881 src -= 2; \
836 format = ((format & ~0x0008) | AUDIO_U16MSB); 882 dst[-1] = r; \
883 dst[-2] = l; \
884 dst[-3] = r; \
885 dst[-4] = l; \
886 dst -= 4; \
887 } \
888 }
889
890 switch (SDL_AUDIO_BITSIZE(format)) {
891 case 8:
892 mul2_stereo(Uint8);
893 break;
894 case 16:
895 mul2_stereo(Uint16);
896 break;
897 case 32:
898 mul2_stereo(Uint32);
899 break;
900 }
901
902 #undef mul2_stereo
903
837 cvt->len_cvt *= 2; 904 cvt->len_cvt *= 2;
838 if (cvt->filters[++cvt->filter_index]) { 905 if (cvt->filters[++cvt->filter_index]) {
839 cvt->filters[cvt->filter_index] (cvt, format); 906 cvt->filters[cvt->filter_index] (cvt, format);
840 } 907 }
841 } 908 }
842 909
843 /* Convert 16-bit to 8-bit */ 910 /* Convert rate up by multiple of 2, for quad */
844 void SDLCALL 911 static void SDLCALL
845 SDL_Convert8(SDL_AudioCVT * cvt, Uint16 format) 912 SDL_RateMUL2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
846 { 913 {
847 int i; 914 int i;
848 Uint8 *src, *dst;
849 915
850 #ifdef DEBUG_CONVERT 916 #ifdef DEBUG_CONVERT
851 fprintf(stderr, "Converting to 8-bit\n"); 917 fprintf(stderr, "Converting audio rate * 2 (quad)\n");
852 #endif 918 #endif
853 src = cvt->buf; 919
854 dst = cvt->buf; 920 #define mul2_quad(type) { \
855 if ((format & 0x1000) != 0x1000) { /* Little endian */ 921 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
856 ++src; 922 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
857 } 923 for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
858 for (i = cvt->len_cvt / 2; i; --i) { 924 const type c1 = src[-1]; \
859 *dst = *src; 925 const type c2 = src[-2]; \
860 src += 2; 926 const type c3 = src[-3]; \
861 dst += 1; 927 const type c4 = src[-4]; \
862 } 928 src -= 4; \
863 format = ((format & ~0x9010) | AUDIO_U8); 929 dst[-1] = c1; \
930 dst[-2] = c2; \
931 dst[-3] = c3; \
932 dst[-4] = c4; \
933 dst[-5] = c1; \
934 dst[-6] = c2; \
935 dst[-7] = c3; \
936 dst[-8] = c4; \
937 dst -= 8; \
938 } \
939 }
940
941 switch (SDL_AUDIO_BITSIZE(format)) {
942 case 8:
943 mul2_quad(Uint8);
944 break;
945 case 16:
946 mul2_quad(Uint16);
947 break;
948 case 32:
949 mul2_quad(Uint32);
950 break;
951 }
952
953 #undef mul2_quad
954
955 cvt->len_cvt *= 2;
956 if (cvt->filters[++cvt->filter_index]) {
957 cvt->filters[cvt->filter_index] (cvt, format);
958 }
959 }
960
961
962 /* Convert rate up by multiple of 2, for 5.1 */
963 static void SDLCALL
964 SDL_RateMUL2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
965 {
966 int i;
967
968 #ifdef DEBUG_CONVERT
969 fprintf(stderr, "Converting audio rate * 2 (six channels)\n");
970 #endif
971
972 #define mul2_chansix(type) { \
973 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
974 type *dst = (type *) (cvt->buf + (cvt->len_cvt * 2)); \
975 for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
976 const type c1 = src[-1]; \
977 const type c2 = src[-2]; \
978 const type c3 = src[-3]; \
979 const type c4 = src[-4]; \
980 const type c5 = src[-5]; \
981 const type c6 = src[-6]; \
982 src -= 6; \
983 dst[-1] = c1; \
984 dst[-2] = c2; \
985 dst[-3] = c3; \
986 dst[-4] = c4; \
987 dst[-5] = c5; \
988 dst[-6] = c6; \
989 dst[-7] = c1; \
990 dst[-8] = c2; \
991 dst[-9] = c3; \
992 dst[-10] = c4; \
993 dst[-11] = c5; \
994 dst[-12] = c6; \
995 dst -= 12; \
996 } \
997 }
998
999 switch (SDL_AUDIO_BITSIZE(format)) {
1000 case 8:
1001 mul2_chansix(Uint8);
1002 break;
1003 case 16:
1004 mul2_chansix(Uint16);
1005 break;
1006 case 32:
1007 mul2_chansix(Uint32);
1008 break;
1009 }
1010
1011 #undef mul2_chansix
1012
1013 cvt->len_cvt *= 2;
1014 if (cvt->filters[++cvt->filter_index]) {
1015 cvt->filters[cvt->filter_index] (cvt, format);
1016 }
1017 }
1018
1019 /* Convert rate down by multiple of 2 */
1020 static void SDLCALL
1021 SDL_RateDIV2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1022 {
1023 int i;
1024
1025 #ifdef DEBUG_CONVERT
1026 fprintf(stderr, "Converting audio rate / 2 (mono)\n");
1027 #endif
1028
1029 #define div2_mono(type) { \
1030 const type *src = (const type *) cvt->buf; \
1031 type *dst = (type *) cvt->buf; \
1032 for (i = cvt->len_cvt / (sizeof (type) * 2); i; --i) { \
1033 dst[0] = src[0]; \
1034 src += 2; \
1035 dst++; \
1036 } \
1037 }
1038
1039 switch (SDL_AUDIO_BITSIZE(format)) {
1040 case 8:
1041 div2_mono(Uint8);
1042 break;
1043 case 16:
1044 div2_mono(Uint16);
1045 break;
1046 case 32:
1047 div2_mono(Uint32);
1048 break;
1049 }
1050
1051 #undef div2_mono
1052
864 cvt->len_cvt /= 2; 1053 cvt->len_cvt /= 2;
865 if (cvt->filters[++cvt->filter_index]) { 1054 if (cvt->filters[++cvt->filter_index]) {
866 cvt->filters[cvt->filter_index] (cvt, format); 1055 cvt->filters[cvt->filter_index] (cvt, format);
867 } 1056 }
868 } 1057 }
869 1058
870 /* Toggle signed/unsigned */ 1059
871 void SDLCALL 1060 /* Convert rate down by multiple of 2, for stereo */
872 SDL_ConvertSign(SDL_AudioCVT * cvt, Uint16 format) 1061 static void SDLCALL
1062 SDL_RateDIV2_c2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
873 { 1063 {
874 int i; 1064 int i;
875 Uint8 *data;
876 1065
877 #ifdef DEBUG_CONVERT 1066 #ifdef DEBUG_CONVERT
878 fprintf(stderr, "Converting audio signedness\n"); 1067 fprintf(stderr, "Converting audio rate / 2 (stereo)\n");
879 #endif 1068 #endif
880 data = cvt->buf; 1069
881 if ((format & 0xFF) == 16) { 1070 #define div2_stereo(type) { \
882 if ((format & 0x1000) != 0x1000) { /* Little endian */ 1071 const type *src = (const type *) cvt->buf; \
883 ++data; 1072 type *dst = (type *) cvt->buf; \
884 } 1073 for (i = cvt->len_cvt / (sizeof (type) * 4); i; --i) { \
885 for (i = cvt->len_cvt / 2; i; --i) { 1074 dst[0] = src[0]; \
886 *data ^= 0x80; 1075 dst[1] = src[1]; \
887 data += 2; 1076 src += 4; \
888 } 1077 dst += 2; \
889 } else { 1078 } \
890 for (i = cvt->len_cvt; i; --i) { 1079 }
891 *data++ ^= 0x80; 1080
892 } 1081 switch (SDL_AUDIO_BITSIZE(format)) {
893 }
894 format = (format ^ 0x8000);
895 if (cvt->filters[++cvt->filter_index]) {
896 cvt->filters[cvt->filter_index] (cvt, format);
897 }
898 }
899
900 /* Toggle endianness */
901 void SDLCALL
902 SDL_ConvertEndian(SDL_AudioCVT * cvt, Uint16 format)
903 {
904 int i;
905 Uint8 *data, tmp;
906
907 #ifdef DEBUG_CONVERT
908 fprintf(stderr, "Converting audio endianness\n");
909 #endif
910 data = cvt->buf;
911 for (i = cvt->len_cvt / 2; i; --i) {
912 tmp = data[0];
913 data[0] = data[1];
914 data[1] = tmp;
915 data += 2;
916 }
917 format = (format ^ 0x1000);
918 if (cvt->filters[++cvt->filter_index]) {
919 cvt->filters[cvt->filter_index] (cvt, format);
920 }
921 }
922
923 /* Convert rate up by multiple of 2 */
924 void SDLCALL
925 SDL_RateMUL2(SDL_AudioCVT * cvt, Uint16 format)
926 {
927 int i;
928 Uint8 *src, *dst;
929
930 #ifdef DEBUG_CONVERT
931 fprintf(stderr, "Converting audio rate * 2\n");
932 #endif
933 src = cvt->buf + cvt->len_cvt;
934 dst = cvt->buf + cvt->len_cvt * 2;
935 switch (format & 0xFF) {
936 case 8: 1082 case 8:
937 for (i = cvt->len_cvt; i; --i) { 1083 div2_stereo(Uint8);
938 src -= 1;
939 dst -= 2;
940 dst[0] = src[0];
941 dst[1] = src[0];
942 }
943 break; 1084 break;
944 case 16: 1085 case 16:
945 for (i = cvt->len_cvt / 2; i; --i) { 1086 div2_stereo(Uint16);
946 src -= 2; 1087 break;
947 dst -= 4; 1088 case 32:
948 dst[0] = src[0]; 1089 div2_stereo(Uint32);
949 dst[1] = src[1]; 1090 break;
950 dst[2] = src[0]; 1091 }
951 dst[3] = src[1]; 1092
952 } 1093 #undef div2_stereo
953 break; 1094
954 }
955 cvt->len_cvt *= 2;
956 if (cvt->filters[++cvt->filter_index]) {
957 cvt->filters[cvt->filter_index] (cvt, format);
958 }
959 }
960
961
962 /* Convert rate up by multiple of 2, for stereo */
963 void SDLCALL
964 SDL_RateMUL2_c2(SDL_AudioCVT * cvt, Uint16 format)
965 {
966 int i;
967 Uint8 *src, *dst;
968
969 #ifdef DEBUG_CONVERT
970 fprintf(stderr, "Converting audio rate * 2\n");
971 #endif
972 src = cvt->buf + cvt->len_cvt;
973 dst = cvt->buf + cvt->len_cvt * 2;
974 switch (format & 0xFF) {
975 case 8:
976 for (i = cvt->len_cvt / 2; i; --i) {
977 src -= 2;
978 dst -= 4;
979 dst[0] = src[0];
980 dst[1] = src[1];
981 dst[2] = src[0];
982 dst[3] = src[1];
983 }
984 break;
985 case 16:
986 for (i = cvt->len_cvt / 4; i; --i) {
987 src -= 4;
988 dst -= 8;
989 dst[0] = src[0];
990 dst[1] = src[1];
991 dst[2] = src[2];
992 dst[3] = src[3];
993 dst[4] = src[0];
994 dst[5] = src[1];
995 dst[6] = src[2];
996 dst[7] = src[3];
997 }
998 break;
999 }
1000 cvt->len_cvt *= 2;
1001 if (cvt->filters[++cvt->filter_index]) {
1002 cvt->filters[cvt->filter_index] (cvt, format);
1003 }
1004 }
1005
1006 /* Convert rate up by multiple of 2, for quad */
1007 void SDLCALL
1008 SDL_RateMUL2_c4(SDL_AudioCVT * cvt, Uint16 format)
1009 {
1010 int i;
1011 Uint8 *src, *dst;
1012
1013 #ifdef DEBUG_CONVERT
1014 fprintf(stderr, "Converting audio rate * 2\n");
1015 #endif
1016 src = cvt->buf + cvt->len_cvt;
1017 dst = cvt->buf + cvt->len_cvt * 2;
1018 switch (format & 0xFF) {
1019 case 8:
1020 for (i = cvt->len_cvt / 4; i; --i) {
1021 src -= 4;
1022 dst -= 8;
1023 dst[0] = src[0];
1024 dst[1] = src[1];
1025 dst[2] = src[2];
1026 dst[3] = src[3];
1027 dst[4] = src[0];
1028 dst[5] = src[1];
1029 dst[6] = src[2];
1030 dst[7] = src[3];
1031 }
1032 break;
1033 case 16:
1034 for (i = cvt->len_cvt / 8; i; --i) {
1035 src -= 8;
1036 dst -= 16;
1037 dst[0] = src[0];
1038 dst[1] = src[1];
1039 dst[2] = src[2];
1040 dst[3] = src[3];
1041 dst[4] = src[4];
1042 dst[5] = src[5];
1043 dst[6] = src[6];
1044 dst[7] = src[7];
1045 dst[8] = src[0];
1046 dst[9] = src[1];
1047 dst[10] = src[2];
1048 dst[11] = src[3];
1049 dst[12] = src[4];
1050 dst[13] = src[5];
1051 dst[14] = src[6];
1052 dst[15] = src[7];
1053 }
1054 break;
1055 }
1056 cvt->len_cvt *= 2;
1057 if (cvt->filters[++cvt->filter_index]) {
1058 cvt->filters[cvt->filter_index] (cvt, format);
1059 }
1060 }
1061
1062
1063 /* Convert rate up by multiple of 2, for 5.1 */
1064 void SDLCALL
1065 SDL_RateMUL2_c6(SDL_AudioCVT * cvt, Uint16 format)
1066 {
1067 int i;
1068 Uint8 *src, *dst;
1069
1070 #ifdef DEBUG_CONVERT
1071 fprintf(stderr, "Converting audio rate * 2\n");
1072 #endif
1073 src = cvt->buf + cvt->len_cvt;
1074 dst = cvt->buf + cvt->len_cvt * 2;
1075 switch (format & 0xFF) {
1076 case 8:
1077 for (i = cvt->len_cvt / 6; i; --i) {
1078 src -= 6;
1079 dst -= 12;
1080 dst[0] = src[0];
1081 dst[1] = src[1];
1082 dst[2] = src[2];
1083 dst[3] = src[3];
1084 dst[4] = src[4];
1085 dst[5] = src[5];
1086 dst[6] = src[0];
1087 dst[7] = src[1];
1088 dst[8] = src[2];
1089 dst[9] = src[3];
1090 dst[10] = src[4];
1091 dst[11] = src[5];
1092 }
1093 break;
1094 case 16:
1095 for (i = cvt->len_cvt / 12; i; --i) {
1096 src -= 12;
1097 dst -= 24;
1098 dst[0] = src[0];
1099 dst[1] = src[1];
1100 dst[2] = src[2];
1101 dst[3] = src[3];
1102 dst[4] = src[4];
1103 dst[5] = src[5];
1104 dst[6] = src[6];
1105 dst[7] = src[7];
1106 dst[8] = src[8];
1107 dst[9] = src[9];
1108 dst[10] = src[10];
1109 dst[11] = src[11];
1110 dst[12] = src[0];
1111 dst[13] = src[1];
1112 dst[14] = src[2];
1113 dst[15] = src[3];
1114 dst[16] = src[4];
1115 dst[17] = src[5];
1116 dst[18] = src[6];
1117 dst[19] = src[7];
1118 dst[20] = src[8];
1119 dst[21] = src[9];
1120 dst[22] = src[10];
1121 dst[23] = src[11];
1122 }
1123 break;
1124 }
1125 cvt->len_cvt *= 2;
1126 if (cvt->filters[++cvt->filter_index]) {
1127 cvt->filters[cvt->filter_index] (cvt, format);
1128 }
1129 }
1130
1131 /* Convert rate down by multiple of 2 */
1132 void SDLCALL
1133 SDL_RateDIV2(SDL_AudioCVT * cvt, Uint16 format)
1134 {
1135 int i;
1136 Uint8 *src, *dst;
1137
1138 #ifdef DEBUG_CONVERT
1139 fprintf(stderr, "Converting audio rate / 2\n");
1140 #endif
1141 src = cvt->buf;
1142 dst = cvt->buf;
1143 switch (format & 0xFF) {
1144 case 8:
1145 for (i = cvt->len_cvt / 2; i; --i) {
1146 dst[0] = src[0];
1147 src += 2;
1148 dst += 1;
1149 }
1150 break;
1151 case 16:
1152 for (i = cvt->len_cvt / 4; i; --i) {
1153 dst[0] = src[0];
1154 dst[1] = src[1];
1155 src += 4;
1156 dst += 2;
1157 }
1158 break;
1159 }
1160 cvt->len_cvt /= 2; 1095 cvt->len_cvt /= 2;
1161 if (cvt->filters[++cvt->filter_index]) { 1096 if (cvt->filters[++cvt->filter_index]) {
1162 cvt->filters[cvt->filter_index] (cvt, format); 1097 cvt->filters[cvt->filter_index] (cvt, format);
1163 } 1098 }
1164 } 1099 }
1165 1100
1166 1101
1167 /* Convert rate down by multiple of 2, for stereo */ 1102 /* Convert rate down by multiple of 2, for quad */
1168 void SDLCALL 1103 static void SDLCALL
1169 SDL_RateDIV2_c2(SDL_AudioCVT * cvt, Uint16 format) 1104 SDL_RateDIV2_c4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1170 { 1105 {
1171 int i; 1106 int i;
1172 Uint8 *src, *dst;
1173 1107
1174 #ifdef DEBUG_CONVERT 1108 #ifdef DEBUG_CONVERT
1175 fprintf(stderr, "Converting audio rate / 2\n"); 1109 fprintf(stderr, "Converting audio rate / 2 (quad)\n");
1176 #endif 1110 #endif
1177 src = cvt->buf; 1111
1178 dst = cvt->buf; 1112 #define div2_quad(type) { \
1179 switch (format & 0xFF) { 1113 const type *src = (const type *) cvt->buf; \
1114 type *dst = (type *) cvt->buf; \
1115 for (i = cvt->len_cvt / (sizeof (type) * 8); i; --i) { \
1116 dst[0] = src[0]; \
1117 dst[1] = src[1]; \
1118 dst[2] = src[2]; \
1119 dst[3] = src[3]; \
1120 src += 8; \
1121 dst += 4; \
1122 } \
1123 }
1124
1125 switch (SDL_AUDIO_BITSIZE(format)) {
1180 case 8: 1126 case 8:
1181 for (i = cvt->len_cvt / 4; i; --i) { 1127 div2_quad(Uint8);
1182 dst[0] = src[0];
1183 dst[1] = src[1];
1184 src += 4;
1185 dst += 2;
1186 }
1187 break; 1128 break;
1188 case 16: 1129 case 16:
1189 for (i = cvt->len_cvt / 8; i; --i) { 1130 div2_quad(Uint16);
1190 dst[0] = src[0]; 1131 break;
1191 dst[1] = src[1]; 1132 case 32:
1192 dst[2] = src[2]; 1133 div2_quad(Uint32);
1193 dst[3] = src[3]; 1134 break;
1194 src += 8; 1135 }
1195 dst += 4; 1136
1196 } 1137 #undef div2_quad
1197 break; 1138
1198 }
1199 cvt->len_cvt /= 2; 1139 cvt->len_cvt /= 2;
1200 if (cvt->filters[++cvt->filter_index]) { 1140 if (cvt->filters[++cvt->filter_index]) {
1201 cvt->filters[cvt->filter_index] (cvt, format); 1141 cvt->filters[cvt->filter_index] (cvt, format);
1202 } 1142 }
1203 } 1143 }
1204 1144
1205 1145 /* Convert rate down by multiple of 2, for 5.1 */
1206 /* Convert rate down by multiple of 2, for quad */ 1146 static void SDLCALL
1207 void SDLCALL 1147 SDL_RateDIV2_c6(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1208 SDL_RateDIV2_c4(SDL_AudioCVT * cvt, Uint16 format)
1209 { 1148 {
1210 int i; 1149 int i;
1211 Uint8 *src, *dst;
1212 1150
1213 #ifdef DEBUG_CONVERT 1151 #ifdef DEBUG_CONVERT
1214 fprintf(stderr, "Converting audio rate / 2\n"); 1152 fprintf(stderr, "Converting audio rate / 2 (six channels)\n");
1215 #endif 1153 #endif
1216 src = cvt->buf; 1154
1217 dst = cvt->buf; 1155 #define div2_chansix(type) { \
1218 switch (format & 0xFF) { 1156 const type *src = (const type *) cvt->buf; \
1157 type *dst = (type *) cvt->buf; \
1158 for (i = cvt->len_cvt / (sizeof (type) * 12); i; --i) { \
1159 dst[0] = src[0]; \
1160 dst[1] = src[1]; \
1161 dst[2] = src[2]; \
1162 dst[3] = src[3]; \
1163 dst[4] = src[4]; \
1164 dst[5] = src[5]; \
1165 src += 12; \
1166 dst += 6; \
1167 } \
1168 }
1169
1170 switch (SDL_AUDIO_BITSIZE(format)) {
1219 case 8: 1171 case 8:
1220 for (i = cvt->len_cvt / 8; i; --i) { 1172 div2_chansix(Uint8);
1221 dst[0] = src[0];
1222 dst[1] = src[1];
1223 dst[2] = src[2];
1224 dst[3] = src[3];
1225 src += 8;
1226 dst += 4;
1227 }
1228 break; 1173 break;
1229 case 16: 1174 case 16:
1230 for (i = cvt->len_cvt / 16; i; --i) { 1175 div2_chansix(Uint16);
1231 dst[0] = src[0]; 1176 break;
1232 dst[1] = src[1]; 1177 case 32:
1233 dst[2] = src[2]; 1178 div2_chansix(Uint32);
1234 dst[3] = src[3]; 1179 break;
1235 dst[4] = src[4]; 1180 }
1236 dst[5] = src[5]; 1181
1237 dst[6] = src[6]; 1182 #undef div_chansix
1238 dst[7] = src[7]; 1183
1239 src += 16;
1240 dst += 8;
1241 }
1242 break;
1243 }
1244 cvt->len_cvt /= 2; 1184 cvt->len_cvt /= 2;
1245 if (cvt->filters[++cvt->filter_index]) { 1185 if (cvt->filters[++cvt->filter_index]) {
1246 cvt->filters[cvt->filter_index] (cvt, format); 1186 cvt->filters[cvt->filter_index] (cvt, format);
1247 } 1187 }
1248 } 1188 }
1249 1189
1250 /* Convert rate down by multiple of 2, for 5.1 */
1251 void SDLCALL
1252 SDL_RateDIV2_c6(SDL_AudioCVT * cvt, Uint16 format)
1253 {
1254 int i;
1255 Uint8 *src, *dst;
1256
1257 #ifdef DEBUG_CONVERT
1258 fprintf(stderr, "Converting audio rate / 2\n");
1259 #endif
1260 src = cvt->buf;
1261 dst = cvt->buf;
1262 switch (format & 0xFF) {
1263 case 8:
1264 for (i = cvt->len_cvt / 12; i; --i) {
1265 dst[0] = src[0];
1266 dst[1] = src[1];
1267 dst[2] = src[2];
1268 dst[3] = src[3];
1269 dst[4] = src[4];
1270 dst[5] = src[5];
1271 src += 12;
1272 dst += 6;
1273 }
1274 break;
1275 case 16:
1276 for (i = cvt->len_cvt / 24; i; --i) {
1277 dst[0] = src[0];
1278 dst[1] = src[1];
1279 dst[2] = src[2];
1280 dst[3] = src[3];
1281 dst[4] = src[4];
1282 dst[5] = src[5];
1283 dst[6] = src[6];
1284 dst[7] = src[7];
1285 dst[8] = src[8];
1286 dst[9] = src[9];
1287 dst[10] = src[10];
1288 dst[11] = src[11];
1289 src += 24;
1290 dst += 12;
1291 }
1292 break;
1293 }
1294 cvt->len_cvt /= 2;
1295 if (cvt->filters[++cvt->filter_index]) {
1296 cvt->filters[cvt->filter_index] (cvt, format);
1297 }
1298 }
1299
1300 /* Very slow rate conversion routine */ 1190 /* Very slow rate conversion routine */
1301 void SDLCALL 1191 static void SDLCALL
1302 SDL_RateSLOW(SDL_AudioCVT * cvt, Uint16 format) 1192 SDL_RateSLOW(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1303 { 1193 {
1304 double ipos; 1194 double ipos;
1305 int i, clen; 1195 int i, clen;
1306 1196
1307 #ifdef DEBUG_CONVERT 1197 #ifdef DEBUG_CONVERT
1308 fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0 / cvt->rate_incr); 1198 fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0 / cvt->rate_incr);
1309 #endif 1199 #endif
1310 clen = (int) ((double) cvt->len_cvt / cvt->rate_incr); 1200 clen = (int) ((double) cvt->len_cvt / cvt->rate_incr);
1311 if (cvt->rate_incr > 1.0) { 1201 if (cvt->rate_incr > 1.0) {
1312 switch (format & 0xFF) { 1202 switch (SDL_AUDIO_BITSIZE(format)) {
1313 case 8: 1203 case 8:
1314 { 1204 {
1315 Uint8 *output; 1205 Uint8 *output;
1316 1206
1317 output = cvt->buf; 1207 output = cvt->buf;
1336 ipos += cvt->rate_incr; 1226 ipos += cvt->rate_incr;
1337 output += 1; 1227 output += 1;
1338 } 1228 }
1339 } 1229 }
1340 break; 1230 break;
1231
1232 case 32:
1233 {
1234 /* !!! FIXME: need 32-bit converter here! */
1235 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
1236 }
1341 } 1237 }
1342 } else { 1238 } else {
1343 switch (format & 0xFF) { 1239 switch (SDL_AUDIO_BITSIZE(format)) {
1344 case 8: 1240 case 8:
1345 { 1241 {
1346 Uint8 *output; 1242 Uint8 *output;
1347 1243
1348 output = cvt->buf + clen; 1244 output = cvt->buf + clen;
1367 output -= 1; 1263 output -= 1;
1368 *output = ((Uint16 *) cvt->buf)[(int) ipos]; 1264 *output = ((Uint16 *) cvt->buf)[(int) ipos];
1369 } 1265 }
1370 } 1266 }
1371 break; 1267 break;
1372 } 1268
1373 } 1269 case 32:
1270 {
1271 /* !!! FIXME: need 32-bit converter here! */
1272 fprintf(stderr, "FIXME: need 32-bit converter here!\n");
1273 }
1274 }
1275 }
1276
1374 cvt->len_cvt = clen; 1277 cvt->len_cvt = clen;
1375 if (cvt->filters[++cvt->filter_index]) { 1278 if (cvt->filters[++cvt->filter_index]) {
1376 cvt->filters[cvt->filter_index] (cvt, format); 1279 cvt->filters[cvt->filter_index] (cvt, format);
1377 } 1280 }
1378 } 1281 }
1395 cvt->filter_index = 0; 1298 cvt->filter_index = 0;
1396 cvt->filters[0] (cvt, cvt->src_format); 1299 cvt->filters[0] (cvt, cvt->src_format);
1397 return (0); 1300 return (0);
1398 } 1301 }
1399 1302
1400 /* Creates a set of audio filters to convert from one format to another. 1303
1401 Returns -1 if the format conversion is not supported, or 1 if the 1304 static SDL_AudioFilter
1402 audio filter is set up. 1305 SDL_HandTunedTypeCVT(SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
1306 {
1307 /*
1308 * Fill in any future conversions that are specialized to a
1309 * processor, platform, compiler, or library here.
1310 */
1311
1312 return NULL; /* no specialized converter code available. */
1313 }
1314
1315
1316 /*
1317 * Find a converter between two data types. We try to select a hand-tuned
1318 * asm/vectorized/optimized function first, and then fallback to an
1319 * autogenerated function that is customized to convert between two
1320 * specific data types.
1321 */
1322 static int
1323 SDL_BuildAudioTypeCVT(SDL_AudioCVT * cvt,
1324 SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
1325 {
1326 if (src_fmt != dst_fmt) {
1327 const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt);
1328 const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt);
1329 SDL_AudioFilter filter = SDL_HandTunedTypeCVT(src_fmt, dst_fmt);
1330
1331 /* No hand-tuned converter? Try the autogenerated ones. */
1332 if (filter == NULL) {
1333 int i;
1334 for (i = 0; sdl_audio_type_filters[i].filter != NULL; i++) {
1335 const SDL_AudioTypeFilters *filt = &sdl_audio_type_filters[i];
1336 if ((filt->src_fmt == src_fmt) && (filt->dst_fmt == dst_fmt)) {
1337 filter = filt->filter;
1338 break;
1339 }
1340 }
1341
1342 if (filter == NULL) {
1343 return -1; /* Still no matching converter?! */
1344 }
1345 }
1346
1347 /* Update (cvt) with filter details... */
1348 cvt->filters[cvt->filter_index++] = filter;
1349 if (src_bitsize < dst_bitsize) {
1350 const int mult = (dst_bitsize / src_bitsize);
1351 cvt->len_mult *= mult;
1352 cvt->len_ratio *= mult;
1353 } else if (src_bitsize > dst_bitsize) {
1354 cvt->len_ratio /= (src_bitsize / dst_bitsize);
1355 }
1356
1357 return 1; /* added a converter. */
1358 }
1359
1360 return 0; /* no conversion necessary. */
1361 }
1362
1363
1364
1365 /* Creates a set of audio filters to convert from one format to another.
1366 Returns -1 if the format conversion is not supported, 0 if there's
1367 no conversion needed, or 1 if the audio filter is set up.
1403 */ 1368 */
1404 1369
1405 int 1370 int
1406 SDL_BuildAudioCVT(SDL_AudioCVT * cvt, 1371 SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
1407 Uint16 src_format, Uint8 src_channels, int src_rate, 1372 SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
1408 Uint16 dst_format, Uint8 dst_channels, int dst_rate) 1373 SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
1409 { 1374 {
1410 /*printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n", 1375 /* there are no unsigned types over 16 bits, so catch this upfront. */
1411 src_format, dst_format, src_channels, dst_channels, src_rate, dst_rate);*/ 1376 if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
1377 return -1;
1378 }
1379 if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
1380 return -1;
1381 }
1382
1383 #ifdef DEBUG_CONVERT
1384 printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
1385 src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
1386 #endif
1387
1412 /* Start off with no conversion necessary */ 1388 /* Start off with no conversion necessary */
1389
1390 cvt->src_format = src_fmt;
1391 cvt->dst_format = dst_fmt;
1413 cvt->needed = 0; 1392 cvt->needed = 0;
1414 cvt->filter_index = 0; 1393 cvt->filter_index = 0;
1415 cvt->filters[0] = NULL; 1394 cvt->filters[0] = NULL;
1416 cvt->len_mult = 1; 1395 cvt->len_mult = 1;
1417 cvt->len_ratio = 1.0; 1396 cvt->len_ratio = 1.0;
1418 1397
1419 /* First filter: Endian conversion from src to dst */ 1398 /* Convert data types, if necessary. Updates (cvt). */
1420 if ((src_format & 0x1000) != (dst_format & 0x1000) 1399 if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1)
1421 && ((src_format & 0xff) != 8)) { 1400 return -1; /* shouldn't happen, but just in case... */
1422 cvt->filters[cvt->filter_index++] = SDL_ConvertEndian; 1401
1423 } 1402 /* Channel conversion */
1424
1425 /* Second filter: Sign conversion -- signed/unsigned */
1426 if ((src_format & 0x8000) != (dst_format & 0x8000)) {
1427 cvt->filters[cvt->filter_index++] = SDL_ConvertSign;
1428 }
1429
1430 /* Next filter: Convert 16 bit <--> 8 bit PCM */
1431 if ((src_format & 0xFF) != (dst_format & 0xFF)) {
1432 switch (dst_format & 0x10FF) {
1433 case AUDIO_U8:
1434 cvt->filters[cvt->filter_index++] = SDL_Convert8;
1435 cvt->len_ratio /= 2;
1436 break;
1437 case AUDIO_U16LSB:
1438 cvt->filters[cvt->filter_index++] = SDL_Convert16LSB;
1439 cvt->len_mult *= 2;
1440 cvt->len_ratio *= 2;
1441 break;
1442 case AUDIO_U16MSB:
1443 cvt->filters[cvt->filter_index++] = SDL_Convert16MSB;
1444 cvt->len_mult *= 2;
1445 cvt->len_ratio *= 2;
1446 break;
1447 }
1448 }
1449
1450 /* Last filter: Mono/Stereo conversion */
1451 if (src_channels != dst_channels) { 1403 if (src_channels != dst_channels) {
1452 if ((src_channels == 1) && (dst_channels > 1)) { 1404 if ((src_channels == 1) && (dst_channels > 1)) {
1453 cvt->filters[cvt->filter_index++] = SDL_ConvertStereo; 1405 cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
1454 cvt->len_mult *= 2; 1406 cvt->len_mult *= 2;
1455 src_channels = 2; 1407 src_channels = 2;
1502 cvt->rate_incr = 0.0; 1454 cvt->rate_incr = 0.0;
1503 if ((src_rate / 100) != (dst_rate / 100)) { 1455 if ((src_rate / 100) != (dst_rate / 100)) {
1504 Uint32 hi_rate, lo_rate; 1456 Uint32 hi_rate, lo_rate;
1505 int len_mult; 1457 int len_mult;
1506 double len_ratio; 1458 double len_ratio;
1507 void (SDLCALL * rate_cvt) (SDL_AudioCVT * cvt, Uint16 format); 1459 SDL_AudioFilter rate_cvt = NULL;
1508 1460
1509 if (src_rate > dst_rate) { 1461 if (src_rate > dst_rate) {
1510 hi_rate = src_rate; 1462 hi_rate = src_rate;
1511 lo_rate = dst_rate; 1463 lo_rate = dst_rate;
1512 switch (src_channels) { 1464 switch (src_channels) {
1581 } 1533 }
1582 1534
1583 /* Set up the filter information */ 1535 /* Set up the filter information */
1584 if (cvt->filter_index != 0) { 1536 if (cvt->filter_index != 0) {
1585 cvt->needed = 1; 1537 cvt->needed = 1;
1586 cvt->src_format = src_format; 1538 cvt->src_format = src_fmt;
1587 cvt->dst_format = dst_format; 1539 cvt->dst_format = dst_fmt;
1588 cvt->len = 0; 1540 cvt->len = 0;
1589 cvt->buf = NULL; 1541 cvt->buf = NULL;
1590 cvt->filters[cvt->filter_index] = NULL; 1542 cvt->filters[cvt->filter_index] = NULL;
1591 } 1543 }
1592 return (cvt->needed); 1544 return (cvt->needed);