Re: [Qemu-devel] [PATCH v5 04/14] audio: -audiodev command line option basic implementation
Hi, > And magic errors like "'vfio-pci' is not a valid device model name" > after update. Try a full rebuild then. I see strange errors now and then too, that fixed it. Seems the qemu build fails now and then that an object file needs a rebuild. cheers, Gerd
Re: [Qemu-devel] [PATCH v5 04/14] audio: -audiodev command line option basic implementation
On 2019-03-08 08:21, Markus Armbruster wrote: > "Zoltán Kővágó" writes: > >> On 2019-03-07 16:56, Gerd Hoffmann wrote: >>> On Tue, Feb 26, 2019 at 02:39:38AM +0100, Zoltán Kővágó wrote: On 2019-02-20 22:37, Kővágó, Zoltán wrote: [...] > diff --git a/audio/audio.c b/audio/audio.c > index ce8e6ea8c2..8ad8cbe559 100644 > --- a/audio/audio.c > +++ b/audio/audio.c [...] > @@ -2129,3 +1866,170 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, > uint8_t lvol, uint8_t rvol) > } > } > } > + > +void audio_create_pdos(Audiodev *dev) > +{ > +switch (dev->driver) { > +#define CASE(DRIVER, driver, pdo_name) \ > +case AUDIODEV_DRIVER_##DRIVER: \ > +dev->u.driver.in = g_malloc0( \ > +sizeof(Audiodev##pdo_name##PerDirectionOptions)); \ This should check has_in before overwriting. It'll work correctly when called from audio_legacy.c, but when using -audiodev it will overwrite the options passed by user (and leak memory) when called from audio_validate_opts. I'll fix it in the next update. >>> >>> Ping. 4.0 freeze is next tuesday. Any chance for a v6 early enough >>> that we have a chance to get the first chunk into 4.0? Monday latest, >>> preferably earlier ... >> >> I'll try to do something this weekend, but I can't promise anything. I >> still haven't got to reading through Markus' comments... > > Quoting myself: "We're down to minor stylistic issues. Good work!" > > Addressing these should not be hard. > I blame it on my horrible time management. Also the recent sdl/audio patches generated some conflicts, I had to solve them first. And magic errors like "'vfio-pci' is not a valid device model name" after update. Regards, Zoltan
Re: [Qemu-devel] [PATCH v5 04/14] audio: -audiodev command line option basic implementation
"Zoltán Kővágó" writes: > On 2019-03-07 16:56, Gerd Hoffmann wrote: >> On Tue, Feb 26, 2019 at 02:39:38AM +0100, Zoltán Kővágó wrote: >>> On 2019-02-20 22:37, Kővágó, Zoltán wrote: >>> [...] diff --git a/audio/audio.c b/audio/audio.c index ce8e6ea8c2..8ad8cbe559 100644 --- a/audio/audio.c +++ b/audio/audio.c >>> [...] @@ -2129,3 +1866,170 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol) } } } + +void audio_create_pdos(Audiodev *dev) +{ +switch (dev->driver) { +#define CASE(DRIVER, driver, pdo_name) \ +case AUDIODEV_DRIVER_##DRIVER: \ +dev->u.driver.in = g_malloc0( \ +sizeof(Audiodev##pdo_name##PerDirectionOptions)); \ >>> This should check has_in before overwriting. It'll work correctly when >>> called from audio_legacy.c, but when using -audiodev it will overwrite >>> the options passed by user (and leak memory) when called from >>> audio_validate_opts. I'll fix it in the next update. >> >> Ping. 4.0 freeze is next tuesday. Any chance for a v6 early enough >> that we have a chance to get the first chunk into 4.0? Monday latest, >> preferably earlier ... > > I'll try to do something this weekend, but I can't promise anything. I > still haven't got to reading through Markus' comments... Quoting myself: "We're down to minor stylistic issues. Good work!" Addressing these should not be hard.
Re: [Qemu-devel] [PATCH v5 04/14] audio: -audiodev command line option basic implementation
On 2019-03-07 16:56, Gerd Hoffmann wrote: > On Tue, Feb 26, 2019 at 02:39:38AM +0100, Zoltán Kővágó wrote: >> On 2019-02-20 22:37, Kővágó, Zoltán wrote: >> [...] >>> diff --git a/audio/audio.c b/audio/audio.c >>> index ce8e6ea8c2..8ad8cbe559 100644 >>> --- a/audio/audio.c >>> +++ b/audio/audio.c >> [...] >>> @@ -2129,3 +1866,170 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, >>> uint8_t lvol, uint8_t rvol) >>> } >>> } >>> } >>> + >>> +void audio_create_pdos(Audiodev *dev) >>> +{ >>> +switch (dev->driver) { >>> +#define CASE(DRIVER, driver, pdo_name) \ >>> +case AUDIODEV_DRIVER_##DRIVER: \ >>> +dev->u.driver.in = g_malloc0( \ >>> +sizeof(Audiodev##pdo_name##PerDirectionOptions)); \ >> This should check has_in before overwriting. It'll work correctly when >> called from audio_legacy.c, but when using -audiodev it will overwrite >> the options passed by user (and leak memory) when called from >> audio_validate_opts. I'll fix it in the next update. > > Ping. 4.0 freeze is next tuesday. Any chance for a v6 early enough > that we have a chance to get the first chunk into 4.0? Monday latest, > preferably earlier ... I'll try to do something this weekend, but I can't promise anything. I still haven't got to reading through Markus' comments... Regards, Zoltan
Re: [Qemu-devel] [PATCH v5 04/14] audio: -audiodev command line option basic implementation
On Tue, Feb 26, 2019 at 02:39:38AM +0100, Zoltán Kővágó wrote: > On 2019-02-20 22:37, Kővágó, Zoltán wrote: > [...] > > diff --git a/audio/audio.c b/audio/audio.c > > index ce8e6ea8c2..8ad8cbe559 100644 > > --- a/audio/audio.c > > +++ b/audio/audio.c > [...] > > @@ -2129,3 +1866,170 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, > > uint8_t lvol, uint8_t rvol) > > } > > } > > } > > + > > +void audio_create_pdos(Audiodev *dev) > > +{ > > +switch (dev->driver) { > > +#define CASE(DRIVER, driver, pdo_name) \ > > +case AUDIODEV_DRIVER_##DRIVER: \ > > +dev->u.driver.in = g_malloc0( \ > > +sizeof(Audiodev##pdo_name##PerDirectionOptions)); \ > This should check has_in before overwriting. It'll work correctly when > called from audio_legacy.c, but when using -audiodev it will overwrite > the options passed by user (and leak memory) when called from > audio_validate_opts. I'll fix it in the next update. Ping. 4.0 freeze is next tuesday. Any chance for a v6 early enough that we have a chance to get the first chunk into 4.0? Monday latest, preferably earlier ... thanks, Gerd
Re: [Qemu-devel] [PATCH v5 04/14] audio: -audiodev command line option basic implementation
On 2019-02-20 22:37, Kővágó, Zoltán wrote: [...] > diff --git a/audio/audio.c b/audio/audio.c > index ce8e6ea8c2..8ad8cbe559 100644 > --- a/audio/audio.c > +++ b/audio/audio.c [...] > @@ -2129,3 +1866,170 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, > uint8_t lvol, uint8_t rvol) > } > } > } > + > +void audio_create_pdos(Audiodev *dev) > +{ > +switch (dev->driver) { > +#define CASE(DRIVER, driver, pdo_name) \ > +case AUDIODEV_DRIVER_##DRIVER: \ > +dev->u.driver.in = g_malloc0( \ > +sizeof(Audiodev##pdo_name##PerDirectionOptions)); \ This should check has_in before overwriting. It'll work correctly when called from audio_legacy.c, but when using -audiodev it will overwrite the options passed by user (and leak memory) when called from audio_validate_opts. I'll fix it in the next update. > +dev->u.driver.has_in = true;\ > +dev->u.driver.out = g_malloc0( \ > +sizeof(AudiodevAlsaPerDirectionOptions)); \ > +dev->u.driver.has_out = true; \ > +break > + > +CASE(NONE, none, ); > +CASE(ALSA, alsa, Alsa); > +CASE(COREAUDIO, coreaudio, Coreaudio); > +CASE(DSOUND, dsound, ); > +CASE(OSS, oss, Oss); > +CASE(PA, pa, Pa); > +CASE(SDL, sdl, ); > +CASE(SPICE, spice, ); > +CASE(WAV, wav, ); > + > +case AUDIODEV_DRIVER__MAX: > +abort(); > +}; > +} > + > +static void audio_validate_per_direction_opts( > +AudiodevPerDirectionOptions *pdo, Error **errp) > +{ > +if (!pdo->has_fixed_settings) { > +pdo->has_fixed_settings = true; > +pdo->fixed_settings = true; > +} > +if (!pdo->fixed_settings && > +(pdo->has_frequency || pdo->has_channels || pdo->has_format)) { > +error_setg(errp, > + "You can't use frequency, channels or format with > fixed-settings=off"); > +return; > +} > + > +if (!pdo->has_frequency) { > +pdo->has_frequency = true; > +pdo->frequency = 44100; > +} > +if (!pdo->has_channels) { > +pdo->has_channels = true; > +pdo->channels = 2; > +} > +if (!pdo->has_voices) { > +pdo->has_voices = true; > +pdo->voices = 1; > +} > +if (!pdo->has_format) { > +pdo->has_format = true; > +pdo->format = AUDIO_FORMAT_S16; > +} > +} > + > +static void audio_validate_opts(Audiodev *dev, Error **errp) > +{ > +Error *err = NULL; > + > +audio_create_pdos(dev); > + > +audio_validate_per_direction_opts(audio_get_pdo_in(dev), ); > +if (err) { > +error_propagate(errp, err); > +return; > +} > + > +audio_validate_per_direction_opts(audio_get_pdo_out(dev), ); > +if (err) { > +error_propagate(errp, err); > +return; > +} > + > +if (!dev->has_timer_period) { > +dev->has_timer_period = true; > +dev->timer_period = 1; /* 100Hz -> 10ms */ > +} > +} > + > +void audio_parse_option(const char *opt) > +{ > +AudiodevListEntry *e; > +Audiodev *dev = NULL; > + > +Visitor *v = qobject_input_visitor_new_str(opt, "driver", _fatal); > +visit_type_Audiodev(v, NULL, , _fatal); > +visit_free(v); > + > +audio_validate_opts(dev, _fatal); > + > +e = g_malloc0(sizeof(AudiodevListEntry)); > +e->dev = dev; > +QSIMPLEQ_INSERT_TAIL(, e, next); > +} > + [...] Regards, Zoltan
[Qemu-devel] [PATCH v5 04/14] audio: -audiodev command line option basic implementation
Audio drivers now get an Audiodev * as config paramters, instead of the global audio_option structs. There is some code in audio/audio_legacy.c that converts the old environment variables to audiodev options (this way backends do not have to worry about legacy options). It also contains a replacement of -audio-help, which prints out the equivalent -audiodev based config of the currently specified environment variables. Note that backends are not updated and still rely on environment variables. Also note that (due to moving try-poll from global to backend specific option) currently ALSA and OSS will always try poll mode, regardless of environment variables or -audiodev options. Signed-off-by: Kővágó, Zoltán --- Notes: Currently audiodev_get_pdo_in is essentially: return (AudiodevPerDirectionOptions *) dev->u.none.in; This depends on in and out always be the first two member of backend specific options, and the compiler not playing tricks with the union/pointers, so I went with a safer version. This also catches type coversion errors for a small runtime performance penalty. audio/audio.h | 18 +- audio/audio_int.h | 20 +- audio/audio_template.h | 42 ++- audio/alsaaudio.c | 2 +- audio/audio.c | 626 + audio/audio_legacy.c | 293 +++ audio/coreaudio.c | 2 +- audio/dsoundaudio.c| 2 +- audio/noaudio.c| 2 +- audio/ossaudio.c | 2 +- audio/paaudio.c| 2 +- audio/sdlaudio.c | 2 +- audio/spiceaudio.c | 2 +- audio/wavaudio.c | 2 +- vl.c | 7 +- audio/Makefile.objs| 2 +- 16 files changed, 646 insertions(+), 380 deletions(-) create mode 100644 audio/audio_legacy.c diff --git a/audio/audio.h b/audio/audio.h index 02f29a3b3e..64b0f761bc 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -36,12 +36,21 @@ typedef void (*audio_callback_fn) (void *opaque, int avail); #define AUDIO_HOST_ENDIANNESS 0 #endif -struct audsettings { +typedef struct audsettings { int freq; int nchannels; AudioFormat fmt; int endianness; -}; +} audsettings; + +audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo); +int audioformat_bytes_per_sample(AudioFormat fmt); +int audio_buffer_frames(AudiodevPerDirectionOptions *pdo, +audsettings *as, int def_usecs); +int audio_buffer_samples(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs); +int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs); typedef enum { AUD_CNOTIFY_ENABLE, @@ -81,7 +90,6 @@ typedef struct QEMUAudioTimeStamp { void AUD_vlog (const char *cap, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -void AUD_help (void); void AUD_register_card (const char *name, QEMUSoundCard *card); void AUD_remove_card (QEMUSoundCard *card); CaptureVoiceOut *AUD_add_capture ( @@ -163,4 +171,8 @@ void audio_sample_to_uint64(void *samples, int pos, void audio_sample_from_uint64(void *samples, int pos, uint64_t left, uint64_t right); +void audio_parse_option(const char *opt); +void audio_init_audiodevs(void); +void audio_legacy_help(void); + #endif /* QEMU_AUDIO_H */ diff --git a/audio/audio_int.h b/audio/audio_int.h index 6c451b995c..7bf5dfc0b5 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -146,7 +146,7 @@ struct audio_driver { const char *name; const char *descr; struct audio_option *options; -void *(*init) (void); +void *(*init) (Audiodev *); void (*fini) (void *); struct audio_pcm_ops *pcm_ops; int can_be_default; @@ -193,6 +193,7 @@ struct SWVoiceCap { typedef struct AudioState { struct audio_driver *drv; +Audiodev *dev; void *drv_opaque; QEMUTimer *ts; @@ -203,10 +204,13 @@ typedef struct AudioState { int nb_hw_voices_out; int nb_hw_voices_in; int vm_running; +int64_t period_ticks; } AudioState; extern const struct mixeng_volume nominal_volume; +extern const char *audio_prio_list[]; + void audio_driver_register(audio_driver *drv); audio_driver *audio_driver_lookup(const char *name); @@ -248,4 +252,18 @@ static inline int audio_ring_dist (int dst, int src, int len) #define AUDIO_STRINGIFY_(n) #n #define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n) +typedef struct AudiodevListEntry { +Audiodev *dev; +QSIMPLEQ_ENTRY(AudiodevListEntry) next; +} AudiodevListEntry; + +typedef QSIMPLEQ_HEAD(, AudiodevListEntry) AudiodevListHead; +AudiodevListHead audio_handle_legacy_opts(void); + +void audio_free_audiodev_list(AudiodevListHead *head); + +void audio_create_pdos(Audiodev *dev); +AudiodevPerDirectionOptions *audio_get_pdo_in(Audiodev *dev); +AudiodevPerDirectionOptions