Commit 7372f88dc171775c2918b3a874edf0a1d5266b19
1 parent
d7382233
audio fixes (malc)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1133 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
8 changed files
with
145 additions
and
12 deletions
Makefile.target
| @@ -274,7 +274,7 @@ VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o | @@ -274,7 +274,7 @@ VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o | ||
| 274 | VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o | 274 | VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o |
| 275 | 275 | ||
| 276 | SOUND_HW = sb16.o | 276 | SOUND_HW = sb16.o |
| 277 | -AUDIODRV = audio.o wavaudio.o | 277 | +AUDIODRV = audio.o noaudio.o wavaudio.o |
| 278 | ifdef CONFIG_SDL | 278 | ifdef CONFIG_SDL |
| 279 | AUDIODRV += sdlaudio.o | 279 | AUDIODRV += sdlaudio.o |
| 280 | endif | 280 | endif |
audio/audio.c
| @@ -183,7 +183,6 @@ int pcm_hw_alloc_resources (HWVoice *hw) | @@ -183,7 +183,6 @@ int pcm_hw_alloc_resources (HWVoice *hw) | ||
| 183 | return 0; | 183 | return 0; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | - | ||
| 187 | void pcm_hw_fini (HWVoice *hw) | 186 | void pcm_hw_fini (HWVoice *hw) |
| 188 | { | 187 | { |
| 189 | if (hw->active) { | 188 | if (hw->active) { |
| @@ -786,6 +785,7 @@ static struct audio_output_driver *drvtab[] = { | @@ -786,6 +785,7 @@ static struct audio_output_driver *drvtab[] = { | ||
| 786 | #ifdef CONFIG_SDL | 785 | #ifdef CONFIG_SDL |
| 787 | &sdl_output_driver, | 786 | &sdl_output_driver, |
| 788 | #endif | 787 | #endif |
| 788 | + &no_output_driver, | ||
| 789 | #ifdef USE_WAV_AUDIO | 789 | #ifdef USE_WAV_AUDIO |
| 790 | &wav_output_driver, | 790 | &wav_output_driver, |
| 791 | #endif | 791 | #endif |
| @@ -906,6 +906,6 @@ void AUD_init (void) | @@ -906,6 +906,6 @@ void AUD_init (void) | ||
| 906 | register_savevm ("audio", 0, 1, audio_save, audio_load, NULL); | 906 | register_savevm ("audio", 0, 1, audio_save, audio_load, NULL); |
| 907 | if (!done) { | 907 | if (!done) { |
| 908 | dolog ("Can not initialize audio subsystem\n"); | 908 | dolog ("Can not initialize audio subsystem\n"); |
| 909 | - return; | 909 | + voice_init (&no_output_driver); |
| 910 | } | 910 | } |
| 911 | } | 911 | } |
audio/audio_int.h
| @@ -55,6 +55,9 @@ typedef struct HWVoice { | @@ -55,6 +55,9 @@ typedef struct HWVoice { | ||
| 55 | struct pcm_ops *pcm_ops; | 55 | struct pcm_ops *pcm_ops; |
| 56 | } HWVoice; | 56 | } HWVoice; |
| 57 | 57 | ||
| 58 | +extern struct pcm_ops no_pcm_ops; | ||
| 59 | +extern struct audio_output_driver no_output_driver; | ||
| 60 | + | ||
| 58 | extern struct pcm_ops oss_pcm_ops; | 61 | extern struct pcm_ops oss_pcm_ops; |
| 59 | extern struct audio_output_driver oss_output_driver; | 62 | extern struct audio_output_driver oss_output_driver; |
| 60 | 63 |
audio/fmodaudio.c
| @@ -34,7 +34,6 @@ typedef struct FMODVoice { | @@ -34,7 +34,6 @@ typedef struct FMODVoice { | ||
| 34 | int channel; | 34 | int channel; |
| 35 | } FMODVoice; | 35 | } FMODVoice; |
| 36 | 36 | ||
| 37 | - | ||
| 38 | #define dolog(...) AUD_log ("fmod", __VA_ARGS__) | 37 | #define dolog(...) AUD_log ("fmod", __VA_ARGS__) |
| 39 | #ifdef DEBUG | 38 | #ifdef DEBUG |
| 40 | #define ldebug(...) dolog (__VA_ARGS__) | 39 | #define ldebug(...) dolog (__VA_ARGS__) |
audio/noaudio.c
0 → 100644
| 1 | +/* | ||
| 2 | + * QEMU NULL audio output driver | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2004 Vassili Karpov (malc) | ||
| 5 | + * | ||
| 6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 7 | + * of this software and associated documentation files (the "Software"), to deal | ||
| 8 | + * in the Software without restriction, including without limitation the rights | ||
| 9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 10 | + * copies of the Software, and to permit persons to whom the Software is | ||
| 11 | + * furnished to do so, subject to the following conditions: | ||
| 12 | + * | ||
| 13 | + * The above copyright notice and this permission notice shall be included in | ||
| 14 | + * all copies or substantial portions of the Software. | ||
| 15 | + * | ||
| 16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 19 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 22 | + * THE SOFTWARE. | ||
| 23 | + */ | ||
| 24 | +#include "vl.h" | ||
| 25 | + | ||
| 26 | +#include "audio/audio_int.h" | ||
| 27 | + | ||
| 28 | +typedef struct NoVoice { | ||
| 29 | + HWVoice hw; | ||
| 30 | + int64_t old_ticks; | ||
| 31 | +} NoVoice; | ||
| 32 | + | ||
| 33 | +#define dolog(...) AUD_log ("noaudio", __VA_ARGS__) | ||
| 34 | +#ifdef DEBUG | ||
| 35 | +#define ldebug(...) dolog (__VA_ARGS__) | ||
| 36 | +#else | ||
| 37 | +#define ldebug(...) | ||
| 38 | +#endif | ||
| 39 | + | ||
| 40 | +static void no_hw_run (HWVoice *hw) | ||
| 41 | +{ | ||
| 42 | + NoVoice *no = (NoVoice *) hw; | ||
| 43 | + int rpos, live, decr, samples; | ||
| 44 | + uint8_t *dst; | ||
| 45 | + st_sample_t *src; | ||
| 46 | + int64_t now = qemu_get_clock (vm_clock); | ||
| 47 | + int64_t ticks = now - no->old_ticks; | ||
| 48 | + int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec; | ||
| 49 | + | ||
| 50 | + if (bytes > INT_MAX) | ||
| 51 | + samples = INT_MAX >> hw->shift; | ||
| 52 | + else | ||
| 53 | + samples = bytes >> hw->shift; | ||
| 54 | + | ||
| 55 | + live = pcm_hw_get_live (hw); | ||
| 56 | + if (live <= 0) | ||
| 57 | + return; | ||
| 58 | + | ||
| 59 | + no->old_ticks = now; | ||
| 60 | + decr = audio_MIN (live, samples); | ||
| 61 | + samples = decr; | ||
| 62 | + rpos = hw->rpos; | ||
| 63 | + while (samples) { | ||
| 64 | + int left_till_end_samples = hw->samples - rpos; | ||
| 65 | + int convert_samples = audio_MIN (samples, left_till_end_samples); | ||
| 66 | + | ||
| 67 | + src = advance (hw->mix_buf, rpos * sizeof (st_sample_t)); | ||
| 68 | + memset (src, 0, convert_samples * sizeof (st_sample_t)); | ||
| 69 | + | ||
| 70 | + rpos = (rpos + convert_samples) % hw->samples; | ||
| 71 | + samples -= convert_samples; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + pcm_hw_dec_live (hw, decr); | ||
| 75 | + hw->rpos = rpos; | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +static int no_hw_write (SWVoice *sw, void *buf, int len) | ||
| 79 | +{ | ||
| 80 | + return pcm_hw_write (sw, buf, len); | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +static int no_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt) | ||
| 84 | +{ | ||
| 85 | + NoVoice *no = (NoVoice *) hw; | ||
| 86 | + hw->freq = freq; | ||
| 87 | + hw->nchannels = nchannels; | ||
| 88 | + hw->fmt = fmt; | ||
| 89 | + hw->bufsize = 4096; | ||
| 90 | + return 0; | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +static void no_hw_fini (HWVoice *hw) | ||
| 94 | +{ | ||
| 95 | + (void) hw; | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +static int no_hw_ctl (HWVoice *hw, int cmd, ...) | ||
| 99 | +{ | ||
| 100 | + (void) hw; | ||
| 101 | + (void) cmd; | ||
| 102 | + return 0; | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +static void *no_audio_init (void) | ||
| 106 | +{ | ||
| 107 | + return &no_audio_init; | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +static void no_audio_fini (void *opaque) | ||
| 111 | +{ | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +struct pcm_ops no_pcm_ops = { | ||
| 115 | + no_hw_init, | ||
| 116 | + no_hw_fini, | ||
| 117 | + no_hw_run, | ||
| 118 | + no_hw_write, | ||
| 119 | + no_hw_ctl | ||
| 120 | +}; | ||
| 121 | + | ||
| 122 | +struct audio_output_driver no_output_driver = { | ||
| 123 | + "none", | ||
| 124 | + no_audio_init, | ||
| 125 | + no_audio_fini, | ||
| 126 | + &no_pcm_ops, | ||
| 127 | + 1, | ||
| 128 | + 1, | ||
| 129 | + sizeof (NoVoice) | ||
| 130 | +}; |
audio/ossaudio.c
| @@ -40,7 +40,6 @@ typedef struct OSSVoice { | @@ -40,7 +40,6 @@ typedef struct OSSVoice { | ||
| 40 | int old_optr; | 40 | int old_optr; |
| 41 | } OSSVoice; | 41 | } OSSVoice; |
| 42 | 42 | ||
| 43 | - | ||
| 44 | #define dolog(...) AUD_log ("oss", __VA_ARGS__) | 43 | #define dolog(...) AUD_log ("oss", __VA_ARGS__) |
| 45 | #ifdef DEBUG | 44 | #ifdef DEBUG |
| 46 | #define ldebug(...) dolog (__VA_ARGS__) | 45 | #define ldebug(...) dolog (__VA_ARGS__) |
| @@ -371,9 +370,7 @@ static int oss_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt) | @@ -371,9 +370,7 @@ static int oss_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt) | ||
| 371 | if (oss->pcm_buf == MAP_FAILED) { | 370 | if (oss->pcm_buf == MAP_FAILED) { |
| 372 | dolog ("Failed to mmap OSS device\nReason: %s\n", | 371 | dolog ("Failed to mmap OSS device\nReason: %s\n", |
| 373 | errstr ()); | 372 | errstr ()); |
| 374 | - } | ||
| 375 | - | ||
| 376 | - for (;;) { | 373 | + } else for (;;) { |
| 377 | int err; | 374 | int err; |
| 378 | int trig = 0; | 375 | int trig = 0; |
| 379 | if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { | 376 | if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { |
audio/wavaudio.c
| @@ -55,7 +55,6 @@ static void wav_hw_run (HWVoice *hw) | @@ -55,7 +55,6 @@ static void wav_hw_run (HWVoice *hw) | ||
| 55 | int64_t now = qemu_get_clock (vm_clock); | 55 | int64_t now = qemu_get_clock (vm_clock); |
| 56 | int64_t ticks = now - wav->old_ticks; | 56 | int64_t ticks = now - wav->old_ticks; |
| 57 | int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec; | 57 | int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec; |
| 58 | - wav->old_ticks = now; | ||
| 59 | 58 | ||
| 60 | if (bytes > INT_MAX) | 59 | if (bytes > INT_MAX) |
| 61 | samples = INT_MAX >> hw->shift; | 60 | samples = INT_MAX >> hw->shift; |
| @@ -66,6 +65,7 @@ static void wav_hw_run (HWVoice *hw) | @@ -66,6 +65,7 @@ static void wav_hw_run (HWVoice *hw) | ||
| 66 | if (live <= 0) | 65 | if (live <= 0) |
| 67 | return; | 66 | return; |
| 68 | 67 | ||
| 68 | + wav->old_ticks = now; | ||
| 69 | decr = audio_MIN (live, samples); | 69 | decr = audio_MIN (live, samples); |
| 70 | samples = decr; | 70 | samples = decr; |
| 71 | rpos = hw->rpos; | 71 | rpos = hw->rpos; |
| @@ -94,7 +94,6 @@ static int wav_hw_write (SWVoice *sw, void *buf, int len) | @@ -94,7 +94,6 @@ static int wav_hw_write (SWVoice *sw, void *buf, int len) | ||
| 94 | return pcm_hw_write (sw, buf, len); | 94 | return pcm_hw_write (sw, buf, len); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | - | ||
| 98 | /* VICE code: Store number as little endian. */ | 97 | /* VICE code: Store number as little endian. */ |
| 99 | static void le_store (uint8_t *buf, uint32_t val, int len) | 98 | static void le_store (uint8_t *buf, uint32_t val, int len) |
| 100 | { | 99 | { |
| @@ -145,6 +144,8 @@ static int wav_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt) | @@ -145,6 +144,8 @@ static int wav_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt) | ||
| 145 | if (!wav->f) { | 144 | if (!wav->f) { |
| 146 | dolog ("failed to open wave file `%s'\nReason: %s\n", | 145 | dolog ("failed to open wave file `%s'\nReason: %s\n", |
| 147 | conf.wav_path, strerror (errno)); | 146 | conf.wav_path, strerror (errno)); |
| 147 | + qemu_free (wav->pcm_buf); | ||
| 148 | + wav->pcm_buf = NULL; | ||
| 148 | return -1; | 149 | return -1; |
| 149 | } | 150 | } |
| 150 | 151 | ||
| @@ -175,6 +176,9 @@ static void wav_hw_fini (HWVoice *hw) | @@ -175,6 +176,9 @@ static void wav_hw_fini (HWVoice *hw) | ||
| 175 | 176 | ||
| 176 | fclose (wav->f); | 177 | fclose (wav->f); |
| 177 | wav->f = NULL; | 178 | wav->f = NULL; |
| 179 | + | ||
| 180 | + qemu_free (wav->pcm_buf); | ||
| 181 | + wav->pcm_buf = NULL; | ||
| 178 | } | 182 | } |
| 179 | 183 | ||
| 180 | static int wav_hw_ctl (HWVoice *hw, int cmd, ...) | 184 | static int wav_hw_ctl (HWVoice *hw, int cmd, ...) |
hw/sb16.c
| @@ -640,8 +640,8 @@ static void complete (SB16State *s) | @@ -640,8 +640,8 @@ static void complete (SB16State *s) | ||
| 640 | s->freq = 11025; | 640 | s->freq = 11025; |
| 641 | samples = dsp_get_lohi (s); | 641 | samples = dsp_get_lohi (s); |
| 642 | bytes = samples << s->fmt_stereo << (s->fmt_bits == 16); | 642 | bytes = samples << s->fmt_stereo << (s->fmt_bits == 16); |
| 643 | - ticks = ticks_per_sec / (s->freq / bytes); | ||
| 644 | - if (ticks < ticks_per_sec / 1024) | 643 | + ticks = bytes ? (ticks_per_sec / (s->freq / bytes)) : 0; |
| 644 | + if (!bytes || ticks < ticks_per_sec / 1024) | ||
| 645 | pic_set_irq (s->irq, 1); | 645 | pic_set_irq (s->irq, 1); |
| 646 | else | 646 | else |
| 647 | qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks); | 647 | qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks); |