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); | ... | ... |