Commit f941aa256f2254c3f35f00fcf5d7f20dba55a5b7
1 parent
b93aebec
Qemu support for S32 and U32 alsa output, by Vassili Karpov.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2427 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
9 changed files
with
214 additions
and
48 deletions
audio/alsaaudio.c
| @@ -157,6 +157,12 @@ static int aud_to_alsafmt (audfmt_e fmt) | @@ -157,6 +157,12 @@ static int aud_to_alsafmt (audfmt_e fmt) | ||
| 157 | case AUD_FMT_U16: | 157 | case AUD_FMT_U16: |
| 158 | return SND_PCM_FORMAT_U16_LE; | 158 | return SND_PCM_FORMAT_U16_LE; |
| 159 | 159 | ||
| 160 | + case AUD_FMT_S32: | ||
| 161 | + return SND_PCM_FORMAT_S32_LE; | ||
| 162 | + | ||
| 163 | + case AUD_FMT_U32: | ||
| 164 | + return SND_PCM_FORMAT_U32_LE; | ||
| 165 | + | ||
| 160 | default: | 166 | default: |
| 161 | dolog ("Internal logic error: Bad audio format %d\n", fmt); | 167 | dolog ("Internal logic error: Bad audio format %d\n", fmt); |
| 162 | #ifdef DEBUG_AUDIO | 168 | #ifdef DEBUG_AUDIO |
| @@ -199,6 +205,26 @@ static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness) | @@ -199,6 +205,26 @@ static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness) | ||
| 199 | *fmt = AUD_FMT_U16; | 205 | *fmt = AUD_FMT_U16; |
| 200 | break; | 206 | break; |
| 201 | 207 | ||
| 208 | + case SND_PCM_FORMAT_S32_LE: | ||
| 209 | + *endianness = 0; | ||
| 210 | + *fmt = AUD_FMT_S32; | ||
| 211 | + break; | ||
| 212 | + | ||
| 213 | + case SND_PCM_FORMAT_U32_LE: | ||
| 214 | + *endianness = 0; | ||
| 215 | + *fmt = AUD_FMT_U32; | ||
| 216 | + break; | ||
| 217 | + | ||
| 218 | + case SND_PCM_FORMAT_S32_BE: | ||
| 219 | + *endianness = 1; | ||
| 220 | + *fmt = AUD_FMT_S32; | ||
| 221 | + break; | ||
| 222 | + | ||
| 223 | + case SND_PCM_FORMAT_U32_BE: | ||
| 224 | + *endianness = 1; | ||
| 225 | + *fmt = AUD_FMT_U32; | ||
| 226 | + break; | ||
| 227 | + | ||
| 202 | default: | 228 | default: |
| 203 | dolog ("Unrecognized audio format %d\n", alsafmt); | 229 | dolog ("Unrecognized audio format %d\n", alsafmt); |
| 204 | return -1; | 230 | return -1; |
audio/audio.c
| @@ -80,7 +80,8 @@ static struct { | @@ -80,7 +80,8 @@ static struct { | ||
| 80 | { | 80 | { |
| 81 | 44100, /* freq */ | 81 | 44100, /* freq */ |
| 82 | 2, /* nchannels */ | 82 | 2, /* nchannels */ |
| 83 | - AUD_FMT_S16 /* fmt */ | 83 | + AUD_FMT_S16, /* fmt */ |
| 84 | + AUDIO_HOST_ENDIANNESS | ||
| 84 | } | 85 | } |
| 85 | }, | 86 | }, |
| 86 | 87 | ||
| @@ -91,7 +92,8 @@ static struct { | @@ -91,7 +92,8 @@ static struct { | ||
| 91 | { | 92 | { |
| 92 | 44100, /* freq */ | 93 | 44100, /* freq */ |
| 93 | 2, /* nchannels */ | 94 | 2, /* nchannels */ |
| 94 | - AUD_FMT_S16 /* fmt */ | 95 | + AUD_FMT_S16, /* fmt */ |
| 96 | + AUDIO_HOST_ENDIANNESS | ||
| 95 | } | 97 | } |
| 96 | }, | 98 | }, |
| 97 | 99 | ||
| @@ -166,6 +168,25 @@ int audio_bug (const char *funcname, int cond) | @@ -166,6 +168,25 @@ int audio_bug (const char *funcname, int cond) | ||
| 166 | } | 168 | } |
| 167 | #endif | 169 | #endif |
| 168 | 170 | ||
| 171 | +static inline int audio_bits_to_index (int bits) | ||
| 172 | +{ | ||
| 173 | + switch (bits) { | ||
| 174 | + case 8: | ||
| 175 | + return 0; | ||
| 176 | + | ||
| 177 | + case 16: | ||
| 178 | + return 1; | ||
| 179 | + | ||
| 180 | + case 32: | ||
| 181 | + return 2; | ||
| 182 | + | ||
| 183 | + default: | ||
| 184 | + audio_bug ("bits_to_index", 1); | ||
| 185 | + AUD_log (NULL, "invalid bits %d\n", bits); | ||
| 186 | + return 0; | ||
| 187 | + } | ||
| 188 | +} | ||
| 189 | + | ||
| 169 | void *audio_calloc (const char *funcname, int nmemb, size_t size) | 190 | void *audio_calloc (const char *funcname, int nmemb, size_t size) |
| 170 | { | 191 | { |
| 171 | int cond; | 192 | int cond; |
| @@ -227,6 +248,12 @@ const char *audio_audfmt_to_string (audfmt_e fmt) | @@ -227,6 +248,12 @@ const char *audio_audfmt_to_string (audfmt_e fmt) | ||
| 227 | 248 | ||
| 228 | case AUD_FMT_S16: | 249 | case AUD_FMT_S16: |
| 229 | return "S16"; | 250 | return "S16"; |
| 251 | + | ||
| 252 | + case AUD_FMT_U32: | ||
| 253 | + return "U32"; | ||
| 254 | + | ||
| 255 | + case AUD_FMT_S32: | ||
| 256 | + return "S32"; | ||
| 230 | } | 257 | } |
| 231 | 258 | ||
| 232 | dolog ("Bogus audfmt %d returning S16\n", fmt); | 259 | dolog ("Bogus audfmt %d returning S16\n", fmt); |
| @@ -243,6 +270,10 @@ audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp) | @@ -243,6 +270,10 @@ audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp) | ||
| 243 | *defaultp = 0; | 270 | *defaultp = 0; |
| 244 | return AUD_FMT_U16; | 271 | return AUD_FMT_U16; |
| 245 | } | 272 | } |
| 273 | + else if (!strcasecmp (s, "u32")) { | ||
| 274 | + *defaultp = 0; | ||
| 275 | + return AUD_FMT_U32; | ||
| 276 | + } | ||
| 246 | else if (!strcasecmp (s, "s8")) { | 277 | else if (!strcasecmp (s, "s8")) { |
| 247 | *defaultp = 0; | 278 | *defaultp = 0; |
| 248 | return AUD_FMT_S8; | 279 | return AUD_FMT_S8; |
| @@ -251,6 +282,10 @@ audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp) | @@ -251,6 +282,10 @@ audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp) | ||
| 251 | *defaultp = 0; | 282 | *defaultp = 0; |
| 252 | return AUD_FMT_S16; | 283 | return AUD_FMT_S16; |
| 253 | } | 284 | } |
| 285 | + else if (!strcasecmp (s, "s32")) { | ||
| 286 | + *defaultp = 0; | ||
| 287 | + return AUD_FMT_S32; | ||
| 288 | + } | ||
| 254 | else { | 289 | else { |
| 255 | dolog ("Bogus audio format `%s' using %s\n", | 290 | dolog ("Bogus audio format `%s' using %s\n", |
| 256 | s, audio_audfmt_to_string (defval)); | 291 | s, audio_audfmt_to_string (defval)); |
| @@ -538,6 +573,8 @@ static int audio_validate_settings (audsettings_t *as) | @@ -538,6 +573,8 @@ static int audio_validate_settings (audsettings_t *as) | ||
| 538 | case AUD_FMT_U8: | 573 | case AUD_FMT_U8: |
| 539 | case AUD_FMT_S16: | 574 | case AUD_FMT_S16: |
| 540 | case AUD_FMT_U16: | 575 | case AUD_FMT_U16: |
| 576 | + case AUD_FMT_S32: | ||
| 577 | + case AUD_FMT_U32: | ||
| 541 | break; | 578 | break; |
| 542 | default: | 579 | default: |
| 543 | invalid = 1; | 580 | invalid = 1; |
| @@ -563,6 +600,12 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as) | @@ -563,6 +600,12 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as) | ||
| 563 | case AUD_FMT_U16: | 600 | case AUD_FMT_U16: |
| 564 | bits = 16; | 601 | bits = 16; |
| 565 | break; | 602 | break; |
| 603 | + | ||
| 604 | + case AUD_FMT_S32: | ||
| 605 | + sign = 1; | ||
| 606 | + case AUD_FMT_U32: | ||
| 607 | + bits = 32; | ||
| 608 | + break; | ||
| 566 | } | 609 | } |
| 567 | return info->freq == as->freq | 610 | return info->freq == as->freq |
| 568 | && info->nchannels == as->nchannels | 611 | && info->nchannels == as->nchannels |
| @@ -573,7 +616,7 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as) | @@ -573,7 +616,7 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as) | ||
| 573 | 616 | ||
| 574 | void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as) | 617 | void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as) |
| 575 | { | 618 | { |
| 576 | - int bits = 8, sign = 0; | 619 | + int bits = 8, sign = 0, shift = 0; |
| 577 | 620 | ||
| 578 | switch (as->fmt) { | 621 | switch (as->fmt) { |
| 579 | case AUD_FMT_S8: | 622 | case AUD_FMT_S8: |
| @@ -585,6 +628,14 @@ void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as) | @@ -585,6 +628,14 @@ void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as) | ||
| 585 | sign = 1; | 628 | sign = 1; |
| 586 | case AUD_FMT_U16: | 629 | case AUD_FMT_U16: |
| 587 | bits = 16; | 630 | bits = 16; |
| 631 | + shift = 1; | ||
| 632 | + break; | ||
| 633 | + | ||
| 634 | + case AUD_FMT_S32: | ||
| 635 | + sign = 1; | ||
| 636 | + case AUD_FMT_U32: | ||
| 637 | + bits = 32; | ||
| 638 | + shift = 2; | ||
| 588 | break; | 639 | break; |
| 589 | } | 640 | } |
| 590 | 641 | ||
| @@ -592,7 +643,7 @@ void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as) | @@ -592,7 +643,7 @@ void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as) | ||
| 592 | info->bits = bits; | 643 | info->bits = bits; |
| 593 | info->sign = sign; | 644 | info->sign = sign; |
| 594 | info->nchannels = as->nchannels; | 645 | info->nchannels = as->nchannels; |
| 595 | - info->shift = (as->nchannels == 2) + (bits == 16); | 646 | + info->shift = (as->nchannels == 2) + shift; |
| 596 | info->align = (1 << info->shift) - 1; | 647 | info->align = (1 << info->shift) - 1; |
| 597 | info->bytes_per_second = info->freq << info->shift; | 648 | info->bytes_per_second = info->freq << info->shift; |
| 598 | info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS); | 649 | info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS); |
| @@ -608,22 +659,49 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) | @@ -608,22 +659,49 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) | ||
| 608 | memset (buf, 0x00, len << info->shift); | 659 | memset (buf, 0x00, len << info->shift); |
| 609 | } | 660 | } |
| 610 | else { | 661 | else { |
| 611 | - if (info->bits == 8) { | 662 | + switch (info->bits) { |
| 663 | + case 8: | ||
| 612 | memset (buf, 0x80, len << info->shift); | 664 | memset (buf, 0x80, len << info->shift); |
| 613 | - } | ||
| 614 | - else { | ||
| 615 | - int i; | ||
| 616 | - uint16_t *p = buf; | ||
| 617 | - int shift = info->nchannels - 1; | ||
| 618 | - short s = INT16_MAX; | 665 | + break; |
| 619 | 666 | ||
| 620 | - if (info->swap_endianness) { | ||
| 621 | - s = bswap16 (s); | 667 | + case 16: |
| 668 | + { | ||
| 669 | + int i; | ||
| 670 | + uint16_t *p = buf; | ||
| 671 | + int shift = info->nchannels - 1; | ||
| 672 | + short s = INT16_MAX; | ||
| 673 | + | ||
| 674 | + if (info->swap_endianness) { | ||
| 675 | + s = bswap16 (s); | ||
| 676 | + } | ||
| 677 | + | ||
| 678 | + for (i = 0; i < len << shift; i++) { | ||
| 679 | + p[i] = s; | ||
| 680 | + } | ||
| 622 | } | 681 | } |
| 682 | + break; | ||
| 683 | + | ||
| 684 | + case 32: | ||
| 685 | + { | ||
| 686 | + int i; | ||
| 687 | + uint32_t *p = buf; | ||
| 688 | + int shift = info->nchannels - 1; | ||
| 689 | + int32_t s = INT32_MAX; | ||
| 690 | + | ||
| 691 | + if (info->swap_endianness) { | ||
| 692 | + s = bswap32 (s); | ||
| 693 | + } | ||
| 623 | 694 | ||
| 624 | - for (i = 0; i < len << shift; i++) { | ||
| 625 | - p[i] = s; | 695 | + for (i = 0; i < len << shift; i++) { |
| 696 | + p[i] = s; | ||
| 697 | + } | ||
| 626 | } | 698 | } |
| 699 | + break; | ||
| 700 | + | ||
| 701 | + default: | ||
| 702 | + AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n", | ||
| 703 | + info->bits); | ||
| 704 | + break; | ||
| 627 | } | 705 | } |
| 628 | } | 706 | } |
| 629 | } | 707 | } |
| @@ -1811,7 +1889,7 @@ CaptureVoiceOut *AUD_add_capture ( | @@ -1811,7 +1889,7 @@ CaptureVoiceOut *AUD_add_capture ( | ||
| 1811 | [hw->info.nchannels == 2] | 1889 | [hw->info.nchannels == 2] |
| 1812 | [hw->info.sign] | 1890 | [hw->info.sign] |
| 1813 | [hw->info.swap_endianness] | 1891 | [hw->info.swap_endianness] |
| 1814 | - [hw->info.bits == 16]; | 1892 | + [audio_bits_to_index (hw->info.bits)]; |
| 1815 | 1893 | ||
| 1816 | LIST_INSERT_HEAD (&s->cap_head, cap, entries); | 1894 | LIST_INSERT_HEAD (&s->cap_head, cap, entries); |
| 1817 | LIST_INSERT_HEAD (&cap->cb_head, cb, entries); | 1895 | LIST_INSERT_HEAD (&cap->cb_head, cb, entries); |
audio/audio.h
| @@ -33,7 +33,9 @@ typedef enum { | @@ -33,7 +33,9 @@ typedef enum { | ||
| 33 | AUD_FMT_U8, | 33 | AUD_FMT_U8, |
| 34 | AUD_FMT_S8, | 34 | AUD_FMT_S8, |
| 35 | AUD_FMT_U16, | 35 | AUD_FMT_U16, |
| 36 | - AUD_FMT_S16 | 36 | + AUD_FMT_S16, |
| 37 | + AUD_FMT_U32, | ||
| 38 | + AUD_FMT_S32 | ||
| 37 | } audfmt_e; | 39 | } audfmt_e; |
| 38 | 40 | ||
| 39 | #ifdef WORDS_BIGENDIAN | 41 | #ifdef WORDS_BIGENDIAN |
audio/audio_template.h
| @@ -164,7 +164,7 @@ static int glue (audio_pcm_sw_init_, TYPE) ( | @@ -164,7 +164,7 @@ static int glue (audio_pcm_sw_init_, TYPE) ( | ||
| 164 | [sw->info.nchannels == 2] | 164 | [sw->info.nchannels == 2] |
| 165 | [sw->info.sign] | 165 | [sw->info.sign] |
| 166 | [sw->info.swap_endianness] | 166 | [sw->info.swap_endianness] |
| 167 | - [sw->info.bits == 16]; | 167 | + [audio_bits_to_index (sw->info.bits)]; |
| 168 | 168 | ||
| 169 | sw->name = qemu_strdup (name); | 169 | sw->name = qemu_strdup (name); |
| 170 | err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw); | 170 | err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw); |
| @@ -288,7 +288,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as) | @@ -288,7 +288,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as) | ||
| 288 | [hw->info.nchannels == 2] | 288 | [hw->info.nchannels == 2] |
| 289 | [hw->info.sign] | 289 | [hw->info.sign] |
| 290 | [hw->info.swap_endianness] | 290 | [hw->info.swap_endianness] |
| 291 | - [hw->info.bits == 16]; | 291 | + [audio_bits_to_index (hw->info.bits)]; |
| 292 | 292 | ||
| 293 | if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) { | 293 | if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) { |
| 294 | goto err1; | 294 | goto err1; |
audio/coreaudio.c
| @@ -294,7 +294,6 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as) | @@ -294,7 +294,6 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as) | ||
| 294 | coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; | 294 | coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; |
| 295 | UInt32 propertySize; | 295 | UInt32 propertySize; |
| 296 | int err; | 296 | int err; |
| 297 | - int bits = 8; | ||
| 298 | const char *typ = "playback"; | 297 | const char *typ = "playback"; |
| 299 | AudioValueRange frameRange; | 298 | AudioValueRange frameRange; |
| 300 | 299 | ||
| @@ -305,10 +304,6 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as) | @@ -305,10 +304,6 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as) | ||
| 305 | return -1; | 304 | return -1; |
| 306 | } | 305 | } |
| 307 | 306 | ||
| 308 | - if (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) { | ||
| 309 | - bits = 16; | ||
| 310 | - } | ||
| 311 | - | ||
| 312 | audio_pcm_init_info (&hw->info, as); | 307 | audio_pcm_init_info (&hw->info, as); |
| 313 | 308 | ||
| 314 | /* open default output device */ | 309 | /* open default output device */ |
audio/mixeng.c
| @@ -82,6 +82,7 @@ | @@ -82,6 +82,7 @@ | ||
| 82 | #undef IN_T | 82 | #undef IN_T |
| 83 | #undef SHIFT | 83 | #undef SHIFT |
| 84 | 84 | ||
| 85 | +/* Unsigned 16 bit */ | ||
| 85 | #define IN_T uint16_t | 86 | #define IN_T uint16_t |
| 86 | #define IN_MIN 0 | 87 | #define IN_MIN 0 |
| 87 | #define IN_MAX USHRT_MAX | 88 | #define IN_MAX USHRT_MAX |
| @@ -101,26 +102,72 @@ | @@ -101,26 +102,72 @@ | ||
| 101 | #undef IN_T | 102 | #undef IN_T |
| 102 | #undef SHIFT | 103 | #undef SHIFT |
| 103 | 104 | ||
| 104 | -t_sample *mixeng_conv[2][2][2][2] = { | 105 | +/* Signed 32 bit */ |
| 106 | +#define IN_T int32_t | ||
| 107 | +#define IN_MIN INT32_MIN | ||
| 108 | +#define IN_MAX INT32_MAX | ||
| 109 | +#define SIGNED | ||
| 110 | +#define SHIFT 32 | ||
| 111 | +#define ENDIAN_CONVERSION natural | ||
| 112 | +#define ENDIAN_CONVERT(v) (v) | ||
| 113 | +#include "mixeng_template.h" | ||
| 114 | +#undef ENDIAN_CONVERT | ||
| 115 | +#undef ENDIAN_CONVERSION | ||
| 116 | +#define ENDIAN_CONVERSION swap | ||
| 117 | +#define ENDIAN_CONVERT(v) bswap32 (v) | ||
| 118 | +#include "mixeng_template.h" | ||
| 119 | +#undef ENDIAN_CONVERT | ||
| 120 | +#undef ENDIAN_CONVERSION | ||
| 121 | +#undef SIGNED | ||
| 122 | +#undef IN_MAX | ||
| 123 | +#undef IN_MIN | ||
| 124 | +#undef IN_T | ||
| 125 | +#undef SHIFT | ||
| 126 | + | ||
| 127 | +/* Unsigned 16 bit */ | ||
| 128 | +#define IN_T uint32_t | ||
| 129 | +#define IN_MIN 0 | ||
| 130 | +#define IN_MAX UINT32_MAX | ||
| 131 | +#define SHIFT 32 | ||
| 132 | +#define ENDIAN_CONVERSION natural | ||
| 133 | +#define ENDIAN_CONVERT(v) (v) | ||
| 134 | +#include "mixeng_template.h" | ||
| 135 | +#undef ENDIAN_CONVERT | ||
| 136 | +#undef ENDIAN_CONVERSION | ||
| 137 | +#define ENDIAN_CONVERSION swap | ||
| 138 | +#define ENDIAN_CONVERT(v) bswap32 (v) | ||
| 139 | +#include "mixeng_template.h" | ||
| 140 | +#undef ENDIAN_CONVERT | ||
| 141 | +#undef ENDIAN_CONVERSION | ||
| 142 | +#undef IN_MAX | ||
| 143 | +#undef IN_MIN | ||
| 144 | +#undef IN_T | ||
| 145 | +#undef SHIFT | ||
| 146 | + | ||
| 147 | +t_sample *mixeng_conv[2][2][2][3] = { | ||
| 105 | { | 148 | { |
| 106 | { | 149 | { |
| 107 | { | 150 | { |
| 108 | conv_natural_uint8_t_to_mono, | 151 | conv_natural_uint8_t_to_mono, |
| 109 | - conv_natural_uint16_t_to_mono | 152 | + conv_natural_uint16_t_to_mono, |
| 153 | + conv_natural_uint32_t_to_mono | ||
| 110 | }, | 154 | }, |
| 111 | { | 155 | { |
| 112 | conv_natural_uint8_t_to_mono, | 156 | conv_natural_uint8_t_to_mono, |
| 113 | - conv_swap_uint16_t_to_mono | 157 | + conv_swap_uint16_t_to_mono, |
| 158 | + conv_swap_uint32_t_to_mono, | ||
| 114 | } | 159 | } |
| 115 | }, | 160 | }, |
| 116 | { | 161 | { |
| 117 | { | 162 | { |
| 118 | conv_natural_int8_t_to_mono, | 163 | conv_natural_int8_t_to_mono, |
| 119 | - conv_natural_int16_t_to_mono | 164 | + conv_natural_int16_t_to_mono, |
| 165 | + conv_natural_int32_t_to_mono | ||
| 120 | }, | 166 | }, |
| 121 | { | 167 | { |
| 122 | conv_natural_int8_t_to_mono, | 168 | conv_natural_int8_t_to_mono, |
| 123 | - conv_swap_int16_t_to_mono | 169 | + conv_swap_int16_t_to_mono, |
| 170 | + conv_swap_int32_t_to_mono | ||
| 124 | } | 171 | } |
| 125 | } | 172 | } |
| 126 | }, | 173 | }, |
| @@ -128,46 +175,54 @@ t_sample *mixeng_conv[2][2][2][2] = { | @@ -128,46 +175,54 @@ t_sample *mixeng_conv[2][2][2][2] = { | ||
| 128 | { | 175 | { |
| 129 | { | 176 | { |
| 130 | conv_natural_uint8_t_to_stereo, | 177 | conv_natural_uint8_t_to_stereo, |
| 131 | - conv_natural_uint16_t_to_stereo | 178 | + conv_natural_uint16_t_to_stereo, |
| 179 | + conv_natural_uint32_t_to_stereo | ||
| 132 | }, | 180 | }, |
| 133 | { | 181 | { |
| 134 | conv_natural_uint8_t_to_stereo, | 182 | conv_natural_uint8_t_to_stereo, |
| 135 | - conv_swap_uint16_t_to_stereo | 183 | + conv_swap_uint16_t_to_stereo, |
| 184 | + conv_swap_uint32_t_to_stereo | ||
| 136 | } | 185 | } |
| 137 | }, | 186 | }, |
| 138 | { | 187 | { |
| 139 | { | 188 | { |
| 140 | conv_natural_int8_t_to_stereo, | 189 | conv_natural_int8_t_to_stereo, |
| 141 | - conv_natural_int16_t_to_stereo | 190 | + conv_natural_int16_t_to_stereo, |
| 191 | + conv_natural_int32_t_to_stereo | ||
| 142 | }, | 192 | }, |
| 143 | { | 193 | { |
| 144 | conv_natural_int8_t_to_stereo, | 194 | conv_natural_int8_t_to_stereo, |
| 145 | - conv_swap_int16_t_to_stereo | 195 | + conv_swap_int16_t_to_stereo, |
| 196 | + conv_swap_int32_t_to_stereo, | ||
| 146 | } | 197 | } |
| 147 | } | 198 | } |
| 148 | } | 199 | } |
| 149 | }; | 200 | }; |
| 150 | 201 | ||
| 151 | -f_sample *mixeng_clip[2][2][2][2] = { | 202 | +f_sample *mixeng_clip[2][2][2][3] = { |
| 152 | { | 203 | { |
| 153 | { | 204 | { |
| 154 | { | 205 | { |
| 155 | clip_natural_uint8_t_from_mono, | 206 | clip_natural_uint8_t_from_mono, |
| 156 | - clip_natural_uint16_t_from_mono | 207 | + clip_natural_uint16_t_from_mono, |
| 208 | + clip_natural_uint32_t_from_mono | ||
| 157 | }, | 209 | }, |
| 158 | { | 210 | { |
| 159 | clip_natural_uint8_t_from_mono, | 211 | clip_natural_uint8_t_from_mono, |
| 160 | - clip_swap_uint16_t_from_mono | 212 | + clip_swap_uint16_t_from_mono, |
| 213 | + clip_swap_uint32_t_from_mono | ||
| 161 | } | 214 | } |
| 162 | }, | 215 | }, |
| 163 | { | 216 | { |
| 164 | { | 217 | { |
| 165 | clip_natural_int8_t_from_mono, | 218 | clip_natural_int8_t_from_mono, |
| 166 | - clip_natural_int16_t_from_mono | 219 | + clip_natural_int16_t_from_mono, |
| 220 | + clip_natural_int32_t_from_mono | ||
| 167 | }, | 221 | }, |
| 168 | { | 222 | { |
| 169 | clip_natural_int8_t_from_mono, | 223 | clip_natural_int8_t_from_mono, |
| 170 | - clip_swap_int16_t_from_mono | 224 | + clip_swap_int16_t_from_mono, |
| 225 | + clip_swap_int32_t_from_mono | ||
| 171 | } | 226 | } |
| 172 | } | 227 | } |
| 173 | }, | 228 | }, |
| @@ -175,21 +230,25 @@ f_sample *mixeng_clip[2][2][2][2] = { | @@ -175,21 +230,25 @@ f_sample *mixeng_clip[2][2][2][2] = { | ||
| 175 | { | 230 | { |
| 176 | { | 231 | { |
| 177 | clip_natural_uint8_t_from_stereo, | 232 | clip_natural_uint8_t_from_stereo, |
| 178 | - clip_natural_uint16_t_from_stereo | 233 | + clip_natural_uint16_t_from_stereo, |
| 234 | + clip_natural_uint32_t_from_stereo | ||
| 179 | }, | 235 | }, |
| 180 | { | 236 | { |
| 181 | clip_natural_uint8_t_from_stereo, | 237 | clip_natural_uint8_t_from_stereo, |
| 182 | - clip_swap_uint16_t_from_stereo | 238 | + clip_swap_uint16_t_from_stereo, |
| 239 | + clip_swap_uint32_t_from_stereo | ||
| 183 | } | 240 | } |
| 184 | }, | 241 | }, |
| 185 | { | 242 | { |
| 186 | { | 243 | { |
| 187 | clip_natural_int8_t_from_stereo, | 244 | clip_natural_int8_t_from_stereo, |
| 188 | - clip_natural_int16_t_from_stereo | 245 | + clip_natural_int16_t_from_stereo, |
| 246 | + clip_natural_int32_t_from_stereo | ||
| 189 | }, | 247 | }, |
| 190 | { | 248 | { |
| 191 | clip_natural_int8_t_from_stereo, | 249 | clip_natural_int8_t_from_stereo, |
| 192 | - clip_swap_int16_t_from_stereo | 250 | + clip_swap_int16_t_from_stereo, |
| 251 | + clip_swap_int32_t_from_stereo | ||
| 193 | } | 252 | } |
| 194 | } | 253 | } |
| 195 | } | 254 | } |
audio/mixeng.h
| @@ -37,8 +37,8 @@ typedef void (t_sample) (st_sample_t *dst, const void *src, | @@ -37,8 +37,8 @@ typedef void (t_sample) (st_sample_t *dst, const void *src, | ||
| 37 | int samples, volume_t *vol); | 37 | int samples, volume_t *vol); |
| 38 | typedef void (f_sample) (void *dst, const st_sample_t *src, int samples); | 38 | typedef void (f_sample) (void *dst, const st_sample_t *src, int samples); |
| 39 | 39 | ||
| 40 | -extern t_sample *mixeng_conv[2][2][2][2]; | ||
| 41 | -extern f_sample *mixeng_clip[2][2][2][2]; | 40 | +extern t_sample *mixeng_conv[2][2][2][3]; |
| 41 | +extern f_sample *mixeng_clip[2][2][2][3]; | ||
| 42 | 42 | ||
| 43 | void *st_rate_start (int inrate, int outrate); | 43 | void *st_rate_start (int inrate, int outrate); |
| 44 | void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf, | 44 | void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf, |
audio/wavaudio.c
| @@ -41,7 +41,8 @@ static struct { | @@ -41,7 +41,8 @@ static struct { | ||
| 41 | { | 41 | { |
| 42 | 44100, | 42 | 44100, |
| 43 | 2, | 43 | 2, |
| 44 | - AUD_FMT_S16 | 44 | + AUD_FMT_S16, |
| 45 | + AUDIO_HOST_ENDIANNESS | ||
| 45 | }, | 46 | }, |
| 46 | "qemu.wav" | 47 | "qemu.wav" |
| 47 | }; | 48 | }; |
| @@ -131,6 +132,11 @@ static int wav_init_out (HWVoiceOut *hw, audsettings_t *as) | @@ -131,6 +132,11 @@ static int wav_init_out (HWVoiceOut *hw, audsettings_t *as) | ||
| 131 | case AUD_FMT_U16: | 132 | case AUD_FMT_U16: |
| 132 | bits16 = 1; | 133 | bits16 = 1; |
| 133 | break; | 134 | break; |
| 135 | + | ||
| 136 | + case AUD_FMT_S32: | ||
| 137 | + case AUD_FMT_U32: | ||
| 138 | + dolog ("WAVE files can not handle 32bit formats\n"); | ||
| 139 | + return -1; | ||
| 134 | } | 140 | } |
| 135 | 141 | ||
| 136 | hdr[34] = bits16 ? 0x10 : 0x08; | 142 | hdr[34] = bits16 ? 0x10 : 0x08; |
audio/wavcapture.c
| @@ -37,15 +37,15 @@ static void wav_destroy (void *opaque) | @@ -37,15 +37,15 @@ static void wav_destroy (void *opaque) | ||
| 37 | if (wav->f) { | 37 | if (wav->f) { |
| 38 | le_store (rlen, rifflen, 4); | 38 | le_store (rlen, rifflen, 4); |
| 39 | le_store (dlen, datalen, 4); | 39 | le_store (dlen, datalen, 4); |
| 40 | - | 40 | + |
| 41 | qemu_fseek (wav->f, 4, SEEK_SET); | 41 | qemu_fseek (wav->f, 4, SEEK_SET); |
| 42 | qemu_put_buffer (wav->f, rlen, 4); | 42 | qemu_put_buffer (wav->f, rlen, 4); |
| 43 | - | 43 | + |
| 44 | qemu_fseek (wav->f, 32, SEEK_CUR); | 44 | qemu_fseek (wav->f, 32, SEEK_CUR); |
| 45 | qemu_put_buffer (wav->f, dlen, 4); | 45 | qemu_put_buffer (wav->f, dlen, 4); |
| 46 | qemu_fclose (wav->f); | 46 | qemu_fclose (wav->f); |
| 47 | } | 47 | } |
| 48 | - | 48 | + |
| 49 | qemu_free (wav->path); | 49 | qemu_free (wav->path); |
| 50 | } | 50 | } |
| 51 | 51 |