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 | 274 | VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o |
| 275 | 275 | |
| 276 | 276 | SOUND_HW = sb16.o |
| 277 | -AUDIODRV = audio.o wavaudio.o | |
| 277 | +AUDIODRV = audio.o noaudio.o wavaudio.o | |
| 278 | 278 | ifdef CONFIG_SDL |
| 279 | 279 | AUDIODRV += sdlaudio.o |
| 280 | 280 | endif | ... | ... |
audio/audio.c
| ... | ... | @@ -183,7 +183,6 @@ int pcm_hw_alloc_resources (HWVoice *hw) |
| 183 | 183 | return 0; |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | - | |
| 187 | 186 | void pcm_hw_fini (HWVoice *hw) |
| 188 | 187 | { |
| 189 | 188 | if (hw->active) { |
| ... | ... | @@ -786,6 +785,7 @@ static struct audio_output_driver *drvtab[] = { |
| 786 | 785 | #ifdef CONFIG_SDL |
| 787 | 786 | &sdl_output_driver, |
| 788 | 787 | #endif |
| 788 | + &no_output_driver, | |
| 789 | 789 | #ifdef USE_WAV_AUDIO |
| 790 | 790 | &wav_output_driver, |
| 791 | 791 | #endif |
| ... | ... | @@ -906,6 +906,6 @@ void AUD_init (void) |
| 906 | 906 | register_savevm ("audio", 0, 1, audio_save, audio_load, NULL); |
| 907 | 907 | if (!done) { |
| 908 | 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 | 55 | struct pcm_ops *pcm_ops; |
| 56 | 56 | } HWVoice; |
| 57 | 57 | |
| 58 | +extern struct pcm_ops no_pcm_ops; | |
| 59 | +extern struct audio_output_driver no_output_driver; | |
| 60 | + | |
| 58 | 61 | extern struct pcm_ops oss_pcm_ops; |
| 59 | 62 | extern struct audio_output_driver oss_output_driver; |
| 60 | 63 | ... | ... |
audio/fmodaudio.c
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 | 40 | int old_optr; |
| 41 | 41 | } OSSVoice; |
| 42 | 42 | |
| 43 | - | |
| 44 | 43 | #define dolog(...) AUD_log ("oss", __VA_ARGS__) |
| 45 | 44 | #ifdef DEBUG |
| 46 | 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 | 370 | if (oss->pcm_buf == MAP_FAILED) { |
| 372 | 371 | dolog ("Failed to mmap OSS device\nReason: %s\n", |
| 373 | 372 | errstr ()); |
| 374 | - } | |
| 375 | - | |
| 376 | - for (;;) { | |
| 373 | + } else for (;;) { | |
| 377 | 374 | int err; |
| 378 | 375 | int trig = 0; |
| 379 | 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 | 55 | int64_t now = qemu_get_clock (vm_clock); |
| 56 | 56 | int64_t ticks = now - wav->old_ticks; |
| 57 | 57 | int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec; |
| 58 | - wav->old_ticks = now; | |
| 59 | 58 | |
| 60 | 59 | if (bytes > INT_MAX) |
| 61 | 60 | samples = INT_MAX >> hw->shift; |
| ... | ... | @@ -66,6 +65,7 @@ static void wav_hw_run (HWVoice *hw) |
| 66 | 65 | if (live <= 0) |
| 67 | 66 | return; |
| 68 | 67 | |
| 68 | + wav->old_ticks = now; | |
| 69 | 69 | decr = audio_MIN (live, samples); |
| 70 | 70 | samples = decr; |
| 71 | 71 | rpos = hw->rpos; |
| ... | ... | @@ -94,7 +94,6 @@ static int wav_hw_write (SWVoice *sw, void *buf, int len) |
| 94 | 94 | return pcm_hw_write (sw, buf, len); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | - | |
| 98 | 97 | /* VICE code: Store number as little endian. */ |
| 99 | 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 | 144 | if (!wav->f) { |
| 146 | 145 | dolog ("failed to open wave file `%s'\nReason: %s\n", |
| 147 | 146 | conf.wav_path, strerror (errno)); |
| 147 | + qemu_free (wav->pcm_buf); | |
| 148 | + wav->pcm_buf = NULL; | |
| 148 | 149 | return -1; |
| 149 | 150 | } |
| 150 | 151 | |
| ... | ... | @@ -175,6 +176,9 @@ static void wav_hw_fini (HWVoice *hw) |
| 175 | 176 | |
| 176 | 177 | fclose (wav->f); |
| 177 | 178 | wav->f = NULL; |
| 179 | + | |
| 180 | + qemu_free (wav->pcm_buf); | |
| 181 | + wav->pcm_buf = NULL; | |
| 178 | 182 | } |
| 179 | 183 | |
| 180 | 184 | static int wav_hw_ctl (HWVoice *hw, int cmd, ...) | ... | ... |
hw/sb16.c
| ... | ... | @@ -640,8 +640,8 @@ static void complete (SB16State *s) |
| 640 | 640 | s->freq = 11025; |
| 641 | 641 | samples = dsp_get_lohi (s); |
| 642 | 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 | 645 | pic_set_irq (s->irq, 1); |
| 646 | 646 | else |
| 647 | 647 | qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks); | ... | ... |