zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_audiocvt.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 /* Functions for audio drivers to perform runtime conversion of audio format */
24 
25 #include "SDL_audio.h"
26 #include "SDL_audio_c.h"
27 
28 #include "SDL_assert.h"
29 
30 /* #define DEBUG_CONVERT */
31 
32 /* Effectively mix right and left channels into a single channel */
33 static void SDLCALL
35 {
36  int i;
37  Sint32 sample;
38 
39 #ifdef DEBUG_CONVERT
40  fprintf(stderr, "Converting to mono\n");
41 #endif
42  switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
43  case AUDIO_U8:
44  {
45  Uint8 *src, *dst;
46 
47  src = cvt->buf;
48  dst = cvt->buf;
49  for (i = cvt->len_cvt / 2; i; --i) {
50  sample = src[0] + src[1];
51  *dst = (Uint8) (sample / 2);
52  src += 2;
53  dst += 1;
54  }
55  }
56  break;
57 
58  case AUDIO_S8:
59  {
60  Sint8 *src, *dst;
61 
62  src = (Sint8 *) cvt->buf;
63  dst = (Sint8 *) cvt->buf;
64  for (i = cvt->len_cvt / 2; i; --i) {
65  sample = src[0] + src[1];
66  *dst = (Sint8) (sample / 2);
67  src += 2;
68  dst += 1;
69  }
70  }
71  break;
72 
73  case AUDIO_U16:
74  {
75  Uint8 *src, *dst;
76 
77  src = cvt->buf;
78  dst = cvt->buf;
79  if (SDL_AUDIO_ISBIGENDIAN(format)) {
80  for (i = cvt->len_cvt / 4; i; --i) {
81  sample = (Uint16) ((src[0] << 8) | src[1]) +
82  (Uint16) ((src[2] << 8) | src[3]);
83  sample /= 2;
84  dst[1] = (sample & 0xFF);
85  sample >>= 8;
86  dst[0] = (sample & 0xFF);
87  src += 4;
88  dst += 2;
89  }
90  } else {
91  for (i = cvt->len_cvt / 4; i; --i) {
92  sample = (Uint16) ((src[1] << 8) | src[0]) +
93  (Uint16) ((src[3] << 8) | src[2]);
94  sample /= 2;
95  dst[0] = (sample & 0xFF);
96  sample >>= 8;
97  dst[1] = (sample & 0xFF);
98  src += 4;
99  dst += 2;
100  }
101  }
102  }
103  break;
104 
105  case AUDIO_S16:
106  {
107  Uint8 *src, *dst;
108 
109  src = cvt->buf;
110  dst = cvt->buf;
111  if (SDL_AUDIO_ISBIGENDIAN(format)) {
112  for (i = cvt->len_cvt / 4; i; --i) {
113  sample = (Sint16) ((src[0] << 8) | src[1]) +
114  (Sint16) ((src[2] << 8) | src[3]);
115  sample /= 2;
116  dst[1] = (sample & 0xFF);
117  sample >>= 8;
118  dst[0] = (sample & 0xFF);
119  src += 4;
120  dst += 2;
121  }
122  } else {
123  for (i = cvt->len_cvt / 4; i; --i) {
124  sample = (Sint16) ((src[1] << 8) | src[0]) +
125  (Sint16) ((src[3] << 8) | src[2]);
126  sample /= 2;
127  dst[0] = (sample & 0xFF);
128  sample >>= 8;
129  dst[1] = (sample & 0xFF);
130  src += 4;
131  dst += 2;
132  }
133  }
134  }
135  break;
136 
137  case AUDIO_S32:
138  {
139  const Uint32 *src = (const Uint32 *) cvt->buf;
140  Uint32 *dst = (Uint32 *) cvt->buf;
141  if (SDL_AUDIO_ISBIGENDIAN(format)) {
142  for (i = cvt->len_cvt / 8; i; --i, src += 2) {
143  const Sint64 added =
144  (((Sint64) (Sint32) SDL_SwapBE32(src[0])) +
145  ((Sint64) (Sint32) SDL_SwapBE32(src[1])));
146  *(dst++) = SDL_SwapBE32((Uint32) ((Sint32) (added / 2)));
147  }
148  } else {
149  for (i = cvt->len_cvt / 8; i; --i, src += 2) {
150  const Sint64 added =
151  (((Sint64) (Sint32) SDL_SwapLE32(src[0])) +
152  ((Sint64) (Sint32) SDL_SwapLE32(src[1])));
153  *(dst++) = SDL_SwapLE32((Uint32) ((Sint32) (added / 2)));
154  }
155  }
156  }
157  break;
158 
159  case AUDIO_F32:
160  {
161  const float *src = (const float *) cvt->buf;
162  float *dst = (float *) cvt->buf;
163  if (SDL_AUDIO_ISBIGENDIAN(format)) {
164  for (i = cvt->len_cvt / 8; i; --i, src += 2) {
165  const float src1 = SDL_SwapFloatBE(src[0]);
166  const float src2 = SDL_SwapFloatBE(src[1]);
167  const double added = ((double) src1) + ((double) src2);
168  const float halved = (float) (added * 0.5);
169  *(dst++) = SDL_SwapFloatBE(halved);
170  }
171  } else {
172  for (i = cvt->len_cvt / 8; i; --i, src += 2) {
173  const float src1 = SDL_SwapFloatLE(src[0]);
174  const float src2 = SDL_SwapFloatLE(src[1]);
175  const double added = ((double) src1) + ((double) src2);
176  const float halved = (float) (added * 0.5);
177  *(dst++) = SDL_SwapFloatLE(halved);
178  }
179  }
180  }
181  break;
182  }
183 
184  cvt->len_cvt /= 2;
185  if (cvt->filters[++cvt->filter_index]) {
186  cvt->filters[cvt->filter_index] (cvt, format);
187  }
188 }
189 
190 
191 /* Discard top 4 channels */
192 static void SDLCALL
194 {
195  int i;
196 
197 #ifdef DEBUG_CONVERT
198  fprintf(stderr, "Converting down from 6 channels to stereo\n");
199 #endif
200 
201 #define strip_chans_6_to_2(type) \
202  { \
203  const type *src = (const type *) cvt->buf; \
204  type *dst = (type *) cvt->buf; \
205  for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
206  dst[0] = src[0]; \
207  dst[1] = src[1]; \
208  src += 6; \
209  dst += 2; \
210  } \
211  }
212 
213  /* this function only cares about typesize, and data as a block of bits. */
214  switch (SDL_AUDIO_BITSIZE(format)) {
215  case 8:
217  break;
218  case 16:
220  break;
221  case 32:
223  break;
224  }
225 
226 #undef strip_chans_6_to_2
227 
228  cvt->len_cvt /= 3;
229  if (cvt->filters[++cvt->filter_index]) {
230  cvt->filters[cvt->filter_index] (cvt, format);
231  }
232 }
233 
234 
235 /* Discard top 2 channels of 6 */
236 static void SDLCALL
238 {
239  int i;
240 
241 #ifdef DEBUG_CONVERT
242  fprintf(stderr, "Converting 6 down to quad\n");
243 #endif
244 
245 #define strip_chans_6_to_4(type) \
246  { \
247  const type *src = (const type *) cvt->buf; \
248  type *dst = (type *) cvt->buf; \
249  for (i = cvt->len_cvt / (sizeof (type) * 6); i; --i) { \
250  dst[0] = src[0]; \
251  dst[1] = src[1]; \
252  dst[2] = src[2]; \
253  dst[3] = src[3]; \
254  src += 6; \
255  dst += 4; \
256  } \
257  }
258 
259  /* this function only cares about typesize, and data as a block of bits. */
260  switch (SDL_AUDIO_BITSIZE(format)) {
261  case 8:
263  break;
264  case 16:
266  break;
267  case 32:
269  break;
270  }
271 
272 #undef strip_chans_6_to_4
273 
274  cvt->len_cvt /= 6;
275  cvt->len_cvt *= 4;
276  if (cvt->filters[++cvt->filter_index]) {
277  cvt->filters[cvt->filter_index] (cvt, format);
278  }
279 }
280 
281 /* Duplicate a mono channel to both stereo channels */
282 static void SDLCALL
284 {
285  int i;
286 
287 #ifdef DEBUG_CONVERT
288  fprintf(stderr, "Converting to stereo\n");
289 #endif
290 
291 #define dup_chans_1_to_2(type) \
292  { \
293  const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
294  type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
295  for (i = cvt->len_cvt / sizeof(type); i; --i) { \
296  src -= 1; \
297  dst -= 2; \
298  dst[0] = dst[1] = *src; \
299  } \
300  }
301 
302  /* this function only cares about typesize, and data as a block of bits. */
303  switch (SDL_AUDIO_BITSIZE(format)) {
304  case 8:
306  break;
307  case 16:
309  break;
310  case 32:
312  break;
313  }
314 
315 #undef dup_chans_1_to_2
316 
317  cvt->len_cvt *= 2;
318  if (cvt->filters[++cvt->filter_index]) {
319  cvt->filters[cvt->filter_index] (cvt, format);
320  }
321 }
322 
323 
324 /* Duplicate a stereo channel to a pseudo-5.1 stream */
325 static void SDLCALL
327 {
328  int i;
329 
330 #ifdef DEBUG_CONVERT
331  fprintf(stderr, "Converting stereo to surround\n");
332 #endif
333 
334  switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
335  case AUDIO_U8:
336  {
337  Uint8 *src, *dst, lf, rf, ce;
338 
339  src = (Uint8 *) (cvt->buf + cvt->len_cvt);
340  dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 3);
341  for (i = cvt->len_cvt; i; --i) {
342  dst -= 6;
343  src -= 2;
344  lf = src[0];
345  rf = src[1];
346  ce = (lf / 2) + (rf / 2);
347  dst[0] = lf;
348  dst[1] = rf;
349  dst[2] = lf - ce;
350  dst[3] = rf - ce;
351  dst[4] = ce;
352  dst[5] = ce;
353  }
354  }
355  break;
356 
357  case AUDIO_S8:
358  {
359  Sint8 *src, *dst, lf, rf, ce;
360 
361  src = (Sint8 *) cvt->buf + cvt->len_cvt;
362  dst = (Sint8 *) cvt->buf + cvt->len_cvt * 3;
363  for (i = cvt->len_cvt; i; --i) {
364  dst -= 6;
365  src -= 2;
366  lf = src[0];
367  rf = src[1];
368  ce = (lf / 2) + (rf / 2);
369  dst[0] = lf;
370  dst[1] = rf;
371  dst[2] = lf - ce;
372  dst[3] = rf - ce;
373  dst[4] = ce;
374  dst[5] = ce;
375  }
376  }
377  break;
378 
379  case AUDIO_U16:
380  {
381  Uint8 *src, *dst;
382  Uint16 lf, rf, ce, lr, rr;
383 
384  src = cvt->buf + cvt->len_cvt;
385  dst = cvt->buf + cvt->len_cvt * 3;
386 
387  if (SDL_AUDIO_ISBIGENDIAN(format)) {
388  for (i = cvt->len_cvt / 4; i; --i) {
389  dst -= 12;
390  src -= 4;
391  lf = (Uint16) ((src[0] << 8) | src[1]);
392  rf = (Uint16) ((src[2] << 8) | src[3]);
393  ce = (lf / 2) + (rf / 2);
394  rr = lf - ce;
395  lr = rf - ce;
396  dst[1] = (lf & 0xFF);
397  dst[0] = ((lf >> 8) & 0xFF);
398  dst[3] = (rf & 0xFF);
399  dst[2] = ((rf >> 8) & 0xFF);
400 
401  dst[1 + 4] = (lr & 0xFF);
402  dst[0 + 4] = ((lr >> 8) & 0xFF);
403  dst[3 + 4] = (rr & 0xFF);
404  dst[2 + 4] = ((rr >> 8) & 0xFF);
405 
406  dst[1 + 8] = (ce & 0xFF);
407  dst[0 + 8] = ((ce >> 8) & 0xFF);
408  dst[3 + 8] = (ce & 0xFF);
409  dst[2 + 8] = ((ce >> 8) & 0xFF);
410  }
411  } else {
412  for (i = cvt->len_cvt / 4; i; --i) {
413  dst -= 12;
414  src -= 4;
415  lf = (Uint16) ((src[1] << 8) | src[0]);
416  rf = (Uint16) ((src[3] << 8) | src[2]);
417  ce = (lf / 2) + (rf / 2);
418  rr = lf - ce;
419  lr = rf - ce;
420  dst[0] = (lf & 0xFF);
421  dst[1] = ((lf >> 8) & 0xFF);
422  dst[2] = (rf & 0xFF);
423  dst[3] = ((rf >> 8) & 0xFF);
424 
425  dst[0 + 4] = (lr & 0xFF);
426  dst[1 + 4] = ((lr >> 8) & 0xFF);
427  dst[2 + 4] = (rr & 0xFF);
428  dst[3 + 4] = ((rr >> 8) & 0xFF);
429 
430  dst[0 + 8] = (ce & 0xFF);
431  dst[1 + 8] = ((ce >> 8) & 0xFF);
432  dst[2 + 8] = (ce & 0xFF);
433  dst[3 + 8] = ((ce >> 8) & 0xFF);
434  }
435  }
436  }
437  break;
438 
439  case AUDIO_S16:
440  {
441  Uint8 *src, *dst;
442  Sint16 lf, rf, ce, lr, rr;
443 
444  src = cvt->buf + cvt->len_cvt;
445  dst = cvt->buf + cvt->len_cvt * 3;
446 
447  if (SDL_AUDIO_ISBIGENDIAN(format)) {
448  for (i = cvt->len_cvt / 4; i; --i) {
449  dst -= 12;
450  src -= 4;
451  lf = (Sint16) ((src[0] << 8) | src[1]);
452  rf = (Sint16) ((src[2] << 8) | src[3]);
453  ce = (lf / 2) + (rf / 2);
454  rr = lf - ce;
455  lr = rf - ce;
456  dst[1] = (lf & 0xFF);
457  dst[0] = ((lf >> 8) & 0xFF);
458  dst[3] = (rf & 0xFF);
459  dst[2] = ((rf >> 8) & 0xFF);
460 
461  dst[1 + 4] = (lr & 0xFF);
462  dst[0 + 4] = ((lr >> 8) & 0xFF);
463  dst[3 + 4] = (rr & 0xFF);
464  dst[2 + 4] = ((rr >> 8) & 0xFF);
465 
466  dst[1 + 8] = (ce & 0xFF);
467  dst[0 + 8] = ((ce >> 8) & 0xFF);
468  dst[3 + 8] = (ce & 0xFF);
469  dst[2 + 8] = ((ce >> 8) & 0xFF);
470  }
471  } else {
472  for (i = cvt->len_cvt / 4; i; --i) {
473  dst -= 12;
474  src -= 4;
475  lf = (Sint16) ((src[1] << 8) | src[0]);
476  rf = (Sint16) ((src[3] << 8) | src[2]);
477  ce = (lf / 2) + (rf / 2);
478  rr = lf - ce;
479  lr = rf - ce;
480  dst[0] = (lf & 0xFF);
481  dst[1] = ((lf >> 8) & 0xFF);
482  dst[2] = (rf & 0xFF);
483  dst[3] = ((rf >> 8) & 0xFF);
484 
485  dst[0 + 4] = (lr & 0xFF);
486  dst[1 + 4] = ((lr >> 8) & 0xFF);
487  dst[2 + 4] = (rr & 0xFF);
488  dst[3 + 4] = ((rr >> 8) & 0xFF);
489 
490  dst[0 + 8] = (ce & 0xFF);
491  dst[1 + 8] = ((ce >> 8) & 0xFF);
492  dst[2 + 8] = (ce & 0xFF);
493  dst[3 + 8] = ((ce >> 8) & 0xFF);
494  }
495  }
496  }
497  break;
498 
499  case AUDIO_S32:
500  {
501  Sint32 lf, rf, ce;
502  const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
503  Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
504 
505  if (SDL_AUDIO_ISBIGENDIAN(format)) {
506  for (i = cvt->len_cvt / 8; i; --i) {
507  dst -= 6;
508  src -= 2;
509  lf = (Sint32) SDL_SwapBE32(src[0]);
510  rf = (Sint32) SDL_SwapBE32(src[1]);
511  ce = (lf / 2) + (rf / 2);
512  dst[0] = SDL_SwapBE32((Uint32) lf);
513  dst[1] = SDL_SwapBE32((Uint32) rf);
514  dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
515  dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
516  dst[4] = SDL_SwapBE32((Uint32) ce);
517  dst[5] = SDL_SwapBE32((Uint32) ce);
518  }
519  } else {
520  for (i = cvt->len_cvt / 8; i; --i) {
521  dst -= 6;
522  src -= 2;
523  lf = (Sint32) SDL_SwapLE32(src[0]);
524  rf = (Sint32) SDL_SwapLE32(src[1]);
525  ce = (lf / 2) + (rf / 2);
526  dst[0] = src[0];
527  dst[1] = src[1];
528  dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
529  dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
530  dst[4] = SDL_SwapLE32((Uint32) ce);
531  dst[5] = SDL_SwapLE32((Uint32) ce);
532  }
533  }
534  }
535  break;
536 
537  case AUDIO_F32:
538  {
539  float lf, rf, ce;
540  const float *src = (const float *) cvt->buf + cvt->len_cvt;
541  float *dst = (float *) cvt->buf + cvt->len_cvt * 3;
542 
543  if (SDL_AUDIO_ISBIGENDIAN(format)) {
544  for (i = cvt->len_cvt / 8; i; --i) {
545  dst -= 6;
546  src -= 2;
547  lf = SDL_SwapFloatBE(src[0]);
548  rf = SDL_SwapFloatBE(src[1]);
549  ce = (lf * 0.5f) + (rf * 0.5f);
550  dst[0] = src[0];
551  dst[1] = src[1];
552  dst[2] = SDL_SwapFloatBE(lf - ce);
553  dst[3] = SDL_SwapFloatBE(rf - ce);
554  dst[4] = dst[5] = SDL_SwapFloatBE(ce);
555  }
556  } else {
557  for (i = cvt->len_cvt / 8; i; --i) {
558  dst -= 6;
559  src -= 2;
560  lf = SDL_SwapFloatLE(src[0]);
561  rf = SDL_SwapFloatLE(src[1]);
562  ce = (lf * 0.5f) + (rf * 0.5f);
563  dst[0] = src[0];
564  dst[1] = src[1];
565  dst[2] = SDL_SwapFloatLE(lf - ce);
566  dst[3] = SDL_SwapFloatLE(rf - ce);
567  dst[4] = dst[5] = SDL_SwapFloatLE(ce);
568  }
569  }
570  }
571  break;
572 
573  }
574  cvt->len_cvt *= 3;
575  if (cvt->filters[++cvt->filter_index]) {
576  cvt->filters[cvt->filter_index] (cvt, format);
577  }
578 }
579 
580 
581 /* Duplicate a stereo channel to a pseudo-4.0 stream */
582 static void SDLCALL
584 {
585  int i;
586 
587 #ifdef DEBUG_CONVERT
588  fprintf(stderr, "Converting stereo to quad\n");
589 #endif
590 
591  switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
592  case AUDIO_U8:
593  {
594  Uint8 *src, *dst, lf, rf, ce;
595 
596  src = (Uint8 *) (cvt->buf + cvt->len_cvt);
597  dst = (Uint8 *) (cvt->buf + cvt->len_cvt * 2);
598  for (i = cvt->len_cvt; i; --i) {
599  dst -= 4;
600  src -= 2;
601  lf = src[0];
602  rf = src[1];
603  ce = (lf / 2) + (rf / 2);
604  dst[0] = lf;
605  dst[1] = rf;
606  dst[2] = lf - ce;
607  dst[3] = rf - ce;
608  }
609  }
610  break;
611 
612  case AUDIO_S8:
613  {
614  Sint8 *src, *dst, lf, rf, ce;
615 
616  src = (Sint8 *) cvt->buf + cvt->len_cvt;
617  dst = (Sint8 *) cvt->buf + cvt->len_cvt * 2;
618  for (i = cvt->len_cvt; i; --i) {
619  dst -= 4;
620  src -= 2;
621  lf = src[0];
622  rf = src[1];
623  ce = (lf / 2) + (rf / 2);
624  dst[0] = lf;
625  dst[1] = rf;
626  dst[2] = lf - ce;
627  dst[3] = rf - ce;
628  }
629  }
630  break;
631 
632  case AUDIO_U16:
633  {
634  Uint8 *src, *dst;
635  Uint16 lf, rf, ce, lr, rr;
636 
637  src = cvt->buf + cvt->len_cvt;
638  dst = cvt->buf + cvt->len_cvt * 2;
639 
640  if (SDL_AUDIO_ISBIGENDIAN(format)) {
641  for (i = cvt->len_cvt / 4; i; --i) {
642  dst -= 8;
643  src -= 4;
644  lf = (Uint16) ((src[0] << 8) | src[1]);
645  rf = (Uint16) ((src[2] << 8) | src[3]);
646  ce = (lf / 2) + (rf / 2);
647  rr = lf - ce;
648  lr = rf - ce;
649  dst[1] = (lf & 0xFF);
650  dst[0] = ((lf >> 8) & 0xFF);
651  dst[3] = (rf & 0xFF);
652  dst[2] = ((rf >> 8) & 0xFF);
653 
654  dst[1 + 4] = (lr & 0xFF);
655  dst[0 + 4] = ((lr >> 8) & 0xFF);
656  dst[3 + 4] = (rr & 0xFF);
657  dst[2 + 4] = ((rr >> 8) & 0xFF);
658  }
659  } else {
660  for (i = cvt->len_cvt / 4; i; --i) {
661  dst -= 8;
662  src -= 4;
663  lf = (Uint16) ((src[1] << 8) | src[0]);
664  rf = (Uint16) ((src[3] << 8) | src[2]);
665  ce = (lf / 2) + (rf / 2);
666  rr = lf - ce;
667  lr = rf - ce;
668  dst[0] = (lf & 0xFF);
669  dst[1] = ((lf >> 8) & 0xFF);
670  dst[2] = (rf & 0xFF);
671  dst[3] = ((rf >> 8) & 0xFF);
672 
673  dst[0 + 4] = (lr & 0xFF);
674  dst[1 + 4] = ((lr >> 8) & 0xFF);
675  dst[2 + 4] = (rr & 0xFF);
676  dst[3 + 4] = ((rr >> 8) & 0xFF);
677  }
678  }
679  }
680  break;
681 
682  case AUDIO_S16:
683  {
684  Uint8 *src, *dst;
685  Sint16 lf, rf, ce, lr, rr;
686 
687  src = cvt->buf + cvt->len_cvt;
688  dst = cvt->buf + cvt->len_cvt * 2;
689 
690  if (SDL_AUDIO_ISBIGENDIAN(format)) {
691  for (i = cvt->len_cvt / 4; i; --i) {
692  dst -= 8;
693  src -= 4;
694  lf = (Sint16) ((src[0] << 8) | src[1]);
695  rf = (Sint16) ((src[2] << 8) | src[3]);
696  ce = (lf / 2) + (rf / 2);
697  rr = lf - ce;
698  lr = rf - ce;
699  dst[1] = (lf & 0xFF);
700  dst[0] = ((lf >> 8) & 0xFF);
701  dst[3] = (rf & 0xFF);
702  dst[2] = ((rf >> 8) & 0xFF);
703 
704  dst[1 + 4] = (lr & 0xFF);
705  dst[0 + 4] = ((lr >> 8) & 0xFF);
706  dst[3 + 4] = (rr & 0xFF);
707  dst[2 + 4] = ((rr >> 8) & 0xFF);
708  }
709  } else {
710  for (i = cvt->len_cvt / 4; i; --i) {
711  dst -= 8;
712  src -= 4;
713  lf = (Sint16) ((src[1] << 8) | src[0]);
714  rf = (Sint16) ((src[3] << 8) | src[2]);
715  ce = (lf / 2) + (rf / 2);
716  rr = lf - ce;
717  lr = rf - ce;
718  dst[0] = (lf & 0xFF);
719  dst[1] = ((lf >> 8) & 0xFF);
720  dst[2] = (rf & 0xFF);
721  dst[3] = ((rf >> 8) & 0xFF);
722 
723  dst[0 + 4] = (lr & 0xFF);
724  dst[1 + 4] = ((lr >> 8) & 0xFF);
725  dst[2 + 4] = (rr & 0xFF);
726  dst[3 + 4] = ((rr >> 8) & 0xFF);
727  }
728  }
729  }
730  break;
731 
732  case AUDIO_S32:
733  {
734  const Uint32 *src = (const Uint32 *) (cvt->buf + cvt->len_cvt);
735  Uint32 *dst = (Uint32 *) (cvt->buf + cvt->len_cvt * 2);
736  Sint32 lf, rf, ce;
737 
738  if (SDL_AUDIO_ISBIGENDIAN(format)) {
739  for (i = cvt->len_cvt / 8; i; --i) {
740  dst -= 4;
741  src -= 2;
742  lf = (Sint32) SDL_SwapBE32(src[0]);
743  rf = (Sint32) SDL_SwapBE32(src[1]);
744  ce = (lf / 2) + (rf / 2);
745  dst[0] = src[0];
746  dst[1] = src[1];
747  dst[2] = SDL_SwapBE32((Uint32) (lf - ce));
748  dst[3] = SDL_SwapBE32((Uint32) (rf - ce));
749  }
750  } else {
751  for (i = cvt->len_cvt / 8; i; --i) {
752  dst -= 4;
753  src -= 2;
754  lf = (Sint32) SDL_SwapLE32(src[0]);
755  rf = (Sint32) SDL_SwapLE32(src[1]);
756  ce = (lf / 2) + (rf / 2);
757  dst[0] = src[0];
758  dst[1] = src[1];
759  dst[2] = SDL_SwapLE32((Uint32) (lf - ce));
760  dst[3] = SDL_SwapLE32((Uint32) (rf - ce));
761  }
762  }
763  }
764  break;
765  }
766  cvt->len_cvt *= 2;
767  if (cvt->filters[++cvt->filter_index]) {
768  cvt->filters[cvt->filter_index] (cvt, format);
769  }
770 }
771 
772 
773 int
775 {
776  /* !!! FIXME: (cvt) should be const; stack-copy it here. */
777  /* !!! FIXME: (actually, we can't...len_cvt needs to be updated. Grr.) */
778 
779  /* Make sure there's data to convert */
780  if (cvt->buf == NULL) {
781  SDL_SetError("No buffer allocated for conversion");
782  return (-1);
783  }
784  /* Return okay if no conversion is necessary */
785  cvt->len_cvt = cvt->len;
786  if (cvt->filters[0] == NULL) {
787  return (0);
788  }
789 
790  /* Set up the conversion and go! */
791  cvt->filter_index = 0;
792  cvt->filters[0] (cvt, cvt->src_format);
793  return (0);
794 }
795 
796 
797 static SDL_AudioFilter
799 {
800  /*
801  * Fill in any future conversions that are specialized to a
802  * processor, platform, compiler, or library here.
803  */
804 
805  return NULL; /* no specialized converter code available. */
806 }
807 
808 
809 /*
810  * Find a converter between two data types. We try to select a hand-tuned
811  * asm/vectorized/optimized function first, and then fallback to an
812  * autogenerated function that is customized to convert between two
813  * specific data types.
814  */
815 static int
817  SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
818 {
819  if (src_fmt != dst_fmt) {
820  const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt);
821  const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt);
822  SDL_AudioFilter filter = SDL_HandTunedTypeCVT(src_fmt, dst_fmt);
823 
824  /* No hand-tuned converter? Try the autogenerated ones. */
825  if (filter == NULL) {
826  int i;
827  for (i = 0; sdl_audio_type_filters[i].filter != NULL; i++) {
829  if ((filt->src_fmt == src_fmt) && (filt->dst_fmt == dst_fmt)) {
830  filter = filt->filter;
831  break;
832  }
833  }
834 
835  if (filter == NULL) {
836  SDL_SetError("No conversion available for these formats");
837  return -1;
838  }
839  }
840 
841  /* Update (cvt) with filter details... */
842  cvt->filters[cvt->filter_index++] = filter;
843  if (src_bitsize < dst_bitsize) {
844  const int mult = (dst_bitsize / src_bitsize);
845  cvt->len_mult *= mult;
846  cvt->len_ratio *= mult;
847  } else if (src_bitsize > dst_bitsize) {
848  cvt->len_ratio /= (src_bitsize / dst_bitsize);
849  }
850 
851  return 1; /* added a converter. */
852  }
853 
854  return 0; /* no conversion necessary. */
855 }
856 
857 
858 static SDL_AudioFilter
859 SDL_HandTunedResampleCVT(SDL_AudioCVT * cvt, int dst_channels,
860  int src_rate, int dst_rate)
861 {
862  /*
863  * Fill in any future conversions that are specialized to a
864  * processor, platform, compiler, or library here.
865  */
866 
867  return NULL; /* no specialized converter code available. */
868 }
869 
870 static int
871 SDL_FindFrequencyMultiple(const int src_rate, const int dst_rate)
872 {
873  int retval = 0;
874 
875  /* If we only built with the arbitrary resamplers, ignore multiples. */
876 #if !LESS_RESAMPLERS
877  int lo, hi;
878  int div;
879 
880  SDL_assert(src_rate != 0);
881  SDL_assert(dst_rate != 0);
882  SDL_assert(src_rate != dst_rate);
883 
884  if (src_rate < dst_rate) {
885  lo = src_rate;
886  hi = dst_rate;
887  } else {
888  lo = dst_rate;
889  hi = src_rate;
890  }
891 
892  /* zero means "not a supported multiple" ... we only do 2x and 4x. */
893  if ((hi % lo) != 0)
894  return 0; /* not a multiple. */
895 
896  div = hi / lo;
897  retval = ((div == 2) || (div == 4)) ? div : 0;
898 #endif
899 
900  return retval;
901 }
902 
903 static int
904 SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, int dst_channels,
905  int src_rate, int dst_rate)
906 {
907  if (src_rate != dst_rate) {
908  SDL_AudioFilter filter = SDL_HandTunedResampleCVT(cvt, dst_channels,
909  src_rate, dst_rate);
910 
911  /* No hand-tuned converter? Try the autogenerated ones. */
912  if (filter == NULL) {
913  int i;
914  const int upsample = (src_rate < dst_rate) ? 1 : 0;
915  const int multiple =
916  SDL_FindFrequencyMultiple(src_rate, dst_rate);
917 
918  for (i = 0; sdl_audio_rate_filters[i].filter != NULL; i++) {
920  if ((filt->fmt == cvt->dst_format) &&
921  (filt->channels == dst_channels) &&
922  (filt->upsample == upsample) &&
923  (filt->multiple == multiple)) {
924  filter = filt->filter;
925  break;
926  }
927  }
928 
929  if (filter == NULL) {
930  SDL_SetError("No conversion available for these rates");
931  return -1;
932  }
933  }
934 
935  /* Update (cvt) with filter details... */
936  cvt->filters[cvt->filter_index++] = filter;
937  if (src_rate < dst_rate) {
938  const double mult = ((double) dst_rate) / ((double) src_rate);
939  cvt->len_mult *= (int) SDL_ceil(mult);
940  cvt->len_ratio *= mult;
941  } else {
942  cvt->len_ratio /= ((double) src_rate) / ((double) dst_rate);
943  }
944 
945  return 1; /* added a converter. */
946  }
947 
948  return 0; /* no conversion necessary. */
949 }
950 
951 
952 /* Creates a set of audio filters to convert from one format to another.
953  Returns -1 if the format conversion is not supported, 0 if there's
954  no conversion needed, or 1 if the audio filter is set up.
955 */
956 
957 int
959  SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
960  SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
961 {
962  /*
963  * !!! FIXME: reorder filters based on which grow/shrink the buffer.
964  * !!! FIXME: ideally, we should do everything that shrinks the buffer
965  * !!! FIXME: first, so we don't have to process as many bytes in a given
966  * !!! FIXME: filter and abuse the CPU cache less. This might not be as
967  * !!! FIXME: good in practice as it sounds in theory, though.
968  */
969 
970  /* Sanity check target pointer */
971  if (cvt == NULL) {
972  return SDL_InvalidParamError("cvt");
973  }
974 
975  /* there are no unsigned types over 16 bits, so catch this up front. */
976  if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
977  return SDL_SetError("Invalid source format");
978  }
979  if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
980  return SDL_SetError("Invalid destination format");
981  }
982 
983  /* prevent possible divisions by zero, etc. */
984  if ((src_channels == 0) || (dst_channels == 0)) {
985  return SDL_SetError("Source or destination channels is zero");
986  }
987  if ((src_rate == 0) || (dst_rate == 0)) {
988  return SDL_SetError("Source or destination rate is zero");
989  }
990 #ifdef DEBUG_CONVERT
991  printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
992  src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
993 #endif
994 
995  /* Start off with no conversion necessary */
996  SDL_zerop(cvt);
997  cvt->src_format = src_fmt;
998  cvt->dst_format = dst_fmt;
999  cvt->needed = 0;
1000  cvt->filter_index = 0;
1001  cvt->filters[0] = NULL;
1002  cvt->len_mult = 1;
1003  cvt->len_ratio = 1.0;
1004  cvt->rate_incr = ((double) dst_rate) / ((double) src_rate);
1005 
1006  /* Convert data types, if necessary. Updates (cvt). */
1007  if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1) {
1008  return -1; /* shouldn't happen, but just in case... */
1009  }
1010 
1011  /* Channel conversion */
1012  if (src_channels != dst_channels) {
1013  if ((src_channels == 1) && (dst_channels > 1)) {
1014  cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
1015  cvt->len_mult *= 2;
1016  src_channels = 2;
1017  cvt->len_ratio *= 2;
1018  }
1019  if ((src_channels == 2) && (dst_channels == 6)) {
1020  cvt->filters[cvt->filter_index++] = SDL_ConvertSurround;
1021  src_channels = 6;
1022  cvt->len_mult *= 3;
1023  cvt->len_ratio *= 3;
1024  }
1025  if ((src_channels == 2) && (dst_channels == 4)) {
1027  src_channels = 4;
1028  cvt->len_mult *= 2;
1029  cvt->len_ratio *= 2;
1030  }
1031  while ((src_channels * 2) <= dst_channels) {
1032  cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
1033  cvt->len_mult *= 2;
1034  src_channels *= 2;
1035  cvt->len_ratio *= 2;
1036  }
1037  if ((src_channels == 6) && (dst_channels <= 2)) {
1038  cvt->filters[cvt->filter_index++] = SDL_ConvertStrip;
1039  src_channels = 2;
1040  cvt->len_ratio /= 3;
1041  }
1042  if ((src_channels == 6) && (dst_channels == 4)) {
1043  cvt->filters[cvt->filter_index++] = SDL_ConvertStrip_2;
1044  src_channels = 4;
1045  cvt->len_ratio /= 2;
1046  }
1047  /* This assumes that 4 channel audio is in the format:
1048  Left {front/back} + Right {front/back}
1049  so converting to L/R stereo works properly.
1050  */
1051  while (((src_channels % 2) == 0) &&
1052  ((src_channels / 2) >= dst_channels)) {
1053  cvt->filters[cvt->filter_index++] = SDL_ConvertMono;
1054  src_channels /= 2;
1055  cvt->len_ratio /= 2;
1056  }
1057  if (src_channels != dst_channels) {
1058  /* Uh oh.. */ ;
1059  }
1060  }
1061 
1062  /* Do rate conversion, if necessary. Updates (cvt). */
1063  if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) ==
1064  -1) {
1065  return -1; /* shouldn't happen, but just in case... */
1066  }
1067 
1068  /* Set up the filter information */
1069  if (cvt->filter_index != 0) {
1070  cvt->needed = 1;
1071  cvt->src_format = src_fmt;
1072  cvt->dst_format = dst_fmt;
1073  cvt->len = 0;
1074  cvt->buf = NULL;
1075  cvt->filters[cvt->filter_index] = NULL;
1076  }
1077  return (cvt->needed);
1078 }
1079 
1080 
1081 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_SwapFloatBE(X)
Definition: SDL_endian.h:218
static void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, SDL_AudioFormat format)
Definition: SDL_audiocvt.c:34
int32_t Sint32
A signed 32-bit integer type.
Definition: SDL_stdinc.h:141
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: gl2ext.h:961
#define SDL_AUDIO_ISBIGENDIAN(x)
Definition: SDL_audio.h:77
#define NULL
Definition: ftobjs.h:61
GLclampf f
Definition: glew.h:3390
Uint8 * buf
Definition: SDL_audio.h:203
#define strip_chans_6_to_4(type)
#define dup_chans_1_to_2(type)
static void SDLCALL SDL_ConvertStrip(SDL_AudioCVT *cvt, SDL_AudioFormat format)
Definition: SDL_audiocvt.c:193
int hi
Definition: cordic.py:54
int filter_index
Definition: SDL_audio.h:209
double len_ratio
Definition: SDL_audio.h:207
tuple lo
Definition: cordic.py:53
#define SDL_AUDIO_ISSIGNED(x)
Definition: SDL_audio.h:78
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
const SDL_AudioTypeFilters sdl_audio_type_filters[]
#define SDL_SwapFloatLE(X)
Definition: SDL_endian.h:214
static void SDLCALL SDL_ConvertStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format)
Definition: SDL_audiocvt.c:283
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
#define SDLCALL
Definition: begin_code.h:72
static SDL_AudioFilter SDL_HandTunedTypeCVT(SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
Definition: SDL_audiocvt.c:798
#define SDL_SwapBE32(X)
Definition: SDL_endian.h:216
static void SDLCALL SDL_ConvertSurround(SDL_AudioCVT *cvt, SDL_AudioFormat format)
Definition: SDL_audiocvt.c:326
SDL_AudioFilter filter
Definition: SDL_audio_c.h:51
DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT *cvt, SDL_AudioFormat src_format, Uint8 src_channels, int src_rate, SDL_AudioFormat dst_format, Uint8 dst_channels, int dst_rate)
Definition: SDL_audiocvt.c:958
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
#define AUDIO_U8
Definition: SDL_audio.h:89
static int SDL_BuildAudioResampleCVT(SDL_AudioCVT *cvt, int dst_channels, int src_rate, int dst_rate)
Definition: SDL_audiocvt.c:904
GLenum GLenum dst
Definition: glew.h:2396
static void SDLCALL SDL_ConvertStrip_2(SDL_AudioCVT *cvt, SDL_AudioFormat format)
Definition: SDL_audiocvt.c:237
int
Definition: SDL_systhread.c:37
SDL_AudioFilter filters[10]
Definition: SDL_audio.h:208
#define SDL_AUDIO_BITSIZE(x)
Definition: SDL_audio.h:75
#define SDL_SwapLE32(X)
Definition: SDL_endian.h:212
#define AUDIO_S32
Definition: SDL_audio.h:105
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
static void SDLCALL SDL_ConvertSurround_4(SDL_AudioCVT *cvt, SDL_AudioFormat format)
Definition: SDL_audiocvt.c:583
SDL_AudioFormat fmt
Definition: SDL_audio_c.h:47
SDL_AudioFormat src_format
Definition: SDL_audio.h:200
#define SDL_AUDIO_MASK_SIGNED
Definition: SDL_audio.h:74
#define SDL_assert(condition)
Definition: SDL_assert.h:159
static int SDL_FindFrequencyMultiple(const int src_rate, const int dst_rate)
Definition: SDL_audiocvt.c:871
SDL_AudioFormat dst_format
Definition: SDL_audio.h:201
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
double rate_incr
Definition: SDL_audio.h:202
#define SDL_zerop(x)
Definition: SDL_stdinc.h:255
#define AUDIO_S16
Definition: SDL_audio.h:96
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:133
const SDL_AudioRateFilters sdl_audio_rate_filters[]
DECLSPEC double SDLCALL SDL_ceil(double x)
Definition: SDL_stdlib.c:50
SDL_AudioFilter filter
Definition: SDL_audio_c.h:40
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
SDL_AudioFormat dst_fmt
Definition: SDL_audio_c.h:39
GLenum src
Definition: glew.h:2396
#define AUDIO_F32
Definition: SDL_audio.h:114
int i
Definition: pngrutil.c:1377
SDL_AudioFormat src_fmt
Definition: SDL_audio_c.h:38
#define AUDIO_U16
Definition: SDL_audio.h:95
#define AUDIO_S8
Definition: SDL_audio.h:90
#define SDL_AUDIO_MASK_BITSIZE
Definition: SDL_audio.h:71
int64_t Sint64
A signed 64-bit integer type.
Definition: SDL_stdinc.h:150
int8_t Sint8
A signed 8-bit integer type.
Definition: SDL_stdinc.h:125
DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT *cvt)
Definition: SDL_audiocvt.c:774
static int SDL_BuildAudioTypeCVT(SDL_AudioCVT *cvt, SDL_AudioFormat src_fmt, SDL_AudioFormat dst_fmt)
Definition: SDL_audiocvt.c:816
#define strip_chans_6_to_2(type)
static SDL_AudioFilter SDL_HandTunedResampleCVT(SDL_AudioCVT *cvt, int dst_channels, int src_rate, int dst_rate)
Definition: SDL_audiocvt.c:859