[Qemu-devel] gsoc idea

2015-03-07 Thread Kővágó Zoltán

hi,

i'm thinking about doing a gsoc this year, and i'm interested if you 
have any opinions on my idea. (i hope i'm not late for this...)


currently the audio system in qemu is limited to 2 channels (stereo) 
sound. also it mixes all sound (if there's more than one sound card) 
into a single stream, you can't send them to different physical sound 
cards for example. if you need something like that, you'll have to 
either pass-through a sound card (but then you can't use it from the 
host), or use pulseaudio/jack/etc to send the audio over the network 
(which is problematic in case of a windows guest)


imho the audio subsystem should be rewritten to support any number of 
audio channels. also, the current global mix everything together into a 
single output method (along with it's environment variable based 
configuration, since it only allows global options, not per-device) 
should be replaced, with a system similar to how network or drives works 
(i.e. each virtual sound card would be connected to an audio device, 
with their own options)


is it a viable idea, or i should scrap it altogether?



[Qemu-devel] Removing old/unused audio backends

2015-05-20 Thread Kővágó Zoltán

Hi,

I'll be doing doing gsoc this year, where I'll rework the audio backend 
of qemu to allow multiple backend instances and multichannel audio. 
This will of course require modifications of the existing audio drivers 
in qemu, so it's probably a good idea to remove drivers that nobody use 
anymore (and probably bug rotten anyway).


Here are the drivers that could go in my opinion:
esd: no longer maintained, last release in 2008, replaced by PulseAudio
fmod: not sure about this one, but apparently it's some no longer 
developed library that's also proprietary.
sdl: is broken 
(http://lists.nongnu.org/archive/html/qemu-devel/2015-05/msg02198.html), 
and we have native drivers for almost all platforms
winwave: DirectSound should be a superior choice on windows (even though 
it's also deprecated)


alsa needed on Linux, oss on BSDs, coreaudio on Mac, dsound on Windows; 
spice and pa are also needed.  wav is probably useful for debugging.


Do you guys have any objections about removing the above mentioned audio 
drivers in the near future?


Thanks,
Zoltan



Re: [Qemu-devel] [PATCH v2 00/12] Audio backend cleanup

2015-06-03 Thread Kővágó Zoltán

2015-06-03 21:08 keltezéssel, Peter Maydell írta:

On 3 June 2015 at 12:44, Peter Maydell peter.mayd...@linaro.org wrote:

On 3 June 2015 at 12:37, Gerd Hoffmann kra...@redhat.com wrote:

Any takers to verify coreaudio changes?
Alex?  Peter?


I can have a go but it may take me a while to get to.


...if you have a simple working test image that produces sound
that would help, so I'm not trying to mess around configuring
audio in the guest. Something which isn't full-fat modern
OS config would be good, ie something which will run OK in
TCG emulation.


I've used day24 from the Qemu advent calendar for some tests, it's 
pretty minimal.

http://www.qemu-advent-calendar.org/

Thanks,
Zoltan



[Qemu-devel] [PATCH v3 04/12] audio: expose drv_opaque to init_out and init_in

2015-06-03 Thread Kővágó, Zoltán
Currently the opaque pointer returned by audio_driver's init is only
exposed to the driver's fini, but not to audio_pcm_ops. This way if
someone wants to share a variable with the driver and the pcm, he must
use global variables. This patch fixes it by adding a third parameter to
audio_pcm_op's init_out and init_in.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c   | 5 +++--
 audio/audio_int.h   | 4 ++--
 audio/audio_template.h  | 2 +-
 audio/coreaudio.c   | 3 ++-
 audio/dsound_template.h | 6 --
 audio/noaudio.c | 4 ++--
 audio/ossaudio.c| 5 +++--
 audio/paaudio.c | 5 +++--
 audio/sdlaudio.c| 3 ++-
 audio/spiceaudio.c  | 5 +++--
 audio/wavaudio.c| 5 ++---
 11 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 74ead97..87e71c6 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -819,7 +819,8 @@ static void alsa_fini_out (HWVoiceOut *hw)
 alsa-pcm_buf = NULL;
 }
 
-static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
+ void *drv_opaque)
 {
 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 struct alsa_params_req req;
@@ -928,7 +929,7 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return -1;
 }
 
-static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void 
*drv_opaque)
 {
 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 struct alsa_params_req req;
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 0eba44f..566df5e 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -156,13 +156,13 @@ struct audio_driver {
 };
 
 struct audio_pcm_ops {
-int  (*init_out)(HWVoiceOut *hw, struct audsettings *as);
+int  (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_out)(HWVoiceOut *hw);
 int  (*run_out) (HWVoiceOut *hw, int live);
 int  (*write)   (SWVoiceOut *sw, void *buf, int size);
 int  (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
 
-int  (*init_in) (HWVoiceIn *hw, struct audsettings *as);
+int  (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_in) (HWVoiceIn *hw);
 int  (*run_in)  (HWVoiceIn *hw);
 int  (*read)(SWVoiceIn *sw, void *buf, int size);
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 584e536..f716d97 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -262,7 +262,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct 
audsettings *as)
 #ifdef DAC
 QLIST_INIT (hw-cap_head);
 #endif
-if (glue (hw-pcm_ops-init_, TYPE) (hw, as)) {
+if (glue (hw-pcm_ops-init_, TYPE) (hw, as, s-drv_opaque)) {
 goto err0;
 }
 
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 5964c62..20346bc 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -287,7 +287,8 @@ static int coreaudio_write (SWVoiceOut *sw, void *buf, int 
len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
+  void *drv_opaque)
 {
 OSStatus status;
 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 8b37d16..98276fb 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -174,9 +174,11 @@ static void dsound_fini_out (HWVoiceOut *hw)
 }
 
 #ifdef DSBTYPE_IN
-static int dsound_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
+  void *drv_opaque)
 #else
-static int dsound_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
+   void *drv_opaque)
 #endif
 {
 int err;
diff --git a/audio/noaudio.c b/audio/noaudio.c
index cb38662..50db1f3 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -63,7 +63,7 @@ static int no_write (SWVoiceOut *sw, void *buf, int len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int no_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void 
*drv_opaque)
 {
 audio_pcm_init_info (hw-info, as);
 hw-samples = 1024;
@@ -82,7 +82,7 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return 0;
 }
 
-static int no_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
 {
 audio_pcm_init_info (hw-info, as);
 hw-samples = 1024;
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 4db2ca6..069ff60 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -510,7 +510,8 @@ static void oss_fini_out

[Qemu-devel] [PATCH v3 06/12] paaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/paaudio.c | 98 ++---
 1 file changed, 52 insertions(+), 46 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index bdf6cd5..35e8887 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -9,6 +9,19 @@
 #include audio_pt_int.h
 
 typedef struct {
+int samples;
+char *server;
+char *sink;
+char *source;
+} PAConf;
+
+typedef struct {
+PAConf conf;
+pa_threaded_mainloop *mainloop;
+pa_context *context;
+} paaudio;
+
+typedef struct {
 HWVoiceOut hw;
 int done;
 int live;
@@ -17,6 +30,7 @@ typedef struct {
 pa_stream *stream;
 void *pcm_buf;
 struct audio_pt pt;
+paaudio *g;
 } PAVoiceOut;
 
 typedef struct {
@@ -30,21 +44,9 @@ typedef struct {
 struct audio_pt pt;
 const void *read_data;
 size_t read_index, read_length;
+paaudio *g;
 } PAVoiceIn;
 
-typedef struct {
-int samples;
-char *server;
-char *sink;
-char *source;
-pa_threaded_mainloop *mainloop;
-pa_context *context;
-} paaudio;
-
-static paaudio glob_paaudio = {
-.samples = 4096,
-};
-
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
 va_list ap;
@@ -106,7 +108,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
 
 static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int 
*rerror)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = p-g;
 
 pa_threaded_mainloop_lock (g-mainloop);
 
@@ -160,7 +162,7 @@ unlock_and_fail:
 
 static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, 
int *rerror)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = p-g;
 
 pa_threaded_mainloop_lock (g-mainloop);
 
@@ -222,7 +224,7 @@ static void *qpa_thread_out (void *arg)
 }
 }
 
-decr = to_mix = audio_MIN (pa-live, glob_paaudio.samples  2);
+decr = to_mix = audio_MIN (pa-live, pa-g-conf.samples  2);
 rpos = pa-rpos;
 
 if (audio_pt_unlock (pa-pt, AUDIO_FUNC)) {
@@ -314,7 +316,7 @@ static void *qpa_thread_in (void *arg)
 }
 }
 
-incr = to_grab = audio_MIN (pa-dead, glob_paaudio.samples  2);
+incr = to_grab = audio_MIN (pa-dead, pa-g-conf.samples  2);
 wpos = pa-wpos;
 
 if (audio_pt_unlock (pa-pt, AUDIO_FUNC)) {
@@ -430,7 +432,7 @@ static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int 
*endianness)
 
 static void context_state_cb (pa_context *c, void *userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 switch (pa_context_get_state(c)) {
 case PA_CONTEXT_READY:
@@ -449,7 +451,7 @@ static void context_state_cb (pa_context *c, void *userdata)
 
 static void stream_state_cb (pa_stream *s, void * userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 switch (pa_stream_get_state (s)) {
 
@@ -467,23 +469,21 @@ static void stream_state_cb (pa_stream *s, void * 
userdata)
 
 static void stream_request_cb (pa_stream *s, size_t length, void *userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 pa_threaded_mainloop_signal (g-mainloop, 0);
 }
 
 static pa_stream *qpa_simple_new (
-const char *server,
+paaudio *g,
 const char *name,
 pa_stream_direction_t dir,
 const char *dev,
-const char *stream_name,
 const pa_sample_spec *ss,
 const pa_channel_map *map,
 const pa_buffer_attr *attr,
 int *rerror)
 {
-paaudio *g = glob_paaudio;
 int r;
 pa_stream *stream;
 
@@ -538,10 +538,11 @@ static int qpa_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 void *drv_opaque)
 {
 int error;
-static pa_sample_spec ss;
-static pa_buffer_attr ba;
+pa_sample_spec ss;
+pa_buffer_attr ba;
 struct audsettings obt_as = *as;
 PAVoiceOut *pa = (PAVoiceOut *) hw;
+paaudio *g = pa-g = drv_opaque;
 
 ss.format = audfmt_to_pa (as-fmt, as-endianness);
 ss.channels = as-nchannels;
@@ -559,11 +560,10 @@ static int qpa_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 obt_as.fmt = pa_to_audfmt (ss.format, obt_as.endianness);
 
 pa-stream = qpa_simple_new (
-glob_paaudio.server,
+g,
 qemu,
 PA_STREAM_PLAYBACK,
-glob_paaudio.sink,
-pcm.playback,
+g-conf.sink,
 ss,
 NULL,   /* channel map */
 ba,/* buffering attributes */
@@ -575,7 +575,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 }
 
 audio_pcm_init_info (hw-info, obt_as);
-hw-samples = glob_paaudio.samples;
+hw-samples = g-conf.samples;
 pa-pcm_buf = audio_calloc (AUDIO_FUNC, hw-samples, 1  hw-info.shift);
 pa-rpos = hw-rpos;
 if (!pa-pcm_buf) {
@@ -605,9 +605,10 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 static

[Qemu-devel] [PATCH v3 00/12] Audio backend cleanup

2015-06-03 Thread Kővágó, Zoltán
This series of patch removes the following audio backends:
esd, fmod, winwave.

It also cleans up the remaining drivers to do not use global variables where
possible. This is a preparation for my GSoC project where I will enable multiple
simultaneous audio backends.

Please also test the coreaudio backend, as I do not have a Mac to test it.

Patches are also available at https://github.com/DirtYiCE/qemu.git in tag
audio-cleanup-v3 to simplify testing.

Changes since v1:
* sdl no longer removed
* fixed style issues in `audio: expose drv_opaque to init_out and init_in'

Changes since v2:
* fixed typo in coreaudio

Please review.

Kővágó, Zoltán (12):
  audio: remove esd backend
  audio: remove fmod backend
  audio: remove winwave audio driver
  audio: expose drv_opaque to init_out and init_in
  alsaaudio: do not use global variables
  paaudio: do not use global variables
  ossaudio: do not use global variables
  wavaudio: do not use global variables
  dsoundaudio: do not use global variables
  paaudio: fix possible resource leak
  coreaudio: do not use global variables where possible
  sdlaudio: do not allow multiple instances

 audio/Makefile.objs |   4 -
 audio/alsaaudio.c   | 165 ++-
 audio/audio_int.h   |   7 +-
 audio/audio_template.h  |   2 +-
 audio/coreaudio.c   |  46 ++--
 audio/dsound_template.h |  24 +-
 audio/dsoundaudio.c | 106 ---
 audio/esdaudio.c| 557 -
 audio/fmodaudio.c   | 685 -
 audio/noaudio.c |   4 +-
 audio/ossaudio.c| 115 
 audio/paaudio.c | 105 +++
 audio/sdlaudio.c|  10 +-
 audio/spiceaudio.c  |   5 +-
 audio/wavaudio.c|  42 +--
 audio/winwaveaudio.c| 717 
 configure   |  56 +---
 17 files changed, 367 insertions(+), 2283 deletions(-)
 delete mode 100644 audio/esdaudio.c
 delete mode 100644 audio/fmodaudio.c
 delete mode 100644 audio/winwaveaudio.c

-- 
2.4.2




[Qemu-devel] [PATCH v3 12/12] sdlaudio: do not allow multiple instances

2015-06-03 Thread Kővágó, Zoltán
Since SDL uses a lot of global data, we can't create independent
instances of sdl audio backend.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/sdlaudio.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index b95a7e0..1140f2e 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -55,6 +55,7 @@ static struct SDLAudioState {
 SDL_mutex *mutex;
 SDL_sem *sem;
 int initialized;
+bool driver_created;
 } glob_sdl;
 typedef struct SDLAudioState SDLAudioState;
 
@@ -393,6 +394,10 @@ static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
 static void *sdl_audio_init (void)
 {
 SDLAudioState *s = glob_sdl;
+if (s-driver_created) {
+sdl_logerr(Can't create multiple sdl backends\n);
+return NULL;
+}
 
 if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
 sdl_logerr (SDL failed to initialize audio subsystem\n);
@@ -414,6 +419,7 @@ static void *sdl_audio_init (void)
 return NULL;
 }
 
+s-driver_created = true;
 return s;
 }
 
@@ -424,6 +430,7 @@ static void sdl_audio_fini (void *opaque)
 SDL_DestroySemaphore (s-sem);
 SDL_DestroyMutex (s-mutex);
 SDL_QuitSubSystem (SDL_INIT_AUDIO);
+s-driver_created = false;
 }
 
 static struct audio_option sdl_options[] = {
-- 
2.4.2




[Qemu-devel] [PATCH v3 02/12] audio: remove fmod backend

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   2 -
 audio/audio_int.h   |   1 -
 audio/fmodaudio.c   | 685 
 configure   |  27 +--
 4 files changed, 2 insertions(+), 713 deletions(-)
 delete mode 100644 audio/fmodaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 5573ac1..b4c0608 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -5,12 +5,10 @@ common-obj-$(CONFIG_SPICE) += spiceaudio.o
 common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
-common-obj-$(CONFIG_FMOD) += fmodaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
 common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
 
-$(obj)/audio.o $(obj)/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
 sdlaudio.o-cflags := $(SDL_CFLAGS)
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 9dd6b7f..7445602 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -206,7 +206,6 @@ extern struct audio_driver no_audio_driver;
 extern struct audio_driver oss_audio_driver;
 extern struct audio_driver sdl_audio_driver;
 extern struct audio_driver wav_audio_driver;
-extern struct audio_driver fmod_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c
deleted file mode 100644
index fabf84d..000
--- a/audio/fmodaudio.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * QEMU FMOD audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include fmod.h
-#include fmod_errors.h
-#include qemu-common.h
-#include audio.h
-
-#define AUDIO_CAP fmod
-#include audio_int.h
-
-typedef struct FMODVoiceOut {
-HWVoiceOut hw;
-unsigned int old_pos;
-FSOUND_SAMPLE *fmod_sample;
-int channel;
-} FMODVoiceOut;
-
-typedef struct FMODVoiceIn {
-HWVoiceIn hw;
-FSOUND_SAMPLE *fmod_sample;
-} FMODVoiceIn;
-
-static struct {
-const char *drvname;
-int nb_samples;
-int freq;
-int nb_channels;
-int bufsize;
-int broken_adc;
-} conf = {
-.nb_samples  = 2048 * 2,
-.freq= 44100,
-.nb_channels = 2,
-};
-
-static void GCC_FMT_ATTR (1, 2) fmod_logerr (const char *fmt, ...)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n,
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
-const char *typ,
-const char *fmt,
-...
-)
-{
-va_list ap;
-
-AUD_log (AUDIO_CAP, Could not initialize %s\n, typ);
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n,
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static int fmod_write (SWVoiceOut *sw, void *buf, int len)
-{
-return audio_pcm_sw_write (sw, buf, len);
-}
-
-static void fmod_clear_sample (FMODVoiceOut *fmd)
-{
-HWVoiceOut *hw = fmd-hw;
-int status;
-void *p1 = 0, *p2 = 0;
-unsigned int len1 = 0, len2 = 0;
-
-status = FSOUND_Sample_Lock (
-fmd-fmod_sample,
-0,
-hw-samples  hw-info.shift,
-p1,
-p2,
-len1,
-len2
-);
-
-if (!status) {
-fmod_logerr (Failed to lock sample\n);
-return;
-}
-
-if ((len1  hw-info.align) || (len2  hw-info.align)) {
-dolog (Lock returned misaligned length %d, %d, alignment %d\n,
-   len1, len2, hw-info.align + 1);
-goto fail;
-}
-
-if ((len1 + len2) - (hw-samples  hw-info.shift)) {
-dolog (Lock returned

[Qemu-devel] [PATCH v3 07/12] ossaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/ossaudio.c | 110 ++-
 1 file changed, 61 insertions(+), 49 deletions(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 069ff60..d247969 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -38,6 +38,17 @@
 #define USE_DSP_POLICY
 #endif
 
+typedef struct OSSConf {
+int try_mmap;
+int nfrags;
+int fragsize;
+const char *devpath_out;
+const char *devpath_in;
+int debug;
+int exclusive;
+int policy;
+} OSSConf;
+
 typedef struct OSSVoiceOut {
 HWVoiceOut hw;
 void *pcm_buf;
@@ -47,6 +58,7 @@ typedef struct OSSVoiceOut {
 int fragsize;
 int mmapped;
 int pending;
+OSSConf *conf;
 } OSSVoiceOut;
 
 typedef struct OSSVoiceIn {
@@ -55,28 +67,9 @@ typedef struct OSSVoiceIn {
 int fd;
 int nfrags;
 int fragsize;
+OSSConf *conf;
 } OSSVoiceIn;
 
-static struct {
-int try_mmap;
-int nfrags;
-int fragsize;
-const char *devpath_out;
-const char *devpath_in;
-int debug;
-int exclusive;
-int policy;
-} conf = {
-.try_mmap = 0,
-.nfrags = 4,
-.fragsize = 4096,
-.devpath_out = /dev/dsp,
-.devpath_in = /dev/dsp,
-.debug = 0,
-.exclusive = 0,
-.policy = 5
-};
-
 struct oss_params {
 int freq;
 audfmt_e fmt;
@@ -272,18 +265,18 @@ static int oss_get_version (int fd, int *version, const 
char *typ)
 #endif
 
 static int oss_open (int in, struct oss_params *req,
- struct oss_params *obt, int *pfd)
+ struct oss_params *obt, int *pfd, OSSConf* conf)
 {
 int fd;
-int oflags = conf.exclusive ? O_EXCL : 0;
+int oflags = conf-exclusive ? O_EXCL : 0;
 audio_buf_info abinfo;
 int fmt, freq, nchannels;
 int setfragment = 1;
-const char *dspname = in ? conf.devpath_in : conf.devpath_out;
+const char *dspname = in ? conf-devpath_in : conf-devpath_out;
 const char *typ = in ? ADC : DAC;
 
 /* Kludge needed to have working mmap on Linux */
-oflags |= conf.try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
+oflags |= conf-try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
 
 fd = open (dspname, oflags | O_NONBLOCK);
 if (-1 == fd) {
@@ -317,20 +310,20 @@ static int oss_open (int in, struct oss_params *req,
 }
 
 #ifdef USE_DSP_POLICY
-if (conf.policy = 0) {
+if (conf-policy = 0) {
 int version;
 
 if (!oss_get_version (fd, version, typ)) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (OSS version = %#x\n, version);
 }
 
 if (version = 0x04) {
-int policy = conf.policy;
+int policy = conf-policy;
 if (ioctl (fd, SNDCTL_DSP_POLICY, policy)) {
 oss_logerr2 (errno, typ,
  Failed to set timing policy to %d\n,
- conf.policy);
+ conf-policy);
 goto err;
 }
 setfragment = 0;
@@ -434,6 +427,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 struct audio_buf_info abinfo;
 struct count_info cntinfo;
 int bufsize;
+OSSConf *conf = oss-conf;
 
 bufsize = hw-samples  hw-info.shift;
 
@@ -458,7 +452,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 }
 
 if (abinfo.bytes  bufsize) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (warning: Invalid available size, size=%d bufsize=%d\n
please report your OS/audio hw to av1...@comtv.ru\n,
abinfo.bytes, bufsize);
@@ -467,7 +461,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 }
 
 if (abinfo.bytes  0) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (warning: Invalid available size, size=%d bufsize=%d\n,
abinfo.bytes, bufsize);
 }
@@ -520,16 +514,17 @@ static int oss_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 int fd;
 audfmt_e effective_fmt;
 struct audsettings obt_as;
+OSSConf *conf = drv_opaque;
 
 oss-fd = -1;
 
 req.fmt = aud_to_ossfmt (as-fmt, as-endianness);
 req.freq = as-freq;
 req.nchannels = as-nchannels;
-req.fragsize = conf.fragsize;
-req.nfrags = conf.nfrags;
+req.fragsize = conf-fragsize;
+req.nfrags = conf-nfrags;
 
-if (oss_open (0, req, obt, fd)) {
+if (oss_open (0, req, obt, fd, conf)) {
 return -1;
 }
 
@@ -556,7 +551,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 hw-samples = (obt.nfrags * obt.fragsize)  hw-info.shift;
 
 oss-mmapped = 0;
-if (conf.try_mmap) {
+if (conf-try_mmap) {
 oss-pcm_buf = mmap (
 NULL,
 hw-samples  hw-info.shift,
@@ -616,6 +611,7

[Qemu-devel] [PATCH v3 10/12] paaudio: fix possible resource leak

2015-06-03 Thread Kővágó, Zoltán
qpa_audio_init did not clean up resources properly if the initialization
failed. This hopefully fixes it.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/paaudio.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 35e8887..fea6071 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -47,6 +47,8 @@ typedef struct {
 paaudio *g;
 } PAVoiceIn;
 
+static void qpa_audio_fini(void *opaque);
+
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
 va_list ap;
@@ -814,6 +816,8 @@ static void *qpa_audio_init (void)
 {
 paaudio *g = g_malloc(sizeof(paaudio));
 g-conf = glob_conf;
+g-mainloop = NULL;
+g-context = NULL;
 
 g-mainloop = pa_threaded_mainloop_new ();
 if (!g-mainloop) {
@@ -867,7 +871,7 @@ unlock_and_fail:
 pa_threaded_mainloop_unlock (g-mainloop);
 fail:
 AUD_log (AUDIO_CAP, Failed to initialize PA context);
-g_free(g);
+qpa_audio_fini(g);
 return NULL;
 }
 
-- 
2.4.2




Re: [Qemu-devel] [RFC PATCH] qapi for audio backends

2015-06-03 Thread Kővágó Zoltán

2015-06-03 21:17 keltezéssel, Eric Blake írta:

On 06/03/2015 10:48 AM, Kővágó, Zoltán wrote:

This is a proposal to add structures into qapi-schema.json to replace the
existing configuration structures used by audio backends currently. I'm going to
use it to implement a new way to specify audio backend options (an -audiodev
command line option, instead of environment variables. This will also allow us
to use multiple audio backends in one qemu instance), so the structure used here
will be the basis of the command line syntax.

This is currently more or less a direct translation of the current audio backend
options. I've changed some names, trying to accomplish a more consistent naming
scheme. I wouldn't be surprised if there were options that doesn't work if you
set their value to anything other than the default (for example, log to monitor
can crash qemu, QEMU_DSOUND_RESTOURE_RETRIES has a typo, so probably nobody used
it, etc). I've also tried to reduce copy-paste, when the same set of options can
be given to output and input (QEMU_*_DAC_* and QEMU_*_ADC_* options), also using
in and out instead of ADC and DAC, as in the world of SPDIF and HDMI it's
completely possible that your computer has nothing to do with analog converters.
Plus a non technician user probably has no idea what ADC and DAC stands for.

Any comment is appreciated.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
  qapi-schema.json | 330 +++
  1 file changed, 330 insertions(+)

diff --git a/qapi-schema.json b/qapi-schema.json
index 0662a9b..ff67d5a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3769,3 +3769,333 @@
  # Since: 2.1
  ##
  { 'command': 'rtc-reset-reinjection' }
+
+##
+# @AudiodevNoneOptions
+#
+# The dummy audio backend has no options.
+#
+# Since: XXX


It's okay to tentatively put 2.4 here, if you are aiming for 2.4.  If
you think it will be a big enough project to miss the current release
window, put 2.5.


+##
+{ 'struct': 'AudiodevNoneOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use.
+#
+# @period_size_usec: #optional the period size in microseconds. Must not be
+#specified with @period_size_frames.
+#
+# @period_size_frames: #optional the period size in frames. Must not be
+#  specified with @period_size_usec.
+#
+# @buffer_size_usec: #optional the buffer size in microseconds. Must not be
+#specified with @buffer_size_frames.
+#
+# @buffer_size_frames: #optional the buffer size in frames. Must not be
+#  specified with @buffer_size_usec.


Can we name these with s/_/-/?  We've documented that QMP prefers dash
unless there is compelling reason or consistency to worry about, and I
don't see the compelling reason here.


There's no particular reason other than when I looked through 
qapi-schema.json I've mostly seen underscores. Will fix this.





+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data': {
+'*dev':'str',
+'*period_size_usec':   'int',
+'*period_size_frames': 'int',
+'*buffer_size_usec':   'int',
+'*buffer_size_frames': 'int' } }
+
+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @in: #optional options of the capture stream.
+#
+# @out: #optional options of the playback stream.
+#
+# @threshold: #optional


Document this.


This (and some other option) currently only has the documentation 
(undocumented), but I will try to figure out what they do...





+#
+# @verbose: #optional behave in a more verbose way
+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevAlsaOptions',
+  'data': {
+'*in':  'AudiodevAlsaPerDirectionOptions',
+'*out': 'AudiodevAlsaPerDirectionOptions',
+'*threshold': 'int',
+'*verbose':   'bool' } }
+
+##
+# @AudiodevCoreaudioOptions
+#
+# Options of the coreaudio backend.
+#
+# @buffer_size: #optional size of the buffer in frames
+#
+# @buffer_count: #optional number of buffers


Again, dashes would be nicer, if there is no compelling reason otherwise
(I'll quit repeating it).


+#
+# Since: XXX


(and I'll quit pointing out XXX in Since lines)


+##
+{ 'struct': 'AudiodevCoreaudioOptions',
+  'data': {
+'*buffer_size':  'int',
+'*buffer_count': 'int' } }
+
+##
+# @AudiodevDsoundPerDirectionOptions
+#
+# Options of the dsound backend that are used for both playback and recording.
+#
+# @bufsize: #optional


Document this


+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevDsoundPerDirectionOptions',
+  'data' : {
+'*bufsize': 'int' } }
+
+##
+# @AudiodevDsoundOptions
+#
+# Options of the dsound audio backend.
+#
+# @in: #optional options of the capture stream.
+#
+# @out: #optional options of the playback stream.
+#
+# @lock_retries: #optional number of times to attempt locking

[Qemu-devel] [PATCH v3 08/12] wavaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/wavaudio.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 09083da..c586020 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -36,15 +36,10 @@ typedef struct WAVVoiceOut {
 int total_samples;
 } WAVVoiceOut;
 
-static struct {
+typedef struct {
 struct audsettings settings;
 const char *wav_path;
-} conf = {
-.settings.freq  = 44100,
-.settings.nchannels = 2,
-.settings.fmt   = AUD_FMT_S16,
-.wav_path   = qemu.wav
-};
+} WAVConf;
 
 static int wav_run_out (HWVoiceOut *hw, int live)
 {
@@ -116,7 +111,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
 };
-struct audsettings wav_as = conf.settings;
+WAVConf *conf = drv_opaque;
+struct audsettings wav_as = conf-settings;
 
 stereo = wav_as.nchannels == 2;
 switch (wav_as.fmt) {
@@ -154,10 +150,10 @@ static int wav_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 le_store (hdr + 28, hw-info.freq  (bits16 + stereo), 4);
 le_store (hdr + 32, 1  (bits16 + stereo), 2);
 
-wav-f = fopen (conf.wav_path, wb);
+wav-f = fopen (conf-wav_path, wb);
 if (!wav-f) {
 dolog (Failed to open wave file `%s'\nReason: %s\n,
-   conf.wav_path, strerror (errno));
+   conf-wav_path, strerror (errno));
 g_free (wav-pcm_buf);
 wav-pcm_buf = NULL;
 return -1;
@@ -225,40 +221,49 @@ static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return 0;
 }
 
+static WAVConf glob_conf = {
+.settings.freq  = 44100,
+.settings.nchannels = 2,
+.settings.fmt   = AUD_FMT_S16,
+.wav_path   = qemu.wav
+};
+
 static void *wav_audio_init (void)
 {
-return conf;
+WAVConf *conf = g_malloc(sizeof(WAVConf));
+*conf = glob_conf;
+return conf;
 }
 
 static void wav_audio_fini (void *opaque)
 {
-(void) opaque;
 ldebug (wav_fini);
+g_free(opaque);
 }
 
 static struct audio_option wav_options[] = {
 {
 .name  = FREQUENCY,
 .tag   = AUD_OPT_INT,
-.valp  = conf.settings.freq,
+.valp  = glob_conf.settings.freq,
 .descr = Frequency
 },
 {
 .name  = FORMAT,
 .tag   = AUD_OPT_FMT,
-.valp  = conf.settings.fmt,
+.valp  = glob_conf.settings.fmt,
 .descr = Format
 },
 {
 .name  = DAC_FIXED_CHANNELS,
 .tag   = AUD_OPT_INT,
-.valp  = conf.settings.nchannels,
+.valp  = glob_conf.settings.nchannels,
 .descr = Number of channels (1 - mono, 2 - stereo)
 },
 {
 .name  = PATH,
 .tag   = AUD_OPT_STR,
-.valp  = conf.wav_path,
+.valp  = glob_conf.wav_path,
 .descr = Path to wave file
 },
 { /* End of list */ }
-- 
2.4.2




Re: [Qemu-devel] [PATCH v2 11/12] coreaudio: do not use global variables where possible

2015-06-03 Thread Kővágó Zoltán

2015-06-03 21:19 keltezéssel, Peter Maydell írta:

On 3 June 2015 at 11:49, Kővágó, Zoltán dirty.ice...@gmail.com wrote:

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
  audio/coreaudio.c | 43 ---
  1 file changed, 24 insertions(+), 19 deletions(-)



+static CoreaudioConf glob_conf = {
+.buffer_frames = 512,
+.nbuffers = 4,
+};
+
  static void *coreaudio_audio_init (void)
  {
+CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
+*conf = glob_conf;
+
  atexit(coreaudio_atexit);
-return coreaudio_audio_init;
+return conf;
  }

  static void coreaudio_audio_fini (void *opaque)
  {
-(void) opaque;
+g_free(opaque);
  }

  static struct audio_option coreaudio_options[] = {
  {
  .name  = BUFFER_SIZE,
  .tag   = AUD_OPT_INT,
-.valp  = conf.buffer_frames,
+.valp  = glob_conf.buffer_frames,
  .descr = Size of the buffer in frames
  },
  {
  .name  = BUFFER_COUNT,
  .tag   = AUD_OPT_INT,
-.valp  = conf.nbuffers,
+.valp  = glostconf.nbuffers,
  .descr = Number of buffers
  },


/Users/pm215/src/qemu/audio/coreaudio.c:529:19: error: use of
undeclared identifier 'glostconf'; did you mean 'glob_conf'?
 .valp  = glostconf.nbuffers,
   ^
   glob_conf
/Users/pm215/src/qemu/audio/coreaudio.c:500:22: note: 'glob_conf' declared here
static CoreaudioConf glob_conf = {
  ^
10 warnings and 1 error generated.


crap, i should used search  replace... does it work with glob_conf or 
there are other problems?


Thanks,
Zoltan




[Qemu-devel] [PATCH v3 11/12] coreaudio: do not use global variables where possible

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/coreaudio.c | 43 ---
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 20346bc..6dfd63e 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -32,20 +32,16 @@
 #define AUDIO_CAP coreaudio
 #include audio_int.h
 
-struct {
+static int isAtexit;
+
+typedef struct {
 int buffer_frames;
 int nbuffers;
-int isAtexit;
-} conf = {
-.buffer_frames = 512,
-.nbuffers = 4,
-.isAtexit = 0
-};
+} CoreaudioConf;
 
 typedef struct coreaudioVoiceOut {
 HWVoiceOut hw;
 pthread_mutex_t mutex;
-int isAtexit;
 AudioDeviceID outputDeviceID;
 UInt32 audioDevicePropertyBufferFrameSize;
 AudioStreamBasicDescription outputStreamBasicDescription;
@@ -161,7 +157,7 @@ static inline UInt32 isPlaying (AudioDeviceID 
outputDeviceID)
 
 static void coreaudio_atexit (void)
 {
-conf.isAtexit = 1;
+isAtexit = 1;
 }
 
 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
@@ -296,6 +292,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 int err;
 const char *typ = playback;
 AudioValueRange frameRange;
+CoreaudioConf *conf = drv_opaque;
 
 /* create mutex */
 err = pthread_mutex_init(core-mutex, NULL);
@@ -337,16 +334,16 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 return -1;
 }
 
-if (frameRange.mMinimum  conf.buffer_frames) {
+if (frameRange.mMinimum  conf-buffer_frames) {
 core-audioDevicePropertyBufferFrameSize = (UInt32) 
frameRange.mMinimum;
 dolog (warning: Upsizing Buffer Frames to %f\n, frameRange.mMinimum);
 }
-else if (frameRange.mMaximum  conf.buffer_frames) {
+else if (frameRange.mMaximum  conf-buffer_frames) {
 core-audioDevicePropertyBufferFrameSize = (UInt32) 
frameRange.mMaximum;
 dolog (warning: Downsizing Buffer Frames to %f\n, 
frameRange.mMaximum);
 }
 else {
-core-audioDevicePropertyBufferFrameSize = conf.buffer_frames;
+core-audioDevicePropertyBufferFrameSize = conf-buffer_frames;
 }
 
 /* set Buffer Frame Size */
@@ -380,7 +377,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
Could not get device buffer frame size\n);
 return -1;
 }
-hw-samples = conf.nbuffers * core-audioDevicePropertyBufferFrameSize;
+hw-samples = conf-nbuffers * core-audioDevicePropertyBufferFrameSize;
 
 /* get StreamFormat */
 propertySize = sizeof(core-outputStreamBasicDescription);
@@ -444,7 +441,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
 int err;
 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
 
-if (!conf.isAtexit) {
+if (!isAtexit) {
 /* stop playback */
 if (isPlaying(core-outputDeviceID)) {
 status = AudioDeviceStop(core-outputDeviceID, audioDeviceIOProc);
@@ -487,7 +484,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
 case VOICE_DISABLE:
 /* stop playback */
-if (!conf.isAtexit) {
+if (!isAtexit) {
 if (isPlaying(core-outputDeviceID)) {
 status = AudioDeviceStop(core-outputDeviceID, 
audioDeviceIOProc);
 if (status != kAudioHardwareNoError) {
@@ -500,28 +497,36 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, 
...)
 return 0;
 }
 
+static CoreaudioConf glob_conf = {
+.buffer_frames = 512,
+.nbuffers = 4,
+};
+
 static void *coreaudio_audio_init (void)
 {
+CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
+*conf = glob_conf;
+
 atexit(coreaudio_atexit);
-return coreaudio_audio_init;
+return conf;
 }
 
 static void coreaudio_audio_fini (void *opaque)
 {
-(void) opaque;
+g_free(opaque);
 }
 
 static struct audio_option coreaudio_options[] = {
 {
 .name  = BUFFER_SIZE,
 .tag   = AUD_OPT_INT,
-.valp  = conf.buffer_frames,
+.valp  = glob_conf.buffer_frames,
 .descr = Size of the buffer in frames
 },
 {
 .name  = BUFFER_COUNT,
 .tag   = AUD_OPT_INT,
-.valp  = conf.nbuffers,
+.valp  = glob_conf.nbuffers,
 .descr = Number of buffers
 },
 { /* End of list */ }
-- 
2.4.2




[Qemu-devel] [PATCH v3 01/12] audio: remove esd backend

2015-06-03 Thread Kővágó, Zoltán
ESD is no longer developed and replaced by PulseAudio.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   1 -
 audio/audio_int.h   |   1 -
 audio/esdaudio.c| 557 
 configure   |  18 +-
 4 files changed, 6 insertions(+), 571 deletions(-)
 delete mode 100644 audio/esdaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 26a0ac9..5573ac1 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -6,7 +6,6 @@ common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
 common-obj-$(CONFIG_FMOD) += fmodaudio.o
-common-obj-$(CONFIG_ESD) += esdaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
 common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
diff --git a/audio/audio_int.h b/audio/audio_int.h
index fd019a0..9dd6b7f 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -210,7 +210,6 @@ extern struct audio_driver fmod_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
-extern struct audio_driver esd_audio_driver;
 extern struct audio_driver pa_audio_driver;
 extern struct audio_driver spice_audio_driver;
 extern struct audio_driver winwave_audio_driver;
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
deleted file mode 100644
index eea9cce..000
--- a/audio/esdaudio.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * QEMU ESD audio driver
- *
- * Copyright (c) 2006 Frederick Reeve (brushed up by malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include esd.h
-#include qemu-common.h
-#include audio.h
-
-#define AUDIO_CAP esd
-#include audio_int.h
-#include audio_pt_int.h
-
-typedef struct {
-HWVoiceOut hw;
-int done;
-int live;
-int decr;
-int rpos;
-void *pcm_buf;
-int fd;
-struct audio_pt pt;
-} ESDVoiceOut;
-
-typedef struct {
-HWVoiceIn hw;
-int done;
-int dead;
-int incr;
-int wpos;
-void *pcm_buf;
-int fd;
-struct audio_pt pt;
-} ESDVoiceIn;
-
-static struct {
-int samples;
-int divisor;
-char *dac_host;
-char *adc_host;
-} conf = {
-.samples = 1024,
-.divisor = 2,
-};
-
-static void GCC_FMT_ATTR (2, 3) qesd_logerr (int err, const char *fmt, ...)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n, strerror (err));
-}
-
-/* playback */
-static void *qesd_thread_out (void *arg)
-{
-ESDVoiceOut *esd = arg;
-HWVoiceOut *hw = esd-hw;
-int threshold;
-
-threshold = conf.divisor ? hw-samples / conf.divisor : 0;
-
-if (audio_pt_lock (esd-pt, AUDIO_FUNC)) {
-return NULL;
-}
-
-for (;;) {
-int decr, to_mix, rpos;
-
-for (;;) {
-if (esd-done) {
-goto exit;
-}
-
-if (esd-live  threshold) {
-break;
-}
-
-if (audio_pt_wait (esd-pt, AUDIO_FUNC)) {
-goto exit;
-}
-}
-
-decr = to_mix = esd-live;
-rpos = hw-rpos;
-
-if (audio_pt_unlock (esd-pt, AUDIO_FUNC)) {
-return NULL;
-}
-
-while (to_mix) {
-ssize_t written;
-int chunk = audio_MIN (to_mix, hw-samples - rpos);
-struct st_sample *src = hw-mix_buf + rpos;
-
-hw-clip (esd-pcm_buf, src, chunk);
-
-again:
-written = write (esd-fd, esd-pcm_buf, chunk  hw-info.shift);
-if (written == -1) {
-if (errno == EINTR || errno == EAGAIN) {
-goto again;
-}
-qesd_logerr (errno, write failed\n);
-return NULL;
-}
-
-if (written != chunk

[Qemu-devel] [PATCH v3 09/12] dsoundaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/dsound_template.h |  18 
 audio/dsoundaudio.c | 106 
 2 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 98276fb..85ba858 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -67,7 +67,8 @@ static int glue (dsound_lock_, TYPE) (
 LPVOID *p2p,
 DWORD *blen1p,
 DWORD *blen2p,
-int entire
+int entire,
+dsound *s
 )
 {
 HRESULT hr;
@@ -75,13 +76,14 @@ static int glue (dsound_lock_, TYPE) (
 LPVOID p1 = NULL, p2 = NULL;
 DWORD blen1 = 0, blen2 = 0;
 DWORD flag;
+DSoundConf *conf = s-conf;
 
 #ifdef DSBTYPE_IN
 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
 #else
 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
 #endif
-for (i = 0; i  conf.lock_retries; ++i) {
+for (i = 0; i  conf-lock_retries; ++i) {
 hr = glue (IFACE, _Lock) (
 buf,
 pos,
@@ -96,7 +98,7 @@ static int glue (dsound_lock_, TYPE) (
 if (FAILED (hr)) {
 #ifndef DSBTYPE_IN
 if (hr == DSERR_BUFFERLOST) {
-if (glue (dsound_restore_, TYPE) (buf)) {
+if (glue (dsound_restore_, TYPE) (buf, s)) {
 dsound_logerr (hr, Could not lock  NAME \n);
 goto fail;
 }
@@ -110,7 +112,7 @@ static int glue (dsound_lock_, TYPE) (
 break;
 }
 
-if (i == conf.lock_retries) {
+if (i == conf-lock_retries) {
 dolog (%d attempts to lock  NAME  failed\n, i);
 goto fail;
 }
@@ -183,9 +185,10 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 {
 int err;
 HRESULT hr;
-dsound *s = glob_dsound;
+dsound *s = drv_opaque;
 WAVEFORMATEX wfx;
 struct audsettings obt_as;
+DSoundConf *conf = s-conf;
 #ifdef DSBTYPE_IN
 const char *typ = ADC;
 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
@@ -212,7 +215,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 bd.dwSize = sizeof (bd);
 bd.lpwfxFormat = wfx;
 #ifdef DSBTYPE_IN
-bd.dwBufferBytes = conf.bufsize_in;
+bd.dwBufferBytes = conf-bufsize_in;
 hr = IDirectSoundCapture_CreateCaptureBuffer (
 s-dsound_capture,
 bd,
@@ -221,7 +224,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 );
 #else
 bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
-bd.dwBufferBytes = conf.bufsize_out;
+bd.dwBufferBytes = conf-bufsize_out;
 hr = IDirectSound_CreateSoundBuffer (
 s-dsound,
 bd,
@@ -271,6 +274,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 );
 }
 hw-samples = bc.dwBufferBytes  hw-info.shift;
+ds-s = s;
 
 #ifdef DEBUG_DSOUND
 dolog (caps %ld, desc %ld\n,
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index e2d89fd..c8b09e2 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -41,7 +41,7 @@
 
 /* #define DEBUG_DSOUND */
 
-static struct {
+typedef struct {
 int lock_retries;
 int restore_retries;
 int getstatus_retries;
@@ -50,33 +50,22 @@ static struct {
 int bufsize_out;
 struct audsettings settings;
 int latency_millis;
-} conf = {
-.lock_retries   = 1,
-.restore_retries= 1,
-.getstatus_retries  = 1,
-.set_primary= 0,
-.bufsize_in = 16384,
-.bufsize_out= 16384,
-.settings.freq  = 44100,
-.settings.nchannels = 2,
-.settings.fmt   = AUD_FMT_S16,
-.latency_millis = 10
-};
+} DSoundConf;
 
 typedef struct {
 LPDIRECTSOUND dsound;
 LPDIRECTSOUNDCAPTURE dsound_capture;
 LPDIRECTSOUNDBUFFER dsound_primary_buffer;
 struct audsettings settings;
+DSoundConf conf;
 } dsound;
 
-static dsound glob_dsound;
-
 typedef struct {
 HWVoiceOut hw;
 LPDIRECTSOUNDBUFFER dsound_buffer;
 DWORD old_pos;
 int first_time;
+dsound *s;
 #ifdef DEBUG_DSOUND
 DWORD old_ppos;
 DWORD played;
@@ -88,6 +77,7 @@ typedef struct {
 HWVoiceIn hw;
 int first_time;
 LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+dsound *s;
 } DSoundVoiceIn;
 
 static void dsound_log_hresult (HRESULT hr)
@@ -281,12 +271,12 @@ static void print_wave_format (WAVEFORMATEX *wfx)
 }
 #endif
 
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
+static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
 {
 HRESULT hr;
 int i;
 
-for (i = 0; i  conf.restore_retries; ++i) {
+for (i = 0; i  s-conf.restore_retries; ++i) {
 hr = IDirectSoundBuffer_Restore (dsb);
 
 switch (hr) {
@@ -311,12 +301,13 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
 #include dsound_template.h
 #undef DSBTYPE_IN
 
-static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
+static int

[Qemu-devel] [PATCH v3 03/12] audio: remove winwave audio driver

2015-06-03 Thread Kővágó, Zoltán
DirectSound should be a superior choice on Windows.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs  |   1 -
 audio/audio_int.h|   1 -
 audio/winwaveaudio.c | 717 ---
 configure|  13 +-
 4 files changed, 4 insertions(+), 728 deletions(-)
 delete mode 100644 audio/winwaveaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index b4c0608..481d1aa 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -6,7 +6,6 @@ common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
-common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 7445602..0eba44f 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -211,7 +211,6 @@ extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
 extern struct audio_driver pa_audio_driver;
 extern struct audio_driver spice_audio_driver;
-extern struct audio_driver winwave_audio_driver;
 extern const struct mixeng_volume nominal_volume;
 
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
deleted file mode 100644
index 8dbd145..000
--- a/audio/winwaveaudio.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* public domain */
-
-#include qemu-common.h
-#include sysemu/sysemu.h
-#include audio.h
-
-#define AUDIO_CAP winwave
-#include audio_int.h
-
-#include windows.h
-#include mmsystem.h
-
-#include audio_win_int.h
-
-static struct {
-int dac_headers;
-int dac_samples;
-int adc_headers;
-int adc_samples;
-} conf = {
-.dac_headers = 4,
-.dac_samples = 1024,
-.adc_headers = 4,
-.adc_samples = 1024
-};
-
-typedef struct {
-HWVoiceOut hw;
-HWAVEOUT hwo;
-WAVEHDR *hdrs;
-HANDLE event;
-void *pcm_buf;
-int avail;
-int pending;
-int curhdr;
-int paused;
-CRITICAL_SECTION crit_sect;
-} WaveVoiceOut;
-
-typedef struct {
-HWVoiceIn hw;
-HWAVEIN hwi;
-WAVEHDR *hdrs;
-HANDLE event;
-void *pcm_buf;
-int curhdr;
-int paused;
-int rpos;
-int avail;
-CRITICAL_SECTION crit_sect;
-} WaveVoiceIn;
-
-static void winwave_log_mmresult (MMRESULT mr)
-{
-const char *str = BUG;
-
-switch (mr) {
-case MMSYSERR_NOERROR:
-str = Success;
-break;
-
-case MMSYSERR_INVALHANDLE:
-str = Specified device handle is invalid;
-break;
-
-case MMSYSERR_BADDEVICEID:
-str = Specified device id is out of range;
-break;
-
-case MMSYSERR_NODRIVER:
-str = No device driver is present;
-break;
-
-case MMSYSERR_NOMEM:
-str = Unable to allocate or lock memory;
-break;
-
-case WAVERR_SYNC:
-str = Device is synchronous but waveOutOpen was called 
-without using the WINWAVE_ALLOWSYNC flag;
-break;
-
-case WAVERR_UNPREPARED:
-str = The data block pointed to by the pwh parameter 
-hasn't been prepared;
-break;
-
-case WAVERR_STILLPLAYING:
-str = There are still buffers in the queue;
-break;
-
-default:
-dolog (Reason: Unknown (MMRESULT %#x)\n, mr);
-return;
-}
-
-dolog (Reason: %s\n, str);
-}
-
-static void GCC_FMT_ATTR (2, 3) winwave_logerr (
-MMRESULT mr,
-const char *fmt,
-...
-)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (NULL,  failed\n);
-winwave_log_mmresult (mr);
-}
-
-static void winwave_anal_close_out (WaveVoiceOut *wave)
-{
-MMRESULT mr;
-
-mr = waveOutClose (wave-hwo);
-if (mr != MMSYSERR_NOERROR) {
-winwave_logerr (mr, waveOutClose);
-}
-wave-hwo = NULL;
-}
-
-static void CALLBACK winwave_callback_out (
-HWAVEOUT hwo,
-UINT msg,
-DWORD_PTR dwInstance,
-DWORD_PTR dwParam1,
-DWORD_PTR dwParam2
-)
-{
-WaveVoiceOut *wave = (WaveVoiceOut *) dwInstance;
-
-switch (msg) {
-case WOM_DONE:
-{
-WAVEHDR *h = (WAVEHDR *) dwParam1;
-if (!h-dwUser) {
-h-dwUser = 1;
-EnterCriticalSection (wave-crit_sect);
-{
-wave-avail += conf.dac_samples;
-}
-LeaveCriticalSection (wave-crit_sect);
-if (wave-hw.poll_mode) {
-if (!SetEvent (wave-event)) {
-dolog (DAC SetEvent failed %lx\n, GetLastError ());
-}
-}
-}
-}
-break;
-
-case WOM_CLOSE:
-case WOM_OPEN:
-break;
-
-default

Re: [Qemu-devel] [RFC PATCH v2] qapi for audio backends

2015-06-04 Thread Kővágó Zoltán

Hi,

2015-06-04 17:30 keltezéssel, Gerd Hoffmann írta:

Not sure about this one, so it's not yet in this patch:
* remove poll_mode: another obscure setting, and it's only matter of time until
   the code bitrots enough to break it.


I'd tend to drop this too, but it's probably good to check what exactly
it is doing and to test whenever it actually works.


In my quick test it actually worked (but that was with pulseaudio's alsa 
emulation). Plus currently only alsa an oss seem to care about this 
option, so even if we keep it, we should probably move it into alsa's 
and oss's backend options.



Any comment is appreciated.


Looks good to me as draft to start working with.  I expect we'll find
some details which need tweeking when implementing this.



Yeah, I've already hit a problem. The opts_visitor doesn't really handle 
nested structs (it just flattens it into a single, non hierarchic 
namespace), which is a problem because of the input and output options. 
First I need to make them required (the in and out in Audiodev) if I 
want the current visitor to visit them at all, but it's still not enough.


Doing something like -audiodev frequency=8000 sets the input frequency 
to 8000 and leaves output frequency undefined. I think I should add an 
additional syntax: -audiodev in.frequency=8000,out.frequency=16000 (of 
course it should support deeper nesting like foo.bar.baz.asd=13). The 
question is what should happen if the user specifies frequency=8000. I 
see two alternatives:


0. set every frequency field to 8000 (i.e. the same as 
in.frequency=8000,out.frequency=8000 in this example)

1. bail out with a parameter ambiguous error

In the case of audiodev, the 0. approach seems more straightforward (if 
the user sets frequency, he wants to set both input and output 
frequency), but in more generic scenarios, the 1. is maybe better.


Thanks,
Zoltan



[Qemu-devel] [PATCH v3 05/12] alsaaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c | 160 +-
 1 file changed, 87 insertions(+), 73 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 87e71c6..d7e181b 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -33,30 +33,7 @@
 #define AUDIO_CAP alsa
 #include audio_int.h
 
-struct pollhlp {
-snd_pcm_t *handle;
-struct pollfd *pfds;
-int count;
-int mask;
-};
-
-typedef struct ALSAVoiceOut {
-HWVoiceOut hw;
-int wpos;
-int pending;
-void *pcm_buf;
-snd_pcm_t *handle;
-struct pollhlp pollhlp;
-} ALSAVoiceOut;
-
-typedef struct ALSAVoiceIn {
-HWVoiceIn hw;
-snd_pcm_t *handle;
-void *pcm_buf;
-struct pollhlp pollhlp;
-} ALSAVoiceIn;
-
-static struct {
+typedef struct ALSAConf {
 int size_in_usec_in;
 int size_in_usec_out;
 const char *pcm_name_in;
@@ -73,13 +50,32 @@ static struct {
 int buffer_size_out_overridden;
 int period_size_out_overridden;
 int verbose;
-} conf = {
-.buffer_size_out = 4096,
-.period_size_out = 1024,
-.pcm_name_out = default,
-.pcm_name_in = default,
+} ALSAConf;
+
+struct pollhlp {
+snd_pcm_t *handle;
+struct pollfd *pfds;
+ALSAConf *conf;
+int count;
+int mask;
 };
 
+typedef struct ALSAVoiceOut {
+HWVoiceOut hw;
+int wpos;
+int pending;
+void *pcm_buf;
+snd_pcm_t *handle;
+struct pollhlp pollhlp;
+} ALSAVoiceOut;
+
+typedef struct ALSAVoiceIn {
+HWVoiceIn hw;
+snd_pcm_t *handle;
+void *pcm_buf;
+struct pollhlp pollhlp;
+} ALSAVoiceIn;
+
 struct alsa_params_req {
 int freq;
 snd_pcm_format_t fmt;
@@ -184,6 +180,7 @@ static void alsa_poll_handler (void *opaque)
 snd_pcm_state_t state;
 struct pollhlp *hlp = opaque;
 unsigned short revents;
+ALSAConf *conf = hlp-conf;
 
 count = poll (hlp-pfds, hlp-count, 0);
 if (count  0) {
@@ -205,7 +202,7 @@ static void alsa_poll_handler (void *opaque)
 }
 
 if (!(revents  hlp-mask)) {
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (revents = %d\n, revents);
 }
 return;
@@ -242,6 +239,7 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
 {
 int i, count, err;
 struct pollfd *pfds;
+ALSAConf *conf = hlp-conf;
 
 count = snd_pcm_poll_descriptors_count (handle);
 if (count = 0) {
@@ -270,13 +268,13 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
NULL, hlp);
 }
 if (pfds[i].events  POLLOUT) {
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (POLLOUT %d %d\n, i, pfds[i].fd);
 }
 err = qemu_set_fd_handler (pfds[i].fd, NULL,
alsa_poll_handler, hlp);
 }
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (Set handler events=%#x index=%d fd=%d err=%d\n,
pfds[i].events, i, pfds[i].fd, err);
 }
@@ -476,14 +474,15 @@ static void alsa_set_threshold (snd_pcm_t *handle, 
snd_pcm_uframes_t threshold)
 }
 
 static int alsa_open (int in, struct alsa_params_req *req,
-  struct alsa_params_obt *obt, snd_pcm_t **handlep)
+  struct alsa_params_obt *obt, snd_pcm_t **handlep,
+  ALSAConf *conf)
 {
 snd_pcm_t *handle;
 snd_pcm_hw_params_t *hw_params;
 int err;
 int size_in_usec;
 unsigned int freq, nchannels;
-const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
+const char *pcm_name = in ? conf-pcm_name_in : conf-pcm_name_out;
 snd_pcm_uframes_t obt_buffer_size;
 const char *typ = in ? ADC : DAC;
 snd_pcm_format_t obtfmt;
@@ -522,7 +521,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 }
 
 err = snd_pcm_hw_params_set_format (handle, hw_params, req-fmt);
-if (err  0  conf.verbose) {
+if (err  0  conf-verbose) {
 alsa_logerr2 (err, typ, Failed to set format %d\n, req-fmt);
 }
 
@@ -654,7 +653,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 goto err;
 }
 
-if (!in  conf.threshold) {
+if (!in  conf-threshold) {
 snd_pcm_uframes_t threshold;
 int bytes_per_sec;
 
@@ -676,7 +675,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 break;
 }
 
-threshold = (conf.threshold * bytes_per_sec) / 1000;
+threshold = (conf-threshold * bytes_per_sec) / 1000;
 alsa_set_threshold (handle, threshold);
 }
 
@@ -686,7 +685,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 
 *handlep = handle;
 
-if (conf.verbose 
+if (conf-verbose 
 (obtfmt != req-fmt ||
  obt-nchannels != req-nchannels ||
  obt-freq != req-freq)) {
@@ -729,6

Re: [Qemu-devel] [RFC PATCH v2] qapi for audio backends

2015-06-05 Thread Kővágó Zoltán

Hi,

2015-06-05 12:57 keltezéssel, Gerd Hoffmann írta:

Yeah, I've already hit a problem. The opts_visitor doesn't really handle
nested structs (it just flattens it into a single, non hierarchic
namespace), which is a problem because of the input and output options.
First I need to make them required (the in and out in Audiodev) if I
want the current visitor to visit them at all, but it's still not enough.


I think we should improve the visitor instead of making in  out
mandatory just because the current implementation (which simply
implements the stuff needed for Netdev) can't handle it.


It's not that simple I think. The visit_optional only receives a field 
name, but no info about the type of the field, but it has to decide if 
it wants the field using only this info. So sort of hacking an if 
(strcmp(name, in) == 0 || strcmp(name, out) == 0) ... into the 
option visitor code, the only way is probably to add a type parameter to 
visit_optional (struct/union/uint32/whatever) and in the opts visitor if 
type is struct or union, force visiting it. Is it ok?



There is always the option to be more specific (in.frequency=...) if
setting all parameters named 'frequency' doesn't do what you want.  Also
I wouldn't worry too much about possible cases which don't exist right
now.  I'd suggest to go for (0).


Alright.

Thanks,
Zoltan



[Qemu-devel] [PATCH v2 08/12] wavaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/wavaudio.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 09083da..c586020 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -36,15 +36,10 @@ typedef struct WAVVoiceOut {
 int total_samples;
 } WAVVoiceOut;
 
-static struct {
+typedef struct {
 struct audsettings settings;
 const char *wav_path;
-} conf = {
-.settings.freq  = 44100,
-.settings.nchannels = 2,
-.settings.fmt   = AUD_FMT_S16,
-.wav_path   = qemu.wav
-};
+} WAVConf;
 
 static int wav_run_out (HWVoiceOut *hw, int live)
 {
@@ -116,7 +111,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
 };
-struct audsettings wav_as = conf.settings;
+WAVConf *conf = drv_opaque;
+struct audsettings wav_as = conf-settings;
 
 stereo = wav_as.nchannels == 2;
 switch (wav_as.fmt) {
@@ -154,10 +150,10 @@ static int wav_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 le_store (hdr + 28, hw-info.freq  (bits16 + stereo), 4);
 le_store (hdr + 32, 1  (bits16 + stereo), 2);
 
-wav-f = fopen (conf.wav_path, wb);
+wav-f = fopen (conf-wav_path, wb);
 if (!wav-f) {
 dolog (Failed to open wave file `%s'\nReason: %s\n,
-   conf.wav_path, strerror (errno));
+   conf-wav_path, strerror (errno));
 g_free (wav-pcm_buf);
 wav-pcm_buf = NULL;
 return -1;
@@ -225,40 +221,49 @@ static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return 0;
 }
 
+static WAVConf glob_conf = {
+.settings.freq  = 44100,
+.settings.nchannels = 2,
+.settings.fmt   = AUD_FMT_S16,
+.wav_path   = qemu.wav
+};
+
 static void *wav_audio_init (void)
 {
-return conf;
+WAVConf *conf = g_malloc(sizeof(WAVConf));
+*conf = glob_conf;
+return conf;
 }
 
 static void wav_audio_fini (void *opaque)
 {
-(void) opaque;
 ldebug (wav_fini);
+g_free(opaque);
 }
 
 static struct audio_option wav_options[] = {
 {
 .name  = FREQUENCY,
 .tag   = AUD_OPT_INT,
-.valp  = conf.settings.freq,
+.valp  = glob_conf.settings.freq,
 .descr = Frequency
 },
 {
 .name  = FORMAT,
 .tag   = AUD_OPT_FMT,
-.valp  = conf.settings.fmt,
+.valp  = glob_conf.settings.fmt,
 .descr = Format
 },
 {
 .name  = DAC_FIXED_CHANNELS,
 .tag   = AUD_OPT_INT,
-.valp  = conf.settings.nchannels,
+.valp  = glob_conf.settings.nchannels,
 .descr = Number of channels (1 - mono, 2 - stereo)
 },
 {
 .name  = PATH,
 .tag   = AUD_OPT_STR,
-.valp  = conf.wav_path,
+.valp  = glob_conf.wav_path,
 .descr = Path to wave file
 },
 { /* End of list */ }
-- 
2.4.2




[Qemu-devel] [PATCH v2 01/12] audio: remove esd backend

2015-06-03 Thread Kővágó, Zoltán
ESD is no longer developed and replaced by PulseAudio.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   1 -
 audio/audio_int.h   |   1 -
 audio/esdaudio.c| 557 
 configure   |  18 +-
 4 files changed, 6 insertions(+), 571 deletions(-)
 delete mode 100644 audio/esdaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 26a0ac9..5573ac1 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -6,7 +6,6 @@ common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
 common-obj-$(CONFIG_FMOD) += fmodaudio.o
-common-obj-$(CONFIG_ESD) += esdaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
 common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
diff --git a/audio/audio_int.h b/audio/audio_int.h
index fd019a0..9dd6b7f 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -210,7 +210,6 @@ extern struct audio_driver fmod_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
-extern struct audio_driver esd_audio_driver;
 extern struct audio_driver pa_audio_driver;
 extern struct audio_driver spice_audio_driver;
 extern struct audio_driver winwave_audio_driver;
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
deleted file mode 100644
index eea9cce..000
--- a/audio/esdaudio.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * QEMU ESD audio driver
- *
- * Copyright (c) 2006 Frederick Reeve (brushed up by malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include esd.h
-#include qemu-common.h
-#include audio.h
-
-#define AUDIO_CAP esd
-#include audio_int.h
-#include audio_pt_int.h
-
-typedef struct {
-HWVoiceOut hw;
-int done;
-int live;
-int decr;
-int rpos;
-void *pcm_buf;
-int fd;
-struct audio_pt pt;
-} ESDVoiceOut;
-
-typedef struct {
-HWVoiceIn hw;
-int done;
-int dead;
-int incr;
-int wpos;
-void *pcm_buf;
-int fd;
-struct audio_pt pt;
-} ESDVoiceIn;
-
-static struct {
-int samples;
-int divisor;
-char *dac_host;
-char *adc_host;
-} conf = {
-.samples = 1024,
-.divisor = 2,
-};
-
-static void GCC_FMT_ATTR (2, 3) qesd_logerr (int err, const char *fmt, ...)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n, strerror (err));
-}
-
-/* playback */
-static void *qesd_thread_out (void *arg)
-{
-ESDVoiceOut *esd = arg;
-HWVoiceOut *hw = esd-hw;
-int threshold;
-
-threshold = conf.divisor ? hw-samples / conf.divisor : 0;
-
-if (audio_pt_lock (esd-pt, AUDIO_FUNC)) {
-return NULL;
-}
-
-for (;;) {
-int decr, to_mix, rpos;
-
-for (;;) {
-if (esd-done) {
-goto exit;
-}
-
-if (esd-live  threshold) {
-break;
-}
-
-if (audio_pt_wait (esd-pt, AUDIO_FUNC)) {
-goto exit;
-}
-}
-
-decr = to_mix = esd-live;
-rpos = hw-rpos;
-
-if (audio_pt_unlock (esd-pt, AUDIO_FUNC)) {
-return NULL;
-}
-
-while (to_mix) {
-ssize_t written;
-int chunk = audio_MIN (to_mix, hw-samples - rpos);
-struct st_sample *src = hw-mix_buf + rpos;
-
-hw-clip (esd-pcm_buf, src, chunk);
-
-again:
-written = write (esd-fd, esd-pcm_buf, chunk  hw-info.shift);
-if (written == -1) {
-if (errno == EINTR || errno == EAGAIN) {
-goto again;
-}
-qesd_logerr (errno, write failed\n);
-return NULL;
-}
-
-if (written != chunk

[Qemu-devel] [PATCH v2 00/12] Audio backend cleanup

2015-06-03 Thread Kővágó, Zoltán
This series of patch removes the following audio backends:
esd, fmod, winwave.

It also cleans up the remaining drivers to do not use global variables where
possible. This is a preparation for my GSoC project where I will enable multiple
simultaneous audio backends.

Please also test the coreaudio backend, as I do not have a Mac to test it.

Patches are also available at https://github.com/DirtYiCE/qemu.git in tag
audio-cleanup-v2 to simplify testing.

Changes since v1:
* sdl no longer removed
* fixed style issues in `audio: expose drv_opaque to init_out and init_in'

Please review.

Kővágó, Zoltán (12):
  audio: remove esd backend
  audio: remove fmod backend
  audio: remove winwave audio driver
  audio: expose drv_opaque to init_out and init_in
  alsaaudio: do not use global variables
  paaudio: do not use global variables
  ossaudio: do not use global variables
  wavaudio: do not use global variables
  dsoundaudio: do not use global variables
  paaudio: fix possible resource leak
  coreaudio: do not use global variables where possible
  sdlaudio: do not allow multiple instances

 audio/Makefile.objs |   4 -
 audio/alsaaudio.c   | 165 ++-
 audio/audio_int.h   |   7 +-
 audio/audio_template.h  |   2 +-
 audio/coreaudio.c   |  46 ++--
 audio/dsound_template.h |  24 +-
 audio/dsoundaudio.c | 106 ---
 audio/esdaudio.c| 557 -
 audio/fmodaudio.c   | 685 -
 audio/noaudio.c |   4 +-
 audio/ossaudio.c| 115 
 audio/paaudio.c | 105 +++
 audio/sdlaudio.c|  10 +-
 audio/spiceaudio.c  |   5 +-
 audio/wavaudio.c|  42 +--
 audio/winwaveaudio.c| 717 
 configure   |  56 +---
 17 files changed, 367 insertions(+), 2283 deletions(-)
 delete mode 100644 audio/esdaudio.c
 delete mode 100644 audio/fmodaudio.c
 delete mode 100644 audio/winwaveaudio.c

-- 
2.4.2




[Qemu-devel] [PATCH v2 07/12] ossaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/ossaudio.c | 110 ++-
 1 file changed, 61 insertions(+), 49 deletions(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 069ff60..d247969 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -38,6 +38,17 @@
 #define USE_DSP_POLICY
 #endif
 
+typedef struct OSSConf {
+int try_mmap;
+int nfrags;
+int fragsize;
+const char *devpath_out;
+const char *devpath_in;
+int debug;
+int exclusive;
+int policy;
+} OSSConf;
+
 typedef struct OSSVoiceOut {
 HWVoiceOut hw;
 void *pcm_buf;
@@ -47,6 +58,7 @@ typedef struct OSSVoiceOut {
 int fragsize;
 int mmapped;
 int pending;
+OSSConf *conf;
 } OSSVoiceOut;
 
 typedef struct OSSVoiceIn {
@@ -55,28 +67,9 @@ typedef struct OSSVoiceIn {
 int fd;
 int nfrags;
 int fragsize;
+OSSConf *conf;
 } OSSVoiceIn;
 
-static struct {
-int try_mmap;
-int nfrags;
-int fragsize;
-const char *devpath_out;
-const char *devpath_in;
-int debug;
-int exclusive;
-int policy;
-} conf = {
-.try_mmap = 0,
-.nfrags = 4,
-.fragsize = 4096,
-.devpath_out = /dev/dsp,
-.devpath_in = /dev/dsp,
-.debug = 0,
-.exclusive = 0,
-.policy = 5
-};
-
 struct oss_params {
 int freq;
 audfmt_e fmt;
@@ -272,18 +265,18 @@ static int oss_get_version (int fd, int *version, const 
char *typ)
 #endif
 
 static int oss_open (int in, struct oss_params *req,
- struct oss_params *obt, int *pfd)
+ struct oss_params *obt, int *pfd, OSSConf* conf)
 {
 int fd;
-int oflags = conf.exclusive ? O_EXCL : 0;
+int oflags = conf-exclusive ? O_EXCL : 0;
 audio_buf_info abinfo;
 int fmt, freq, nchannels;
 int setfragment = 1;
-const char *dspname = in ? conf.devpath_in : conf.devpath_out;
+const char *dspname = in ? conf-devpath_in : conf-devpath_out;
 const char *typ = in ? ADC : DAC;
 
 /* Kludge needed to have working mmap on Linux */
-oflags |= conf.try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
+oflags |= conf-try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
 
 fd = open (dspname, oflags | O_NONBLOCK);
 if (-1 == fd) {
@@ -317,20 +310,20 @@ static int oss_open (int in, struct oss_params *req,
 }
 
 #ifdef USE_DSP_POLICY
-if (conf.policy = 0) {
+if (conf-policy = 0) {
 int version;
 
 if (!oss_get_version (fd, version, typ)) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (OSS version = %#x\n, version);
 }
 
 if (version = 0x04) {
-int policy = conf.policy;
+int policy = conf-policy;
 if (ioctl (fd, SNDCTL_DSP_POLICY, policy)) {
 oss_logerr2 (errno, typ,
  Failed to set timing policy to %d\n,
- conf.policy);
+ conf-policy);
 goto err;
 }
 setfragment = 0;
@@ -434,6 +427,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 struct audio_buf_info abinfo;
 struct count_info cntinfo;
 int bufsize;
+OSSConf *conf = oss-conf;
 
 bufsize = hw-samples  hw-info.shift;
 
@@ -458,7 +452,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 }
 
 if (abinfo.bytes  bufsize) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (warning: Invalid available size, size=%d bufsize=%d\n
please report your OS/audio hw to av1...@comtv.ru\n,
abinfo.bytes, bufsize);
@@ -467,7 +461,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 }
 
 if (abinfo.bytes  0) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (warning: Invalid available size, size=%d bufsize=%d\n,
abinfo.bytes, bufsize);
 }
@@ -520,16 +514,17 @@ static int oss_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 int fd;
 audfmt_e effective_fmt;
 struct audsettings obt_as;
+OSSConf *conf = drv_opaque;
 
 oss-fd = -1;
 
 req.fmt = aud_to_ossfmt (as-fmt, as-endianness);
 req.freq = as-freq;
 req.nchannels = as-nchannels;
-req.fragsize = conf.fragsize;
-req.nfrags = conf.nfrags;
+req.fragsize = conf-fragsize;
+req.nfrags = conf-nfrags;
 
-if (oss_open (0, req, obt, fd)) {
+if (oss_open (0, req, obt, fd, conf)) {
 return -1;
 }
 
@@ -556,7 +551,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 hw-samples = (obt.nfrags * obt.fragsize)  hw-info.shift;
 
 oss-mmapped = 0;
-if (conf.try_mmap) {
+if (conf-try_mmap) {
 oss-pcm_buf = mmap (
 NULL,
 hw-samples  hw-info.shift,
@@ -616,6 +611,7

[Qemu-devel] [PATCH v2 11/12] coreaudio: do not use global variables where possible

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/coreaudio.c | 43 ---
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 20346bc..9f731b7 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -32,20 +32,16 @@
 #define AUDIO_CAP coreaudio
 #include audio_int.h
 
-struct {
+static int isAtexit;
+
+typedef struct {
 int buffer_frames;
 int nbuffers;
-int isAtexit;
-} conf = {
-.buffer_frames = 512,
-.nbuffers = 4,
-.isAtexit = 0
-};
+} CoreaudioConf;
 
 typedef struct coreaudioVoiceOut {
 HWVoiceOut hw;
 pthread_mutex_t mutex;
-int isAtexit;
 AudioDeviceID outputDeviceID;
 UInt32 audioDevicePropertyBufferFrameSize;
 AudioStreamBasicDescription outputStreamBasicDescription;
@@ -161,7 +157,7 @@ static inline UInt32 isPlaying (AudioDeviceID 
outputDeviceID)
 
 static void coreaudio_atexit (void)
 {
-conf.isAtexit = 1;
+isAtexit = 1;
 }
 
 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
@@ -296,6 +292,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 int err;
 const char *typ = playback;
 AudioValueRange frameRange;
+CoreaudioConf *conf = drv_opaque;
 
 /* create mutex */
 err = pthread_mutex_init(core-mutex, NULL);
@@ -337,16 +334,16 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 return -1;
 }
 
-if (frameRange.mMinimum  conf.buffer_frames) {
+if (frameRange.mMinimum  conf-buffer_frames) {
 core-audioDevicePropertyBufferFrameSize = (UInt32) 
frameRange.mMinimum;
 dolog (warning: Upsizing Buffer Frames to %f\n, frameRange.mMinimum);
 }
-else if (frameRange.mMaximum  conf.buffer_frames) {
+else if (frameRange.mMaximum  conf-buffer_frames) {
 core-audioDevicePropertyBufferFrameSize = (UInt32) 
frameRange.mMaximum;
 dolog (warning: Downsizing Buffer Frames to %f\n, 
frameRange.mMaximum);
 }
 else {
-core-audioDevicePropertyBufferFrameSize = conf.buffer_frames;
+core-audioDevicePropertyBufferFrameSize = conf-buffer_frames;
 }
 
 /* set Buffer Frame Size */
@@ -380,7 +377,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
Could not get device buffer frame size\n);
 return -1;
 }
-hw-samples = conf.nbuffers * core-audioDevicePropertyBufferFrameSize;
+hw-samples = conf-nbuffers * core-audioDevicePropertyBufferFrameSize;
 
 /* get StreamFormat */
 propertySize = sizeof(core-outputStreamBasicDescription);
@@ -444,7 +441,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
 int err;
 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
 
-if (!conf.isAtexit) {
+if (!isAtexit) {
 /* stop playback */
 if (isPlaying(core-outputDeviceID)) {
 status = AudioDeviceStop(core-outputDeviceID, audioDeviceIOProc);
@@ -487,7 +484,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
 case VOICE_DISABLE:
 /* stop playback */
-if (!conf.isAtexit) {
+if (!isAtexit) {
 if (isPlaying(core-outputDeviceID)) {
 status = AudioDeviceStop(core-outputDeviceID, 
audioDeviceIOProc);
 if (status != kAudioHardwareNoError) {
@@ -500,28 +497,36 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, 
...)
 return 0;
 }
 
+static CoreaudioConf glob_conf = {
+.buffer_frames = 512,
+.nbuffers = 4,
+};
+
 static void *coreaudio_audio_init (void)
 {
+CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
+*conf = glob_conf;
+
 atexit(coreaudio_atexit);
-return coreaudio_audio_init;
+return conf;
 }
 
 static void coreaudio_audio_fini (void *opaque)
 {
-(void) opaque;
+g_free(opaque);
 }
 
 static struct audio_option coreaudio_options[] = {
 {
 .name  = BUFFER_SIZE,
 .tag   = AUD_OPT_INT,
-.valp  = conf.buffer_frames,
+.valp  = glob_conf.buffer_frames,
 .descr = Size of the buffer in frames
 },
 {
 .name  = BUFFER_COUNT,
 .tag   = AUD_OPT_INT,
-.valp  = conf.nbuffers,
+.valp  = glostconf.nbuffers,
 .descr = Number of buffers
 },
 { /* End of list */ }
-- 
2.4.2




[Qemu-devel] [PATCH v2 05/12] alsaaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c | 160 +-
 1 file changed, 87 insertions(+), 73 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 87e71c6..d7e181b 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -33,30 +33,7 @@
 #define AUDIO_CAP alsa
 #include audio_int.h
 
-struct pollhlp {
-snd_pcm_t *handle;
-struct pollfd *pfds;
-int count;
-int mask;
-};
-
-typedef struct ALSAVoiceOut {
-HWVoiceOut hw;
-int wpos;
-int pending;
-void *pcm_buf;
-snd_pcm_t *handle;
-struct pollhlp pollhlp;
-} ALSAVoiceOut;
-
-typedef struct ALSAVoiceIn {
-HWVoiceIn hw;
-snd_pcm_t *handle;
-void *pcm_buf;
-struct pollhlp pollhlp;
-} ALSAVoiceIn;
-
-static struct {
+typedef struct ALSAConf {
 int size_in_usec_in;
 int size_in_usec_out;
 const char *pcm_name_in;
@@ -73,13 +50,32 @@ static struct {
 int buffer_size_out_overridden;
 int period_size_out_overridden;
 int verbose;
-} conf = {
-.buffer_size_out = 4096,
-.period_size_out = 1024,
-.pcm_name_out = default,
-.pcm_name_in = default,
+} ALSAConf;
+
+struct pollhlp {
+snd_pcm_t *handle;
+struct pollfd *pfds;
+ALSAConf *conf;
+int count;
+int mask;
 };
 
+typedef struct ALSAVoiceOut {
+HWVoiceOut hw;
+int wpos;
+int pending;
+void *pcm_buf;
+snd_pcm_t *handle;
+struct pollhlp pollhlp;
+} ALSAVoiceOut;
+
+typedef struct ALSAVoiceIn {
+HWVoiceIn hw;
+snd_pcm_t *handle;
+void *pcm_buf;
+struct pollhlp pollhlp;
+} ALSAVoiceIn;
+
 struct alsa_params_req {
 int freq;
 snd_pcm_format_t fmt;
@@ -184,6 +180,7 @@ static void alsa_poll_handler (void *opaque)
 snd_pcm_state_t state;
 struct pollhlp *hlp = opaque;
 unsigned short revents;
+ALSAConf *conf = hlp-conf;
 
 count = poll (hlp-pfds, hlp-count, 0);
 if (count  0) {
@@ -205,7 +202,7 @@ static void alsa_poll_handler (void *opaque)
 }
 
 if (!(revents  hlp-mask)) {
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (revents = %d\n, revents);
 }
 return;
@@ -242,6 +239,7 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
 {
 int i, count, err;
 struct pollfd *pfds;
+ALSAConf *conf = hlp-conf;
 
 count = snd_pcm_poll_descriptors_count (handle);
 if (count = 0) {
@@ -270,13 +268,13 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
NULL, hlp);
 }
 if (pfds[i].events  POLLOUT) {
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (POLLOUT %d %d\n, i, pfds[i].fd);
 }
 err = qemu_set_fd_handler (pfds[i].fd, NULL,
alsa_poll_handler, hlp);
 }
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (Set handler events=%#x index=%d fd=%d err=%d\n,
pfds[i].events, i, pfds[i].fd, err);
 }
@@ -476,14 +474,15 @@ static void alsa_set_threshold (snd_pcm_t *handle, 
snd_pcm_uframes_t threshold)
 }
 
 static int alsa_open (int in, struct alsa_params_req *req,
-  struct alsa_params_obt *obt, snd_pcm_t **handlep)
+  struct alsa_params_obt *obt, snd_pcm_t **handlep,
+  ALSAConf *conf)
 {
 snd_pcm_t *handle;
 snd_pcm_hw_params_t *hw_params;
 int err;
 int size_in_usec;
 unsigned int freq, nchannels;
-const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
+const char *pcm_name = in ? conf-pcm_name_in : conf-pcm_name_out;
 snd_pcm_uframes_t obt_buffer_size;
 const char *typ = in ? ADC : DAC;
 snd_pcm_format_t obtfmt;
@@ -522,7 +521,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 }
 
 err = snd_pcm_hw_params_set_format (handle, hw_params, req-fmt);
-if (err  0  conf.verbose) {
+if (err  0  conf-verbose) {
 alsa_logerr2 (err, typ, Failed to set format %d\n, req-fmt);
 }
 
@@ -654,7 +653,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 goto err;
 }
 
-if (!in  conf.threshold) {
+if (!in  conf-threshold) {
 snd_pcm_uframes_t threshold;
 int bytes_per_sec;
 
@@ -676,7 +675,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 break;
 }
 
-threshold = (conf.threshold * bytes_per_sec) / 1000;
+threshold = (conf-threshold * bytes_per_sec) / 1000;
 alsa_set_threshold (handle, threshold);
 }
 
@@ -686,7 +685,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 
 *handlep = handle;
 
-if (conf.verbose 
+if (conf-verbose 
 (obtfmt != req-fmt ||
  obt-nchannels != req-nchannels ||
  obt-freq != req-freq)) {
@@ -729,6

[Qemu-devel] [PATCH v2 03/12] audio: remove winwave audio driver

2015-06-03 Thread Kővágó, Zoltán
DirectSound should be a superior choice on Windows.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs  |   1 -
 audio/audio_int.h|   1 -
 audio/winwaveaudio.c | 717 ---
 configure|  13 +-
 4 files changed, 4 insertions(+), 728 deletions(-)
 delete mode 100644 audio/winwaveaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index b4c0608..481d1aa 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -6,7 +6,6 @@ common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
-common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 7445602..0eba44f 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -211,7 +211,6 @@ extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
 extern struct audio_driver pa_audio_driver;
 extern struct audio_driver spice_audio_driver;
-extern struct audio_driver winwave_audio_driver;
 extern const struct mixeng_volume nominal_volume;
 
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
deleted file mode 100644
index 8dbd145..000
--- a/audio/winwaveaudio.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* public domain */
-
-#include qemu-common.h
-#include sysemu/sysemu.h
-#include audio.h
-
-#define AUDIO_CAP winwave
-#include audio_int.h
-
-#include windows.h
-#include mmsystem.h
-
-#include audio_win_int.h
-
-static struct {
-int dac_headers;
-int dac_samples;
-int adc_headers;
-int adc_samples;
-} conf = {
-.dac_headers = 4,
-.dac_samples = 1024,
-.adc_headers = 4,
-.adc_samples = 1024
-};
-
-typedef struct {
-HWVoiceOut hw;
-HWAVEOUT hwo;
-WAVEHDR *hdrs;
-HANDLE event;
-void *pcm_buf;
-int avail;
-int pending;
-int curhdr;
-int paused;
-CRITICAL_SECTION crit_sect;
-} WaveVoiceOut;
-
-typedef struct {
-HWVoiceIn hw;
-HWAVEIN hwi;
-WAVEHDR *hdrs;
-HANDLE event;
-void *pcm_buf;
-int curhdr;
-int paused;
-int rpos;
-int avail;
-CRITICAL_SECTION crit_sect;
-} WaveVoiceIn;
-
-static void winwave_log_mmresult (MMRESULT mr)
-{
-const char *str = BUG;
-
-switch (mr) {
-case MMSYSERR_NOERROR:
-str = Success;
-break;
-
-case MMSYSERR_INVALHANDLE:
-str = Specified device handle is invalid;
-break;
-
-case MMSYSERR_BADDEVICEID:
-str = Specified device id is out of range;
-break;
-
-case MMSYSERR_NODRIVER:
-str = No device driver is present;
-break;
-
-case MMSYSERR_NOMEM:
-str = Unable to allocate or lock memory;
-break;
-
-case WAVERR_SYNC:
-str = Device is synchronous but waveOutOpen was called 
-without using the WINWAVE_ALLOWSYNC flag;
-break;
-
-case WAVERR_UNPREPARED:
-str = The data block pointed to by the pwh parameter 
-hasn't been prepared;
-break;
-
-case WAVERR_STILLPLAYING:
-str = There are still buffers in the queue;
-break;
-
-default:
-dolog (Reason: Unknown (MMRESULT %#x)\n, mr);
-return;
-}
-
-dolog (Reason: %s\n, str);
-}
-
-static void GCC_FMT_ATTR (2, 3) winwave_logerr (
-MMRESULT mr,
-const char *fmt,
-...
-)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (NULL,  failed\n);
-winwave_log_mmresult (mr);
-}
-
-static void winwave_anal_close_out (WaveVoiceOut *wave)
-{
-MMRESULT mr;
-
-mr = waveOutClose (wave-hwo);
-if (mr != MMSYSERR_NOERROR) {
-winwave_logerr (mr, waveOutClose);
-}
-wave-hwo = NULL;
-}
-
-static void CALLBACK winwave_callback_out (
-HWAVEOUT hwo,
-UINT msg,
-DWORD_PTR dwInstance,
-DWORD_PTR dwParam1,
-DWORD_PTR dwParam2
-)
-{
-WaveVoiceOut *wave = (WaveVoiceOut *) dwInstance;
-
-switch (msg) {
-case WOM_DONE:
-{
-WAVEHDR *h = (WAVEHDR *) dwParam1;
-if (!h-dwUser) {
-h-dwUser = 1;
-EnterCriticalSection (wave-crit_sect);
-{
-wave-avail += conf.dac_samples;
-}
-LeaveCriticalSection (wave-crit_sect);
-if (wave-hw.poll_mode) {
-if (!SetEvent (wave-event)) {
-dolog (DAC SetEvent failed %lx\n, GetLastError ());
-}
-}
-}
-}
-break;
-
-case WOM_CLOSE:
-case WOM_OPEN:
-break;
-
-default

[Qemu-devel] [PATCH v2 12/12] sdlaudio: do not allow multiple instances

2015-06-03 Thread Kővágó, Zoltán
Since SDL uses a lot of global data, we can't create independent
instances of sdl audio backend.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/sdlaudio.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index b95a7e0..1140f2e 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -55,6 +55,7 @@ static struct SDLAudioState {
 SDL_mutex *mutex;
 SDL_sem *sem;
 int initialized;
+bool driver_created;
 } glob_sdl;
 typedef struct SDLAudioState SDLAudioState;
 
@@ -393,6 +394,10 @@ static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
 static void *sdl_audio_init (void)
 {
 SDLAudioState *s = glob_sdl;
+if (s-driver_created) {
+sdl_logerr(Can't create multiple sdl backends\n);
+return NULL;
+}
 
 if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
 sdl_logerr (SDL failed to initialize audio subsystem\n);
@@ -414,6 +419,7 @@ static void *sdl_audio_init (void)
 return NULL;
 }
 
+s-driver_created = true;
 return s;
 }
 
@@ -424,6 +430,7 @@ static void sdl_audio_fini (void *opaque)
 SDL_DestroySemaphore (s-sem);
 SDL_DestroyMutex (s-mutex);
 SDL_QuitSubSystem (SDL_INIT_AUDIO);
+s-driver_created = false;
 }
 
 static struct audio_option sdl_options[] = {
-- 
2.4.2




[Qemu-devel] [PATCH v2 10/12] paaudio: fix possible resource leak

2015-06-03 Thread Kővágó, Zoltán
qpa_audio_init did not clean up resources properly if the initialization
failed. This hopefully fixes it.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/paaudio.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 35e8887..fea6071 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -47,6 +47,8 @@ typedef struct {
 paaudio *g;
 } PAVoiceIn;
 
+static void qpa_audio_fini(void *opaque);
+
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
 va_list ap;
@@ -814,6 +816,8 @@ static void *qpa_audio_init (void)
 {
 paaudio *g = g_malloc(sizeof(paaudio));
 g-conf = glob_conf;
+g-mainloop = NULL;
+g-context = NULL;
 
 g-mainloop = pa_threaded_mainloop_new ();
 if (!g-mainloop) {
@@ -867,7 +871,7 @@ unlock_and_fail:
 pa_threaded_mainloop_unlock (g-mainloop);
 fail:
 AUD_log (AUDIO_CAP, Failed to initialize PA context);
-g_free(g);
+qpa_audio_fini(g);
 return NULL;
 }
 
-- 
2.4.2




[Qemu-devel] [PATCH v2 02/12] audio: remove fmod backend

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   2 -
 audio/audio_int.h   |   1 -
 audio/fmodaudio.c   | 685 
 configure   |  27 +--
 4 files changed, 2 insertions(+), 713 deletions(-)
 delete mode 100644 audio/fmodaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 5573ac1..b4c0608 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -5,12 +5,10 @@ common-obj-$(CONFIG_SPICE) += spiceaudio.o
 common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
-common-obj-$(CONFIG_FMOD) += fmodaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
 common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
 
-$(obj)/audio.o $(obj)/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
 sdlaudio.o-cflags := $(SDL_CFLAGS)
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 9dd6b7f..7445602 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -206,7 +206,6 @@ extern struct audio_driver no_audio_driver;
 extern struct audio_driver oss_audio_driver;
 extern struct audio_driver sdl_audio_driver;
 extern struct audio_driver wav_audio_driver;
-extern struct audio_driver fmod_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c
deleted file mode 100644
index fabf84d..000
--- a/audio/fmodaudio.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * QEMU FMOD audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include fmod.h
-#include fmod_errors.h
-#include qemu-common.h
-#include audio.h
-
-#define AUDIO_CAP fmod
-#include audio_int.h
-
-typedef struct FMODVoiceOut {
-HWVoiceOut hw;
-unsigned int old_pos;
-FSOUND_SAMPLE *fmod_sample;
-int channel;
-} FMODVoiceOut;
-
-typedef struct FMODVoiceIn {
-HWVoiceIn hw;
-FSOUND_SAMPLE *fmod_sample;
-} FMODVoiceIn;
-
-static struct {
-const char *drvname;
-int nb_samples;
-int freq;
-int nb_channels;
-int bufsize;
-int broken_adc;
-} conf = {
-.nb_samples  = 2048 * 2,
-.freq= 44100,
-.nb_channels = 2,
-};
-
-static void GCC_FMT_ATTR (1, 2) fmod_logerr (const char *fmt, ...)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n,
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
-const char *typ,
-const char *fmt,
-...
-)
-{
-va_list ap;
-
-AUD_log (AUDIO_CAP, Could not initialize %s\n, typ);
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n,
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static int fmod_write (SWVoiceOut *sw, void *buf, int len)
-{
-return audio_pcm_sw_write (sw, buf, len);
-}
-
-static void fmod_clear_sample (FMODVoiceOut *fmd)
-{
-HWVoiceOut *hw = fmd-hw;
-int status;
-void *p1 = 0, *p2 = 0;
-unsigned int len1 = 0, len2 = 0;
-
-status = FSOUND_Sample_Lock (
-fmd-fmod_sample,
-0,
-hw-samples  hw-info.shift,
-p1,
-p2,
-len1,
-len2
-);
-
-if (!status) {
-fmod_logerr (Failed to lock sample\n);
-return;
-}
-
-if ((len1  hw-info.align) || (len2  hw-info.align)) {
-dolog (Lock returned misaligned length %d, %d, alignment %d\n,
-   len1, len2, hw-info.align + 1);
-goto fail;
-}
-
-if ((len1 + len2) - (hw-samples  hw-info.shift)) {
-dolog (Lock returned

[Qemu-devel] [PATCH v2 06/12] paaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/paaudio.c | 98 ++---
 1 file changed, 52 insertions(+), 46 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index bdf6cd5..35e8887 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -9,6 +9,19 @@
 #include audio_pt_int.h
 
 typedef struct {
+int samples;
+char *server;
+char *sink;
+char *source;
+} PAConf;
+
+typedef struct {
+PAConf conf;
+pa_threaded_mainloop *mainloop;
+pa_context *context;
+} paaudio;
+
+typedef struct {
 HWVoiceOut hw;
 int done;
 int live;
@@ -17,6 +30,7 @@ typedef struct {
 pa_stream *stream;
 void *pcm_buf;
 struct audio_pt pt;
+paaudio *g;
 } PAVoiceOut;
 
 typedef struct {
@@ -30,21 +44,9 @@ typedef struct {
 struct audio_pt pt;
 const void *read_data;
 size_t read_index, read_length;
+paaudio *g;
 } PAVoiceIn;
 
-typedef struct {
-int samples;
-char *server;
-char *sink;
-char *source;
-pa_threaded_mainloop *mainloop;
-pa_context *context;
-} paaudio;
-
-static paaudio glob_paaudio = {
-.samples = 4096,
-};
-
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
 va_list ap;
@@ -106,7 +108,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
 
 static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int 
*rerror)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = p-g;
 
 pa_threaded_mainloop_lock (g-mainloop);
 
@@ -160,7 +162,7 @@ unlock_and_fail:
 
 static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, 
int *rerror)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = p-g;
 
 pa_threaded_mainloop_lock (g-mainloop);
 
@@ -222,7 +224,7 @@ static void *qpa_thread_out (void *arg)
 }
 }
 
-decr = to_mix = audio_MIN (pa-live, glob_paaudio.samples  2);
+decr = to_mix = audio_MIN (pa-live, pa-g-conf.samples  2);
 rpos = pa-rpos;
 
 if (audio_pt_unlock (pa-pt, AUDIO_FUNC)) {
@@ -314,7 +316,7 @@ static void *qpa_thread_in (void *arg)
 }
 }
 
-incr = to_grab = audio_MIN (pa-dead, glob_paaudio.samples  2);
+incr = to_grab = audio_MIN (pa-dead, pa-g-conf.samples  2);
 wpos = pa-wpos;
 
 if (audio_pt_unlock (pa-pt, AUDIO_FUNC)) {
@@ -430,7 +432,7 @@ static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int 
*endianness)
 
 static void context_state_cb (pa_context *c, void *userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 switch (pa_context_get_state(c)) {
 case PA_CONTEXT_READY:
@@ -449,7 +451,7 @@ static void context_state_cb (pa_context *c, void *userdata)
 
 static void stream_state_cb (pa_stream *s, void * userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 switch (pa_stream_get_state (s)) {
 
@@ -467,23 +469,21 @@ static void stream_state_cb (pa_stream *s, void * 
userdata)
 
 static void stream_request_cb (pa_stream *s, size_t length, void *userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 pa_threaded_mainloop_signal (g-mainloop, 0);
 }
 
 static pa_stream *qpa_simple_new (
-const char *server,
+paaudio *g,
 const char *name,
 pa_stream_direction_t dir,
 const char *dev,
-const char *stream_name,
 const pa_sample_spec *ss,
 const pa_channel_map *map,
 const pa_buffer_attr *attr,
 int *rerror)
 {
-paaudio *g = glob_paaudio;
 int r;
 pa_stream *stream;
 
@@ -538,10 +538,11 @@ static int qpa_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 void *drv_opaque)
 {
 int error;
-static pa_sample_spec ss;
-static pa_buffer_attr ba;
+pa_sample_spec ss;
+pa_buffer_attr ba;
 struct audsettings obt_as = *as;
 PAVoiceOut *pa = (PAVoiceOut *) hw;
+paaudio *g = pa-g = drv_opaque;
 
 ss.format = audfmt_to_pa (as-fmt, as-endianness);
 ss.channels = as-nchannels;
@@ -559,11 +560,10 @@ static int qpa_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 obt_as.fmt = pa_to_audfmt (ss.format, obt_as.endianness);
 
 pa-stream = qpa_simple_new (
-glob_paaudio.server,
+g,
 qemu,
 PA_STREAM_PLAYBACK,
-glob_paaudio.sink,
-pcm.playback,
+g-conf.sink,
 ss,
 NULL,   /* channel map */
 ba,/* buffering attributes */
@@ -575,7 +575,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 }
 
 audio_pcm_init_info (hw-info, obt_as);
-hw-samples = glob_paaudio.samples;
+hw-samples = g-conf.samples;
 pa-pcm_buf = audio_calloc (AUDIO_FUNC, hw-samples, 1  hw-info.shift);
 pa-rpos = hw-rpos;
 if (!pa-pcm_buf) {
@@ -605,9 +605,10 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 static

[Qemu-devel] [PATCH v2 04/12] audio: expose drv_opaque to init_out and init_in

2015-06-03 Thread Kővágó, Zoltán
Currently the opaque pointer returned by audio_driver's init is only
exposed to the driver's fini, but not to audio_pcm_ops. This way if
someone wants to share a variable with the driver and the pcm, he must
use global variables. This patch fixes it by adding a third parameter to
audio_pcm_op's init_out and init_in.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c   | 5 +++--
 audio/audio_int.h   | 4 ++--
 audio/audio_template.h  | 2 +-
 audio/coreaudio.c   | 3 ++-
 audio/dsound_template.h | 6 --
 audio/noaudio.c | 4 ++--
 audio/ossaudio.c| 5 +++--
 audio/paaudio.c | 5 +++--
 audio/sdlaudio.c| 3 ++-
 audio/spiceaudio.c  | 5 +++--
 audio/wavaudio.c| 5 ++---
 11 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 74ead97..87e71c6 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -819,7 +819,8 @@ static void alsa_fini_out (HWVoiceOut *hw)
 alsa-pcm_buf = NULL;
 }
 
-static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
+ void *drv_opaque)
 {
 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 struct alsa_params_req req;
@@ -928,7 +929,7 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return -1;
 }
 
-static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void 
*drv_opaque)
 {
 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 struct alsa_params_req req;
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 0eba44f..566df5e 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -156,13 +156,13 @@ struct audio_driver {
 };
 
 struct audio_pcm_ops {
-int  (*init_out)(HWVoiceOut *hw, struct audsettings *as);
+int  (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_out)(HWVoiceOut *hw);
 int  (*run_out) (HWVoiceOut *hw, int live);
 int  (*write)   (SWVoiceOut *sw, void *buf, int size);
 int  (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
 
-int  (*init_in) (HWVoiceIn *hw, struct audsettings *as);
+int  (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_in) (HWVoiceIn *hw);
 int  (*run_in)  (HWVoiceIn *hw);
 int  (*read)(SWVoiceIn *sw, void *buf, int size);
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 584e536..f716d97 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -262,7 +262,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct 
audsettings *as)
 #ifdef DAC
 QLIST_INIT (hw-cap_head);
 #endif
-if (glue (hw-pcm_ops-init_, TYPE) (hw, as)) {
+if (glue (hw-pcm_ops-init_, TYPE) (hw, as, s-drv_opaque)) {
 goto err0;
 }
 
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 5964c62..20346bc 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -287,7 +287,8 @@ static int coreaudio_write (SWVoiceOut *sw, void *buf, int 
len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
+  void *drv_opaque)
 {
 OSStatus status;
 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 8b37d16..98276fb 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -174,9 +174,11 @@ static void dsound_fini_out (HWVoiceOut *hw)
 }
 
 #ifdef DSBTYPE_IN
-static int dsound_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
+  void *drv_opaque)
 #else
-static int dsound_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
+   void *drv_opaque)
 #endif
 {
 int err;
diff --git a/audio/noaudio.c b/audio/noaudio.c
index cb38662..50db1f3 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -63,7 +63,7 @@ static int no_write (SWVoiceOut *sw, void *buf, int len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int no_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void 
*drv_opaque)
 {
 audio_pcm_init_info (hw-info, as);
 hw-samples = 1024;
@@ -82,7 +82,7 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return 0;
 }
 
-static int no_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
 {
 audio_pcm_init_info (hw-info, as);
 hw-samples = 1024;
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 4db2ca6..069ff60 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -510,7 +510,8 @@ static void oss_fini_out

[Qemu-devel] [PATCH v2 09/12] dsoundaudio: do not use global variables

2015-06-03 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/dsound_template.h |  18 
 audio/dsoundaudio.c | 106 
 2 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 98276fb..85ba858 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -67,7 +67,8 @@ static int glue (dsound_lock_, TYPE) (
 LPVOID *p2p,
 DWORD *blen1p,
 DWORD *blen2p,
-int entire
+int entire,
+dsound *s
 )
 {
 HRESULT hr;
@@ -75,13 +76,14 @@ static int glue (dsound_lock_, TYPE) (
 LPVOID p1 = NULL, p2 = NULL;
 DWORD blen1 = 0, blen2 = 0;
 DWORD flag;
+DSoundConf *conf = s-conf;
 
 #ifdef DSBTYPE_IN
 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
 #else
 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
 #endif
-for (i = 0; i  conf.lock_retries; ++i) {
+for (i = 0; i  conf-lock_retries; ++i) {
 hr = glue (IFACE, _Lock) (
 buf,
 pos,
@@ -96,7 +98,7 @@ static int glue (dsound_lock_, TYPE) (
 if (FAILED (hr)) {
 #ifndef DSBTYPE_IN
 if (hr == DSERR_BUFFERLOST) {
-if (glue (dsound_restore_, TYPE) (buf)) {
+if (glue (dsound_restore_, TYPE) (buf, s)) {
 dsound_logerr (hr, Could not lock  NAME \n);
 goto fail;
 }
@@ -110,7 +112,7 @@ static int glue (dsound_lock_, TYPE) (
 break;
 }
 
-if (i == conf.lock_retries) {
+if (i == conf-lock_retries) {
 dolog (%d attempts to lock  NAME  failed\n, i);
 goto fail;
 }
@@ -183,9 +185,10 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 {
 int err;
 HRESULT hr;
-dsound *s = glob_dsound;
+dsound *s = drv_opaque;
 WAVEFORMATEX wfx;
 struct audsettings obt_as;
+DSoundConf *conf = s-conf;
 #ifdef DSBTYPE_IN
 const char *typ = ADC;
 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
@@ -212,7 +215,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 bd.dwSize = sizeof (bd);
 bd.lpwfxFormat = wfx;
 #ifdef DSBTYPE_IN
-bd.dwBufferBytes = conf.bufsize_in;
+bd.dwBufferBytes = conf-bufsize_in;
 hr = IDirectSoundCapture_CreateCaptureBuffer (
 s-dsound_capture,
 bd,
@@ -221,7 +224,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 );
 #else
 bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
-bd.dwBufferBytes = conf.bufsize_out;
+bd.dwBufferBytes = conf-bufsize_out;
 hr = IDirectSound_CreateSoundBuffer (
 s-dsound,
 bd,
@@ -271,6 +274,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 );
 }
 hw-samples = bc.dwBufferBytes  hw-info.shift;
+ds-s = s;
 
 #ifdef DEBUG_DSOUND
 dolog (caps %ld, desc %ld\n,
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index e2d89fd..c8b09e2 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -41,7 +41,7 @@
 
 /* #define DEBUG_DSOUND */
 
-static struct {
+typedef struct {
 int lock_retries;
 int restore_retries;
 int getstatus_retries;
@@ -50,33 +50,22 @@ static struct {
 int bufsize_out;
 struct audsettings settings;
 int latency_millis;
-} conf = {
-.lock_retries   = 1,
-.restore_retries= 1,
-.getstatus_retries  = 1,
-.set_primary= 0,
-.bufsize_in = 16384,
-.bufsize_out= 16384,
-.settings.freq  = 44100,
-.settings.nchannels = 2,
-.settings.fmt   = AUD_FMT_S16,
-.latency_millis = 10
-};
+} DSoundConf;
 
 typedef struct {
 LPDIRECTSOUND dsound;
 LPDIRECTSOUNDCAPTURE dsound_capture;
 LPDIRECTSOUNDBUFFER dsound_primary_buffer;
 struct audsettings settings;
+DSoundConf conf;
 } dsound;
 
-static dsound glob_dsound;
-
 typedef struct {
 HWVoiceOut hw;
 LPDIRECTSOUNDBUFFER dsound_buffer;
 DWORD old_pos;
 int first_time;
+dsound *s;
 #ifdef DEBUG_DSOUND
 DWORD old_ppos;
 DWORD played;
@@ -88,6 +77,7 @@ typedef struct {
 HWVoiceIn hw;
 int first_time;
 LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+dsound *s;
 } DSoundVoiceIn;
 
 static void dsound_log_hresult (HRESULT hr)
@@ -281,12 +271,12 @@ static void print_wave_format (WAVEFORMATEX *wfx)
 }
 #endif
 
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
+static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
 {
 HRESULT hr;
 int i;
 
-for (i = 0; i  conf.restore_retries; ++i) {
+for (i = 0; i  s-conf.restore_retries; ++i) {
 hr = IDirectSoundBuffer_Restore (dsb);
 
 switch (hr) {
@@ -311,12 +301,13 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
 #include dsound_template.h
 #undef DSBTYPE_IN
 
-static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
+static int

[Qemu-devel] [RFC PATCH] qapi for audio backends

2015-06-03 Thread Kővágó, Zoltán
This is a proposal to add structures into qapi-schema.json to replace the
existing configuration structures used by audio backends currently. I'm going to
use it to implement a new way to specify audio backend options (an -audiodev
command line option, instead of environment variables. This will also allow us
to use multiple audio backends in one qemu instance), so the structure used here
will be the basis of the command line syntax.

This is currently more or less a direct translation of the current audio backend
options. I've changed some names, trying to accomplish a more consistent naming
scheme. I wouldn't be surprised if there were options that doesn't work if you
set their value to anything other than the default (for example, log to monitor
can crash qemu, QEMU_DSOUND_RESTOURE_RETRIES has a typo, so probably nobody used
it, etc). I've also tried to reduce copy-paste, when the same set of options can
be given to output and input (QEMU_*_DAC_* and QEMU_*_ADC_* options), also using
in and out instead of ADC and DAC, as in the world of SPDIF and HDMI it's
completely possible that your computer has nothing to do with analog converters.
Plus a non technician user probably has no idea what ADC and DAC stands for.

Any comment is appreciated.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 qapi-schema.json | 330 +++
 1 file changed, 330 insertions(+)

diff --git a/qapi-schema.json b/qapi-schema.json
index 0662a9b..ff67d5a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3769,3 +3769,333 @@
 # Since: 2.1
 ##
 { 'command': 'rtc-reset-reinjection' }
+
+##
+# @AudiodevNoneOptions
+#
+# The dummy audio backend has no options.
+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevNoneOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use.
+#
+# @period_size_usec: #optional the period size in microseconds. Must not be
+#specified with @period_size_frames.
+#
+# @period_size_frames: #optional the period size in frames. Must not be
+#  specified with @period_size_usec.
+#
+# @buffer_size_usec: #optional the buffer size in microseconds. Must not be
+#specified with @buffer_size_frames.
+#
+# @buffer_size_frames: #optional the buffer size in frames. Must not be
+#  specified with @buffer_size_usec.
+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data': {
+'*dev':'str',
+'*period_size_usec':   'int',
+'*period_size_frames': 'int',
+'*buffer_size_usec':   'int',
+'*buffer_size_frames': 'int' } }
+
+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @in: #optional options of the capture stream.
+#
+# @out: #optional options of the playback stream.
+#
+# @threshold: #optional
+#
+# @verbose: #optional behave in a more verbose way
+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevAlsaOptions',
+  'data': {
+'*in':  'AudiodevAlsaPerDirectionOptions',
+'*out': 'AudiodevAlsaPerDirectionOptions',
+'*threshold': 'int',
+'*verbose':   'bool' } }
+
+##
+# @AudiodevCoreaudioOptions
+#
+# Options of the coreaudio backend.
+#
+# @buffer_size: #optional size of the buffer in frames
+#
+# @buffer_count: #optional number of buffers
+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevCoreaudioOptions',
+  'data': {
+'*buffer_size':  'int',
+'*buffer_count': 'int' } }
+
+##
+# @AudiodevDsoundPerDirectionOptions
+#
+# Options of the dsound backend that are used for both playback and recording.
+#
+# @bufsize: #optional
+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevDsoundPerDirectionOptions',
+  'data' : {
+'*bufsize': 'int' } }
+
+##
+# @AudiodevDsoundOptions
+#
+# Options of the dsound audio backend.
+#
+# @in: #optional options of the capture stream.
+#
+# @out: #optional options of the playback stream.
+#
+# @lock_retries: #optional number of times to attempt locking the buffer
+#
+# @restore_retries: #optional number of times to attempt restoring the buffer
+#
+# @getstatus_retries: #optional number of times to attempt getting status of 
the
+# buffer
+#
+# @set_primary: #optional set the parameters of primary buffer
+#
+# @latency_millis: #optional
+#
+# @primary_freq: #optional primary buffer frequency
+#
+# @primary_channels: #optional primary buffer number of channels
+#
+# @primary_format: #optional primary buffer format
+#
+# Since: XXX
+##
+{ 'struct': 'AudiodevDsoundOptions',
+  'data': {
+'*in':'AudiodevDsoundPerDirectionOptions',
+'*out':   'AudiodevDsoundPerDirectionOptions',
+'*lock_retries':  'int',
+'*restore_retries':   'int',
+'*getstatus_retries': 'int',
+'*set_primary':   'bool',
+'*latency_millis':'int',
+'*primary_freq':  'int

Re: [Qemu-devel] [PULL 00/12] audio patch queue

2015-06-09 Thread Kővágó Zoltán

2015-06-09 15:03 keltezéssel, Peter Maydell írta:


...and a further long list of errors which I assume are mostly
run-on from not finding the header file.

This looks like it's because configure is now using
dsound by default rather than winwave.


Yes, the winwave backend was removed, so dsound is the new default.

Thanks,
Zoltan




[Qemu-devel] [PATCH 3/5] qapi: change Netdev and NetLegacy into a flat union

2015-06-23 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 hw/arm/musicpal.c|   2 +-
 hw/core/qdev-properties-system.c |   2 +-
 hw/net/allwinner_emac.c  |   2 +-
 hw/net/cadence_gem.c |   2 +-
 hw/net/dp8393x.c |   2 +-
 hw/net/e1000.c   |   2 +-
 hw/net/eepro100.c|   2 +-
 hw/net/etraxfs_eth.c |   2 +-
 hw/net/fsl_etsec/etsec.c |   2 +-
 hw/net/lan9118.c |   2 +-
 hw/net/lance.c   |   2 +-
 hw/net/mcf_fec.c |   2 +-
 hw/net/milkymist-minimac2.c  |   2 +-
 hw/net/mipsnet.c |   2 +-
 hw/net/ne2000-isa.c  |   2 +-
 hw/net/ne2000.c  |   2 +-
 hw/net/opencores_eth.c   |   2 +-
 hw/net/pcnet-pci.c   |   2 +-
 hw/net/rocker/rocker_fp.c|   2 +-
 hw/net/rtl8139.c |   2 +-
 hw/net/smc91c111.c   |   2 +-
 hw/net/spapr_llan.c  |   2 +-
 hw/net/stellaris_enet.c  |   2 +-
 hw/net/vhost_net.c   |  18 +++
 hw/net/virtio-net.c  |   6 +--
 hw/net/vmxnet3.c |   2 +-
 hw/net/xen_nic.c |   2 +-
 hw/net/xgmac.c   |   2 +-
 hw/net/xilinx_axienet.c  |   2 +-
 hw/net/xilinx_ethlite.c  |   2 +-
 hw/usb/dev-network.c |   2 +-
 include/net/net.h|   4 +-
 monitor.c|  14 ++---
 net/clients.h|  20 +++
 net/dump.c   |   9 ++--
 net/hub.c|  24 -
 net/l2tpv3.c |   9 ++--
 net/net.c| 110 +++
 net/netmap.c |   6 +--
 net/slirp.c  |   9 ++--
 net/socket.c |  11 ++--
 net/tap-win32.c  |   9 ++--
 net/tap.c|  29 +--
 net/vde.c|   9 ++--
 net/vhost-user.c |  15 +++---
 qapi-schema.json | 103 +---
 46 files changed, 239 insertions(+), 224 deletions(-)

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index a3b1314..72e2f8f 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -379,7 +379,7 @@ static void eth_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_mv88w8618_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = eth_can_receive,
 .receive = eth_receive,
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index aa794ca..65ab5a9 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -213,7 +213,7 @@ static void set_netdev(Object *obj, Visitor *v, void 
*opaque,
 }
 
 queues = qemu_find_net_clients_except(str, peers,
-  NET_CLIENT_OPTIONS_KIND_NIC,
+  NET_CLIENT_DRIVER_NIC,
   MAX_QUEUE_NUM);
 if (queues == 0) {
 err = -ENOENT;
diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index 0407dee..4fdf824 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -422,7 +422,7 @@ static const MemoryRegionOps aw_emac_mem_ops = {
 };
 
 static NetClientInfo net_aw_emac_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = aw_emac_can_receive,
 .receive = aw_emac_receive,
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 494a346..d74136a 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1175,7 +1175,7 @@ static void gem_set_link(NetClientState *nc)
 }
 
 static NetClientInfo net_gem_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = gem_can_receive,
 .receive = gem_receive,
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index cd889bc..504a4a1 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -807,7 +807,7 @@ static void dp8393x_reset(DeviceState *dev)
 }
 
 static NetClientInfo net_dp83932_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = dp8393x_can_receive,
 .receive = dp8393x_receive,
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index bab8e2a..fc8bf0d 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1512,7 +1512,7 @@ pci_e1000_uninit(PCIDevice *dev)
 }
 
 static NetClientInfo net_e1000_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = e1000_can_receive,
 .receive = e1000_receive,
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index c374c1a..cc4e0ae 100644
--- a/hw

[Qemu-devel] [PATCH 4/5] qapi: support nested structs in OptsVisitor

2015-06-23 Thread Kővágó, Zoltán
The current OptsVisitor flattens the whole structure, if there are same
named fields under different paths the current visitor can't cope with
them (it'll just set the first field, leaving the others unspecified (if
they're optional) or erroring out (if they're required).

This patch add support for it, by always requiring a complete path in
case of nested structs.  Fields in the path are separated by dots,
similar to C structs (without pointers), like `foo.bar'.

You must provide a full path even in non-ambigous cases.  The previous
two commits hopefully ensures that this change doesn't create backward
compatibility problems.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Rationale for this commit: see these threads
http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg04189.html
http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg04186.html

Change from v2 -audiodev patch:
* only fully qualified paths are allowed


 qapi/opts-visitor.c | 114 ++--
 tests/qapi-schema/qapi-schema-test.json |   9 ++-
 tests/test-opts-visitor.c   |  34 ++
 3 files changed, 135 insertions(+), 22 deletions(-)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index aa68814..ff61d42 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -71,6 +71,7 @@ struct OptsVisitor
  * schema, with a single mandatory scalar member. */
 ListMode list_mode;
 GQueue *repeated_opts;
+char *repeated_name;
 
 /* When parsing a list of repeating options as integers, values of the form
  * a-b, representing a closed interval, are allowed. Elements in the
@@ -86,6 +87,9 @@ struct OptsVisitor
  * not survive or escape the OptsVisitor object.
  */
 QemuOpt *fake_id_opt;
+
+/* List of field names leading to the current structure. */
+GQueue *nested_names;
 };
 
 
@@ -100,6 +104,7 @@ static void
 opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt)
 {
 GQueue *list;
+assert(opt);
 
 list = g_hash_table_lookup(unprocessed_opts, opt-name);
 if (list == NULL) {
@@ -127,6 +132,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
 if (obj) {
 *obj = g_malloc0(size  0 ? size : 1);
 }
+
+g_queue_push_tail(ov-nested_names, (gpointer) name);
+
 if (ov-depth++  0) {
 return;
 }
@@ -169,6 +177,8 @@ opts_end_struct(Visitor *v, Error **errp)
 OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
 GQueue *any;
 
+g_queue_pop_tail(ov-nested_names);
+
 if (--ov-depth  0) {
 return;
 }
@@ -198,15 +208,54 @@ opts_end_implicit_struct(Visitor *v, Error **errp)
 }
 
 
+static void
+sum_strlen(gpointer data, gpointer user_data)
+{
+const char *str = data;
+size_t *sum_len = user_data;
+
+if (str) { /* skip NULLs */
+*sum_len += strlen(str) + 1;
+}
+}
+
+static void
+append_str(gpointer data, gpointer user_data)
+{
+const char *str = data;
+char *concat_str = user_data;
+
+if (str) {
+strcat(concat_str, str);
+strcat(concat_str, .);
+}
+}
+
+/* lookup a name, using a fully qualified version */
 static GQueue *
-lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp)
+lookup_distinct(const OptsVisitor *ov, const char *name, char **out_key,
+Error **errp)
 {
-GQueue *list;
+GQueue *list = NULL;
+char *key;
+size_t sum_len = strlen(name);
+
+g_queue_foreach(ov-nested_names, sum_strlen, sum_len);
+key = g_malloc(sum_len+1);
+key[0] = 0;
+g_queue_foreach(ov-nested_names, append_str, key);
+strcat(key, name);
+
+list = g_hash_table_lookup(ov-unprocessed_opts, key);
+if (list  out_key) {
+*out_key = g_strdup(key);
+}
 
-list = g_hash_table_lookup(ov-unprocessed_opts, name);
 if (!list) {
 error_setg(errp, QERR_MISSING_PARAMETER, name);
 }
+
+g_free(key);
 return list;
 }
 
@@ -218,7 +267,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)
 
 /* we can't traverse a list in a list */
 assert(ov-list_mode == LM_NONE);
-ov-repeated_opts = lookup_distinct(ov, name, errp);
+ov-repeated_opts = lookup_distinct(ov, name, ov-repeated_name, errp);
 if (ov-repeated_opts != NULL) {
 ov-list_mode = LM_STARTED;
 }
@@ -254,11 +303,9 @@ opts_next_list(Visitor *v, GenericList **list, Error 
**errp)
 /* range has been completed, fall through in order to pop option */
 
 case LM_IN_PROGRESS: {
-const QemuOpt *opt;
-
-opt = g_queue_pop_head(ov-repeated_opts);
+g_queue_pop_head(ov-repeated_opts);
 if (g_queue_is_empty(ov-repeated_opts)) {
-g_hash_table_remove(ov-unprocessed_opts, opt-name);
+g_hash_table_remove(ov-unprocessed_opts, ov-repeated_name);
 return NULL;
 }
 link = (*list)-next;
@@ -284,22 +331,28 @@ opts_end_list(Visitor *v, Error

[Qemu-devel] [PATCH 0/5] qapi flattening + some miscellaneous patches

2015-06-23 Thread Kővágó, Zoltán
I've cherry-picked the qapi related parts from my previous -audiodev
patch series, we can hopefully concentrate on one thing at a time.  The
most important changes in this patch series are the flattening of the
Netdev structures.  This way we can add proper nested structure support
into OptsVisitor, without requiring backward-compatibility hacks.

These patches are essentially same as the patches in v3 -audiodev
option, except that I updated it to master (and fixed the conflicts due
to error handling related changes).

Please review.

Kővágó, Zoltán (5):
  qapi: support implicit structs in OptsVisitor
  qapi: convert NumaOptions into a flat union
  qapi: change Netdev and NetLegacy into a flat union
  qapi: support nested structs in OptsVisitor
  opts: produce valid command line in qemu_opts_print

 block.c |   2 +-
 hw/arm/musicpal.c   |   2 +-
 hw/core/qdev-properties-system.c|   2 +-
 hw/net/allwinner_emac.c |   2 +-
 hw/net/cadence_gem.c|   2 +-
 hw/net/dp8393x.c|   2 +-
 hw/net/e1000.c  |   2 +-
 hw/net/eepro100.c   |   2 +-
 hw/net/etraxfs_eth.c|   2 +-
 hw/net/fsl_etsec/etsec.c|   2 +-
 hw/net/lan9118.c|   2 +-
 hw/net/lance.c  |   2 +-
 hw/net/mcf_fec.c|   2 +-
 hw/net/milkymist-minimac2.c |   2 +-
 hw/net/mipsnet.c|   2 +-
 hw/net/ne2000-isa.c |   2 +-
 hw/net/ne2000.c |   2 +-
 hw/net/opencores_eth.c  |   2 +-
 hw/net/pcnet-pci.c  |   2 +-
 hw/net/rocker/rocker_fp.c   |   2 +-
 hw/net/rtl8139.c|   2 +-
 hw/net/smc91c111.c  |   2 +-
 hw/net/spapr_llan.c |   2 +-
 hw/net/stellaris_enet.c |   2 +-
 hw/net/vhost_net.c  |  18 ++--
 hw/net/virtio-net.c |   6 +-
 hw/net/vmxnet3.c|   2 +-
 hw/net/xen_nic.c|   2 +-
 hw/net/xgmac.c  |   2 +-
 hw/net/xilinx_axienet.c |   2 +-
 hw/net/xilinx_ethlite.c |   2 +-
 hw/usb/dev-network.c|   2 +-
 include/net/net.h   |   4 +-
 monitor.c   |  14 +--
 net/clients.h   |  20 ++---
 net/dump.c  |   9 +-
 net/hub.c   |  24 +++--
 net/l2tpv3.c|   9 +-
 net/net.c   | 110 +++
 net/netmap.c|   6 +-
 net/slirp.c |   9 +-
 net/socket.c|  11 +--
 net/tap-win32.c |   9 +-
 net/tap.c   |  29 +++---
 net/vde.c   |   9 +-
 net/vhost-user.c|  15 ++--
 numa.c  |   2 +-
 qapi-schema.json| 150 +++-
 qapi/opts-visitor.c | 129 ++-
 tests/qapi-schema/qapi-schema-test.json |   9 +-
 tests/test-opts-visitor.c   |  34 
 util/qemu-option.c  |  47 +-
 52 files changed, 471 insertions(+), 262 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH 2/5] qapi: convert NumaOptions into a flat union

2015-06-23 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 numa.c   |  2 +-
 qapi-schema.json | 47 ---
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/numa.c b/numa.c
index 91fc6c1..8b0755d 100644
--- a/numa.c
+++ b/numa.c
@@ -140,7 +140,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error 
**errp)
 }
 
 switch (object-kind) {
-case NUMA_OPTIONS_KIND_NODE:
+case NUMA_DRIVER_NODE:
 numa_node_parse(object-node, opts, err);
 if (err) {
 goto error;
diff --git a/qapi-schema.json b/qapi-schema.json
index 106008c..7ebf99e 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3537,17 +3537,6 @@
   'data': { '*console':'int', 'events': [ 'InputEvent' ] } }
 
 ##
-# @NumaOptions
-#
-# A discriminated record of NUMA options. (for OptsVisitor)
-#
-# Since 2.1
-##
-{ 'union': 'NumaOptions',
-  'data': {
-'node': 'NumaNodeOptions' }}
-
-##
 # @NumaNodeOptions
 #
 # Create a guest NUMA node. (for OptsVisitor)
@@ -3574,6 +3563,42 @@
'*memdev': 'str' }}
 
 ##
+# @NumaDriver
+#
+# List of possible numa drivers.
+#
+# Since: 2.4
+##
+{ 'enum': 'NumaDriver',
+  'data': [ 'node' ] }
+
+##
+# @NumaCommonOptions
+#
+# Common set of numa options.
+#
+# @type: the numa driver to use
+#
+# Since: 2.4
+##
+{ 'struct': 'NumaCommonOptions',
+  'data': {
+'type': 'NumaDriver' } }
+
+##
+# @NumaOptions
+#
+# A discriminated record of NUMA options. (for OptsVisitor)
+#
+# Since 2.1
+##
+{ 'union': 'NumaOptions',
+  'base': 'NumaCommonOptions',
+  'discriminator': 'type',
+  'data': {
+'node': 'NumaNodeOptions' }}
+
+##
 # @HostMemPolicy
 #
 # Host memory policy types
-- 
2.4.3




[Qemu-devel] [PATCH 5/5] opts: produce valid command line in qemu_opts_print

2015-06-23 Thread Kővágó, Zoltán
This will let us print options in a format that the user would actually
write it on the command line (foo=bar,baz=asd,etc=def), without
prepending a spurious comma at the beginning of the list, or quoting
values unnecessarily.  This patch provides the following changes:
* write and id=, if the option has an id
* do not print separator before the first element
* do not quote string arguments which only contains letters or numbers
* properly escape commas (,) for QEMU, apostrophe (') for shell

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Chages from v1 -audiodev patch:
* print id=
* proper value escaping (apostrophe and comma)
* renamed d_sep - separator


 block.c|  2 +-
 util/qemu-option.c | 47 ---
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/block.c b/block.c
index e2e33fd..a18af00 100644
--- a/block.c
+++ b/block.c
@@ -3825,7 +3825,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 }
 
 if (!quiet) {
-printf(Formatting '%s', fmt=%s, filename, fmt);
+printf(Formatting '%s', fmt=%s , filename, fmt);
 qemu_opts_print(opts,  );
 puts();
 }
diff --git a/util/qemu-option.c b/util/qemu-option.c
index efe9d27..db60ac9 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -730,14 +730,53 @@ void qemu_opts_del(QemuOpts *opts)
 g_free(opts);
 }
 
-void qemu_opts_print(QemuOpts *opts, const char *sep)
+/* print value properly escaping it for the shell (at least for bash) */
+static void escaped_print(const char *value)
+{
+const char *ptr;
+bool need_quote = false;
+
+for (ptr = value; *ptr; ++ptr) {
+if (!qemu_isalnum(*ptr)) {
+need_quote = true;
+break;
+}
+}
+
+if (need_quote) {
+putchar('\'');
+for (ptr = value; *ptr; ++ptr) {
+if (*ptr == '\'') {
+printf('\\'');
+} else if (*ptr == ',') {
+printf(,,);
+} else {
+putchar(*ptr);
+}
+}
+putchar('\'');
+} else {
+printf(%s, value);
+}
+}
+
+void qemu_opts_print(QemuOpts *opts, const char *separator)
 {
 QemuOpt *opt;
 QemuOptDesc *desc = opts-list-desc;
+const char *sep = ;
+
+if (opts-id) {
+printf(id=);
+escaped_print(opts-id);
+sep = separator;
+}
 
 if (desc[0].name == NULL) {
 QTAILQ_FOREACH(opt, opts-head, next) {
-printf(%s%s=\%s\, sep, opt-name, opt-str);
+printf(%s%s=, sep, opt-name);
+escaped_print(opt-str);
+sep = separator;
 }
 return;
 }
@@ -750,13 +789,15 @@ void qemu_opts_print(QemuOpts *opts, const char *sep)
 continue;
 }
 if (desc-type == QEMU_OPT_STRING) {
-printf(%s%s='%s', sep, desc-name, value);
+printf(%s%s=, sep, desc-name);
+escaped_print(value);
 } else if ((desc-type == QEMU_OPT_SIZE ||
 desc-type == QEMU_OPT_NUMBER)  opt) {
 printf(%s%s=% PRId64, sep, desc-name, opt-value.uint);
 } else {
 printf(%s%s=%s, sep, desc-name, value);
 }
+sep = separator;
 }
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH 1/5] qapi: support implicit structs in OptsVisitor

2015-06-23 Thread Kővágó, Zoltán
They are required for flat unions (you still have to allocate the
structs).

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 qapi/opts-visitor.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 7ae33b3..aa68814 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -149,6 +149,12 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
 }
 }
 
+static void
+opts_start_implicit_struct(Visitor *v, void **obj, size_t size, Error **errp)
+{
+opts_start_struct(v, obj, NULL, NULL, size, errp);
+}
+
 
 static gboolean
 ghr_true(gpointer ign_key, gpointer ign_value, gpointer ign_user_data)
@@ -185,6 +191,12 @@ opts_end_struct(Visitor *v, Error **errp)
 ov-fake_id_opt = NULL;
 }
 
+static void
+opts_end_implicit_struct(Visitor *v, Error **errp)
+{
+opts_end_struct(v, errp);
+}
+
 
 static GQueue *
 lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp)
@@ -508,6 +520,9 @@ opts_visitor_new(const QemuOpts *opts)
 ov-visitor.start_struct = opts_start_struct;
 ov-visitor.end_struct   = opts_end_struct;
 
+ov-visitor.start_implicit_struct = opts_start_implicit_struct;
+ov-visitor.end_implicit_struct = opts_end_implicit_struct;
+
 ov-visitor.start_list = opts_start_list;
 ov-visitor.next_list  = opts_next_list;
 ov-visitor.end_list   = opts_end_list;
-- 
2.4.3




[Qemu-devel] [PATCH v3 0/8] -audiodev option

2015-06-18 Thread Kővágó, Zoltán
This series of patches adds a new -audiodev command line option to
specify audio subsytem parameters instead of environment variables.
This  will later allow us to specify multiple audio backends.  The
syntax is something like this:
 -audiodev driver_name,id=id,property=value,...
like:
 -audiodev alsa,id=foo,frequency=8000,channels=1

This series also convert numa and netdev qapi to flat unions, to avoid
extra complexity in OptsVisitor.  Please refer to the thread at v2
patch.

You are encouraged check whether I break anything during the
refactorings (especially at netdev and various audio backends).  For
easier testing, pull https://github.com/DirtYiCE/qemu.git tag 
audio-cmdline-v3.

Please review (especially the qapi refactoring I did...)

Changes from v2:
* consistency, style issues in audio qapi
* converted NumaOptions and Netdev and friends to flat union
* OptsVisitor: only full paths accepted
* qemu_opts_print: hopefully produces valid command line in all cases
* other small fixes...

Changes from v1:
* updated to master, removed commits already merged
* now every time-related option takes usecs
* some small fixes

Kővágó, Zoltán (8):
  qapi: support implicit structs in OptsVisitor
  qapi: convert NumaOptions into a flat union
  qapi: change Netdev and NetLegacy into a flat union
  qapi: qapi for audio backends
  qapi: support nested structs in OptsVisitor
  opts: produce valid command line in qemu_opts_print
  audio: use qapi AudioFormat instead of audfmt_e
  audio: -audiodev command line option

 Makefile|   4 +-
 audio/Makefile.objs |   2 +-
 audio/alsaaudio.c   | 346 +-
 audio/audio.c   | 792 +---
 audio/audio.h   |  34 +-
 audio/audio_int.h   |   7 +-
 audio/audio_legacy.c| 328 +
 audio/audio_template.h  |  13 +-
 audio/audio_win_int.c   |  18 +-
 audio/coreaudio.c   |  49 +-
 audio/dsound_template.h |   6 +-
 audio/dsoundaudio.c |  60 +--
 audio/noaudio.c |   3 +-
 audio/ossaudio.c| 182 +++-
 audio/paaudio.c | 108 ++---
 audio/sdlaudio.c|  50 +-
 audio/spiceaudio.c  |  11 +-
 audio/wavaudio.c|  75 +--
 audio/wavcapture.c  |   2 +-
 block.c |   2 +-
 hw/arm/musicpal.c   |   2 +-
 hw/arm/omap2.c  |   2 +-
 hw/audio/ac97.c |   2 +-
 hw/audio/adlib.c|   2 +-
 hw/audio/cs4231a.c  |   6 +-
 hw/audio/es1370.c   |   4 +-
 hw/audio/gus.c  |   2 +-
 hw/audio/hda-codec.c|  18 +-
 hw/audio/lm4549.c   |   6 +-
 hw/audio/milkymist-ac97.c   |   2 +-
 hw/audio/pcspk.c|   2 +-
 hw/audio/sb16.c |  14 +-
 hw/audio/wm8750.c   |   4 +-
 hw/core/qdev-properties-system.c|   2 +-
 hw/input/tsc210x.c  |   2 +-
 hw/net/allwinner_emac.c |   2 +-
 hw/net/cadence_gem.c|   2 +-
 hw/net/dp8393x.c|   2 +-
 hw/net/e1000.c  |   2 +-
 hw/net/eepro100.c   |   2 +-
 hw/net/etraxfs_eth.c|   2 +-
 hw/net/fsl_etsec/etsec.c|   2 +-
 hw/net/lan9118.c|   2 +-
 hw/net/lance.c  |   2 +-
 hw/net/mcf_fec.c|   2 +-
 hw/net/milkymist-minimac2.c |   2 +-
 hw/net/mipsnet.c|   2 +-
 hw/net/ne2000-isa.c |   2 +-
 hw/net/ne2000.c |   2 +-
 hw/net/opencores_eth.c  |   2 +-
 hw/net/pcnet-pci.c  |   2 +-
 hw/net/rocker/rocker_fp.c   |   2 +-
 hw/net/rtl8139.c|   2 +-
 hw/net/smc91c111.c  |   2 +-
 hw/net/spapr_llan.c |   2 +-
 hw/net/stellaris_enet.c |   2 +-
 hw/net/vhost_net.c  |  18 +-
 hw/net/virtio-net.c |   6 +-
 hw/net/vmxnet3.c|   2 +-
 hw/net/xen_nic.c|   2 +-
 hw/net/xgmac.c  |   2 +-
 hw/net/xilinx_axienet.c |   2 +-
 hw/net/xilinx_ethlite.c |   2 +-
 hw/usb/dev-audio.c  |   2 +-
 hw/usb/dev-network.c|   2 +-
 include/net/net.h   |   4 +-
 monitor.c   |  14 +-
 net/clients.h   |  20 +-
 net

[Qemu-devel] [PATCH v3 2/8] qapi: convert NumaOptions into a flat union

2015-06-18 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 numa.c   |  2 +-
 qapi-schema.json | 47 ---
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/numa.c b/numa.c
index d227ccc..822a22e 100644
--- a/numa.c
+++ b/numa.c
@@ -141,7 +141,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error 
**errp)
 }
 
 switch (object-kind) {
-case NUMA_OPTIONS_KIND_NODE:
+case NUMA_DRIVER_NODE:
 numa_node_parse(object-node, opts, err);
 if (err) {
 goto error;
diff --git a/qapi-schema.json b/qapi-schema.json
index 106008c..7ebf99e 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3537,17 +3537,6 @@
   'data': { '*console':'int', 'events': [ 'InputEvent' ] } }
 
 ##
-# @NumaOptions
-#
-# A discriminated record of NUMA options. (for OptsVisitor)
-#
-# Since 2.1
-##
-{ 'union': 'NumaOptions',
-  'data': {
-'node': 'NumaNodeOptions' }}
-
-##
 # @NumaNodeOptions
 #
 # Create a guest NUMA node. (for OptsVisitor)
@@ -3574,6 +3563,42 @@
'*memdev': 'str' }}
 
 ##
+# @NumaDriver
+#
+# List of possible numa drivers.
+#
+# Since: 2.4
+##
+{ 'enum': 'NumaDriver',
+  'data': [ 'node' ] }
+
+##
+# @NumaCommonOptions
+#
+# Common set of numa options.
+#
+# @type: the numa driver to use
+#
+# Since: 2.4
+##
+{ 'struct': 'NumaCommonOptions',
+  'data': {
+'type': 'NumaDriver' } }
+
+##
+# @NumaOptions
+#
+# A discriminated record of NUMA options. (for OptsVisitor)
+#
+# Since 2.1
+##
+{ 'union': 'NumaOptions',
+  'base': 'NumaCommonOptions',
+  'discriminator': 'type',
+  'data': {
+'node': 'NumaNodeOptions' }}
+
+##
 # @HostMemPolicy
 #
 # Host memory policy types
-- 
2.4.3




[Qemu-devel] [PATCH v3 5/8] qapi: support nested structs in OptsVisitor

2015-06-18 Thread Kővágó, Zoltán
The current OptsVisitor flattens the whole structure, if there are same
named fields under different paths (like `in' and `out' in `Audiodev'),
the current visitor can't cope with them (for example setting
`frequency=44100' will set the in's frequency to 44100 and leave out's
frequency unspecified).

This patch fixes it, by always requiring a complete path in case of
nested structs.  Fields in the path are separated by dots, similar to C
structs (without pointers), like `in.frequency' or`out.frequency'.

You must provide a full path even in non-ambigous cases.  The previous
two commits hopefully ensures that this change doesn't create backward
compatibility problems.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Change from v2:
* only fully qualified paths are allowed

 qapi/opts-visitor.c | 114 ++--
 tests/qapi-schema/qapi-schema-test.json |   9 ++-
 tests/test-opts-visitor.c   |  34 ++
 3 files changed, 135 insertions(+), 22 deletions(-)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index f02059d..7a80442 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -71,6 +71,7 @@ struct OptsVisitor
  * schema, with a single mandatory scalar member. */
 ListMode list_mode;
 GQueue *repeated_opts;
+char *repeated_name;
 
 /* When parsing a list of repeating options as integers, values of the form
  * a-b, representing a closed interval, are allowed. Elements in the
@@ -86,6 +87,9 @@ struct OptsVisitor
  * not survive or escape the OptsVisitor object.
  */
 QemuOpt *fake_id_opt;
+
+/* List of field names leading to the current structure. */
+GQueue *nested_names;
 };
 
 
@@ -100,6 +104,7 @@ static void
 opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt)
 {
 GQueue *list;
+assert(opt);
 
 list = g_hash_table_lookup(unprocessed_opts, opt-name);
 if (list == NULL) {
@@ -127,6 +132,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
 if (obj) {
 *obj = g_malloc0(size  0 ? size : 1);
 }
+
+g_queue_push_tail(ov-nested_names, (gpointer) name);
+
 if (ov-depth++  0) {
 return;
 }
@@ -169,6 +177,8 @@ opts_end_struct(Visitor *v, Error **errp)
 OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
 GQueue *any;
 
+g_queue_pop_tail(ov-nested_names);
+
 if (--ov-depth  0) {
 return;
 }
@@ -198,15 +208,54 @@ opts_end_implicit_struct(Visitor *v, Error **errp)
 }
 
 
+static void
+sum_strlen(gpointer data, gpointer user_data)
+{
+const char *str = data;
+size_t *sum_len = user_data;
+
+if (str) { /* skip NULLs */
+*sum_len += strlen(str) + 1;
+}
+}
+
+static void
+append_str(gpointer data, gpointer user_data)
+{
+const char *str = data;
+char *concat_str = user_data;
+
+if (str) {
+strcat(concat_str, str);
+strcat(concat_str, .);
+}
+}
+
+/* lookup a name, using a fully qualified version */
 static GQueue *
-lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp)
+lookup_distinct(const OptsVisitor *ov, const char *name, char **out_key,
+Error **errp)
 {
-GQueue *list;
+GQueue *list = NULL;
+char *key;
+size_t sum_len = strlen(name);
+
+g_queue_foreach(ov-nested_names, sum_strlen, sum_len);
+key = g_malloc(sum_len+1);
+key[0] = 0;
+g_queue_foreach(ov-nested_names, append_str, key);
+strcat(key, name);
+
+list = g_hash_table_lookup(ov-unprocessed_opts, key);
+if (list  out_key) {
+*out_key = g_strdup(key);
+}
 
-list = g_hash_table_lookup(ov-unprocessed_opts, name);
 if (!list) {
 error_set(errp, QERR_MISSING_PARAMETER, name);
 }
+
+g_free(key);
 return list;
 }
 
@@ -218,7 +267,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)
 
 /* we can't traverse a list in a list */
 assert(ov-list_mode == LM_NONE);
-ov-repeated_opts = lookup_distinct(ov, name, errp);
+ov-repeated_opts = lookup_distinct(ov, name, ov-repeated_name, errp);
 if (ov-repeated_opts != NULL) {
 ov-list_mode = LM_STARTED;
 }
@@ -254,11 +303,9 @@ opts_next_list(Visitor *v, GenericList **list, Error 
**errp)
 /* range has been completed, fall through in order to pop option */
 
 case LM_IN_PROGRESS: {
-const QemuOpt *opt;
-
-opt = g_queue_pop_head(ov-repeated_opts);
+g_queue_pop_head(ov-repeated_opts);
 if (g_queue_is_empty(ov-repeated_opts)) {
-g_hash_table_remove(ov-unprocessed_opts, opt-name);
+g_hash_table_remove(ov-unprocessed_opts, ov-repeated_name);
 return NULL;
 }
 link = (*list)-next;
@@ -284,22 +331,28 @@ opts_end_list(Visitor *v, Error **errp)
ov-list_mode == LM_SIGNED_INTERVAL ||
ov-list_mode == LM_UNSIGNED_INTERVAL);
 ov-repeated_opts = NULL;
+
+g_free(ov

[Qemu-devel] [PATCH v3 7/8] audio: use qapi AudioFormat instead of audfmt_e

2015-06-18 Thread Kővágó, Zoltán
I had to include an enum for audio sampling formats into qapi, but that
meant duplicating the audfmt_e enum.  This patch replaces audfmt_e and
associated values with the qapi generated AudioFormat enum.

This patch is mostly a search-and-replace, except for switches where the
qapi generated AUDIO_FORMAT_MAX caused problems.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v2:
* replaced case AUDIO_FORMAT_MAX with default

 audio/alsaaudio.c | 53 ++
 audio/audio.c | 97 ++-
 audio/audio.h | 11 +-
 audio/audio_win_int.c | 18 -
 audio/ossaudio.c  | 30 +++
 audio/paaudio.c   | 28 +++---
 audio/sdlaudio.c  | 26 ++---
 audio/spiceaudio.c|  4 +-
 audio/wavaudio.c  | 17 +
 audio/wavcapture.c|  2 +-
 hw/arm/omap2.c|  2 +-
 hw/audio/ac97.c   |  2 +-
 hw/audio/adlib.c  |  2 +-
 hw/audio/cs4231a.c|  6 +--
 hw/audio/es1370.c |  4 +-
 hw/audio/gus.c|  2 +-
 hw/audio/hda-codec.c  | 18 -
 hw/audio/lm4549.c |  6 +--
 hw/audio/milkymist-ac97.c |  2 +-
 hw/audio/pcspk.c  |  2 +-
 hw/audio/sb16.c   | 14 +++
 hw/audio/wm8750.c |  4 +-
 hw/input/tsc210x.c|  2 +-
 hw/usb/dev-audio.c|  2 +-
 ui/vnc.c  | 14 +++
 25 files changed, 187 insertions(+), 181 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 6315b2d..2b28b99 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -88,7 +88,7 @@ struct alsa_params_req {
 
 struct alsa_params_obt {
 int freq;
-audfmt_e fmt;
+AudioFormat fmt;
 int endianness;
 int nchannels;
 snd_pcm_uframes_t samples;
@@ -295,16 +295,16 @@ static int alsa_write (SWVoiceOut *sw, void *buf, int len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)
+static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
 {
 switch (fmt) {
-case AUD_FMT_S8:
+case AUDIO_FORMAT_S8:
 return SND_PCM_FORMAT_S8;
 
-case AUD_FMT_U8:
+case AUDIO_FORMAT_U8:
 return SND_PCM_FORMAT_U8;
 
-case AUD_FMT_S16:
+case AUDIO_FORMAT_S16:
 if (endianness) {
 return SND_PCM_FORMAT_S16_BE;
 }
@@ -312,7 +312,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_S16_LE;
 }
 
-case AUD_FMT_U16:
+case AUDIO_FORMAT_U16:
 if (endianness) {
 return SND_PCM_FORMAT_U16_BE;
 }
@@ -320,7 +320,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_U16_LE;
 }
 
-case AUD_FMT_S32:
+case AUDIO_FORMAT_S32:
 if (endianness) {
 return SND_PCM_FORMAT_S32_BE;
 }
@@ -328,7 +328,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_S32_LE;
 }
 
-case AUD_FMT_U32:
+case AUDIO_FORMAT_U32:
 if (endianness) {
 return SND_PCM_FORMAT_U32_BE;
 }
@@ -345,58 +345,58 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 }
 }
 
-static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
+static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt,
int *endianness)
 {
 switch (alsafmt) {
 case SND_PCM_FORMAT_S8:
 *endianness = 0;
-*fmt = AUD_FMT_S8;
+*fmt = AUDIO_FORMAT_S8;
 break;
 
 case SND_PCM_FORMAT_U8:
 *endianness = 0;
-*fmt = AUD_FMT_U8;
+*fmt = AUDIO_FORMAT_U8;
 break;
 
 case SND_PCM_FORMAT_S16_LE:
 *endianness = 0;
-*fmt = AUD_FMT_S16;
+*fmt = AUDIO_FORMAT_S16;
 break;
 
 case SND_PCM_FORMAT_U16_LE:
 *endianness = 0;
-*fmt = AUD_FMT_U16;
+*fmt = AUDIO_FORMAT_U16;
 break;
 
 case SND_PCM_FORMAT_S16_BE:
 *endianness = 1;
-*fmt = AUD_FMT_S16;
+*fmt = AUDIO_FORMAT_S16;
 break;
 
 case SND_PCM_FORMAT_U16_BE:
 *endianness = 1;
-*fmt = AUD_FMT_U16;
+*fmt = AUDIO_FORMAT_U16;
 break;
 
 case SND_PCM_FORMAT_S32_LE:
 *endianness = 0;
-*fmt = AUD_FMT_S32;
+*fmt = AUDIO_FORMAT_S32;
 break;
 
 case SND_PCM_FORMAT_U32_LE:
 *endianness = 0;
-*fmt = AUD_FMT_U32;
+*fmt = AUDIO_FORMAT_U32;
 break;
 
 case SND_PCM_FORMAT_S32_BE:
 *endianness = 1;
-*fmt = AUD_FMT_S32;
+*fmt = AUDIO_FORMAT_S32;
 break;
 
 case SND_PCM_FORMAT_U32_BE:
 *endianness = 1;
-*fmt = AUD_FMT_U32;
+*fmt = AUDIO_FORMAT_U32;
 break

[Qemu-devel] [PATCH v3 3/8] qapi: change Netdev and NetLegacy into a flat union

2015-06-18 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 hw/arm/musicpal.c|   2 +-
 hw/core/qdev-properties-system.c |   2 +-
 hw/net/allwinner_emac.c  |   2 +-
 hw/net/cadence_gem.c |   2 +-
 hw/net/dp8393x.c |   2 +-
 hw/net/e1000.c   |   2 +-
 hw/net/eepro100.c|   2 +-
 hw/net/etraxfs_eth.c |   2 +-
 hw/net/fsl_etsec/etsec.c |   2 +-
 hw/net/lan9118.c |   2 +-
 hw/net/lance.c   |   2 +-
 hw/net/mcf_fec.c |   2 +-
 hw/net/milkymist-minimac2.c  |   2 +-
 hw/net/mipsnet.c |   2 +-
 hw/net/ne2000-isa.c  |   2 +-
 hw/net/ne2000.c  |   2 +-
 hw/net/opencores_eth.c   |   2 +-
 hw/net/pcnet-pci.c   |   2 +-
 hw/net/rocker/rocker_fp.c|   2 +-
 hw/net/rtl8139.c |   2 +-
 hw/net/smc91c111.c   |   2 +-
 hw/net/spapr_llan.c  |   2 +-
 hw/net/stellaris_enet.c  |   2 +-
 hw/net/vhost_net.c   |  18 +++
 hw/net/virtio-net.c  |   6 +--
 hw/net/vmxnet3.c |   2 +-
 hw/net/xen_nic.c |   2 +-
 hw/net/xgmac.c   |   2 +-
 hw/net/xilinx_axienet.c  |   2 +-
 hw/net/xilinx_ethlite.c  |   2 +-
 hw/usb/dev-network.c |   2 +-
 include/net/net.h|   4 +-
 monitor.c|  14 ++---
 net/clients.h|  20 +++
 net/dump.c   |   9 ++--
 net/hub.c|  24 -
 net/l2tpv3.c |   9 ++--
 net/net.c| 110 +++
 net/netmap.c |   6 +--
 net/slirp.c  |   9 ++--
 net/socket.c |  11 ++--
 net/tap-win32.c  |   9 ++--
 net/tap.c|  29 +--
 net/vde.c|   9 ++--
 net/vhost-user.c |  15 +++---
 qapi-schema.json | 103 +---
 46 files changed, 239 insertions(+), 224 deletions(-)

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index a3b1314..72e2f8f 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -379,7 +379,7 @@ static void eth_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_mv88w8618_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = eth_can_receive,
 .receive = eth_receive,
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 0309fe5..f094548 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -213,7 +213,7 @@ static void set_netdev(Object *obj, Visitor *v, void 
*opaque,
 }
 
 queues = qemu_find_net_clients_except(str, peers,
-  NET_CLIENT_OPTIONS_KIND_NIC,
+  NET_CLIENT_DRIVER_NIC,
   MAX_QUEUE_NUM);
 if (queues == 0) {
 err = -ENOENT;
diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index 0407dee..4fdf824 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -422,7 +422,7 @@ static const MemoryRegionOps aw_emac_mem_ops = {
 };
 
 static NetClientInfo net_aw_emac_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = aw_emac_can_receive,
 .receive = aw_emac_receive,
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 494a346..d74136a 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1175,7 +1175,7 @@ static void gem_set_link(NetClientState *nc)
 }
 
 static NetClientInfo net_gem_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = gem_can_receive,
 .receive = gem_receive,
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index cd889bc..504a4a1 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -807,7 +807,7 @@ static void dp8393x_reset(DeviceState *dev)
 }
 
 static NetClientInfo net_dp83932_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = dp8393x_can_receive,
 .receive = dp8393x_receive,
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index bab8e2a..fc8bf0d 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1512,7 +1512,7 @@ pci_e1000_uninit(PCIDevice *dev)
 }
 
 static NetClientInfo net_e1000_info = {
-.type = NET_CLIENT_OPTIONS_KIND_NIC,
+.type = NET_CLIENT_DRIVER_NIC,
 .size = sizeof(NICState),
 .can_receive = e1000_can_receive,
 .receive = e1000_receive,
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index c374c1a..cc4e0ae 100644
--- a/hw

[Qemu-devel] [PATCH v3 6/8] opts: produce valid command line in qemu_opts_print

2015-06-18 Thread Kővágó, Zoltán
This will let us print options in a format that the user would actually
write it on the command line (foo=bar,baz=asd,etc=def), without
prepending a spurious comma at the beginning of the list, or quoting
values unnecessarily.  This patch provides the following changes:
* write and id=, if the option has an id
* do not print separator before the first element
* do not quote string arguments which only contains letters or numbers
* properly escape commas (,) for QEMU, apostrophe (') for shell

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Chages from v2:
* print id=
* proper value escaping (apostrophe and comma)
* renamed d_sep - separator

 block.c|  2 +-
 util/qemu-option.c | 47 ---
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/block.c b/block.c
index dd4f58d..c5d456c 100644
--- a/block.c
+++ b/block.c
@@ -3823,7 +3823,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 }
 
 if (!quiet) {
-printf(Formatting '%s', fmt=%s, filename, fmt);
+printf(Formatting '%s', fmt=%s , filename, fmt);
 qemu_opts_print(opts,  );
 puts();
 }
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 840f5f7..911f02d 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -728,14 +728,53 @@ void qemu_opts_del(QemuOpts *opts)
 g_free(opts);
 }
 
-void qemu_opts_print(QemuOpts *opts, const char *sep)
+/* print value properly escaping it for the shell (at least for bash) */
+static void escaped_print(const char *value)
+{
+const char *ptr;
+bool need_quote = false;
+
+for (ptr = value; *ptr; ++ptr) {
+if (!qemu_isalnum(*ptr)) {
+need_quote = true;
+break;
+}
+}
+
+if (need_quote) {
+putchar('\'');
+for (ptr = value; *ptr; ++ptr) {
+if (*ptr == '\'') {
+printf('\\'');
+} else if (*ptr == ',') {
+printf(,,);
+} else {
+putchar(*ptr);
+}
+}
+putchar('\'');
+} else {
+printf(%s, value);
+}
+}
+
+void qemu_opts_print(QemuOpts *opts, const char *separator)
 {
 QemuOpt *opt;
 QemuOptDesc *desc = opts-list-desc;
+const char *sep = ;
+
+if (opts-id) {
+printf(id=);
+escaped_print(opts-id);
+sep = separator;
+}
 
 if (desc[0].name == NULL) {
 QTAILQ_FOREACH(opt, opts-head, next) {
-printf(%s%s=\%s\, sep, opt-name, opt-str);
+printf(%s%s=, sep, opt-name);
+escaped_print(opt-str);
+sep = separator;
 }
 return;
 }
@@ -748,13 +787,15 @@ void qemu_opts_print(QemuOpts *opts, const char *sep)
 continue;
 }
 if (desc-type == QEMU_OPT_STRING) {
-printf(%s%s='%s', sep, desc-name, value);
+printf(%s%s=, sep, desc-name);
+escaped_print(value);
 } else if ((desc-type == QEMU_OPT_SIZE ||
 desc-type == QEMU_OPT_NUMBER)  opt) {
 printf(%s%s=% PRId64, sep, desc-name, opt-value.uint);
 } else {
 printf(%s%s=%s, sep, desc-name, value);
 }
+sep = separator;
 }
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v3 8/8] audio: -audiodev command line option

2015-06-18 Thread Kővágó, Zoltán
This patch adds an -audiodev command line option, and deprecates the
QEMU_* environment variables for audio backend configuration.  It's
syntax is similar to existing options (-netdev, -device, etc): -audiodev
driver_name,property=value,...

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.

Although now it's possible to specify multiple -audiodev options on
command line, multiple audio backends are not supported yet.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v2:
* fixed alsa threshold
* updated to audio qapi changes

Changes from v1:
* updated to everything usecs without suffix
* better rounding when converting between usecs and frames/samples/bytes
* bugfixes in audio_legacy.c
* fixed code broken by qemu_opts changes by Markus

 audio/Makefile.objs |   2 +-
 audio/alsaaudio.c   | 311 ++--
 audio/audio.c   | 741 +---
 audio/audio.h   |  23 +-
 audio/audio_int.h   |   7 +-
 audio/audio_legacy.c| 328 +
 audio/audio_template.h  |  13 +-
 audio/coreaudio.c   |  49 +---
 audio/dsound_template.h |   6 +-
 audio/dsoundaudio.c |  60 ++--
 audio/noaudio.c |   3 +-
 audio/ossaudio.c| 154 +++---
 audio/paaudio.c |  80 ++
 audio/sdlaudio.c|  24 +-
 audio/spiceaudio.c  |   7 +-
 audio/wavaudio.c|  60 +---
 qemu-options.hx | 230 ++-
 vl.c|   9 +-
 18 files changed, 997 insertions(+), 1110 deletions(-)
 create mode 100644 audio/audio_legacy.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 481d1aa..9d8f579 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
+common-obj-y = audio.o audio_legacy.o noaudio.o wavaudio.o mixeng.o
 common-obj-$(CONFIG_SDL) += sdlaudio.o
 common-obj-$(CONFIG_OSS) += ossaudio.o
 common-obj-$(CONFIG_SPICE) += spiceaudio.o
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 2b28b99..cfe4aec 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include alsa/asoundlib.h
+#include qapi-visit.h
 #include qemu-common.h
 #include qemu/main-loop.h
 #include audio.h
@@ -34,28 +35,9 @@
 #define AUDIO_CAP alsa
 #include audio_int.h
 
-typedef struct ALSAConf {
-int size_in_usec_in;
-int size_in_usec_out;
-const char *pcm_name_in;
-const char *pcm_name_out;
-unsigned int buffer_size_in;
-unsigned int period_size_in;
-unsigned int buffer_size_out;
-unsigned int period_size_out;
-unsigned int threshold;
-
-int buffer_size_in_overridden;
-int period_size_in_overridden;
-
-int buffer_size_out_overridden;
-int period_size_out_overridden;
-} ALSAConf;
-
 struct pollhlp {
 snd_pcm_t *handle;
 struct pollfd *pfds;
-ALSAConf *conf;
 int count;
 int mask;
 };
@@ -67,6 +49,7 @@ typedef struct ALSAVoiceOut {
 void *pcm_buf;
 snd_pcm_t *handle;
 struct pollhlp pollhlp;
+Audiodev *dev;
 } ALSAVoiceOut;
 
 typedef struct ALSAVoiceIn {
@@ -74,16 +57,13 @@ typedef struct ALSAVoiceIn {
 snd_pcm_t *handle;
 void *pcm_buf;
 struct pollhlp pollhlp;
+Audiodev *dev;
 } ALSAVoiceIn;
 
 struct alsa_params_req {
 int freq;
 snd_pcm_format_t fmt;
 int nchannels;
-int size_in_usec;
-int override_mask;
-unsigned int buffer_size;
-unsigned int period_size;
 };
 
 struct alsa_params_obt {
@@ -409,7 +389,8 @@ static int alsa_to_audfmt (snd_pcm_format_t alsafmt, 
AudioFormat *fmt,
 
 static void alsa_dump_info (struct alsa_params_req *req,
 struct alsa_params_obt *obt,
-snd_pcm_format_t obtfmt)
+snd_pcm_format_t obtfmt,
+AudiodevPerDirectionOptions *pdo)
 {
 dolog (parameter | requested value | obtained value\n);
 dolog (format|  %10d | %10d\n, req-fmt, obtfmt);
@@ -417,8 +398,9 @@ static void alsa_dump_info (struct alsa_params_req *req,
req-nchannels, obt-nchannels);
 dolog (frequency |  %10d | %10d\n, req-freq, obt-freq);
 dolog (\n);
-dolog (requested: buffer size %d period size %d\n,
-   req-buffer_size, req-period_size);
+dolog (requested: buffer size % PRId64  buffer count % PRId64 \n,
+   pdo-has_buffer_len ? pdo-buffer_len : 0,
+   pdo-has_buffer_len ? pdo-buffer_len : 0);
 dolog (obtained: samples %ld\n, obt-samples

[Qemu-devel] [PATCH v3 1/8] qapi: support implicit structs in OptsVisitor

2015-06-18 Thread Kővágó, Zoltán
They are required for flat unions (you still have to allocate the
structs).

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 qapi/opts-visitor.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index f2ad6d7..f02059d 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -149,6 +149,12 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
 }
 }
 
+static void
+opts_start_implicit_struct(Visitor *v, void **obj, size_t size, Error **errp)
+{
+opts_start_struct(v, obj, NULL, NULL, size, errp);
+}
+
 
 static gboolean
 ghr_true(gpointer ign_key, gpointer ign_value, gpointer ign_user_data)
@@ -185,6 +191,12 @@ opts_end_struct(Visitor *v, Error **errp)
 ov-fake_id_opt = NULL;
 }
 
+static void
+opts_end_implicit_struct(Visitor *v, Error **errp)
+{
+opts_end_struct(v, errp);
+}
+
 
 static GQueue *
 lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp)
@@ -508,6 +520,9 @@ opts_visitor_new(const QemuOpts *opts)
 ov-visitor.start_struct = opts_start_struct;
 ov-visitor.end_struct   = opts_end_struct;
 
+ov-visitor.start_implicit_struct = opts_start_implicit_struct;
+ov-visitor.end_implicit_struct = opts_end_implicit_struct;
+
 ov-visitor.start_list = opts_start_list;
 ov-visitor.next_list  = opts_next_list;
 ov-visitor.end_list   = opts_end_list;
-- 
2.4.3




[Qemu-devel] [PATCH v3 4/8] qapi: qapi for audio backends

2015-06-18 Thread Kővágó, Zoltán
This patch adds structures into qapi to replace the existing
configuration structures used by audio backends currently. This qapi
will be the base of the -audiodev command line parameter (that replaces
the old environment variables based config).

This is not a 1:1 translation of the old options, I've tried to make
them much more consistent (e.g. almost every backend had an option to
specify buffer size, but the name was different for every backend, and
some backends required usecs, while some other required frames, samples
or bytes). Also tried to reduce the number of abbreviations used by the
config keys.

Some of the more important changes:
* use `in` and `out` instead of `ADC` and `DAC`, as the former is more
  user friendly imho
* moved buffer settings into the global setting area (so it's the same
  for all backends that support it. Backends that can't change buffer
  size will simply ignore them). Also using usecs, as it's probably more
  user friendly than samples or bytes.
* try-poll is now an alsa and oss backend specific option (as all other
  backends currently ignore it)

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v2 patch:
* documentation fixes
* rename mmap - try-mmap, buffer - buffer-len
* id is now required
* converted into flat unions
* renamed alsa's and oss's in an out, because it was incompatible with
  with flat union

Changes from v1 patch:
* every time-related field now take usecs (and removed -usecs, -millis suffixes)
* fixed inconsisten optional marking, language issues

Changes from v2 RFC patch:
* in, out are no longer optional
* try-poll: moved to alsa and oss (as no other backend used them)
* voices: added (env variables had this option)
* dsound: removed primary buffer related fields

Changes from v1 RFC patch:
* fixed style issues
* moved definitions into a separate file
* documented undocumented options (hopefully)
* removed plive option. It was useless even years ago so it can probably safely
  go away: 
https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html
* removed verbose, debug options. Backends should use trace events instead.
* removed *_retries options from dsound. It's a kludge.
* moved buffer_usecs and buffer_count to the global config options. Some driver
  might ignore it (as they do not expose API to change them).
* wav backend: removed frequecy, format, channels as AudiodevPerDirectionOptions
  already have them.

 Makefile |   4 +-
 qapi-schema.json |   3 +
 qapi/audio.json  | 250 +++
 3 files changed, 255 insertions(+), 2 deletions(-)
 create mode 100644 qapi/audio.json

diff --git a/Makefile b/Makefile
index 3f97904..ac566fa 100644
--- a/Makefile
+++ b/Makefile
@@ -257,8 +257,8 @@ $(SRC_PATH)/qga/qapi-schema.json 
$(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
  GEN   $@)
 
 qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
-   $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
-   $(SRC_PATH)/qapi/event.json
+   $(SRC_PATH)/qapi/audio.json  $(SRC_PATH)/qapi/block.json \
+   $(SRC_PATH)/qapi/block-core.json $(SRC_PATH)/qapi/event.json
 
 qapi-types.c qapi-types.h :\
 $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
diff --git a/qapi-schema.json b/qapi-schema.json
index 2a3cfe3..f1896f4 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -5,6 +5,9 @@
 # QAPI common definitions
 { 'include': 'qapi/common.json' }
 
+# QAPI audio definitions
+{ 'include': 'qapi/audio.json' }
+
 # QAPI block definitions
 { 'include': 'qapi/block.json' }
 
diff --git a/qapi/audio.json b/qapi/audio.json
new file mode 100644
index 000..e00f082
--- /dev/null
+++ b/qapi/audio.json
@@ -0,0 +1,250 @@
+# -*- mode: python -*-
+#
+# Copyright (C) 2015 Zoltán Kővágó dirty.ice...@gmail.com
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# @AudiodevNoOptions
+#
+# The none, coreaudio, sdl and spice audio backend have no options.
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevNoOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use (default 'default')
+#
+# @try-poll: #optional attempt to use poll mode, falling back to non polling
+#access on failure (default on)
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data': {
+'*dev':  'str',
+'*try-poll': 'bool' } }
+
+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @alsa-in: options of the capture stream
+#
+# @alsa-out: options of the playback stream
+#
+# @threshold: #optional set the threshold (in microsecods) when playback starts
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaOptions',
+  'data': {
+'alsa

Re: [Qemu-devel] [PATCH v3 5/8] qapi: support nested structs in OptsVisitor

2015-06-18 Thread Kővágó Zoltán

2015-06-18 19:15 keltezéssel, Laszlo Ersek írta:

On 06/18/15 18:43, Kővágó, Zoltán wrote:

The current OptsVisitor flattens the whole structure, if there are same
named fields under different paths (like `in' and `out' in `Audiodev'),
the current visitor can't cope with them (for example setting
`frequency=44100' will set the in's frequency to 44100 and leave out's
frequency unspecified).

This patch fixes it, by always requiring a complete path in case of
nested structs.  Fields in the path are separated by dots, similar to C
structs (without pointers), like `in.frequency' or`out.frequency'.

You must provide a full path even in non-ambigous cases.  The previous
two commits hopefully ensures that this change doesn't create backward
compatibility problems.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Change from v2:
* only fully qualified paths are allowed

  qapi/opts-visitor.c | 114 ++--
  tests/qapi-schema/qapi-schema-test.json |   9 ++-
  tests/test-opts-visitor.c   |  34 ++
  3 files changed, 135 insertions(+), 22 deletions(-)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index f02059d..7a80442 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -71,6 +71,7 @@ struct OptsVisitor
   * schema, with a single mandatory scalar member. */
  ListMode list_mode;
  GQueue *repeated_opts;
+char *repeated_name;

  /* When parsing a list of repeating options as integers, values of the 
form
   * a-b, representing a closed interval, are allowed. Elements in the
@@ -86,6 +87,9 @@ struct OptsVisitor
   * not survive or escape the OptsVisitor object.
   */
  QemuOpt *fake_id_opt;
+
+/* List of field names leading to the current structure. */
+GQueue *nested_names;
  };


@@ -100,6 +104,7 @@ static void
  opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt)
  {
  GQueue *list;
+assert(opt);

  list = g_hash_table_lookup(unprocessed_opts, opt-name);
  if (list == NULL) {
@@ -127,6 +132,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
  if (obj) {
  *obj = g_malloc0(size  0 ? size : 1);
  }
+
+g_queue_push_tail(ov-nested_names, (gpointer) name);
+
  if (ov-depth++  0) {
  return;
  }
@@ -169,6 +177,8 @@ opts_end_struct(Visitor *v, Error **errp)
  OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
  GQueue *any;

+g_queue_pop_tail(ov-nested_names);
+
  if (--ov-depth  0) {
  return;
  }
@@ -198,15 +208,54 @@ opts_end_implicit_struct(Visitor *v, Error **errp)
  }


+static void
+sum_strlen(gpointer data, gpointer user_data)
+{
+const char *str = data;
+size_t *sum_len = user_data;
+
+if (str) { /* skip NULLs */
+*sum_len += strlen(str) + 1;
+}
+}
+
+static void
+append_str(gpointer data, gpointer user_data)
+{
+const char *str = data;
+char *concat_str = user_data;
+
+if (str) {
+strcat(concat_str, str);
+strcat(concat_str, .);
+}
+}
+
+/* lookup a name, using a fully qualified version */
  static GQueue *
-lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp)
+lookup_distinct(const OptsVisitor *ov, const char *name, char **out_key,
+Error **errp)
  {
-GQueue *list;
+GQueue *list = NULL;
+char *key;
+size_t sum_len = strlen(name);
+
+g_queue_foreach(ov-nested_names, sum_strlen, sum_len);
+key = g_malloc(sum_len+1);
+key[0] = 0;
+g_queue_foreach(ov-nested_names, append_str, key);
+strcat(key, name);
+
+list = g_hash_table_lookup(ov-unprocessed_opts, key);
+if (list  out_key) {
+*out_key = g_strdup(key);
+}

-list = g_hash_table_lookup(ov-unprocessed_opts, name);
  if (!list) {
  error_set(errp, QERR_MISSING_PARAMETER, name);
  }
+
+g_free(key);
  return list;
  }

@@ -218,7 +267,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)

  /* we can't traverse a list in a list */
  assert(ov-list_mode == LM_NONE);
-ov-repeated_opts = lookup_distinct(ov, name, errp);
+ov-repeated_opts = lookup_distinct(ov, name, ov-repeated_name, errp);
  if (ov-repeated_opts != NULL) {
  ov-list_mode = LM_STARTED;
  }
@@ -254,11 +303,9 @@ opts_next_list(Visitor *v, GenericList **list, Error 
**errp)
  /* range has been completed, fall through in order to pop option */

  case LM_IN_PROGRESS: {
-const QemuOpt *opt;
-
-opt = g_queue_pop_head(ov-repeated_opts);
+g_queue_pop_head(ov-repeated_opts);
  if (g_queue_is_empty(ov-repeated_opts)) {
-g_hash_table_remove(ov-unprocessed_opts, opt-name);
+g_hash_table_remove(ov-unprocessed_opts, ov-repeated_name);
  return NULL;
  }
  link = (*list)-next;
@@ -284,22 +331,28 @@ opts_end_list(Visitor *v, Error **errp)
 ov-list_mode

Re: [Qemu-devel] [PATCH v3 3/8] qapi: change Netdev and NetLegacy into a flat union

2015-06-19 Thread Kővágó Zoltán

2015-06-19 16:06 keltezéssel, Stefan Hajnoczi írta:

On Thu, Jun 18, 2015 at 06:43:45PM +0200, Kővágó, Zoltán wrote:

@@ -713,8 +710,6 @@ int net_init_tap(const NetClientOptions *opts, const char 
*name,
  const char *vhostfdname;
  char ifname[128];

-assert(opts-kind == NET_CLIENT_OPTIONS_KIND_TAP);
-tap = opts-tap;

...

@@ -109,14 +109,11 @@ static int net_vde_init(NetClientState *peer, const char 
*model,
  return 0;
  }

-int net_init_vde(const NetClientOptions *opts, const char *name,
+int net_init_vde(const void *opts, const char *name,
   NetClientState *peer, Error **errp)
  {
  /* FIXME error_setg(errp, ...) on failure */
-const NetdevVdeOptions *vde;
-
-assert(opts-kind == NET_CLIENT_OPTIONS_KIND_VDE);
-vde = opts-vde;
+const NetdevVdeOptions *vde = opts;

  /* missing optional values have been initialized to all bits zero */
  if (net_vde_init(peer, vde, name, vde-sock, vde-port, vde-group,

...

@@ -228,16 +228,13 @@ static int net_vhost_check_net(void *opaque, QemuOpts 
*opts, Error **errp)
  return 0;
  }

-int net_init_vhost_user(const NetClientOptions *opts, const char *name,
+int net_init_vhost_user(const void *opts, const char *name,
  NetClientState *peer, Error **errp)
  {
  uint32_t queues;
-const NetdevVhostUserOptions *vhost_user_opts;
+const NetdevVhostUserOptions *vhost_user_opts = opts;
  CharDriverState *chr;

-assert(opts-kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
-vhost_user_opts = opts-vhost_user;
-


Why drop the assertion?

Because otherwise you would have to make a version that gets a Netdev 
and an other that gets Netlegacy, because the common NetClientOptions is 
gone. Unless, of course, I'm overlooking something.


(I've actually tried to simply pass the corect type as arguments, like 
net_init_chost_user(const NetdevVhostUserOptions *opts, ...; but then 
net_client_init_fun in net.c becomes problematic. Maybe replacing it 
with a giant swicth-case would be better?)




[Qemu-devel] [PATCH v2 4/6] qapi: AllocVisitor

2015-06-16 Thread Kővágó, Zoltán
Simple visitor that recursively allocates structures with only optional
variables. Unions are initialized to the first type specified. Other non
optional types are not supported.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 include/qapi/alloc-visitor.h | 18 +
 qapi/Makefile.objs   |  1 +
 qapi/alloc-visitor.c | 62 
 3 files changed, 81 insertions(+)
 create mode 100644 include/qapi/alloc-visitor.h
 create mode 100644 qapi/alloc-visitor.c

diff --git a/include/qapi/alloc-visitor.h b/include/qapi/alloc-visitor.h
new file mode 100644
index 000..3d54295
--- /dev/null
+++ b/include/qapi/alloc-visitor.h
@@ -0,0 +1,18 @@
+/*
+ * Alloc Visitor.
+ * Recursively allocates structs, leaving all optional fields unset. In case of
+ * a non-optional field it fails.
+ */
+
+#ifndef ALLOC_VISITOR_H
+#define ALLOC_VISITOR_H
+
+#include qapi/visitor.h
+
+typedef struct AllocVisitor AllocVisitor;
+
+AllocVisitor *alloc_visitor_new(void);
+void alloc_visitor_cleanup(AllocVisitor *v);
+Visitor *alloc_visitor_get_visitor(AllocVisitor *v);
+
+#endif
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index 2278970..7bc26a3 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -4,3 +4,4 @@ util-obj-y += string-input-visitor.o string-output-visitor.o
 util-obj-y += opts-visitor.o
 util-obj-y += qmp-event.o
 util-obj-y += qapi-util.o
+util-obj-y += alloc-visitor.o
diff --git a/qapi/alloc-visitor.c b/qapi/alloc-visitor.c
new file mode 100644
index 000..dbb83af
--- /dev/null
+++ b/qapi/alloc-visitor.c
@@ -0,0 +1,62 @@
+#include qapi/alloc-visitor.h
+#include qemu-common.h
+#include qapi/visitor-impl.h
+
+struct AllocVisitor {
+Visitor visitor;
+};
+
+static void alloc_start_struct(Visitor *v, void **obj, const char* kind,
+   const char *name, size_t size, Error **errp)
+{
+if (obj) {
+*obj = g_malloc0(size);
+}
+}
+
+static void alloc_end_struct(Visitor *v, Error **errp)
+{
+}
+
+static void alloc_start_implicit_struct(Visitor *v, void **obj, size_t size,
+Error **errp)
+{
+if (obj) {
+*obj = g_malloc0(size);
+}
+}
+
+static void alloc_end_implicit_struct(Visitor *v, Error **errp)
+{
+}
+
+static void alloc_type_enum(Visitor *v, int *obj, const char *strings[],
+const char *kind, const char *name, Error **errp)
+{
+assert(*strings); /* there is at least one valid enum value... */
+*obj = 0;
+}
+
+AllocVisitor *alloc_visitor_new(void)
+{
+AllocVisitor *v = g_malloc0(sizeof(AllocVisitor));
+
+v-visitor.start_struct = alloc_start_struct;
+v-visitor.end_struct = alloc_end_struct;
+v-visitor.start_implicit_struct = alloc_start_implicit_struct;
+v-visitor.end_implicit_struct = alloc_end_implicit_struct;
+
+v-visitor.type_enum = alloc_type_enum;
+
+return v;
+}
+
+void alloc_visitor_cleanup(AllocVisitor *v)
+{
+g_free(v);
+}
+
+Visitor *alloc_visitor_get_visitor(AllocVisitor *v)
+{
+return v-visitor;
+}
-- 
2.4.3




[Qemu-devel] [PATCH v2 6/6] audio: -audiodev command line option

2015-06-16 Thread Kővágó, Zoltán
This patch adds an -audiodev command line option, and deprecates the QEMU_*
environment variables for audio backend configuration. It's syntax is similar to
existing options (-netdev, -device, etc):
 -audiodev driver_name,property=value,...

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, also print out them with -audio-help, to ease
migrating to -audiodev).

Although now it's possible to specify multiple -audiodev options on command
line, multiple audio backends are not supported yet.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v1:
* updated to everything usecs without suffix
* better rounding when converting between usecs and frames/samples/bytes
* bugfixes in audio_legacy.c
* fixed code broken by qemu_opts changes by Markus

 audio/Makefile.objs |   2 +-
 audio/alsaaudio.c   | 284 ++
 audio/audio.c   | 747 +---
 audio/audio.h   |  23 +-
 audio/audio_int.h   |   7 +-
 audio/audio_legacy.c| 328 +
 audio/audio_template.h  |  13 +-
 audio/coreaudio.c   |  49 +---
 audio/dsound_template.h |   6 +-
 audio/dsoundaudio.c |  60 ++--
 audio/noaudio.c |   3 +-
 audio/ossaudio.c| 155 +++---
 audio/paaudio.c |  81 ++
 audio/sdlaudio.c|  24 +-
 audio/spiceaudio.c  |   7 +-
 audio/wavaudio.c|  61 +---
 qemu-options.hx | 218 +-
 vl.c|   9 +-
 18 files changed, 994 insertions(+), 1083 deletions(-)
 create mode 100644 audio/audio_legacy.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 481d1aa..9d8f579 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
+common-obj-y = audio.o audio_legacy.o noaudio.o wavaudio.o mixeng.o
 common-obj-$(CONFIG_SDL) += sdlaudio.o
 common-obj-$(CONFIG_OSS) += ossaudio.o
 common-obj-$(CONFIG_SPICE) += spiceaudio.o
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 4d38f5d..a660ae1 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -22,6 +22,8 @@
  * THE SOFTWARE.
  */
 #include alsa/asoundlib.h
+#include qapi/alloc-visitor.h
+#include qapi-visit.h
 #include qemu-common.h
 #include qemu/main-loop.h
 #include audio.h
@@ -34,28 +36,9 @@
 #define AUDIO_CAP alsa
 #include audio_int.h
 
-typedef struct ALSAConf {
-int size_in_usec_in;
-int size_in_usec_out;
-const char *pcm_name_in;
-const char *pcm_name_out;
-unsigned int buffer_size_in;
-unsigned int period_size_in;
-unsigned int buffer_size_out;
-unsigned int period_size_out;
-unsigned int threshold;
-
-int buffer_size_in_overridden;
-int period_size_in_overridden;
-
-int buffer_size_out_overridden;
-int period_size_out_overridden;
-} ALSAConf;
-
 struct pollhlp {
 snd_pcm_t *handle;
 struct pollfd *pfds;
-ALSAConf *conf;
 int count;
 int mask;
 };
@@ -67,6 +50,7 @@ typedef struct ALSAVoiceOut {
 void *pcm_buf;
 snd_pcm_t *handle;
 struct pollhlp pollhlp;
+Audiodev *dev;
 } ALSAVoiceOut;
 
 typedef struct ALSAVoiceIn {
@@ -74,16 +58,13 @@ typedef struct ALSAVoiceIn {
 snd_pcm_t *handle;
 void *pcm_buf;
 struct pollhlp pollhlp;
+Audiodev *dev;
 } ALSAVoiceIn;
 
 struct alsa_params_req {
 int freq;
 snd_pcm_format_t fmt;
 int nchannels;
-int size_in_usec;
-int override_mask;
-unsigned int buffer_size;
-unsigned int period_size;
 };
 
 struct alsa_params_obt {
@@ -409,7 +390,8 @@ static int alsa_to_audfmt (snd_pcm_format_t alsafmt, 
AudioFormat *fmt,
 
 static void alsa_dump_info (struct alsa_params_req *req,
 struct alsa_params_obt *obt,
-snd_pcm_format_t obtfmt)
+snd_pcm_format_t obtfmt,
+AudiodevPerDirectionOptions *pdo)
 {
 dolog (parameter | requested value | obtained value\n);
 dolog (format|  %10d | %10d\n, req-fmt, obtfmt);
@@ -417,8 +399,9 @@ static void alsa_dump_info (struct alsa_params_req *req,
req-nchannels, obt-nchannels);
 dolog (frequency |  %10d | %10d\n, req-freq, obt-freq);
 dolog (\n);
-dolog (requested: buffer size %d period size %d\n,
-   req-buffer_size, req-period_size);
+dolog (requested: buffer size % PRId64  buffer count % PRId64 \n,
+   pdo-has_buffer ? pdo-buffer : 0,
+   pdo-has_buffer ? pdo-buffer : 0);
 dolog (obtained: samples %ld\n, obt-samples);
 }
 
@@ -452,23 +435,24 @@ static void alsa_set_threshold (snd_pcm_t *handle, 
snd_pcm_uframes_t threshold)
 }
 }
 
-static int alsa_open (int

[Qemu-devel] [PATCH v2 3/6] opts: do not print separator before first item in qemu_opts_print

2015-06-16 Thread Kővágó, Zoltán
This allows to print options in a format that the user would actually write it
on the command line (foo=bar,baz=asd,etc=def), without prepending a spurious
comma at the beginning of the list.

Only block.c depended on the old behavior, but it was also updated.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 block.c| 2 +-
 util/qemu-option.c | 5 -
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index dd4f58d..c5d456c 100644
--- a/block.c
+++ b/block.c
@@ -3823,7 +3823,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 }
 
 if (!quiet) {
-printf(Formatting '%s', fmt=%s, filename, fmt);
+printf(Formatting '%s', fmt=%s , filename, fmt);
 qemu_opts_print(opts,  );
 puts();
 }
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 840f5f7..b347d92 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -728,14 +728,16 @@ void qemu_opts_del(QemuOpts *opts)
 g_free(opts);
 }
 
-void qemu_opts_print(QemuOpts *opts, const char *sep)
+void qemu_opts_print(QemuOpts *opts, const char *d_sep)
 {
 QemuOpt *opt;
 QemuOptDesc *desc = opts-list-desc;
+const char *sep = ;
 
 if (desc[0].name == NULL) {
 QTAILQ_FOREACH(opt, opts-head, next) {
 printf(%s%s=\%s\, sep, opt-name, opt-str);
+sep = d_sep;
 }
 return;
 }
@@ -755,6 +757,7 @@ void qemu_opts_print(QemuOpts *opts, const char *sep)
 } else {
 printf(%s%s=%s, sep, desc-name, value);
 }
+sep = d_sep;
 }
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v2 1/6] qapi: qapi for audio backends

2015-06-16 Thread Kővágó, Zoltán
This patch adds structures into qapi to replace the existing configuration
structures used by audio backends currently. This qapi will be the base of the
-audiodev command line parameter (that replaces the old environment variables
based config).

This is not a 1:1 translation of the old options, I've tried to make them much
more consistent (e.g. almost every backend had an option to specify buffer size,
but the name was different for every backend, and some backends required usecs,
while some other required frames, samples or bytes). Also tried to reduce the
number of abbreviations used by the config keys.

Some of the more important changes:
* use `in` and `out` instead of `ADC` and `DAC`, as the former is more user
  friendly imho
* moved buffer settings into the global setting area (so it's the same for all
  backends that support it. Backends that can't change buffer size will simply
  ignore them). Also using usecs, as it's probably more user friendly than
  samples or bytes.
* try-poll is now an alsa and oss backend specific option (as all other backends
  currently ignore it)

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v1 patch:
* every time-related field now take usecs (and removed -usecs, -millis suffixes)
* fixed inconsisten optional marking, language issues

Changes from v2 RFC patch:
* in, out are no longer optional
* try-poll: moved to alsa and oss (as no other backend used them)
* voices: added (env variables had this option)
* dsound: removed primary buffer related fields

Changes from v1 RFC patch:
* fixed style issues
* moved definitions into a separate file
* documented undocumented options (hopefully)
* removed plive option. It was useless even years ago so it can probably safely
  go away: 
https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html
* removed verbose, debug options. Backends should use trace events instead.
* removed *_retries options from dsound. It's a kludge.
* moved buffer_usecs and buffer_count to the global config options. Some driver
  might ignore it (as they do not expose API to change them).
* wav backend: removed frequecy, format, channels as AudiodevPerDirectionOptions
  already have them.

Makefile |   4 +-
 qapi-schema.json |   3 +
 qapi/audio.json  | 223 +++
 3 files changed, 228 insertions(+), 2 deletions(-)
 create mode 100644 qapi/audio.json

diff --git a/Makefile b/Makefile
index 3f97904..ac566fa 100644
--- a/Makefile
+++ b/Makefile
@@ -257,8 +257,8 @@ $(SRC_PATH)/qga/qapi-schema.json 
$(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
  GEN   $@)
 
 qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
-   $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
-   $(SRC_PATH)/qapi/event.json
+   $(SRC_PATH)/qapi/audio.json  $(SRC_PATH)/qapi/block.json \
+   $(SRC_PATH)/qapi/block-core.json $(SRC_PATH)/qapi/event.json
 
 qapi-types.c qapi-types.h :\
 $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
diff --git a/qapi-schema.json b/qapi-schema.json
index 106008c..e751ea3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -5,6 +5,9 @@
 # QAPI common definitions
 { 'include': 'qapi/common.json' }
 
+# QAPI audio definitions
+{ 'include': 'qapi/audio.json' }
+
 # QAPI block definitions
 { 'include': 'qapi/block.json' }
 
diff --git a/qapi/audio.json b/qapi/audio.json
new file mode 100644
index 000..2851689
--- /dev/null
+++ b/qapi/audio.json
@@ -0,0 +1,223 @@
+# -*- mode: python -*-
+#
+# Copyright (C) 2015 Zoltán Kővágó dirty.ice...@gmail.com
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# @AudiodevNoOptions
+#
+# The none, coreaudio, sdl and spice audio backend have no options.
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevNoOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use
+#
+# @try-poll: #optional attempt to use poll mode
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data': {
+'*dev':  'str',
+'*try-poll': 'bool' } }
+
+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @in: options of the capture stream
+#
+# @out: options of the playback stream
+#
+# @threshold: #optional set the threshold (in frames) when playback starts
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaOptions',
+  'data': {
+'in': 'AudiodevAlsaPerDirectionOptions',
+'out':'AudiodevAlsaPerDirectionOptions',
+'*threshold': 'int' } }
+
+##
+# @AudiodevDsoundOptions
+#
+# Options of the dsound audio backend.
+#
+# @latency: #optional add extra latency to playback (in microseconds)
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevDsoundOptions',
+  'data

[Qemu-devel] [PATCH v2 0/6] -audiodev option

2015-06-16 Thread Kővágó, Zoltán
This series of patches adds a new -audiodev command line option to specify audio
subsytem parameters instead of environment variables. This will later allow us
to specify multiple audio backends. The syntax is something like this:
 -audiodev driver_name,property=value,...
like:
 -audiodev alsa,frequency=8000,channels=1

The first commit adds a qapi Audiodev struct that describes the audio backend
options. The next 4 commits are some miscellaneous additions that are needed by
the last commit which finally adds the -audiodev option.

For users with esoteric platforms or needs please check I did not break anything
accidentally. For easier testing, pull https://github.com/DirtYiCE/qemu.git tag
audio-cmdline-v2.

Please review.

---

Changes from v1:
* updated to master, removed commits already merged
* now every time-related option takes usecs
* some small fixes

Kővágó, Zoltán (6):
  qapi: qapi for audio backends
  qapi: support nested structs in OptsVisitor
  opts: do not print separator before first item in qemu_opts_print
  qapi: AllocVisitor
  audio: use qapi AudioFormat instead of audfmt_e
  audio: -audiodev command line option

 Makefile|   4 +-
 audio/Makefile.objs |   2 +-
 audio/alsaaudio.c   | 337 +-
 audio/audio.c   | 798 ++--
 audio/audio.h   |  34 +-
 audio/audio_int.h   |   7 +-
 audio/audio_legacy.c| 328 +
 audio/audio_template.h  |  13 +-
 audio/audio_win_int.c   |  18 +-
 audio/coreaudio.c   |  49 +-
 audio/dsound_template.h |   6 +-
 audio/dsoundaudio.c |  60 +--
 audio/noaudio.c |   3 +-
 audio/ossaudio.c| 183 +++-
 audio/paaudio.c | 109 ++---
 audio/sdlaudio.c|  50 +-
 audio/spiceaudio.c  |  11 +-
 audio/wavaudio.c|  76 +--
 audio/wavcapture.c  |   2 +-
 block.c |   2 +-
 hw/arm/omap2.c  |   2 +-
 hw/audio/ac97.c |   2 +-
 hw/audio/adlib.c|   2 +-
 hw/audio/cs4231a.c  |   6 +-
 hw/audio/es1370.c   |   4 +-
 hw/audio/gus.c  |   2 +-
 hw/audio/hda-codec.c|  18 +-
 hw/audio/lm4549.c   |   6 +-
 hw/audio/milkymist-ac97.c   |   2 +-
 hw/audio/pcspk.c|   2 +-
 hw/audio/sb16.c |  14 +-
 hw/audio/wm8750.c   |   4 +-
 hw/input/tsc210x.c  |   2 +-
 hw/usb/dev-audio.c  |   2 +-
 include/qapi/alloc-visitor.h|  18 +
 qapi-schema.json|   3 +
 qapi/Makefile.objs  |   1 +
 qapi/alloc-visitor.c|  62 +++
 qapi/audio.json | 223 +
 qapi/opts-visitor.c | 144 --
 qemu-options.hx | 218 -
 tests/qapi-schema/qapi-schema-test.json |   9 +-
 tests/test-opts-visitor.c   |  34 ++
 ui/vnc.c|  14 +-
 util/qemu-option.c  |   5 +-
 vl.c|   9 +-
 46 files changed, 1627 insertions(+), 1273 deletions(-)
 create mode 100644 audio/audio_legacy.c
 create mode 100644 include/qapi/alloc-visitor.h
 create mode 100644 qapi/alloc-visitor.c
 create mode 100644 qapi/audio.json

-- 
2.4.3




[Qemu-devel] [PATCH v2 5/6] audio: use qapi AudioFormat instead of audfmt_e

2015-06-16 Thread Kővágó, Zoltán
I had to include an enum for audio sampling formats into qapi, but that meant
duplicating the audfmt_e enum. This patch replaces audfmt_e and associated
values with the qapi generated AudioFormat enum.

This patch is mostly a search-and-replace, except for switches where the qapi
generated AUDIO_FORMAT_MAX caused problems.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c | 53 ++
 audio/audio.c | 97 ++-
 audio/audio.h | 11 +-
 audio/audio_win_int.c | 18 -
 audio/ossaudio.c  | 30 +++
 audio/paaudio.c   | 28 +++---
 audio/sdlaudio.c  | 26 ++---
 audio/spiceaudio.c|  4 +-
 audio/wavaudio.c  | 17 +
 audio/wavcapture.c|  2 +-
 hw/arm/omap2.c|  2 +-
 hw/audio/ac97.c   |  2 +-
 hw/audio/adlib.c  |  2 +-
 hw/audio/cs4231a.c|  6 +--
 hw/audio/es1370.c |  4 +-
 hw/audio/gus.c|  2 +-
 hw/audio/hda-codec.c  | 18 -
 hw/audio/lm4549.c |  6 +--
 hw/audio/milkymist-ac97.c |  2 +-
 hw/audio/pcspk.c  |  2 +-
 hw/audio/sb16.c   | 14 +++
 hw/audio/wm8750.c |  4 +-
 hw/input/tsc210x.c|  2 +-
 hw/usb/dev-audio.c|  2 +-
 ui/vnc.c  | 14 +++
 25 files changed, 187 insertions(+), 181 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 6315b2d..4d38f5d 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -88,7 +88,7 @@ struct alsa_params_req {
 
 struct alsa_params_obt {
 int freq;
-audfmt_e fmt;
+AudioFormat fmt;
 int endianness;
 int nchannels;
 snd_pcm_uframes_t samples;
@@ -295,16 +295,16 @@ static int alsa_write (SWVoiceOut *sw, void *buf, int len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)
+static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
 {
 switch (fmt) {
-case AUD_FMT_S8:
+case AUDIO_FORMAT_S8:
 return SND_PCM_FORMAT_S8;
 
-case AUD_FMT_U8:
+case AUDIO_FORMAT_U8:
 return SND_PCM_FORMAT_U8;
 
-case AUD_FMT_S16:
+case AUDIO_FORMAT_S16:
 if (endianness) {
 return SND_PCM_FORMAT_S16_BE;
 }
@@ -312,7 +312,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_S16_LE;
 }
 
-case AUD_FMT_U16:
+case AUDIO_FORMAT_U16:
 if (endianness) {
 return SND_PCM_FORMAT_U16_BE;
 }
@@ -320,7 +320,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_U16_LE;
 }
 
-case AUD_FMT_S32:
+case AUDIO_FORMAT_S32:
 if (endianness) {
 return SND_PCM_FORMAT_S32_BE;
 }
@@ -328,7 +328,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_S32_LE;
 }
 
-case AUD_FMT_U32:
+case AUDIO_FORMAT_U32:
 if (endianness) {
 return SND_PCM_FORMAT_U32_BE;
 }
@@ -345,58 +345,58 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 }
 }
 
-static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
+static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt,
int *endianness)
 {
 switch (alsafmt) {
 case SND_PCM_FORMAT_S8:
 *endianness = 0;
-*fmt = AUD_FMT_S8;
+*fmt = AUDIO_FORMAT_S8;
 break;
 
 case SND_PCM_FORMAT_U8:
 *endianness = 0;
-*fmt = AUD_FMT_U8;
+*fmt = AUDIO_FORMAT_U8;
 break;
 
 case SND_PCM_FORMAT_S16_LE:
 *endianness = 0;
-*fmt = AUD_FMT_S16;
+*fmt = AUDIO_FORMAT_S16;
 break;
 
 case SND_PCM_FORMAT_U16_LE:
 *endianness = 0;
-*fmt = AUD_FMT_U16;
+*fmt = AUDIO_FORMAT_U16;
 break;
 
 case SND_PCM_FORMAT_S16_BE:
 *endianness = 1;
-*fmt = AUD_FMT_S16;
+*fmt = AUDIO_FORMAT_S16;
 break;
 
 case SND_PCM_FORMAT_U16_BE:
 *endianness = 1;
-*fmt = AUD_FMT_U16;
+*fmt = AUDIO_FORMAT_U16;
 break;
 
 case SND_PCM_FORMAT_S32_LE:
 *endianness = 0;
-*fmt = AUD_FMT_S32;
+*fmt = AUDIO_FORMAT_S32;
 break;
 
 case SND_PCM_FORMAT_U32_LE:
 *endianness = 0;
-*fmt = AUD_FMT_U32;
+*fmt = AUDIO_FORMAT_U32;
 break;
 
 case SND_PCM_FORMAT_S32_BE:
 *endianness = 1;
-*fmt = AUD_FMT_S32;
+*fmt = AUDIO_FORMAT_S32;
 break;
 
 case SND_PCM_FORMAT_U32_BE:
 *endianness = 1;
-*fmt = AUD_FMT_U32;
+*fmt = AUDIO_FORMAT_U32;
 break;
 
 default:
@@ -639,19 +639,22 @@ static int alsa_open (int

[Qemu-devel] [PATCH v2 2/6] qapi: support nested structs in OptsVisitor

2015-06-16 Thread Kővágó, Zoltán
The current OptsVisitor flattens the whole structure, if there are same named
fields under different paths (like `in' and `out' in `Audiodev'), the current
visitor can't cope with them (for example setting `frequency=44100' will set the
in's frequency to 44100 and leave out's frequency unspecified).

This patch fixes it, by the following changes:
1) Specifying just the field name will apply to all fields that has the
   specified name (this means it would set both in's and out's frequency to
   44100 in the above example).
2) Optionally user can specify the path in the hierarchy. Names are separated by
   a dot (e.g. `in.frequency', `foo.bar.something', etc). The user need not
   specify the whole path, only the last few components (i.e. `bar.something' is
   equivalent to `foo.bar.something' if only `foo' has a `bar' field). This way
   1) is just a special case of this when only the last component is specified.
3) In case of an ambiguity (e.g `frequency=44100,in.frequency=8000') the longest
   matching (the most specific) path wins (so in this example, in's frequency
   would become 8000, because `in.frequency' is more specific that `frequency',
   and out's frequency would become 44100, because only `frequency' matches it).

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 qapi/opts-visitor.c | 144 +---
 tests/qapi-schema/qapi-schema-test.json |   9 +-
 tests/test-opts-visitor.c   |  34 
 3 files changed, 157 insertions(+), 30 deletions(-)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index f2ad6d7..409d8b7 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -64,13 +64,14 @@ struct OptsVisitor
 /* Non-null iff depth is positive. Each key is a QemuOpt name. Each value
  * is a non-empty GQueue, enumerating all QemuOpt occurrences with that
  * name. */
-GHashTable *unprocessed_opts;
+GHashTable *unprocessed_opts, *opts;
 
 /* The list currently being traversed with opts_start_list() /
  * opts_next_list(). The list must have a struct element type in the
  * schema, with a single mandatory scalar member. */
 ListMode list_mode;
 GQueue *repeated_opts;
+char *repeated_name;
 
 /* When parsing a list of repeating options as integers, values of the form
  * a-b, representing a closed interval, are allowed. Elements in the
@@ -86,6 +87,9 @@ struct OptsVisitor
  * not survive or escape the OptsVisitor object.
  */
 QemuOpt *fake_id_opt;
+
+/* List of field names leading to the current structure. */
+GQueue *nested_names;
 };
 
 
@@ -97,11 +101,12 @@ destroy_list(gpointer list)
 
 
 static void
-opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt)
+opts_visitor_insert(OptsVisitor *ov, const QemuOpt *opt)
 {
 GQueue *list;
+assert(opt);
 
-list = g_hash_table_lookup(unprocessed_opts, opt-name);
+list = g_hash_table_lookup(ov-opts, opt-name);
 if (list == NULL) {
 list = g_queue_new();
 
@@ -109,7 +114,8 @@ opts_visitor_insert(GHashTable *unprocessed_opts, const 
QemuOpt *opt)
  * key_destroy_func in opts_start_struct(). Thus cast away key
  * const-ness in order to suppress gcc's warning.
  */
-g_hash_table_insert(unprocessed_opts, (gpointer)opt-name, list);
+g_hash_table_insert(ov-opts, (gpointer)opt-name, list);
+g_hash_table_insert(ov-unprocessed_opts, (gpointer)opt-name, list);
 }
 
 /* Similarly, destroy_list() doesn't call g_queue_free_full(). */
@@ -127,17 +133,27 @@ opts_start_struct(Visitor *v, void **obj, const char 
*kind,
 if (obj) {
 *obj = g_malloc0(size  0 ? size : 1);
 }
+
+/* assuming name is a statically allocated string (or at least it's 
lifetime
+ * is longer than the visitor's) */
+if (!name) {
+name = ;
+}
+g_queue_push_tail(ov-nested_names, (gpointer) name);
+
 if (ov-depth++  0) {
 return;
 }
 
-ov-unprocessed_opts = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, destroy_list);
+ov-opts = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, destroy_list);
+ov-unprocessed_opts = g_hash_table_new(g_str_hash, g_str_equal);
+
 QTAILQ_FOREACH(opt, ov-opts_root-head, next) {
 /* ensured by qemu-option.c::opts_do_parse() */
 assert(strcmp(opt-name, id) != 0);
 
-opts_visitor_insert(ov-unprocessed_opts, opt);
+opts_visitor_insert(ov, opt);
 }
 
 if (ov-opts_root-id != NULL) {
@@ -145,7 +161,7 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
 
 ov-fake_id_opt-name = g_strdup(id);
 ov-fake_id_opt-str = g_strdup(ov-opts_root-id);
-opts_visitor_insert(ov-unprocessed_opts, ov-fake_id_opt);
+opts_visitor_insert(ov, ov-fake_id_opt);
 }
 }
 
@@ -163,6 +179,8 @@ opts_end_struct

[Qemu-devel] [PATCH 07/12] qapi: qapi for audio backends

2015-06-12 Thread Kővágó, Zoltán
This patch adds structures into qapi to replace the existing configuration
structures used by audio backends currently. This qapi will be the base of the
-audiodev command line parameter (that replaces the old environment variables
based config).

This is not a 1:1 translation of the old options, I've tried to make them much
more consistent (e.g. almost every backend had an option to specify buffer size,
but the name was different for every backend, and some backends required usecs,
while some other required frames, samples or bytes). Also tried to reduce the
number of abbreviations used by the config keys.

Some of the more important changes:
* use `in` and `out` instead of `ADC` and `DAC`, as the former is more user
  friendly imho
* moved buffer settings into the global setting area (so it's the same for all
  backends that support it. Backends that can't change buffer size will simply
  ignore them). Also using usecs, as it's probably more user friendly than
  samples or bytes.
* try-poll is now an alsa and oss backend specific option (as all other backends
  currently ignore it)

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v2 RFC patch:
* in, out are no longer optional
* try-poll: moved to alsa and oss (as no other backend used them)
* voices: added (env variables had this option)
* dsound: removed primary buffer related fields

Changes from v1 RFC patch:
* fixed style issues
* moved definitions into a separate file
* documented undocumented options (hopefully)
* removed plive option. It was useless even years ago so it can probably safely
  go away: 
https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html
* removed verbose, debug options. Backends should use trace events instead.
* removed *_retries options from dsound. It's a kludge.
* moved buffer_usecs and buffer_count to the global config options. Some driver
  might ignore it (as they do not expose API to change them).
* wav backend: removed frequecy, format, channels as AudiodevPerDirectionOptions
  already have them.

 Makefile |   4 +-
 qapi-schema.json |   3 +
 qapi/audio.json  | 217 +++
 3 files changed, 222 insertions(+), 2 deletions(-)
 create mode 100644 qapi/audio.json

diff --git a/Makefile b/Makefile
index 2d52536..982563e 100644
--- a/Makefile
+++ b/Makefile
@@ -257,8 +257,8 @@ $(SRC_PATH)/qga/qapi-schema.json 
$(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
  GEN   $@)
 
 qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
-   $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
-   $(SRC_PATH)/qapi/event.json
+   $(SRC_PATH)/qapi/audio.json  $(SRC_PATH)/qapi/block.json \
+   $(SRC_PATH)/qapi/block-core.json $(SRC_PATH)/qapi/event.json
 
 qapi-types.c qapi-types.h :\
 $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
diff --git a/qapi-schema.json b/qapi-schema.json
index 6e17a5c..26c470a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -5,6 +5,9 @@
 # QAPI common definitions
 { 'include': 'qapi/common.json' }
 
+# QAPI audio definitions
+{ 'include': 'qapi/audio.json' }
+
 # QAPI block definitions
 { 'include': 'qapi/block.json' }
 
diff --git a/qapi/audio.json b/qapi/audio.json
new file mode 100644
index 000..157ccf6
--- /dev/null
+++ b/qapi/audio.json
@@ -0,0 +1,217 @@
+# -*- mode: python -*-
+
+##
+# @AudiodevNoneOptions
+#
+# The none, coreaudio, sdl and spice audio backend has no options.
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevNoneOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use
+#
+# @try-poll: #optional attempt to use poll mode
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data': {
+'*dev':  'str',
+'*try-poll': 'bool' } }
+
+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @in: #optional options of the capture stream
+#
+# @out: #optional options of the playback stream
+#
+# @threshold: #optional set the threshold (in frames) when playback starts
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaOptions',
+  'data': {
+'in': 'AudiodevAlsaPerDirectionOptions',
+'out':'AudiodevAlsaPerDirectionOptions',
+'*threshold': 'int' } }
+
+##
+# @AudiodevDsoundOptions
+#
+# Options of the dsound audio backend.
+#
+# @latency-millis: #optional add extra latency to playback
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevDsoundOptions',
+  'data': {
+'*latency-millis': 'int' } }
+
+##
+# @AudiodevOssPerDirectionOptions
+#
+# Options of the oss backend that are used for both playback and recording.
+#
+# @dev: #optional path of the oss device
+#
+# @try-poll: #optional attempt to use poll mode
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevOssPerDirectionOptions',
+  'data

[Qemu-devel] [PATCH 10/12] qapi: AllocVisitor

2015-06-12 Thread Kővágó, Zoltán
Simple visitor that recursively allocates structures with only optional
variables. Unions are initialized to the first type specified. Other non
optional types are not supported.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 include/qapi/alloc-visitor.h | 18 +
 qapi/Makefile.objs   |  1 +
 qapi/alloc-visitor.c | 62 
 3 files changed, 81 insertions(+)
 create mode 100644 include/qapi/alloc-visitor.h
 create mode 100644 qapi/alloc-visitor.c

diff --git a/include/qapi/alloc-visitor.h b/include/qapi/alloc-visitor.h
new file mode 100644
index 000..3d54295
--- /dev/null
+++ b/include/qapi/alloc-visitor.h
@@ -0,0 +1,18 @@
+/*
+ * Alloc Visitor.
+ * Recursively allocates structs, leaving all optional fields unset. In case of
+ * a non-optional field it fails.
+ */
+
+#ifndef ALLOC_VISITOR_H
+#define ALLOC_VISITOR_H
+
+#include qapi/visitor.h
+
+typedef struct AllocVisitor AllocVisitor;
+
+AllocVisitor *alloc_visitor_new(void);
+void alloc_visitor_cleanup(AllocVisitor *v);
+Visitor *alloc_visitor_get_visitor(AllocVisitor *v);
+
+#endif
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index 2278970..7bc26a3 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -4,3 +4,4 @@ util-obj-y += string-input-visitor.o string-output-visitor.o
 util-obj-y += opts-visitor.o
 util-obj-y += qmp-event.o
 util-obj-y += qapi-util.o
+util-obj-y += alloc-visitor.o
diff --git a/qapi/alloc-visitor.c b/qapi/alloc-visitor.c
new file mode 100644
index 000..dbb83af
--- /dev/null
+++ b/qapi/alloc-visitor.c
@@ -0,0 +1,62 @@
+#include qapi/alloc-visitor.h
+#include qemu-common.h
+#include qapi/visitor-impl.h
+
+struct AllocVisitor {
+Visitor visitor;
+};
+
+static void alloc_start_struct(Visitor *v, void **obj, const char* kind,
+   const char *name, size_t size, Error **errp)
+{
+if (obj) {
+*obj = g_malloc0(size);
+}
+}
+
+static void alloc_end_struct(Visitor *v, Error **errp)
+{
+}
+
+static void alloc_start_implicit_struct(Visitor *v, void **obj, size_t size,
+Error **errp)
+{
+if (obj) {
+*obj = g_malloc0(size);
+}
+}
+
+static void alloc_end_implicit_struct(Visitor *v, Error **errp)
+{
+}
+
+static void alloc_type_enum(Visitor *v, int *obj, const char *strings[],
+const char *kind, const char *name, Error **errp)
+{
+assert(*strings); /* there is at least one valid enum value... */
+*obj = 0;
+}
+
+AllocVisitor *alloc_visitor_new(void)
+{
+AllocVisitor *v = g_malloc0(sizeof(AllocVisitor));
+
+v-visitor.start_struct = alloc_start_struct;
+v-visitor.end_struct = alloc_end_struct;
+v-visitor.start_implicit_struct = alloc_start_implicit_struct;
+v-visitor.end_implicit_struct = alloc_end_implicit_struct;
+
+v-visitor.type_enum = alloc_type_enum;
+
+return v;
+}
+
+void alloc_visitor_cleanup(AllocVisitor *v)
+{
+g_free(v);
+}
+
+Visitor *alloc_visitor_get_visitor(AllocVisitor *v)
+{
+return v-visitor;
+}
-- 
2.4.2




[Qemu-devel] [PATCH 11/12] audio: use qapi AudioFormat instead of audfmt_e

2015-06-12 Thread Kővágó, Zoltán
I had to include an enum for audio sampling formats into qapi, but that meant
duplicating the audfmt_e enum. This patch replaces audfmt_e and associated
values with the qapi generated AudioFormat enum.

This patch is mostly a search-and-replace, except for switches where the qapi
generated AUDIO_FORMAT_MAX caused problems.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c | 53 ++
 audio/audio.c | 97 ++-
 audio/audio.h | 11 +-
 audio/audio_win_int.c | 18 -
 audio/ossaudio.c  | 30 +++
 audio/paaudio.c   | 28 +++---
 audio/sdlaudio.c  | 26 ++---
 audio/spiceaudio.c|  4 +-
 audio/wavaudio.c  | 17 +
 audio/wavcapture.c|  2 +-
 hw/arm/omap2.c|  2 +-
 hw/audio/ac97.c   |  2 +-
 hw/audio/adlib.c  |  2 +-
 hw/audio/cs4231a.c|  6 +--
 hw/audio/es1370.c |  4 +-
 hw/audio/gus.c|  2 +-
 hw/audio/hda-codec.c  | 18 -
 hw/audio/lm4549.c |  6 +--
 hw/audio/milkymist-ac97.c |  2 +-
 hw/audio/pcspk.c  |  2 +-
 hw/audio/sb16.c   | 14 +++
 hw/audio/wm8750.c |  4 +-
 hw/input/tsc210x.c|  2 +-
 hw/usb/dev-audio.c|  2 +-
 ui/vnc.c  | 14 +++
 25 files changed, 187 insertions(+), 181 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index b0a451a..6882638 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -88,7 +88,7 @@ struct alsa_params_req {
 
 struct alsa_params_obt {
 int freq;
-audfmt_e fmt;
+AudioFormat fmt;
 int endianness;
 int nchannels;
 snd_pcm_uframes_t samples;
@@ -307,16 +307,16 @@ static int alsa_write (SWVoiceOut *sw, void *buf, int len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)
+static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
 {
 switch (fmt) {
-case AUD_FMT_S8:
+case AUDIO_FORMAT_S8:
 return SND_PCM_FORMAT_S8;
 
-case AUD_FMT_U8:
+case AUDIO_FORMAT_U8:
 return SND_PCM_FORMAT_U8;
 
-case AUD_FMT_S16:
+case AUDIO_FORMAT_S16:
 if (endianness) {
 return SND_PCM_FORMAT_S16_BE;
 }
@@ -324,7 +324,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_S16_LE;
 }
 
-case AUD_FMT_U16:
+case AUDIO_FORMAT_U16:
 if (endianness) {
 return SND_PCM_FORMAT_U16_BE;
 }
@@ -332,7 +332,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_U16_LE;
 }
 
-case AUD_FMT_S32:
+case AUDIO_FORMAT_S32:
 if (endianness) {
 return SND_PCM_FORMAT_S32_BE;
 }
@@ -340,7 +340,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 return SND_PCM_FORMAT_S32_LE;
 }
 
-case AUD_FMT_U32:
+case AUDIO_FORMAT_U32:
 if (endianness) {
 return SND_PCM_FORMAT_U32_BE;
 }
@@ -357,58 +357,58 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int 
endianness)
 }
 }
 
-static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
+static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt,
int *endianness)
 {
 switch (alsafmt) {
 case SND_PCM_FORMAT_S8:
 *endianness = 0;
-*fmt = AUD_FMT_S8;
+*fmt = AUDIO_FORMAT_S8;
 break;
 
 case SND_PCM_FORMAT_U8:
 *endianness = 0;
-*fmt = AUD_FMT_U8;
+*fmt = AUDIO_FORMAT_U8;
 break;
 
 case SND_PCM_FORMAT_S16_LE:
 *endianness = 0;
-*fmt = AUD_FMT_S16;
+*fmt = AUDIO_FORMAT_S16;
 break;
 
 case SND_PCM_FORMAT_U16_LE:
 *endianness = 0;
-*fmt = AUD_FMT_U16;
+*fmt = AUDIO_FORMAT_U16;
 break;
 
 case SND_PCM_FORMAT_S16_BE:
 *endianness = 1;
-*fmt = AUD_FMT_S16;
+*fmt = AUDIO_FORMAT_S16;
 break;
 
 case SND_PCM_FORMAT_U16_BE:
 *endianness = 1;
-*fmt = AUD_FMT_U16;
+*fmt = AUDIO_FORMAT_U16;
 break;
 
 case SND_PCM_FORMAT_S32_LE:
 *endianness = 0;
-*fmt = AUD_FMT_S32;
+*fmt = AUDIO_FORMAT_S32;
 break;
 
 case SND_PCM_FORMAT_U32_LE:
 *endianness = 0;
-*fmt = AUD_FMT_U32;
+*fmt = AUDIO_FORMAT_U32;
 break;
 
 case SND_PCM_FORMAT_S32_BE:
 *endianness = 1;
-*fmt = AUD_FMT_S32;
+*fmt = AUDIO_FORMAT_S32;
 break;
 
 case SND_PCM_FORMAT_U32_BE:
 *endianness = 1;
-*fmt = AUD_FMT_U32;
+*fmt = AUDIO_FORMAT_U32;
 break;
 
 default:
@@ -651,19 +651,22 @@ static int alsa_open (int

[Qemu-devel] [PATCH 12/12] audio: -audiodev command line option

2015-06-12 Thread Kővágó, Zoltán
This patch adds an -audiodev command line option, and deprecates the QEMU_*
environment variables for audio backend configuration. It's syntax is similar to
existing options (-netdev, -device, etc):
 -audiodev driver_name,property=value,...

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, also print out them with -audio-help, to ease
migrating to -audiodev).

Although now it's possible to specify multiple -audiodev options on command
line, multiple audio backends are not supported yet.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   2 +-
 audio/alsaaudio.c   | 284 ++
 audio/audio.c   | 745 +---
 audio/audio.h   |  21 +-
 audio/audio_int.h   |   7 +-
 audio/audio_legacy.c| 319 +
 audio/audio_template.h  |  13 +-
 audio/coreaudio.c   |  49 +---
 audio/dsound_template.h |   6 +-
 audio/dsoundaudio.c |  56 +---
 audio/noaudio.c |   3 +-
 audio/ossaudio.c| 155 +++---
 audio/paaudio.c |  81 ++
 audio/sdlaudio.c|  24 +-
 audio/spiceaudio.c  |   7 +-
 audio/wavaudio.c|  61 +---
 qemu-options.hx | 218 +-
 vl.c|   9 +-
 18 files changed, 979 insertions(+), 1081 deletions(-)
 create mode 100644 audio/audio_legacy.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 481d1aa..9d8f579 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
+common-obj-y = audio.o audio_legacy.o noaudio.o wavaudio.o mixeng.o
 common-obj-$(CONFIG_SDL) += sdlaudio.o
 common-obj-$(CONFIG_OSS) += ossaudio.o
 common-obj-$(CONFIG_SPICE) += spiceaudio.o
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 6882638..06230c8 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -22,6 +22,8 @@
  * THE SOFTWARE.
  */
 #include alsa/asoundlib.h
+#include qapi/alloc-visitor.h
+#include qapi-visit.h
 #include qemu-common.h
 #include qemu/main-loop.h
 #include audio.h
@@ -34,28 +36,9 @@
 #define AUDIO_CAP alsa
 #include audio_int.h
 
-typedef struct ALSAConf {
-int size_in_usec_in;
-int size_in_usec_out;
-const char *pcm_name_in;
-const char *pcm_name_out;
-unsigned int buffer_size_in;
-unsigned int period_size_in;
-unsigned int buffer_size_out;
-unsigned int period_size_out;
-unsigned int threshold;
-
-int buffer_size_in_overridden;
-int period_size_in_overridden;
-
-int buffer_size_out_overridden;
-int period_size_out_overridden;
-} ALSAConf;
-
 struct pollhlp {
 snd_pcm_t *handle;
 struct pollfd *pfds;
-ALSAConf *conf;
 int count;
 int mask;
 };
@@ -67,6 +50,7 @@ typedef struct ALSAVoiceOut {
 void *pcm_buf;
 snd_pcm_t *handle;
 struct pollhlp pollhlp;
+Audiodev *dev;
 } ALSAVoiceOut;
 
 typedef struct ALSAVoiceIn {
@@ -74,16 +58,13 @@ typedef struct ALSAVoiceIn {
 snd_pcm_t *handle;
 void *pcm_buf;
 struct pollhlp pollhlp;
+Audiodev *dev;
 } ALSAVoiceIn;
 
 struct alsa_params_req {
 int freq;
 snd_pcm_format_t fmt;
 int nchannels;
-int size_in_usec;
-int override_mask;
-unsigned int buffer_size;
-unsigned int period_size;
 };
 
 struct alsa_params_obt {
@@ -421,7 +402,8 @@ static int alsa_to_audfmt (snd_pcm_format_t alsafmt, 
AudioFormat *fmt,
 
 static void alsa_dump_info (struct alsa_params_req *req,
 struct alsa_params_obt *obt,
-snd_pcm_format_t obtfmt)
+snd_pcm_format_t obtfmt,
+AudiodevPerDirectionOptions *pdo)
 {
 dolog (parameter | requested value | obtained value\n);
 dolog (format|  %10d | %10d\n, req-fmt, obtfmt);
@@ -429,8 +411,9 @@ static void alsa_dump_info (struct alsa_params_req *req,
req-nchannels, obt-nchannels);
 dolog (frequency |  %10d | %10d\n, req-freq, obt-freq);
 dolog (\n);
-dolog (requested: buffer size %d period size %d\n,
-   req-buffer_size, req-period_size);
+dolog (requested: buffer size % PRId64  buffer count % PRId64 \n,
+   pdo-has_buffer_usecs ? pdo-buffer_usecs : 0,
+   pdo-has_buffer_count ? pdo-buffer_count : 0);
 dolog (obtained: samples %ld\n, obt-samples);
 }
 
@@ -464,23 +447,24 @@ static void alsa_set_threshold (snd_pcm_t *handle, 
snd_pcm_uframes_t threshold)
 }
 }
 
-static int alsa_open (int in, struct alsa_params_req *req,
-  struct alsa_params_obt *obt, snd_pcm_t **handlep,
-  ALSAConf *conf)
+static int alsa_open(bool in, struct

[Qemu-devel] [PATCH 06/12] ossaudio: use trace events instead of debug config flag

2015-06-12 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/ossaudio.c | 25 -
 trace-events |  4 
 2 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index d247969..d5362ab 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -30,6 +30,7 @@
 #include qemu/main-loop.h
 #include qemu/host-utils.h
 #include audio.h
+#include trace.h
 
 #define AUDIO_CAP oss
 #include audio_int.h
@@ -44,7 +45,6 @@ typedef struct OSSConf {
 int fragsize;
 const char *devpath_out;
 const char *devpath_in;
-int debug;
 int exclusive;
 int policy;
 } OSSConf;
@@ -314,9 +314,7 @@ static int oss_open (int in, struct oss_params *req,
 int version;
 
 if (!oss_get_version (fd, version, typ)) {
-if (conf-debug) {
-dolog (OSS version = %#x\n, version);
-}
+trace_oss_version(version);
 
 if (version = 0x04) {
 int policy = conf-policy;
@@ -427,7 +425,6 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 struct audio_buf_info abinfo;
 struct count_info cntinfo;
 int bufsize;
-OSSConf *conf = oss-conf;
 
 bufsize = hw-samples  hw-info.shift;
 
@@ -452,19 +449,12 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 }
 
 if (abinfo.bytes  bufsize) {
-if (conf-debug) {
-dolog (warning: Invalid available size, size=%d bufsize=%d\n
-   please report your OS/audio hw to av1...@comtv.ru\n,
-   abinfo.bytes, bufsize);
-}
+trace_oss_invalid_available_size(abinfo.bytes, bufsize);
 abinfo.bytes = bufsize;
 }
 
 if (abinfo.bytes  0) {
-if (conf-debug) {
-dolog (warning: Invalid available size, size=%d bufsize=%d\n,
-   abinfo.bytes, bufsize);
-}
+trace_oss_invalid_available_size(abinfo.bytes, bufsize);
 return 0;
 }
 
@@ -850,7 +840,6 @@ static OSSConf glob_conf = {
 .fragsize = 4096,
 .devpath_out = /dev/dsp,
 .devpath_in = /dev/dsp,
-.debug = 0,
 .exclusive = 0,
 .policy = 5
 };
@@ -917,12 +906,6 @@ static struct audio_option oss_options[] = {
 .descr = Set the timing policy of the device, -1 to use fragment 
mode,
 },
 #endif
-{
-.name  = DEBUG,
-.tag   = AUD_OPT_BOOL,
-.valp  = glob_conf.debug,
-.descr = Turn on some debugging messages
-},
 { /* End of list */ }
 };
 
diff --git a/trace-events b/trace-events
index 0f372bb..2be8e09 100644
--- a/trace-events
+++ b/trace-events
@@ -1638,3 +1638,7 @@ alsa_xrun_in(void) Recovering from capture xrun
 alsa_resume_out(void) Resuming suspended output stream
 alsa_resume_in(void) Resuming suspended input stream
 alsa_no_frames(int state) No frames available and ALSA state is %d
+
+# audio/ossaudio.c
+oss_version(int version) OSS version = %#x
+oss_invalid_available_size(int size, int bufsize) Invalid available size, 
size=%d bufsize=%d
-- 
2.4.2




[Qemu-devel] [PATCH 05/12] alsaaudio: use trace events instead of verbose

2015-06-12 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c | 60 +--
 trace-events  | 12 +++
 2 files changed, 26 insertions(+), 46 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index d7e181b..b0a451a 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -25,6 +25,7 @@
 #include qemu-common.h
 #include qemu/main-loop.h
 #include audio.h
+#include trace.h
 
 #if QEMU_GNUC_PREREQ(4, 3)
 #pragma GCC diagnostic ignored -Waddress
@@ -49,7 +50,6 @@ typedef struct ALSAConf {
 
 int buffer_size_out_overridden;
 int period_size_out_overridden;
-int verbose;
 } ALSAConf;
 
 struct pollhlp {
@@ -180,7 +180,6 @@ static void alsa_poll_handler (void *opaque)
 snd_pcm_state_t state;
 struct pollhlp *hlp = opaque;
 unsigned short revents;
-ALSAConf *conf = hlp-conf;
 
 count = poll (hlp-pfds, hlp-count, 0);
 if (count  0) {
@@ -202,9 +201,7 @@ static void alsa_poll_handler (void *opaque)
 }
 
 if (!(revents  hlp-mask)) {
-if (conf-verbose) {
-dolog (revents = %d\n, revents);
-}
+trace_alsa_revents(revents);
 return;
 }
 
@@ -239,7 +236,6 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
 {
 int i, count, err;
 struct pollfd *pfds;
-ALSAConf *conf = hlp-conf;
 
 count = snd_pcm_poll_descriptors_count (handle);
 if (count = 0) {
@@ -268,16 +264,11 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
NULL, hlp);
 }
 if (pfds[i].events  POLLOUT) {
-if (conf-verbose) {
-dolog (POLLOUT %d %d\n, i, pfds[i].fd);
-}
+trace_alsa_pollout(i, pfds[i].fd);
 err = qemu_set_fd_handler (pfds[i].fd, NULL,
alsa_poll_handler, hlp);
 }
-if (conf-verbose) {
-dolog (Set handler events=%#x index=%d fd=%d err=%d\n,
-   pfds[i].events, i, pfds[i].fd, err);
-}
+trace_alsa_set_handler(pfds[i].events, i, pfds[i].fd, err);
 
 if (err) {
 dolog (Failed to set handler events=%#x index=%d fd=%d err=%d\n,
@@ -521,7 +512,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 }
 
 err = snd_pcm_hw_params_set_format (handle, hw_params, req-fmt);
-if (err  0  conf-verbose) {
+if (err  0) {
 alsa_logerr2 (err, typ, Failed to set format %d\n, req-fmt);
 }
 
@@ -685,10 +676,9 @@ static int alsa_open (int in, struct alsa_params_req *req,
 
 *handlep = handle;
 
-if (conf-verbose 
-(obtfmt != req-fmt ||
+if (obtfmt != req-fmt ||
  obt-nchannels != req-nchannels ||
- obt-freq != req-freq)) {
+ obt-freq != req-freq) {
 dolog (Audio parameters for %s\n, typ);
 alsa_dump_info (req, obt, obtfmt);
 }
@@ -728,7 +718,6 @@ static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
 static void alsa_write_pending (ALSAVoiceOut *alsa)
 {
 HWVoiceOut *hw = alsa-hw;
-ALSAConf *conf = alsa-pollhlp.conf;
 
 while (alsa-pending) {
 int left_till_end_samples = hw-samples - alsa-wpos;
@@ -743,9 +732,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
 if (written = 0) {
 switch (written) {
 case 0:
-if (conf-verbose) {
-dolog (Failed to write %d frames (wrote zero)\n, 
len);
-}
+trace_alsa_wrote_zero(len);
 return;
 
 case -EPIPE:
@@ -754,9 +741,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
  len);
 return;
 }
-if (conf-verbose) {
-dolog (Recovering from playback xrun\n);
-}
+trace_alsa_xrun_out();
 continue;
 
 case -ESTRPIPE:
@@ -767,9 +752,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
  len);
 return;
 }
-if (conf-verbose) {
-dolog (Resuming suspended output stream\n);
-}
+trace_alsa_resume_out();
 continue;
 
 case -EAGAIN:
@@ -1002,7 +985,6 @@ static int alsa_run_in (HWVoiceIn *hw)
 };
 snd_pcm_sframes_t avail;
 snd_pcm_uframes_t read_samples = 0;
-ALSAConf *conf = alsa-pollhlp.conf;
 
 if (!dead) {
 return 0;
@@ -1028,14 +1010,10 @@ static int alsa_run_in (HWVoiceIn *hw)
 dolog (Failed to resume suspended input stream\n);
 return 0;
 }
-if (conf-verbose) {
-dolog

[Qemu-devel] [PATCH 02/12] audio: remove plive

2015-06-12 Thread Kővágó, Zoltán
It was useless even 3 years ago, so it can probably safely go away:
https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/audio.c  | 12 
 audio/audio_template.h | 41 -
 2 files changed, 53 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index cb1cba9..5be4b15 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -30,7 +30,6 @@
 #define AUDIO_CAP audio
 #include audio_int.h
 
-/* #define DEBUG_PLIVE */
 /* #define DEBUG_LIVE */
 /* #define DEBUG_OUT */
 /* #define DEBUG_CAPTURE */
@@ -66,7 +65,6 @@ static struct {
 int hertz;
 int64_t ticks;
 } period;
-int plive;
 int try_poll_in;
 int try_poll_out;
 } conf = {
@@ -95,7 +93,6 @@ static struct {
 },
 
 .period = { .hertz = 100 },
-.plive = 0,
 .try_poll_in = 1,
 .try_poll_out = 1,
 };
@@ -1443,9 +1440,6 @@ static void audio_run_out (AudioState *s)
 while (sw) {
 sw1 = sw-entries.le_next;
 if (!sw-active  !sw-callback.fn) {
-#ifdef DEBUG_PLIVE
-dolog (Finishing with old voice\n);
-#endif
 audio_close_out (sw);
 }
 sw = sw1;
@@ -1637,12 +1631,6 @@ static struct audio_option audio_options[] = {
 .valp  = conf.period.hertz,
 .descr = Timer period in HZ (0 - use lowest possible)
 },
-{
-.name  = PLIVE,
-.tag   = AUD_OPT_BOOL,
-.valp  = conf.plive,
-.descr = (undocumented)
-},
 { /* End of list */ }
 };
 
diff --git a/audio/audio_template.h b/audio/audio_template.h
index f716d97..99b27b2 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -398,10 +398,6 @@ SW *glue (AUD_open_, TYPE) (
 )
 {
 AudioState *s = glob_audio_state;
-#ifdef DAC
-int live = 0;
-SW *old_sw = NULL;
-#endif
 
 if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) {
 dolog (card=%p name=%p callback_fn=%p as=%p\n,
@@ -426,29 +422,6 @@ SW *glue (AUD_open_, TYPE) (
 return sw;
 }
 
-#ifdef DAC
-if (conf.plive  sw  (!sw-active  !sw-empty)) {
-live = sw-total_hw_samples_mixed;
-
-#ifdef DEBUG_PLIVE
-dolog (Replacing voice %s with %d live samples\n, SW_NAME (sw), 
live);
-dolog (Old %s freq %d, bits %d, channels %d\n,
-   SW_NAME (sw), sw-info.freq, sw-info.bits, sw-info.nchannels);
-dolog (New %s freq %d, bits %d, channels %d\n,
-   name,
-   as-freq,
-   (as-fmt == AUD_FMT_S16 || as-fmt == AUD_FMT_U16) ? 16 : 8,
-   as-nchannels);
-#endif
-
-if (live) {
-old_sw = sw;
-old_sw-callback.fn = NULL;
-sw = NULL;
-}
-}
-#endif
-
 if (!glue (conf.fixed_, TYPE).enabled  sw) {
 glue (AUD_close_, TYPE) (card, sw);
 sw = NULL;
@@ -481,20 +454,6 @@ SW *glue (AUD_open_, TYPE) (
 sw-callback.fn = callback_fn;
 sw-callback.opaque = callback_opaque;
 
-#ifdef DAC
-if (live) {
-int mixed =
-(live  old_sw-info.shift)
-* old_sw-info.bytes_per_second
-/ sw-info.bytes_per_second;
-
-#ifdef DEBUG_PLIVE
-dolog (Silence will be mixed %d\n, mixed);
-#endif
-sw-total_hw_samples_mixed += mixed;
-}
-#endif
-
 #ifdef DEBUG_AUDIO
 dolog (%s\n, name);
 audio_pcm_print_info (hw, sw-hw-info);
-- 
2.4.2




[Qemu-devel] [PATCH 00/12] -audiodev option

2015-06-12 Thread Kővágó, Zoltán
Note: this patch depends on my not-yet-merged audio cleanup patches:
https://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg02558.html

This series of patches adds a new -audiodev command line option to specify audio
subsytem parameters instead of environment variables. This will later allow us
to specify multiple audio backends. The syntax is something like this:
 -audiodev driver_name,property=value,...
like:
 -audiodev alsa,frequency=8000,channels=1

The first 6 commits are cleanup commits of the audio backends. The next commit
adds a qapi Audiodev struct that describes the audio backend options. The next 4
commits are some miscellaneous additions that are needed by the last commit
which finally adds the -audiodev option.

For users with esoteric platforms or needs please check I did not break anything
accidentally. For easier testing, pull https://github.com/DirtYiCE/qemu.git tag
audio-cmdline-v1.

Please review.

Kővágó, Zoltán (12):
  audio: remove LOG_TO_MONITOR along with default_mon
  audio: remove plive
  dsoundaudio: remove *_retries kludges
  dsoundaudio: remove primary buffer
  alsaaudio: use trace events instead of verbose
  ossaudio: use trace events instead of debug config flag
  qapi: qapi for audio backends
  qapi: support nested structs in OptsVisitor
  opts: do not print separator before first item in qemu_opts_print
  qapi: AllocVisitor
  audio: use qapi AudioFormat instead of audfmt_e
  audio: -audiodev command line option

 Makefile|   4 +-
 audio/Makefile.objs |   2 +-
 audio/alsaaudio.c   | 397 +--
 audio/audio.c   | 831 +---
 audio/audio.h   |  32 +-
 audio/audio_int.h   |   7 +-
 audio/audio_legacy.c| 319 
 audio/audio_template.h  |  54 +--
 audio/audio_win_int.c   |  18 +-
 audio/coreaudio.c   |  49 +-
 audio/dsound_template.h |  41 +-
 audio/dsoundaudio.c | 228 ++---
 audio/noaudio.c |   3 +-
 audio/ossaudio.c| 208 +++-
 audio/paaudio.c | 109 ++---
 audio/sdlaudio.c|  50 +-
 audio/spiceaudio.c  |  11 +-
 audio/wavaudio.c|  76 +--
 audio/wavcapture.c  |   2 +-
 block.c |   2 +-
 hw/arm/omap2.c  |   2 +-
 hw/audio/ac97.c |   2 +-
 hw/audio/adlib.c|   2 +-
 hw/audio/cs4231a.c  |   6 +-
 hw/audio/es1370.c   |   4 +-
 hw/audio/gus.c  |   2 +-
 hw/audio/hda-codec.c|  18 +-
 hw/audio/lm4549.c   |   6 +-
 hw/audio/milkymist-ac97.c   |   2 +-
 hw/audio/pcspk.c|   2 +-
 hw/audio/sb16.c |  14 +-
 hw/audio/wm8750.c   |   4 +-
 hw/input/tsc210x.c  |   2 +-
 hw/usb/dev-audio.c  |   2 +-
 include/monitor/monitor.h   |   1 -
 include/qapi/alloc-visitor.h|  18 +
 monitor.c   |   4 -
 qapi-schema.json|   3 +
 qapi/Makefile.objs  |   1 +
 qapi/alloc-visitor.c|  62 +++
 qapi/audio.json | 217 +
 qapi/opts-visitor.c | 144 --
 qemu-options.hx | 218 -
 tests/qapi-schema/qapi-schema-test.json |   9 +-
 tests/test-opts-visitor.c   |  34 ++
 trace-events|  16 +
 ui/vnc.c|  14 +-
 util/qemu-option.c  |   5 +-
 vl.c|   9 +-
 49 files changed, 1663 insertions(+), 1603 deletions(-)
 create mode 100644 audio/audio_legacy.c
 create mode 100644 include/qapi/alloc-visitor.h
 create mode 100644 qapi/alloc-visitor.c
 create mode 100644 qapi/audio.json

-- 
2.4.2




[Qemu-devel] [PATCH 01/12] audio: remove LOG_TO_MONITOR along with default_mon

2015-06-12 Thread Kővágó, Zoltán
Setting QEMU_AUDIO_LOG_TO_MONITOR=1 can crash qemu (if qemu tries to log
to the monitor before it's being initialized), and also nothing else in
qemu logs to the monitor.

This log to monitor feature was the last thing that used the default_mon
variable, so I removed it too (as using it can cause problems).

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/audio.c | 23 +++
 include/monitor/monitor.h |  1 -
 monitor.c |  4 
 3 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 9d018e9..cb1cba9 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -67,7 +67,6 @@ static struct {
 int64_t ticks;
 } period;
 int plive;
-int log_to_monitor;
 int try_poll_in;
 int try_poll_out;
 } conf = {
@@ -97,7 +96,6 @@ static struct {
 
 .period = { .hertz = 100 },
 .plive = 0,
-.log_to_monitor = 0,
 .try_poll_in = 1,
 .try_poll_out = 1,
 };
@@ -331,20 +329,11 @@ static const char *audio_get_conf_str (const char *key,
 
 void AUD_vlog (const char *cap, const char *fmt, va_list ap)
 {
-if (conf.log_to_monitor) {
-if (cap) {
-monitor_printf(default_mon, %s: , cap);
-}
-
-monitor_vprintf(default_mon, fmt, ap);
+if (cap) {
+fprintf(stderr, %s: , cap);
 }
-else {
-if (cap) {
-fprintf (stderr, %s: , cap);
-}
 
-vfprintf (stderr, fmt, ap);
-}
+vfprintf(stderr, fmt, ap);
 }
 
 void AUD_log (const char *cap, const char *fmt, ...)
@@ -1654,12 +1643,6 @@ static struct audio_option audio_options[] = {
 .valp  = conf.plive,
 .descr = (undocumented)
 },
-{
-.name  = LOG_TO_MONITOR,
-.tag   = AUD_OPT_BOOL,
-.valp  = conf.log_to_monitor,
-.descr = Print logging messages to monitor instead of stderr
-},
 { /* End of list */ }
 };
 
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 57f8394..88644ce 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -8,7 +8,6 @@
 #include qemu/readline.h
 
 extern Monitor *cur_mon;
-extern Monitor *default_mon;
 
 /* flags for monitor_init */
 #define MONITOR_IS_DEFAULT0x01
diff --git a/monitor.c b/monitor.c
index 9afee7b..06aee1f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -226,7 +226,6 @@ static mon_cmd_t info_cmds[];
 static const mon_cmd_t qmp_cmds[];
 
 Monitor *cur_mon;
-Monitor *default_mon;
 
 static void monitor_command_cb(void *opaque, const char *cmdline,
void *readline_opaque);
@@ -5270,9 +5269,6 @@ void monitor_init(CharDriverState *chr, int flags)
 qemu_mutex_lock(monitor_lock);
 QLIST_INSERT_HEAD(mon_list, mon, entry);
 qemu_mutex_unlock(monitor_lock);
-
-if (!default_mon || (flags  MONITOR_IS_DEFAULT))
-default_mon = mon;
 }
 
 static void bdrv_password_cb(void *opaque, const char *password,
-- 
2.4.2




[Qemu-devel] [PATCH 03/12] dsoundaudio: remove *_retries kludges

2015-06-12 Thread Kővágó, Zoltán
According to MSDN this may happen when the window is not in the foreground, but
the default is 1 since a long time (which means no retries), so it should be ok.
I've found no problems during testing it on Windows 7 and wine, so this was
probably only the case with some old Windows versions.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/dsound_template.h | 35 +
 audio/dsoundaudio.c | 68 ++---
 2 files changed, 20 insertions(+), 83 deletions(-)

diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 85ba858..b439f33 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -72,48 +72,27 @@ static int glue (dsound_lock_, TYPE) (
 )
 {
 HRESULT hr;
-int i;
 LPVOID p1 = NULL, p2 = NULL;
 DWORD blen1 = 0, blen2 = 0;
 DWORD flag;
-DSoundConf *conf = s-conf;
 
 #ifdef DSBTYPE_IN
 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
 #else
 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
 #endif
-for (i = 0; i  conf-lock_retries; ++i) {
-hr = glue (IFACE, _Lock) (
-buf,
-pos,
-len,
-p1,
-blen1,
-p2,
-blen2,
-flag
-);
+hr = glue(IFACE, _Lock)(buf, pos, len, p1, blen1, p2, blen2, flag);
 
-if (FAILED (hr)) {
+if (FAILED (hr)) {
 #ifndef DSBTYPE_IN
-if (hr == DSERR_BUFFERLOST) {
-if (glue (dsound_restore_, TYPE) (buf, s)) {
-dsound_logerr (hr, Could not lock  NAME \n);
-goto fail;
-}
-continue;
+if (hr == DSERR_BUFFERLOST) {
+if (glue (dsound_restore_, TYPE) (buf, s)) {
+dsound_logerr (hr, Could not lock  NAME \n);
 }
-#endif
-dsound_logerr (hr, Could not lock  NAME \n);
 goto fail;
 }
-
-break;
-}
-
-if (i == conf-lock_retries) {
-dolog (%d attempts to lock  NAME  failed\n, i);
+#endif
+dsound_logerr (hr, Could not lock  NAME \n);
 goto fail;
 }
 
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index c8b09e2..28b98bf 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -42,9 +42,6 @@
 /* #define DEBUG_DSOUND */
 
 typedef struct {
-int lock_retries;
-int restore_retries;
-int getstatus_retries;
 int set_primary;
 int bufsize_in;
 int bufsize_out;
@@ -274,26 +271,14 @@ static void print_wave_format (WAVEFORMATEX *wfx)
 static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
 {
 HRESULT hr;
-int i;
 
-for (i = 0; i  s-conf.restore_retries; ++i) {
-hr = IDirectSoundBuffer_Restore (dsb);
+hr = IDirectSoundBuffer_Restore (dsb);
 
-switch (hr) {
-case DS_OK:
-return 0;
-
-case DSERR_BUFFERLOST:
-continue;
-
-default:
-dsound_logerr (hr, Could not restore playback buffer\n);
-return -1;
-}
+if (hr != DS_OK) {
+dsound_logerr (hr, Could not restore playback buffer\n);
+return -1;
 }
-
-dolog (%d attempts to restore playback buffer failed\n, i);
-return -1;
+return 0;
 }
 
 #include dsound_template.h
@@ -305,22 +290,16 @@ static int dsound_get_status_out (LPDIRECTSOUNDBUFFER 
dsb, DWORD *statusp,
   dsound *s)
 {
 HRESULT hr;
-int i;
 
-for (i = 0; i  s-conf.getstatus_retries; ++i) {
-hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
-if (FAILED (hr)) {
-dsound_logerr (hr, Could not get playback buffer status\n);
-return -1;
-}
+hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
+if (FAILED (hr)) {
+dsound_logerr (hr, Could not get playback buffer status\n);
+return -1;
+}
 
-if (*statusp  DSERR_BUFFERLOST) {
-if (dsound_restore_out (dsb, s)) {
-return -1;
-}
-continue;
-}
-break;
+if (*statusp  DSERR_BUFFERLOST) {
+dsound_restore_out(dsb, s);
+return -1;
 }
 
 return 0;
@@ -844,9 +823,6 @@ static int dsound_run_in (HWVoiceIn *hw)
 }
 
 static DSoundConf glob_conf = {
-.lock_retries   = 1,
-.restore_retries= 1,
-.getstatus_retries  = 1,
 .set_primary= 0,
 .bufsize_in = 16384,
 .bufsize_out= 16384,
@@ -959,24 +935,6 @@ static void *dsound_audio_init (void)
 
 static struct audio_option dsound_options[] = {
 {
-.name  = LOCK_RETRIES,
-.tag   = AUD_OPT_INT,
-.valp  = glob_conf.lock_retries,
-.descr = Number of times to attempt locking the buffer
-},
-{
-.name  = RESTOURE_RETRIES,
-.tag   = AUD_OPT_INT,
-.valp  = glob_conf.restore_retries,
-.descr = Number of times to attempt restoring the buffer

[Qemu-devel] [PATCH 04/12] dsoundaudio: remove primary buffer

2015-06-12 Thread Kővágó, Zoltán
Enabling this option just creates a playback buffer with the specified settings,
and then ignores it. It's probably some outdated hack to set audio formats on
windows. (The first created stream dictates all other streams settings, at least
on some Windows versions). Setting DAC_FIXED_SETTINGS should have the same
effect as setting (the now removed) primary buffer.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/dsoundaudio.c | 104 
 1 file changed, 104 deletions(-)

diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index 28b98bf..e9472c1 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -42,17 +42,14 @@
 /* #define DEBUG_DSOUND */
 
 typedef struct {
-int set_primary;
 int bufsize_in;
 int bufsize_out;
-struct audsettings settings;
 int latency_millis;
 } DSoundConf;
 
 typedef struct {
 LPDIRECTSOUND dsound;
 LPDIRECTSOUNDCAPTURE dsound_capture;
-LPDIRECTSOUNDBUFFER dsound_primary_buffer;
 struct audsettings settings;
 DSoundConf conf;
 } dsound;
@@ -387,27 +384,10 @@ static void dsound_clear_sample (HWVoiceOut *hw, 
LPDIRECTSOUNDBUFFER dsb,
 dsound_unlock_out (dsb, p1, p2, blen1, blen2);
 }
 
-static void dsound_close (dsound *s)
-{
-HRESULT hr;
-
-if (s-dsound_primary_buffer) {
-hr = IDirectSoundBuffer_Release (s-dsound_primary_buffer);
-if (FAILED (hr)) {
-dsound_logerr (hr, Could not release primary buffer\n);
-}
-s-dsound_primary_buffer = NULL;
-}
-}
-
 static int dsound_open (dsound *s)
 {
-int err;
 HRESULT hr;
-WAVEFORMATEX wfx;
-DSBUFFERDESC dsbd;
 HWND hwnd;
-DSoundConf *conf = s-conf;
 
 hwnd = GetForegroundWindow ();
 hr = IDirectSound_SetCooperativeLevel (
@@ -422,63 +402,7 @@ static int dsound_open (dsound *s)
 return -1;
 }
 
-if (!conf-set_primary) {
-return 0;
-}
-
-err = waveformat_from_audio_settings (wfx, conf-settings);
-if (err) {
-return -1;
-}
-
-memset (dsbd, 0, sizeof (dsbd));
-dsbd.dwSize = sizeof (dsbd);
-dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
-dsbd.dwBufferBytes = 0;
-dsbd.lpwfxFormat = NULL;
-
-hr = IDirectSound_CreateSoundBuffer (
-s-dsound,
-dsbd,
-s-dsound_primary_buffer,
-NULL
-);
-if (FAILED (hr)) {
-dsound_logerr (hr, Could not create primary playback buffer\n);
-return -1;
-}
-
-hr = IDirectSoundBuffer_SetFormat (s-dsound_primary_buffer, wfx);
-if (FAILED (hr)) {
-dsound_logerr (hr, Could not set primary playback buffer format\n);
-}
-
-hr = IDirectSoundBuffer_GetFormat (
-s-dsound_primary_buffer,
-wfx,
-sizeof (wfx),
-NULL
-);
-if (FAILED (hr)) {
-dsound_logerr (hr, Could not get primary playback buffer format\n);
-goto fail0;
-}
-
-#ifdef DEBUG_DSOUND
-dolog (Primary\n);
-print_wave_format (wfx);
-#endif
-
-err = waveformat_to_audio_settings (wfx, s-settings);
-if (err) {
-goto fail0;
-}
-
 return 0;
-
- fail0:
-dsound_close (s);
-return -1;
 }
 
 static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
@@ -823,12 +747,8 @@ static int dsound_run_in (HWVoiceIn *hw)
 }
 
 static DSoundConf glob_conf = {
-.set_primary= 0,
 .bufsize_in = 16384,
 .bufsize_out= 16384,
-.settings.freq  = 44100,
-.settings.nchannels = 2,
-.settings.fmt   = AUD_FMT_S16,
 .latency_millis = 10
 };
 
@@ -935,36 +855,12 @@ static void *dsound_audio_init (void)
 
 static struct audio_option dsound_options[] = {
 {
-.name  = SET_PRIMARY,
-.tag   = AUD_OPT_BOOL,
-.valp  = glob_conf.set_primary,
-.descr = Set the parameters of primary buffer
-},
-{
 .name  = LATENCY_MILLIS,
 .tag   = AUD_OPT_INT,
 .valp  = glob_conf.latency_millis,
 .descr = (undocumented)
 },
 {
-.name  = PRIMARY_FREQ,
-.tag   = AUD_OPT_INT,
-.valp  = glob_conf.settings.freq,
-.descr = Primary buffer frequency
-},
-{
-.name  = PRIMARY_CHANNELS,
-.tag   = AUD_OPT_INT,
-.valp  = glob_conf.settings.nchannels,
-.descr = Primary buffer number of channels (1 - mono, 2 - stereo)
-},
-{
-.name  = PRIMARY_FMT,
-.tag   = AUD_OPT_FMT,
-.valp  = glob_conf.settings.fmt,
-.descr = Primary buffer format
-},
-{
 .name  = BUFSIZE_OUT,
 .tag   = AUD_OPT_INT,
 .valp  = glob_conf.bufsize_out,
-- 
2.4.2




[Qemu-devel] [PATCH 08/12] qapi: support nested structs in OptsVisitor

2015-06-12 Thread Kővágó, Zoltán
The current OptsVisitor flattens the whole structure, if there are same named
fields under different paths (like `in' and `out' in `Audiodev'), the current
visitor can't cope with them (for example setting `frequency=44100' will set the
in's frequency to 44100 and leave out's frequency unspecified).

This patch fixes it, by the following changes:
1) Specifying just the field name will apply to all fields that has the
   specified name (this means it would set both in's and out's frequency to
   44100 in the above example).
2) Optionally user can specify the path in the hierarchy. Names are separated by
   a dot (e.g. `in.frequency', `foo.bar.something', etc). The user need not
   specify the whole path, only the last few components (i.e. `bar.something' is
   equivalent to `foo.bar.something' if only `foo' has a `bar' field). This way
   1) is just a special case of this when only the last component is specified.
3) In case of an ambiguity (e.g `frequency=44100,in.frequency=8000') the longest
   matching (the most specific) path wins (so in this example, in's frequency
   would become 8000, because `in.frequency' is more specific that `frequency',
   and out's frequency would become 44100, because only `frequency' matches it).

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 qapi/opts-visitor.c | 144 +---
 tests/qapi-schema/qapi-schema-test.json |   9 +-
 tests/test-opts-visitor.c   |  34 
 3 files changed, 157 insertions(+), 30 deletions(-)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index f2ad6d7..409d8b7 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -64,13 +64,14 @@ struct OptsVisitor
 /* Non-null iff depth is positive. Each key is a QemuOpt name. Each value
  * is a non-empty GQueue, enumerating all QemuOpt occurrences with that
  * name. */
-GHashTable *unprocessed_opts;
+GHashTable *unprocessed_opts, *opts;
 
 /* The list currently being traversed with opts_start_list() /
  * opts_next_list(). The list must have a struct element type in the
  * schema, with a single mandatory scalar member. */
 ListMode list_mode;
 GQueue *repeated_opts;
+char *repeated_name;
 
 /* When parsing a list of repeating options as integers, values of the form
  * a-b, representing a closed interval, are allowed. Elements in the
@@ -86,6 +87,9 @@ struct OptsVisitor
  * not survive or escape the OptsVisitor object.
  */
 QemuOpt *fake_id_opt;
+
+/* List of field names leading to the current structure. */
+GQueue *nested_names;
 };
 
 
@@ -97,11 +101,12 @@ destroy_list(gpointer list)
 
 
 static void
-opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt)
+opts_visitor_insert(OptsVisitor *ov, const QemuOpt *opt)
 {
 GQueue *list;
+assert(opt);
 
-list = g_hash_table_lookup(unprocessed_opts, opt-name);
+list = g_hash_table_lookup(ov-opts, opt-name);
 if (list == NULL) {
 list = g_queue_new();
 
@@ -109,7 +114,8 @@ opts_visitor_insert(GHashTable *unprocessed_opts, const 
QemuOpt *opt)
  * key_destroy_func in opts_start_struct(). Thus cast away key
  * const-ness in order to suppress gcc's warning.
  */
-g_hash_table_insert(unprocessed_opts, (gpointer)opt-name, list);
+g_hash_table_insert(ov-opts, (gpointer)opt-name, list);
+g_hash_table_insert(ov-unprocessed_opts, (gpointer)opt-name, list);
 }
 
 /* Similarly, destroy_list() doesn't call g_queue_free_full(). */
@@ -127,17 +133,27 @@ opts_start_struct(Visitor *v, void **obj, const char 
*kind,
 if (obj) {
 *obj = g_malloc0(size  0 ? size : 1);
 }
+
+/* assuming name is a statically allocated string (or at least it's 
lifetime
+ * is longer than the visitor's) */
+if (!name) {
+name = ;
+}
+g_queue_push_tail(ov-nested_names, (gpointer) name);
+
 if (ov-depth++  0) {
 return;
 }
 
-ov-unprocessed_opts = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, destroy_list);
+ov-opts = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, destroy_list);
+ov-unprocessed_opts = g_hash_table_new(g_str_hash, g_str_equal);
+
 QTAILQ_FOREACH(opt, ov-opts_root-head, next) {
 /* ensured by qemu-option.c::opts_do_parse() */
 assert(strcmp(opt-name, id) != 0);
 
-opts_visitor_insert(ov-unprocessed_opts, opt);
+opts_visitor_insert(ov, opt);
 }
 
 if (ov-opts_root-id != NULL) {
@@ -145,7 +161,7 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
 
 ov-fake_id_opt-name = g_strdup(id);
 ov-fake_id_opt-str = g_strdup(ov-opts_root-id);
-opts_visitor_insert(ov-unprocessed_opts, ov-fake_id_opt);
+opts_visitor_insert(ov, ov-fake_id_opt);
 }
 }
 
@@ -163,6 +179,8 @@ opts_end_struct

[Qemu-devel] [PATCH 09/12] opts: do not print separator before first item in qemu_opts_print

2015-06-12 Thread Kővágó, Zoltán
This allows to print options in a format that the user would actually write it
on the command line (foo=bar,baz=asd,etc=def), without prepending a spurious
comma at the beginning of the list.

Only block.c depended on the old behavior, but it was also updated.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 block.c| 2 +-
 util/qemu-option.c | 5 -
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index 2b9ceae..ef335bc 100644
--- a/block.c
+++ b/block.c
@@ -3644,7 +3644,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 }
 
 if (!quiet) {
-printf(Formatting '%s', fmt=%s, filename, fmt);
+printf(Formatting '%s', fmt=%s , filename, fmt);
 qemu_opts_print(opts,  );
 puts();
 }
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 840f5f7..b347d92 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -728,14 +728,16 @@ void qemu_opts_del(QemuOpts *opts)
 g_free(opts);
 }
 
-void qemu_opts_print(QemuOpts *opts, const char *sep)
+void qemu_opts_print(QemuOpts *opts, const char *d_sep)
 {
 QemuOpt *opt;
 QemuOptDesc *desc = opts-list-desc;
+const char *sep = ;
 
 if (desc[0].name == NULL) {
 QTAILQ_FOREACH(opt, opts-head, next) {
 printf(%s%s=\%s\, sep, opt-name, opt-str);
+sep = d_sep;
 }
 return;
 }
@@ -755,6 +757,7 @@ void qemu_opts_print(QemuOpts *opts, const char *sep)
 } else {
 printf(%s%s=%s, sep, desc-name, value);
 }
+sep = d_sep;
 }
 }
 
-- 
2.4.2




Re: [Qemu-devel] [PATCH 07/12] qapi: qapi for audio backends

2015-06-12 Thread Kővágó Zoltán

2015-06-13 00:11 keltezéssel, Eric Blake írta:

+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @in: #optional options of the capture stream
+#
+# @out: #optional options of the playback stream


Marked optional here...


+#
+# @threshold: #optional set the threshold (in frames) when playback starts
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaOptions',
+  'data': {
+'in': 'AudiodevAlsaPerDirectionOptions',
+'out':'AudiodevAlsaPerDirectionOptions',


...but not here.


Oups. The code is the correct (they are not optional), I forgot updating 
the documentation. (Same goes for the other mismatches).





+'*threshold': 'int' } }
+
+##
+# @AudiodevDsoundOptions
+#
+# Options of the dsound audio backend.
+#
+# @latency-millis: #optional add extra latency to playback
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevDsoundOptions',
+  'data': {
+'*latency-millis': 'int' } }


Style question - should we just call this 'latency', and document the
milliseconds unit in the description? But having the name latency_millis
in C code might not be all that bad, so you may not want to change this one.


There is also a buffer-usecs, so I vote for keeping latency-millis. Also 
there is timer-period in Audiodev. Maybe it should be renamed to 
timer-period-hz, to keep consistency. Or maybe change all of them to usecs.



Other issues acked.

Thanks,
Zoltan




Re: [Qemu-devel] [PATCH v2 1/6] qapi: qapi for audio backends

2015-06-17 Thread Kővágó Zoltán

2015-06-17 18:06 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 15:37 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 13:48 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 09:46 keltezéssel, Markus Armbruster írta:

[...]

+##
+# @AudiodevBackendOptions
+#
+# A discriminated record of audio backends.
+#
+# Since: 2.4
+##
+{ 'union': 'AudiodevBackendOptions',
+  'data': {
+'none':  'AudiodevNoOptions',
+'alsa':  'AudiodevAlsaOptions',
+'coreaudio': 'AudiodevNoOptions',
+'dsound':'AudiodevDsoundOptions',
+'oss':   'AudiodevOssOptions',
+'pa':'AudiodevPaOptions',
+'sdl':   'AudiodevNoOptions',
+'spice': 'AudiodevNoOptions',
+'wav':   'AudiodevWavOptions' } }
+
+##
+# @AudioFormat
+#
+# An enumeration of possible audio formats.
+#
+# Since: 2.4
+##
+{ 'enum': 'AudioFormat',
+  'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32' ] }
+
+##
+# @AudiodevPerDirectionOptions
+#
+# General audio backend options that are used for both playback
and recording.
+#
+# @fixed-settings: #optional use fixed settings for host DAC/ADC
+#
+# @frequency: #optional frequency to use when using fixed settings
+#
+# @channels: #optional number of channels when using fixed settings
+#
+# @format: #optional sample format to use when using fixed settings


Are these guys used when @fixed-settings is off?


No.


If @fixed-settings, are the other three all required?  If not, what are
their defaults?


No, they all have defaults: 44100 Hz, 2 channels and s16 format.


Okay, this sort of explains why you have @fixed-settings.

My first thought was that @fixed-settings is redundant, because we can
have any of @frequency, @channels, @format imply fixed settings.  Except
that doesn't let you ask for the *default* fixed settings, as you have
to specify at least one.

What's the default for @fixed-settings?


It's on by default.


What if I specify frequency, channels or format together with explicit
fixed-settings: false?


They will be ignored.

The audio system currently work like this: when an audio frontend
wants to open an output with some format (frequency, channels, format)
it checks fixed-settings. If it's false, it will just open the stream
with the frontend specified settings. If it's true, it'll convert it
into the format specified by @frequency, @channels, @format, then pass
this converted/recoded stream to the backend.


So user typically specifies either fixed-settings=off, or any
combination of the other three (including none of them).  Correct?

We could reject the non-sensical combination of fixed-settings=off plus
any of the other three instead of silently ignoring their values.
Matter of taste, your choice.

Whatever you do, make sure to document how these four work together.

Thank you for educating me so patiently.


The audio backend currently works like that you can pass any 
non-sensical values to it, like negative frequency, or 'kdp' count of 
channels, it will silently fallback to some default value, or just fail, 
but qemu will continue to run. We can make the new config more strict 
(and we should, I think), so if you have any idea where should we be 
more strict (without creating a backward compatibility headache), don't 
hesitate to point it out.




Re: [Qemu-devel] [PATCH v2 4/6] qapi: AllocVisitor

2015-06-17 Thread Kővágó Zoltán

2015-06-17 09:56 keltezéssel, Markus Armbruster írta:

Kővágó, Zoltán dirty.ice...@gmail.com writes:


Simple visitor that recursively allocates structures with only optional
variables. Unions are initialized to the first type specified. Other non
optional types are not supported.


Sounds dubious :)

Can you explain why it's useful?  I guess later patches provide an
example.


Oh, crap, ignore this commit. Just realized that in the refactorings I 
did I removed all references to this visitor... so it's not needed.




Re: [Qemu-devel] [PATCH v2 1/6] qapi: qapi for audio backends

2015-06-17 Thread Kővágó Zoltán

2015-06-17 13:48 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 09:46 keltezéssel, Markus Armbruster írta:

Copying Eric for additional QAPI schema expertise.

My questions inline, pretty sure they show my ignorance.

Kővágó, Zoltán dirty.ice...@gmail.com writes:


This patch adds structures into qapi to replace the existing configuration
structures used by audio backends currently. This qapi will be the base of the
-audiodev command line parameter (that replaces the old environment variables
based config).

This is not a 1:1 translation of the old options, I've tried to make them much
more consistent (e.g. almost every backend had an option to specify buffer size,
but the name was different for every backend, and some backends required usecs,
while some other required frames, samples or bytes). Also tried to reduce the
number of abbreviations used by the config keys.

Some of the more important changes:
* use `in` and `out` instead of `ADC` and `DAC`, as the former is more user
friendly imho
* moved buffer settings into the global setting area (so it's the same for all
backends that support it. Backends that can't change buffer size will simply
ignore them). Also using usecs, as it's probably more user friendly than
samples or bytes.
* try-poll is now an alsa and oss backend specific option (as all other backends
currently ignore it)

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v1 patch:
* every time-related field now take usecs (and removed -usecs, -millis suffixes)
* fixed inconsisten optional marking, language issues

Changes from v2 RFC patch:
* in, out are no longer optional
* try-poll: moved to alsa and oss (as no other backend used them)
* voices: added (env variables had this option)
* dsound: removed primary buffer related fields

Changes from v1 RFC patch:
* fixed style issues
* moved definitions into a separate file
* documented undocumented options (hopefully)
* removed plive option. It was useless even years ago so it can probably safely
go away: 
https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html
* removed verbose, debug options. Backends should use trace events instead.
* removed *_retries options from dsound. It's a kludge.
* moved buffer_usecs and buffer_count to the global config options. Some driver
might ignore it (as they do not expose API to change them).
* wav backend: removed frequecy, format, channels as AudiodevPerDirectionOptions
already have them.

Makefile |   4 +-
   qapi-schema.json |   3 +
   qapi/audio.json  | 223 
+++
   3 files changed, 228 insertions(+), 2 deletions(-)
   create mode 100644 qapi/audio.json

diff --git a/Makefile b/Makefile
index 3f97904..ac566fa 100644
--- a/Makefile
+++ b/Makefile
@@ -257,8 +257,8 @@ $(SRC_PATH)/qga/qapi-schema.json 
$(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
  GEN   $@)

   qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
-   $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
-   $(SRC_PATH)/qapi/event.json
+   $(SRC_PATH)/qapi/audio.json  $(SRC_PATH)/qapi/block.json \
+   $(SRC_PATH)/qapi/block-core.json $(SRC_PATH)/qapi/event.json

   qapi-types.c qapi-types.h :\
   $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
diff --git a/qapi-schema.json b/qapi-schema.json
index 106008c..e751ea3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -5,6 +5,9 @@
   # QAPI common definitions
   { 'include': 'qapi/common.json' }

+# QAPI audio definitions
+{ 'include': 'qapi/audio.json' }
+
   # QAPI block definitions
   { 'include': 'qapi/block.json' }

diff --git a/qapi/audio.json b/qapi/audio.json
new file mode 100644
index 000..2851689
--- /dev/null
+++ b/qapi/audio.json
@@ -0,0 +1,223 @@
+# -*- mode: python -*-
+#
+# Copyright (C) 2015 Zoltán Kővágó dirty.ice...@gmail.com
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# @AudiodevNoOptions
+#
+# The none, coreaudio, sdl and spice audio backend have no options.
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevNoOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use


Who picks the default, QEMU or ALSA?


It defaults to default, which tells alsa to use the default device...


Then make it

 # @dev: #optional the name of the alsa device to use (default 'default')




+#
+# @try-poll: #optional attempt to use poll mode


What happens when the attempt fails?


It falls back to non polling (timer based) mode.


Okay, assuming that's the user interface we want.


+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data

Re: [Qemu-devel] [PATCH v2 2/6] qapi: support nested structs in OptsVisitor

2015-06-17 Thread Kővágó Zoltán

2015-06-17 13:18 keltezéssel, Markus Armbruster írta:

Copying Kevin because similar issues exist in the block layer.

Gerd Hoffmann kra...@redhat.com writes:


On Mi, 2015-06-17 at 09:50 +0200, Markus Armbruster wrote:

Copying László because his fingerprints are on OptsVisitor.

Kővágó, Zoltán dirty.ice...@gmail.com writes:


The current OptsVisitor flattens the whole structure, if there are
same named
fields under different paths (like `in' and `out' in `Audiodev'),
the current
visitor can't cope with them (for example setting
frequency=44100' will set the
in's frequency to 44100 and leave out's frequency unspecified).

This patch fixes it, by the following changes:
1) Specifying just the field name will apply to all fields that has the
specified name (this means it would set both in's and out's frequency to
44100 in the above example).


What if they have different types?

What if one of them can't take the value?


Currently it will error out, requiring the user to be more explicit. 
Probably not the best solution, but I can't really think of a better 
solution. (If we would ignore invalid values that would be very 
confusing imho.)



2) Optionally user can specify the path in the hierarchy. Names
are separated by
a dot (e.g. `in.frequency', `foo.bar.something', etc). The user need not
specify the whole path, only the last few components
(i.e. `bar.something' is
equivalent to `foo.bar.something' if only `foo' has a `bar'
field). This way
1) is just a special case of this when only the last component
is specified.
3) In case of an ambiguity (e.g
frequency=44100,in.frequency=8000') the longest
matching (the most specific) path wins (so in this example,
in's frequency
would become 8000, because `in.frequency' is more specific that
frequency',
and out's frequency would become 44100, because only
frequency' matches it).


The current rule for multiple assignments is last one wins.  E.g. in

 -drive if=none,file=tmp.img,file=tmp.qcow2

file=tmp.qcow2 wins.

If I understand correctly, this patch amends the rule to last most
specific one wins.  Correct?


Yes. (But I didn't really checked that as I didn't know about the last 
one win, and just thought it's an artifact of the current implementation.)



Can you explain why the complexity is needed, i.e. why we can't just
require full paths always?


Keeping the short names is required for -netdev backward compatibility.


I suspect mostly because NetLegacy and Netdev aren't flat unions.
Could be self-inflicted pain.

What about flattening them instead?  Assuming that's possible; I'd have
to try.


Restricting to short or full (i.e. something= or foo.bar.something=, but
disallow bar.something=) should not be a problem.  I'm not sure this
simplifies things much though.  We have to build the full path anyway,
and I think bar.something= is just a convenient thing we get almost for
free ...


We've been bitten by convenience features before.  Adding them tends to
be cheap, but maintaining compatibility can become a terrible headache.






Re: [Qemu-devel] [PATCH v2 6/6] audio: -audiodev command line option

2015-06-17 Thread Kővágó Zoltán

2015-06-17 10:13 keltezéssel, Markus Armbruster írta:

Kővágó, Zoltán dirty.ice...@gmail.com writes:


This patch adds an -audiodev command line option, and deprecates the QEMU_*
environment variables for audio backend configuration. It's syntax is similar to
existing options (-netdev, -device, etc):
  -audiodev driver_name,property=value,...


Sounds really good.

Please wrap your commit message lines a bit earlier, around column 70.


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, also print out them with -audio-help, to ease
migrating to -audiodev).


The parenthesis isn't as clear as the rest of your message, probably
because it deals with two separate things.  Suggest to move out the bit
about help into its own paragraph.


Although now it's possible to specify multiple -audiodev options on command
line, multiple audio backends are not supported yet.


What happens when I specify multiple -audiodev?


You get an error and qemu terminates.


How should the command line look like when multiple audio backends are
supported?


There's an id property of audiodev, so you can identify them:
-audiodev alsa,id=foo,... -audiodev pa,id=bar,...
and audio devices should get an extra parameter, like audiodev or 
something like that:

-device usb-audio,audiodev=foo -device usb-audio,audiodev=bar
And you have two cards, one connected to the alsa device and the other 
connected to pulseaudio.




Do we have a clear backward-compatible path from here to there?


Currently if you specify an -audiodev option, the environment variables 
are completely ignored, and it will create an audio backend using the 
specified options. If you do not provide an -audiodev, it will 
initialize the audio subsystem using the old environment variables when 
you add the first sound card (so no -audiodev and no sound device means 
no audio subsystem, just like the old times).


About multiple backends: if the user does not specify the id of the 
backend when creating the sound card, just use the first -audiodev 
specified on the command line (or the legacy config, if there's no 
-audiodev). This way we stay backward-compatible (there won't be 
multiple -audiodevs in legacy configs).




[...]

  18 files changed, 994 insertions(+), 1083 deletions(-)
  create mode 100644 audio/audio_legacy.c


Very nice delta, but the size is a bit intimidating :)

[...]






Re: [Qemu-devel] [PATCH v2 1/6] qapi: qapi for audio backends

2015-06-17 Thread Kővágó Zoltán

2015-06-17 09:46 keltezéssel, Markus Armbruster írta:

Copying Eric for additional QAPI schema expertise.

My questions inline, pretty sure they show my ignorance.

Kővágó, Zoltán dirty.ice...@gmail.com writes:


This patch adds structures into qapi to replace the existing configuration
structures used by audio backends currently. This qapi will be the base of the
-audiodev command line parameter (that replaces the old environment variables
based config).

This is not a 1:1 translation of the old options, I've tried to make them much
more consistent (e.g. almost every backend had an option to specify buffer size,
but the name was different for every backend, and some backends required usecs,
while some other required frames, samples or bytes). Also tried to reduce the
number of abbreviations used by the config keys.

Some of the more important changes:
* use `in` and `out` instead of `ADC` and `DAC`, as the former is more user
   friendly imho
* moved buffer settings into the global setting area (so it's the same for all
   backends that support it. Backends that can't change buffer size will simply
   ignore them). Also using usecs, as it's probably more user friendly than
   samples or bytes.
* try-poll is now an alsa and oss backend specific option (as all other backends
   currently ignore it)

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com

---

Changes from v1 patch:
* every time-related field now take usecs (and removed -usecs, -millis suffixes)
* fixed inconsisten optional marking, language issues

Changes from v2 RFC patch:
* in, out are no longer optional
* try-poll: moved to alsa and oss (as no other backend used them)
* voices: added (env variables had this option)
* dsound: removed primary buffer related fields

Changes from v1 RFC patch:
* fixed style issues
* moved definitions into a separate file
* documented undocumented options (hopefully)
* removed plive option. It was useless even years ago so it can probably safely
   go away: 
https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html
* removed verbose, debug options. Backends should use trace events instead.
* removed *_retries options from dsound. It's a kludge.
* moved buffer_usecs and buffer_count to the global config options. Some driver
   might ignore it (as they do not expose API to change them).
* wav backend: removed frequecy, format, channels as AudiodevPerDirectionOptions
   already have them.

Makefile |   4 +-
  qapi-schema.json |   3 +
  qapi/audio.json  | 223 +++
  3 files changed, 228 insertions(+), 2 deletions(-)
  create mode 100644 qapi/audio.json

diff --git a/Makefile b/Makefile
index 3f97904..ac566fa 100644
--- a/Makefile
+++ b/Makefile
@@ -257,8 +257,8 @@ $(SRC_PATH)/qga/qapi-schema.json 
$(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
  GEN   $@)

  qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
-   $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
-   $(SRC_PATH)/qapi/event.json
+   $(SRC_PATH)/qapi/audio.json  $(SRC_PATH)/qapi/block.json \
+   $(SRC_PATH)/qapi/block-core.json $(SRC_PATH)/qapi/event.json

  qapi-types.c qapi-types.h :\
  $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
diff --git a/qapi-schema.json b/qapi-schema.json
index 106008c..e751ea3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -5,6 +5,9 @@
  # QAPI common definitions
  { 'include': 'qapi/common.json' }

+# QAPI audio definitions
+{ 'include': 'qapi/audio.json' }
+
  # QAPI block definitions
  { 'include': 'qapi/block.json' }

diff --git a/qapi/audio.json b/qapi/audio.json
new file mode 100644
index 000..2851689
--- /dev/null
+++ b/qapi/audio.json
@@ -0,0 +1,223 @@
+# -*- mode: python -*-
+#
+# Copyright (C) 2015 Zoltán Kővágó dirty.ice...@gmail.com
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# @AudiodevNoOptions
+#
+# The none, coreaudio, sdl and spice audio backend have no options.
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevNoOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use


Who picks the default, QEMU or ALSA?


It defaults to default, which tells alsa to use the default device...




+#
+# @try-poll: #optional attempt to use poll mode


What happens when the attempt fails?


It falls back to non polling (timer based) mode.


+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data': {
+'*dev':  'str',
+'*try-poll': 'bool' } }
+
+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @in: options of the capture stream
+#
+# @out: options of the playback stream
+#
+# @threshold: #optional set the threshold (in frames) when

Re: [Qemu-devel] [PATCH v2 2/6] qapi: support nested structs in OptsVisitor

2015-06-17 Thread Kővágó Zoltán

2015-06-17 10:41 keltezéssel, Gerd Hoffmann írta:

On Mi, 2015-06-17 at 09:50 +0200, Markus Armbruster wrote:

Copying László because his fingerprints are on OptsVisitor.

Kővágó, Zoltán dirty.ice...@gmail.com writes:


The current OptsVisitor flattens the whole structure, if there are same named
fields under different paths (like `in' and `out' in `Audiodev'), the current
visitor can't cope with them (for example setting `frequency=44100' will set the
in's frequency to 44100 and leave out's frequency unspecified).

This patch fixes it, by the following changes:
1) Specifying just the field name will apply to all fields that has the
specified name (this means it would set both in's and out's frequency to
44100 in the above example).
2) Optionally user can specify the path in the hierarchy. Names are separated by
a dot (e.g. `in.frequency', `foo.bar.something', etc). The user need not
specify the whole path, only the last few components (i.e. `bar.something' 
is
equivalent to `foo.bar.something' if only `foo' has a `bar' field). This way
1) is just a special case of this when only the last component is specified.
3) In case of an ambiguity (e.g `frequency=44100,in.frequency=8000') the longest
matching (the most specific) path wins (so in this example, in's frequency
would become 8000, because `in.frequency' is more specific that `frequency',
and out's frequency would become 44100, because only `frequency' matches 
it).


Can you explain why the complexity is needed, i.e. why we can't just
require full paths always?


Keeping the short names is required for -netdev backward compatibility.

Restricting to short or full (i.e. something= or foo.bar.something=, but
disallow bar.something=) should not be a problem.  I'm not sure this
simplifies things much though.  We have to build the full path anyway,
and I think bar.something= is just a convenient thing we get almost for
free ...


With the current implementation you can specify (see my previous patch) 
in.try-poll=off in case of alsa. If we would need full paths, it would 
look like opts.data.in.try-poll=off, which is probably not something we 
want.





Re: [Qemu-devel] [PATCH v2 5/6] audio: use qapi AudioFormat instead of audfmt_e

2015-06-17 Thread Kővágó Zoltán

2015-06-17 10:01 keltezéssel, Markus Armbruster írta:

Kővágó, Zoltán dirty.ice...@gmail.com writes:


I had to include an enum for audio sampling formats into qapi, but that meant
duplicating the audfmt_e enum. This patch replaces audfmt_e and associated
values with the qapi generated AudioFormat enum.

This patch is mostly a search-and-replace, except for switches where the qapi
generated AUDIO_FORMAT_MAX caused problems.

[...]

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 6315b2d..4d38f5d 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c

[...]

@@ -639,19 +639,22 @@ static int alsa_open (int in, struct alsa_params_req *req,
  bytes_per_sec = freq  (nchannels == 2);

  switch (obt-fmt) {
-case AUD_FMT_S8:
-case AUD_FMT_U8:
+case AUDIO_FORMAT_S8:
+case AUDIO_FORMAT_U8:
  break;

-case AUD_FMT_S16:
-case AUD_FMT_U16:
+case AUDIO_FORMAT_S16:
+case AUDIO_FORMAT_U16:
  bytes_per_sec = 1;
  break;

-case AUD_FMT_S32:
-case AUD_FMT_U32:
+case AUDIO_FORMAT_S32:
+case AUDIO_FORMAT_U32:
  bytes_per_sec = 2;
  break;
+
+case AUDIO_FORMAT_MAX:
+break;


Can this happen?


Not under normal circumstances, but gcc warns otherwise.


  }

  threshold = (conf-threshold * bytes_per_sec) / 1000;
diff --git a/audio/audio.c b/audio/audio.c
index 5be4b15..112b57b 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -75,7 +75,7 @@ static struct {
  .settings = {
  .freq = 44100,
  .nchannels = 2,
-.fmt = AUD_FMT_S16,
+.fmt = AUDIO_FORMAT_S16,
  .endianness =  AUDIO_HOST_ENDIANNESS,
  }
  },
@@ -87,7 +87,7 @@ static struct {
  .settings = {
  .freq = 44100,
  .nchannels = 2,
-.fmt = AUD_FMT_S16,
+.fmt = AUDIO_FORMAT_S16,
  .endianness = AUDIO_HOST_ENDIANNESS,
  }
  },
@@ -219,58 +219,61 @@ static char *audio_alloc_prefix (const char *s)
  return r;
  }

-static const char *audio_audfmt_to_string (audfmt_e fmt)
+static const char *audio_audfmt_to_string (AudioFormat fmt)
  {
  switch (fmt) {
-case AUD_FMT_U8:
+case AUDIO_FORMAT_U8:
  return U8;

-case AUD_FMT_U16:
+case AUDIO_FORMAT_U16:
  return U16;

-case AUD_FMT_S8:
+case AUDIO_FORMAT_S8:
  return S8;

-case AUD_FMT_S16:
+case AUDIO_FORMAT_S16:
  return S16;

-case AUD_FMT_U32:
+case AUDIO_FORMAT_U32:
  return U32;

-case AUD_FMT_S32:
+case AUDIO_FORMAT_S32:
  return S32;
+
+case AUDIO_FORMAT_MAX:


default: would be more defensive.  Same elsewhere.


Ok, I'll change them to default.


+abort();
  }

  dolog (Bogus audfmt %d returning S16\n, fmt);
  return S16;
  }

[...]






Re: [Qemu-devel] [PATCH v2 6/6] audio: -audiodev command line option

2015-06-17 Thread Kővágó Zoltán

2015-06-17 14:27 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 10:13 keltezéssel, Markus Armbruster írta:

Kővágó, Zoltán dirty.ice...@gmail.com writes:


This patch adds an -audiodev command line option, and deprecates the QEMU_*
environment variables for audio backend configuration. It's syntax
is similar to
existing options (-netdev, -device, etc):
   -audiodev driver_name,property=value,...


Sounds really good.

Please wrap your commit message lines a bit earlier, around column 70.


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, also print out them with -audio-help, to ease
migrating to -audiodev).


The parenthesis isn't as clear as the rest of your message, probably
because it deals with two separate things.  Suggest to move out the bit
about help into its own paragraph.


Although now it's possible to specify multiple -audiodev options on command
line, multiple audio backends are not supported yet.


What happens when I specify multiple -audiodev?


You get an error and qemu terminates.


Unlikely to create backward compatibility trouble.  Works for me.


How should the command line look like when multiple audio backends are
supported?


There's an id property of audiodev, so you can identify them:
-audiodev alsa,id=foo,... -audiodev pa,id=bar,...
and audio devices should get an extra parameter, like audiodev or
something like that:
-device usb-audio,audiodev=foo -device usb-audio,audiodev=bar
And you have two cards, one connected to the alsa device and the other
connected to pulseaudio.


Good, because it's consistent with how we connect other kinds of
frontends/backends.

Multiple audio frontends (device models) can connect to the same audio
backend, can't they?


Yes. (It's mandatory, since currently all audio frontends connect to a 
single backend.)



Is backend property id mandatory?  Hmm, judging from PATCH 1 it isn't.
It generally is for other kinds of backends, e.g. -netdev, -chardev and
(in the future) -blockdev.  It's optional with -drive only because
-drive is crazy.
It's optional right now (because I thought specifying an id when you 
have a single backend is pretty pointless), but it's probably better 
then if I change it to mandatory.





Do we have a clear backward-compatible path from here to there?


Currently if you specify an -audiodev option, the environment
variables are completely ignored, and it will create an audio backend
using the specified options. If you do not provide an -audiodev, it
will initialize the audio subsystem using the old environment
variables when you add the first sound card (so no -audiodev and no
sound device means no audio subsystem, just like the old times).


Should we document this?  Where?


Maybe adding a phrase to -audiodev documentation like If you specify 
this option, the deprecated environment variables will be ignored.



About multiple backends: if the user does not specify the id of the
backend when creating the sound card, just use the first -audiodev
specified on the command line (or the legacy config, if there's no
-audiodev). This way we stay backward-compatible (there won't be
multiple -audiodevs in legacy configs).


Old way (before your patch): there is only one audio backend, and it's
configuration comes from a bunch of environment variables.

New way (we're not there yet): you can have multiple audio backends, and
you connect frontends to backends using backend ID as usual, i.e. id=ID
on the backend, audiodev=ID on the frontend.

Required backward compatibility: the old way still works, i.e. when
there's no new-way backend, and no frontend has an audiodev=..., then we
create a backend configured from the environment.

Anything beyond required backward compatibility should be carefully
judged on its UI merits.

If I understand your description correctly, the plan is to default a
frontend's audiodev to the first backend, and if there is none, create
one configured from the environment.  That's definitely beyond required.
Is it a good user interface?


The create one configured from the environment is needed for backward 
compatibility. Specifying an audiodev=... on frontend makes no sense 
without an -audiodev, so that's not allowed. The only question is what 
happens with an -audiodev, but no audiodev= on the frontend. We can't 
make audiodev= required because that would break compatibility. So we 
either a) make audiodev= required but only when there's an -audiodev, or 
b) try to find a sensible default when audiodev= is not specified. Imho 
b is better, because having a parameter that's sometimes required, 
sometimes forbidden is a bit confusing.





Re: [Qemu-devel] [PATCH v2 1/6] qapi: qapi for audio backends

2015-06-17 Thread Kővágó Zoltán

2015-06-17 15:37 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 13:48 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 09:46 keltezéssel, Markus Armbruster írta:

Copying Eric for additional QAPI schema expertise.

My questions inline, pretty sure they show my ignorance.

Kővágó, Zoltán dirty.ice...@gmail.com writes:

[...]

+##
+# @AudiodevPaOptions
+#
+# Options of the pa (PulseAudio) audio backend.
+#
+# @server: #optional PulseAudio server address
+#
+# @sink: #optional sink device name
+#
+# @source: #optional source device name


Who picks the defaults, QEMU or PA?


PA


Is there a way to explicitly ask for the PA default?  Something like
source=default?


Not really right now. The default is a NULL pointer (pulseaudio api
wise), so unless we add an arbitrary keyword (like default), it's not
possible to ask explicitly for the default. (But omitting them will
choose the default, of course.)


Treating an empty string like NULL should get us a way to ask for the
default, and a way to document the default concisely, like (default '')
plus a suitable explanation what '' means.

I'm not saying you should do that.  I'm saying whatever you do, document
what happens when an optional parameter is absent :)


+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevPaOptions',
+  'data': {
+'*server': 'str',
+'*sink':   'str',
+'*source': 'str' } }
+
+##
+# @AudiodevWavOptions
+#
+# Options of the wav audio backend.
+#
+# @path: #optional path of the wav file to record
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevWavOptions',
+  'data': {
+'*path': 'str' } }


Who picks the default?


It defaults to qemu.wav


Make it

  # @path: #optional path of the wav file to record (default 'qemu.wav')


+
+
+##
+# @AudiodevBackendOptions
+#
+# A discriminated record of audio backends.
+#
+# Since: 2.4
+##
+{ 'union': 'AudiodevBackendOptions',
+  'data': {
+'none':  'AudiodevNoOptions',
+'alsa':  'AudiodevAlsaOptions',
+'coreaudio': 'AudiodevNoOptions',
+'dsound':'AudiodevDsoundOptions',
+'oss':   'AudiodevOssOptions',
+'pa':'AudiodevPaOptions',
+'sdl':   'AudiodevNoOptions',
+'spice': 'AudiodevNoOptions',
+'wav':   'AudiodevWavOptions' } }
+
+##
+# @AudioFormat
+#
+# An enumeration of possible audio formats.
+#
+# Since: 2.4
+##
+{ 'enum': 'AudioFormat',
+  'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32' ] }
+
+##
+# @AudiodevPerDirectionOptions
+#
+# General audio backend options that are used for both playback
and recording.
+#
+# @fixed-settings: #optional use fixed settings for host DAC/ADC
+#
+# @frequency: #optional frequency to use when using fixed settings
+#
+# @channels: #optional number of channels when using fixed settings
+#
+# @format: #optional sample format to use when using fixed settings


Are these guys used when @fixed-settings is off?


No.


If @fixed-settings, are the other three all required?  If not, what are
their defaults?


No, they all have defaults: 44100 Hz, 2 channels and s16 format.


Okay, this sort of explains why you have @fixed-settings.

My first thought was that @fixed-settings is redundant, because we can
have any of @frequency, @channels, @format imply fixed settings.  Except
that doesn't let you ask for the *default* fixed settings, as you have
to specify at least one.

What's the default for @fixed-settings?


It's on by default.


What if I specify frequency, channels or format together with explicit
fixed-settings: false?


They will be ignored.

The audio system currently work like this: when an audio frontend wants 
to open an output with some format (frequency, channels, format) it 
checks fixed-settings. If it's false, it will just open the stream with 
the frontend specified settings. If it's true, it'll convert it into the 
format specified by @frequency, @channels, @format, then pass this 
converted/recoded stream to the backend.





  I
guess I should also document it...


Yes, please.


+#
+# @buffer: #optional the buffer size (in microseconds)


@buffer suggests this is a buffer, not a buffer length given as time
span.  @buffer-len?


Ok. (It used to be called buffer-usecs before I changed everything to
microseconds.)




+#
+# @buffer-count: #optional number of buffers
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevPerDirectionOptions',
+  'data': {
+'*fixed-settings': 'bool',
+'*frequency':  'int',
+'*channels':   'int',
+'*voices': 'int',
+'*format': 'AudioFormat',
+'*buffer': 'int',
+'*buffer-count':   'int' } }

[...]






Re: [Qemu-devel] [PATCH v2 2/6] qapi: support nested structs in OptsVisitor

2015-06-17 Thread Kővágó Zoltán

2015-06-17 15:41 keltezéssel, Markus Armbruster írta:

Kővágó Zoltán dirty.ice...@gmail.com writes:


2015-06-17 13:18 keltezéssel, Markus Armbruster írta:

Copying Kevin because similar issues exist in the block layer.

Gerd Hoffmann kra...@redhat.com writes:


On Mi, 2015-06-17 at 09:50 +0200, Markus Armbruster wrote:

Copying László because his fingerprints are on OptsVisitor.

Kővágó, Zoltán dirty.ice...@gmail.com writes:


The current OptsVisitor flattens the whole structure, if there are
same named
fields under different paths (like `in' and `out' in `Audiodev'),
the current
visitor can't cope with them (for example setting
frequency=44100' will set the
in's frequency to 44100 and leave out's frequency unspecified).

This patch fixes it, by the following changes:
1) Specifying just the field name will apply to all fields that has the
 specified name (this means it would set both in's and out's
frequency to
 44100 in the above example).


What if they have different types?

What if one of them can't take the value?


Currently it will error out, requiring the user to be more
explicit. Probably not the best solution, but I can't really think of
a better solution. (If we would ignore invalid values that would be
very confusing imho.)


Yes, we clearly don't want foo=0 to set a.foo and b.foo, but foo=x set
only a.foo, because the former can take any string, but the latter only
a number.

Can we require the LHS to be unambiguous?


Originally I designed it that way because it allows you to specify 
frequency=44100 and set both in.frequency and out.frequency. But this 
could also be the convenience feature that we not really need. I don't 
see any other downside of making it unambigous.




Re: [Qemu-devel] [RFC PATCH] qapi for audio backends

2015-06-04 Thread Kővágó Zoltán

2015-06-04 09:43 keltezéssel, Gerd Hoffmann írta:

+#
+# @mmap: #optional try using memory mapped access


IIRC this doesn't work everywhere, especially when the oss api is
implemented as library.

Linux had that, but on linux everybody uses alsa these days ...
Dunno about other platforms.


idk, the code tries to mmap first, and if it fails, falls back to non 
mmapped access. But something is broken there, as with QEMU_OSS_MMAP=1 
it fails (on linux with alsa oss emulation with pulseaudio alsa 
emulation...). But it ought to work on linux, according to the comments. 
Maybe it needs the native oss, and not the alsa emulation.





+# @exclusive: #optional open device in exclusive mode (vmix wont work)

+# @dsp_policy: #optional set the timing policy of the device, -1 to use 
fragment
+#  mode (option ignored on some platforms)


Would be interesting to know on which platforms this actually has an
effect (both options) ...


From a quick google it looks like whatever platform that have oss4 (the 
dsp_policy). exclusive just adds O_EXCL to open flags.




IIRC 'vmix' was a feature of the commercial, ossaudio driver package.






[Qemu-devel] [RFC PATCH v2] qapi for audio backends

2015-06-04 Thread Kővágó, Zoltán
Changes from v1:
* fixed style issues
* moved definitions into a separate file
* documented undocumented options (hopefully)
* removed plive option. It was useless even years ago so it can probably safely
  go away: 
https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html
* removed verbose, debug options. Backends should use trace events instead.
* removed *_retries options from dsound. It's a kludge.
* moved buffer_usecs and buffer_count to the global config options. Some driver
  might ignore it (as they do not expose API to change them).
* wav backend: removed frequecy, format, channels as AudiodevPerDirectionOptions
  already have them.

Not sure about this one, so it's not yet in this patch:
* remove poll_mode: another obscure setting, and it's only matter of time until
  the code bitrots enough to break it.

This is a proposal to add structures into qapi to replace the existing
configuration structures used by audio backends currently. I'm going to use it
to implement a new way to specify audio backend options (an -audiodev command
line option, instead of environment variables. This will also allow us to use
multiple audio backends in one qemu instance), so the structure used here will
be the basis of the command line syntax.

This is currently more or less a direct translation of the current audio backend
options. I've changed some names, trying to accomplish a more consistent naming
scheme. I wouldn't be surprised if there were options that doesn't work if you
set their value to anything other than the default (for example, log to monitor
can crash qemu, QEMU_DSOUND_RESTOURE_RETRIES has a typo, so probably nobody used
it, etc). I've also tried to reduce copy-paste, when the same set of options can
be given to output and input (QEMU_*_DAC_* and QEMU_*_ADC_* options), also using
in and out instead of ADC and DAC, as in the world of SPDIF and HDMI it's
completely possible that your computer has nothing to do with analog converters.
Plus a non technician user probably has no idea what ADC and DAC stands for.

Any comment is appreciated.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 qapi-schema.json |   3 +
 qapi/audio.json  | 225 +++
 2 files changed, 228 insertions(+)
 create mode 100644 qapi/audio.json

diff --git a/qapi-schema.json b/qapi-schema.json
index 0662a9b..ebec127 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -5,6 +5,9 @@
 # QAPI common definitions
 { 'include': 'qapi/common.json' }
 
+# QAPI audio definitions
+{ 'include': 'qapi/audio.json' }
+
 # QAPI block definitions
 { 'include': 'qapi/block.json' }
 
diff --git a/qapi/audio.json b/qapi/audio.json
new file mode 100644
index 000..c864a77
--- /dev/null
+++ b/qapi/audio.json
@@ -0,0 +1,225 @@
+# -*- mode: python -*-
+
+##
+# @AudiodevNoneOptions
+#
+# The none, coreaudio, sdl and spice audio backend has no options.
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevNoneOptions',
+  'data': { } }
+
+##
+# @AudiodevAlsaPerDirectionOptions
+#
+# Options of the alsa backend that are used for both playback and recording.
+#
+# @dev: #optional the name of the alsa device to use
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaPerDirectionOptions',
+  'data': {
+'*dev':'str' } }
+
+##
+# @AudiodevAlsaOptions
+#
+# Options of the alsa audio backend.
+#
+# @in: #optional options of the capture stream
+#
+# @out: #optional options of the playback stream
+#
+# @threshold: #optional set the threshold (in frames) when playback starts
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevAlsaOptions',
+  'data': {
+'*in':  'AudiodevAlsaPerDirectionOptions',
+'*out': 'AudiodevAlsaPerDirectionOptions',
+'*threshold': 'int' } }
+
+##
+# @AudiodevDsoundOptions
+#
+# Options of the dsound audio backend.
+#
+# @set-primary: #optional set the parameters of primary buffer
+#
+# @latency-millis: #optional add extra latency to playback
+#
+# @primary-frequency: #optional primary buffer frequency
+#
+# @primary-channels: #optional primary buffer number of channels
+#
+# @primary-format: #optional primary buffer format
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevDsoundOptions',
+  'data': {
+'*set-primary':   'bool',
+'*latency-millis':'int',
+'*primary-frequency': 'int',
+'*primary-channels':  'int',
+'*primary-format':'AudioFormat' } }
+
+##
+# @AudiodevOssPerDirectionOptions
+#
+# Options of the oss backend that are used for both playback and recording.
+#
+# @dev: #optional path of the oss device
+#
+# Since: 2.4
+##
+{ 'struct': 'AudiodevOssPerDirectionOptions',
+  'data': {
+'*dev': 'str' } }
+
+##
+# @AudiodevOssOptions
+#
+# Options of the oss audio backend.
+#
+# @in: #optional options of the capture stream
+#
+# @out: #optional options of the playback stream
+#
+# @mmap: #optional try using memory mapped access
+#
+# @exclusive: #optional open device in exclusive mode (vmix wont work)
+#
+# @dsp-policy: #optional

[Qemu-devel] [PATCH 05/12] audio: expose drv_opaque to init_out and init_in

2015-06-01 Thread Kővágó, Zoltán
Currently the opaque pointer returned by audio_driver's init is only
exposed to the driver's fini, but not to audio_pcm_ops. This way if
someone wants to share a variable with the driver and the pcm, he must
use global variables. This patch fixes it by adding a third parameter to
audio_pcm_op's init_out and init_in.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c   | 9 +++--
 audio/audio_int.h   | 4 ++--
 audio/audio_template.h  | 2 +-
 audio/coreaudio.c   | 5 -
 audio/dsound_template.h | 6 --
 audio/noaudio.c | 6 --
 audio/ossaudio.c| 9 +++--
 audio/paaudio.c | 9 +++--
 audio/spiceaudio.c  | 9 +++--
 audio/wavaudio.c| 4 +++-
 10 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 74ead97..eb33bff 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -819,7 +819,8 @@ static void alsa_fini_out (HWVoiceOut *hw)
 alsa-pcm_buf = NULL;
 }
 
-static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
+ void *drv_opaque)
 {
 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 struct alsa_params_req req;
@@ -827,6 +828,8 @@ static int alsa_init_out (HWVoiceOut *hw, struct 
audsettings *as)
 snd_pcm_t *handle;
 struct audsettings obt_as;
 
+(void) drv_opaque;
+
 req.fmt = aud_to_alsafmt (as-fmt, as-endianness);
 req.freq = as-freq;
 req.nchannels = as-nchannels;
@@ -928,7 +931,7 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return -1;
 }
 
-static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void 
*drv_opaque)
 {
 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 struct alsa_params_req req;
@@ -936,6 +939,8 @@ static int alsa_init_in (HWVoiceIn *hw, struct audsettings 
*as)
 snd_pcm_t *handle;
 struct audsettings obt_as;
 
+(void) drv_opaque;
+
 req.fmt = aud_to_alsafmt (as-fmt, as-endianness);
 req.freq = as-freq;
 req.nchannels = as-nchannels;
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 92a2f3c..a3efe7b 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -156,13 +156,13 @@ struct audio_driver {
 };
 
 struct audio_pcm_ops {
-int  (*init_out)(HWVoiceOut *hw, struct audsettings *as);
+int  (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_out)(HWVoiceOut *hw);
 int  (*run_out) (HWVoiceOut *hw, int live);
 int  (*write)   (SWVoiceOut *sw, void *buf, int size);
 int  (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
 
-int  (*init_in) (HWVoiceIn *hw, struct audsettings *as);
+int  (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_in) (HWVoiceIn *hw);
 int  (*run_in)  (HWVoiceIn *hw);
 int  (*read)(SWVoiceIn *sw, void *buf, int size);
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 584e536..f716d97 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -262,7 +262,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct 
audsettings *as)
 #ifdef DAC
 QLIST_INIT (hw-cap_head);
 #endif
-if (glue (hw-pcm_ops-init_, TYPE) (hw, as)) {
+if (glue (hw-pcm_ops-init_, TYPE) (hw, as, s-drv_opaque)) {
 goto err0;
 }
 
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 5964c62..f38fd82 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -287,7 +287,8 @@ static int coreaudio_write (SWVoiceOut *sw, void *buf, int 
len)
 return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
+  void *drv_opaque)
 {
 OSStatus status;
 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
@@ -296,6 +297,8 @@ static int coreaudio_init_out (HWVoiceOut *hw, struct 
audsettings *as)
 const char *typ = playback;
 AudioValueRange frameRange;
 
+(void) drv_opaque;
+
 /* create mutex */
 err = pthread_mutex_init(core-mutex, NULL);
 if (err) {
diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 8b37d16..98276fb 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -174,9 +174,11 @@ static void dsound_fini_out (HWVoiceOut *hw)
 }
 
 #ifdef DSBTYPE_IN
-static int dsound_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
+  void *drv_opaque)
 #else
-static int dsound_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
+   void *drv_opaque)
 #endif
 {
 int err;
diff --git a/audio/noaudio.c b/audio/noaudio.c
index cb38662..dd1a87a 100644
--- a/audio/noaudio.c
+++ b/audio

[Qemu-devel] [PATCH 01/12] audio: remove esd backend

2015-06-01 Thread Kővágó, Zoltán
ESD is no longer developed and replaced by PulseAudio.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   1 -
 audio/audio_int.h   |   1 -
 audio/esdaudio.c| 557 
 configure   |  18 +-
 4 files changed, 6 insertions(+), 571 deletions(-)
 delete mode 100644 audio/esdaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 26a0ac9..5573ac1 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -6,7 +6,6 @@ common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
 common-obj-$(CONFIG_FMOD) += fmodaudio.o
-common-obj-$(CONFIG_ESD) += esdaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
 common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
diff --git a/audio/audio_int.h b/audio/audio_int.h
index fd019a0..9dd6b7f 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -210,7 +210,6 @@ extern struct audio_driver fmod_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
-extern struct audio_driver esd_audio_driver;
 extern struct audio_driver pa_audio_driver;
 extern struct audio_driver spice_audio_driver;
 extern struct audio_driver winwave_audio_driver;
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
deleted file mode 100644
index eea9cce..000
--- a/audio/esdaudio.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * QEMU ESD audio driver
- *
- * Copyright (c) 2006 Frederick Reeve (brushed up by malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include esd.h
-#include qemu-common.h
-#include audio.h
-
-#define AUDIO_CAP esd
-#include audio_int.h
-#include audio_pt_int.h
-
-typedef struct {
-HWVoiceOut hw;
-int done;
-int live;
-int decr;
-int rpos;
-void *pcm_buf;
-int fd;
-struct audio_pt pt;
-} ESDVoiceOut;
-
-typedef struct {
-HWVoiceIn hw;
-int done;
-int dead;
-int incr;
-int wpos;
-void *pcm_buf;
-int fd;
-struct audio_pt pt;
-} ESDVoiceIn;
-
-static struct {
-int samples;
-int divisor;
-char *dac_host;
-char *adc_host;
-} conf = {
-.samples = 1024,
-.divisor = 2,
-};
-
-static void GCC_FMT_ATTR (2, 3) qesd_logerr (int err, const char *fmt, ...)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n, strerror (err));
-}
-
-/* playback */
-static void *qesd_thread_out (void *arg)
-{
-ESDVoiceOut *esd = arg;
-HWVoiceOut *hw = esd-hw;
-int threshold;
-
-threshold = conf.divisor ? hw-samples / conf.divisor : 0;
-
-if (audio_pt_lock (esd-pt, AUDIO_FUNC)) {
-return NULL;
-}
-
-for (;;) {
-int decr, to_mix, rpos;
-
-for (;;) {
-if (esd-done) {
-goto exit;
-}
-
-if (esd-live  threshold) {
-break;
-}
-
-if (audio_pt_wait (esd-pt, AUDIO_FUNC)) {
-goto exit;
-}
-}
-
-decr = to_mix = esd-live;
-rpos = hw-rpos;
-
-if (audio_pt_unlock (esd-pt, AUDIO_FUNC)) {
-return NULL;
-}
-
-while (to_mix) {
-ssize_t written;
-int chunk = audio_MIN (to_mix, hw-samples - rpos);
-struct st_sample *src = hw-mix_buf + rpos;
-
-hw-clip (esd-pcm_buf, src, chunk);
-
-again:
-written = write (esd-fd, esd-pcm_buf, chunk  hw-info.shift);
-if (written == -1) {
-if (errno == EINTR || errno == EAGAIN) {
-goto again;
-}
-qesd_logerr (errno, write failed\n);
-return NULL;
-}
-
-if (written != chunk

[Qemu-devel] [PATCH 03/12] audio: remove sdl backend

2015-06-01 Thread Kővágó, Zoltán
It's broken and we have native drivers for almost all platforms.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   3 -
 audio/audio_int.h   |   1 -
 audio/sdlaudio.c| 458 
 configure   |  24 ++-
 4 files changed, 11 insertions(+), 475 deletions(-)
 delete mode 100644 audio/sdlaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index b4c0608..3c84972 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -1,5 +1,4 @@
 common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
-common-obj-$(CONFIG_SDL) += sdlaudio.o
 common-obj-$(CONFIG_OSS) += ossaudio.o
 common-obj-$(CONFIG_SPICE) += spiceaudio.o
 common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
@@ -10,5 +9,3 @@ common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
-
-sdlaudio.o-cflags := $(SDL_CFLAGS)
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 7445602..d593879 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -204,7 +204,6 @@ struct AudioState {
 
 extern struct audio_driver no_audio_driver;
 extern struct audio_driver oss_audio_driver;
-extern struct audio_driver sdl_audio_driver;
 extern struct audio_driver wav_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
deleted file mode 100644
index d24daa5..000
--- a/audio/sdlaudio.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * QEMU SDL audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include SDL.h
-#include SDL_thread.h
-#include qemu-common.h
-#include audio.h
-
-#ifndef _WIN32
-#ifdef __sun__
-#define _POSIX_PTHREAD_SEMANTICS 1
-#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
-#include pthread.h
-#endif
-#endif
-
-#define AUDIO_CAP sdl
-#include audio_int.h
-
-typedef struct SDLVoiceOut {
-HWVoiceOut hw;
-int live;
-int rpos;
-int decr;
-} SDLVoiceOut;
-
-static struct {
-int nb_samples;
-} conf = {
-.nb_samples = 1024
-};
-
-static struct SDLAudioState {
-int exit;
-SDL_mutex *mutex;
-SDL_sem *sem;
-int initialized;
-} glob_sdl;
-typedef struct SDLAudioState SDLAudioState;
-
-static void GCC_FMT_ATTR (1, 2) sdl_logerr (const char *fmt, ...)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n, SDL_GetError ());
-}
-
-static int sdl_lock (SDLAudioState *s, const char *forfn)
-{
-if (SDL_LockMutex (s-mutex)) {
-sdl_logerr (SDL_LockMutex for %s failed\n, forfn);
-return -1;
-}
-return 0;
-}
-
-static int sdl_unlock (SDLAudioState *s, const char *forfn)
-{
-if (SDL_UnlockMutex (s-mutex)) {
-sdl_logerr (SDL_UnlockMutex for %s failed\n, forfn);
-return -1;
-}
-return 0;
-}
-
-static int sdl_post (SDLAudioState *s, const char *forfn)
-{
-if (SDL_SemPost (s-sem)) {
-sdl_logerr (SDL_SemPost for %s failed\n, forfn);
-return -1;
-}
-return 0;
-}
-
-static int sdl_wait (SDLAudioState *s, const char *forfn)
-{
-if (SDL_SemWait (s-sem)) {
-sdl_logerr (SDL_SemWait for %s failed\n, forfn);
-return -1;
-}
-return 0;
-}
-
-static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn)
-{
-if (sdl_unlock (s, forfn)) {
-return -1;
-}
-
-return sdl_post (s, forfn);
-}
-
-static int aud_to_sdlfmt (audfmt_e fmt)
-{
-switch (fmt) {
-case AUD_FMT_S8:
-return AUDIO_S8;
-
-case AUD_FMT_U8:
-return AUDIO_U8;
-
-case AUD_FMT_S16:
-return AUDIO_S16LSB;
-
-case AUD_FMT_U16:
-return AUDIO_U16LSB;
-
-default:
-dolog (Internal

[Qemu-devel] [PATCH 09/12] wavaudio: do not use global variables

2015-06-01 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/wavaudio.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 5132aed..8acea8f 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -36,15 +36,10 @@ typedef struct WAVVoiceOut {
 int total_samples;
 } WAVVoiceOut;
 
-static struct {
+typedef struct {
 struct audsettings settings;
 const char *wav_path;
-} conf = {
-.settings.freq  = 44100,
-.settings.nchannels = 2,
-.settings.fmt   = AUD_FMT_S16,
-.wav_path   = qemu.wav
-};
+} WAVConf;
 
 static int wav_run_out (HWVoiceOut *hw, int live)
 {
@@ -116,7 +111,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
 };
-struct audsettings wav_as = conf.settings;
+WAVConf *conf = drv_opaque;
+struct audsettings wav_as = conf-settings;
 
 (void) as;
 (void) drv_opaque;
@@ -157,10 +153,10 @@ static int wav_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 le_store (hdr + 28, hw-info.freq  (bits16 + stereo), 4);
 le_store (hdr + 32, 1  (bits16 + stereo), 2);
 
-wav-f = fopen (conf.wav_path, wb);
+wav-f = fopen (conf-wav_path, wb);
 if (!wav-f) {
 dolog (Failed to open wave file `%s'\nReason: %s\n,
-   conf.wav_path, strerror (errno));
+   conf-wav_path, strerror (errno));
 g_free (wav-pcm_buf);
 wav-pcm_buf = NULL;
 return -1;
@@ -228,40 +224,49 @@ static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
 return 0;
 }
 
+static WAVConf glob_conf = {
+.settings.freq  = 44100,
+.settings.nchannels = 2,
+.settings.fmt   = AUD_FMT_S16,
+.wav_path   = qemu.wav
+};
+
 static void *wav_audio_init (void)
 {
-return conf;
+WAVConf *conf = g_malloc(sizeof(WAVConf));
+*conf = glob_conf;
+return conf;
 }
 
 static void wav_audio_fini (void *opaque)
 {
-(void) opaque;
 ldebug (wav_fini);
+g_free(opaque);
 }
 
 static struct audio_option wav_options[] = {
 {
 .name  = FREQUENCY,
 .tag   = AUD_OPT_INT,
-.valp  = conf.settings.freq,
+.valp  = glob_conf.settings.freq,
 .descr = Frequency
 },
 {
 .name  = FORMAT,
 .tag   = AUD_OPT_FMT,
-.valp  = conf.settings.fmt,
+.valp  = glob_conf.settings.fmt,
 .descr = Format
 },
 {
 .name  = DAC_FIXED_CHANNELS,
 .tag   = AUD_OPT_INT,
-.valp  = conf.settings.nchannels,
+.valp  = glob_conf.settings.nchannels,
 .descr = Number of channels (1 - mono, 2 - stereo)
 },
 {
 .name  = PATH,
 .tag   = AUD_OPT_STR,
-.valp  = conf.wav_path,
+.valp  = glob_conf.wav_path,
 .descr = Path to wave file
 },
 { /* End of list */ }
-- 
2.4.2




[Qemu-devel] [PATCH 02/12] audio: remove fmod backend

2015-06-01 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs |   2 -
 audio/audio_int.h   |   1 -
 audio/fmodaudio.c   | 685 
 configure   |  27 +--
 4 files changed, 2 insertions(+), 713 deletions(-)
 delete mode 100644 audio/fmodaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 5573ac1..b4c0608 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -5,12 +5,10 @@ common-obj-$(CONFIG_SPICE) += spiceaudio.o
 common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
-common-obj-$(CONFIG_FMOD) += fmodaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
 common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
 
-$(obj)/audio.o $(obj)/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
 sdlaudio.o-cflags := $(SDL_CFLAGS)
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 9dd6b7f..7445602 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -206,7 +206,6 @@ extern struct audio_driver no_audio_driver;
 extern struct audio_driver oss_audio_driver;
 extern struct audio_driver sdl_audio_driver;
 extern struct audio_driver wav_audio_driver;
-extern struct audio_driver fmod_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c
deleted file mode 100644
index fabf84d..000
--- a/audio/fmodaudio.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * QEMU FMOD audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include fmod.h
-#include fmod_errors.h
-#include qemu-common.h
-#include audio.h
-
-#define AUDIO_CAP fmod
-#include audio_int.h
-
-typedef struct FMODVoiceOut {
-HWVoiceOut hw;
-unsigned int old_pos;
-FSOUND_SAMPLE *fmod_sample;
-int channel;
-} FMODVoiceOut;
-
-typedef struct FMODVoiceIn {
-HWVoiceIn hw;
-FSOUND_SAMPLE *fmod_sample;
-} FMODVoiceIn;
-
-static struct {
-const char *drvname;
-int nb_samples;
-int freq;
-int nb_channels;
-int bufsize;
-int broken_adc;
-} conf = {
-.nb_samples  = 2048 * 2,
-.freq= 44100,
-.nb_channels = 2,
-};
-
-static void GCC_FMT_ATTR (1, 2) fmod_logerr (const char *fmt, ...)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n,
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
-const char *typ,
-const char *fmt,
-...
-)
-{
-va_list ap;
-
-AUD_log (AUDIO_CAP, Could not initialize %s\n, typ);
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (AUDIO_CAP, Reason: %s\n,
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static int fmod_write (SWVoiceOut *sw, void *buf, int len)
-{
-return audio_pcm_sw_write (sw, buf, len);
-}
-
-static void fmod_clear_sample (FMODVoiceOut *fmd)
-{
-HWVoiceOut *hw = fmd-hw;
-int status;
-void *p1 = 0, *p2 = 0;
-unsigned int len1 = 0, len2 = 0;
-
-status = FSOUND_Sample_Lock (
-fmd-fmod_sample,
-0,
-hw-samples  hw-info.shift,
-p1,
-p2,
-len1,
-len2
-);
-
-if (!status) {
-fmod_logerr (Failed to lock sample\n);
-return;
-}
-
-if ((len1  hw-info.align) || (len2  hw-info.align)) {
-dolog (Lock returned misaligned length %d, %d, alignment %d\n,
-   len1, len2, hw-info.align + 1);
-goto fail;
-}
-
-if ((len1 + len2) - (hw-samples  hw-info.shift)) {
-dolog (Lock returned

Re: [Qemu-devel] [PATCH 00/12] Audio backend cleanup

2015-06-01 Thread Kővágó Zoltán

2015-06-01 15:38 keltezéssel, Michael Tokarev írta:

01.06.2015 16:23, Kővágó, Zoltán wrote:

This series of patch removes the following audio backends:
esd, fmod, sdl, winwave.


Why do you remove sdl backend?

This is my preferred backend so far, it works better
than all other backends available to me...


I'm removing it because it's broken (see 
http://lists.nongnu.org/archive/html/qemu-devel/2015-05/msg02198.html 
for an example), and nobody had an objection about removing sdl when I 
asked it on the list about a week ago 
(http://lists.nongnu.org/archive/html/qemu-devel/2015-05/msg04116.html).


Thanks,
Zoltan




[Qemu-devel] [PATCH 00/12] Audio backend cleanup

2015-06-01 Thread Kővágó, Zoltán
This series of patch removes the following audio backends:
esd, fmod, sdl, winwave.

It also cleans up the remaining drivers to do not use global variables where
possible. This is a preparation for my GSoC project where I will enable multiple
simultaneous audio backends.

Please also test the coreaudio backend, as I do not have a Mac to test it.

Patches are also available at https://github.com/DirtYiCE/qemu.git in branch
audio-cleanup to simplify testing.

Please review.

Kővágó, Zoltán (12):
  audio: remove esd backend
  audio: remove fmod backend
  audio: remove sdl backend
  audio: remove winwave audio driver
  audio: expose drv_opaque to init_out and init_in
  alsaaudio: do not use global variables
  paaudio: do not use global variables
  ossaudio: do not use global variables
  wavaudio: do not use global variables
  dsoundaudio: do not use global variables
  paaudio: fix possible resource leak
  coreaudio: do not use global variables where possible

 audio/Makefile.objs |   7 -
 audio/alsaaudio.c   | 155 ++-
 audio/audio_int.h   |   8 +-
 audio/audio_template.h  |   2 +-
 audio/coreaudio.c   |  46 ++--
 audio/dsound_template.h |  24 +-
 audio/dsoundaudio.c | 106 ---
 audio/esdaudio.c| 557 -
 audio/fmodaudio.c   | 685 -
 audio/noaudio.c |   6 +-
 audio/ossaudio.c| 115 
 audio/paaudio.c | 105 +++
 audio/sdlaudio.c| 458 ---
 audio/spiceaudio.c  |   9 +-
 audio/wavaudio.c|  41 +--
 audio/winwaveaudio.c| 717 
 configure   |  60 +---
 17 files changed, 360 insertions(+), 2741 deletions(-)
 delete mode 100644 audio/esdaudio.c
 delete mode 100644 audio/fmodaudio.c
 delete mode 100644 audio/sdlaudio.c
 delete mode 100644 audio/winwaveaudio.c

-- 
2.4.2




[Qemu-devel] [PATCH 12/12] coreaudio: do not use global variables where possible

2015-06-01 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/coreaudio.c | 45 -
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index f38fd82..6dfd63e 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -32,20 +32,16 @@
 #define AUDIO_CAP coreaudio
 #include audio_int.h
 
-struct {
+static int isAtexit;
+
+typedef struct {
 int buffer_frames;
 int nbuffers;
-int isAtexit;
-} conf = {
-.buffer_frames = 512,
-.nbuffers = 4,
-.isAtexit = 0
-};
+} CoreaudioConf;
 
 typedef struct coreaudioVoiceOut {
 HWVoiceOut hw;
 pthread_mutex_t mutex;
-int isAtexit;
 AudioDeviceID outputDeviceID;
 UInt32 audioDevicePropertyBufferFrameSize;
 AudioStreamBasicDescription outputStreamBasicDescription;
@@ -161,7 +157,7 @@ static inline UInt32 isPlaying (AudioDeviceID 
outputDeviceID)
 
 static void coreaudio_atexit (void)
 {
-conf.isAtexit = 1;
+isAtexit = 1;
 }
 
 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
@@ -296,8 +292,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 int err;
 const char *typ = playback;
 AudioValueRange frameRange;
-
-(void) drv_opaque;
+CoreaudioConf *conf = drv_opaque;
 
 /* create mutex */
 err = pthread_mutex_init(core-mutex, NULL);
@@ -339,16 +334,16 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 return -1;
 }
 
-if (frameRange.mMinimum  conf.buffer_frames) {
+if (frameRange.mMinimum  conf-buffer_frames) {
 core-audioDevicePropertyBufferFrameSize = (UInt32) 
frameRange.mMinimum;
 dolog (warning: Upsizing Buffer Frames to %f\n, frameRange.mMinimum);
 }
-else if (frameRange.mMaximum  conf.buffer_frames) {
+else if (frameRange.mMaximum  conf-buffer_frames) {
 core-audioDevicePropertyBufferFrameSize = (UInt32) 
frameRange.mMaximum;
 dolog (warning: Downsizing Buffer Frames to %f\n, 
frameRange.mMaximum);
 }
 else {
-core-audioDevicePropertyBufferFrameSize = conf.buffer_frames;
+core-audioDevicePropertyBufferFrameSize = conf-buffer_frames;
 }
 
 /* set Buffer Frame Size */
@@ -382,7 +377,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
Could not get device buffer frame size\n);
 return -1;
 }
-hw-samples = conf.nbuffers * core-audioDevicePropertyBufferFrameSize;
+hw-samples = conf-nbuffers * core-audioDevicePropertyBufferFrameSize;
 
 /* get StreamFormat */
 propertySize = sizeof(core-outputStreamBasicDescription);
@@ -446,7 +441,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
 int err;
 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
 
-if (!conf.isAtexit) {
+if (!isAtexit) {
 /* stop playback */
 if (isPlaying(core-outputDeviceID)) {
 status = AudioDeviceStop(core-outputDeviceID, audioDeviceIOProc);
@@ -489,7 +484,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
 case VOICE_DISABLE:
 /* stop playback */
-if (!conf.isAtexit) {
+if (!isAtexit) {
 if (isPlaying(core-outputDeviceID)) {
 status = AudioDeviceStop(core-outputDeviceID, 
audioDeviceIOProc);
 if (status != kAudioHardwareNoError) {
@@ -502,28 +497,36 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, 
...)
 return 0;
 }
 
+static CoreaudioConf glob_conf = {
+.buffer_frames = 512,
+.nbuffers = 4,
+};
+
 static void *coreaudio_audio_init (void)
 {
+CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
+*conf = glob_conf;
+
 atexit(coreaudio_atexit);
-return coreaudio_audio_init;
+return conf;
 }
 
 static void coreaudio_audio_fini (void *opaque)
 {
-(void) opaque;
+g_free(opaque);
 }
 
 static struct audio_option coreaudio_options[] = {
 {
 .name  = BUFFER_SIZE,
 .tag   = AUD_OPT_INT,
-.valp  = conf.buffer_frames,
+.valp  = glob_conf.buffer_frames,
 .descr = Size of the buffer in frames
 },
 {
 .name  = BUFFER_COUNT,
 .tag   = AUD_OPT_INT,
-.valp  = conf.nbuffers,
+.valp  = glob_conf.nbuffers,
 .descr = Number of buffers
 },
 { /* End of list */ }
-- 
2.4.2




[Qemu-devel] [PATCH 10/12] dsoundaudio: do not use global variables

2015-06-01 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/dsound_template.h |  18 
 audio/dsoundaudio.c | 106 
 2 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 98276fb..85ba858 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -67,7 +67,8 @@ static int glue (dsound_lock_, TYPE) (
 LPVOID *p2p,
 DWORD *blen1p,
 DWORD *blen2p,
-int entire
+int entire,
+dsound *s
 )
 {
 HRESULT hr;
@@ -75,13 +76,14 @@ static int glue (dsound_lock_, TYPE) (
 LPVOID p1 = NULL, p2 = NULL;
 DWORD blen1 = 0, blen2 = 0;
 DWORD flag;
+DSoundConf *conf = s-conf;
 
 #ifdef DSBTYPE_IN
 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
 #else
 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
 #endif
-for (i = 0; i  conf.lock_retries; ++i) {
+for (i = 0; i  conf-lock_retries; ++i) {
 hr = glue (IFACE, _Lock) (
 buf,
 pos,
@@ -96,7 +98,7 @@ static int glue (dsound_lock_, TYPE) (
 if (FAILED (hr)) {
 #ifndef DSBTYPE_IN
 if (hr == DSERR_BUFFERLOST) {
-if (glue (dsound_restore_, TYPE) (buf)) {
+if (glue (dsound_restore_, TYPE) (buf, s)) {
 dsound_logerr (hr, Could not lock  NAME \n);
 goto fail;
 }
@@ -110,7 +112,7 @@ static int glue (dsound_lock_, TYPE) (
 break;
 }
 
-if (i == conf.lock_retries) {
+if (i == conf-lock_retries) {
 dolog (%d attempts to lock  NAME  failed\n, i);
 goto fail;
 }
@@ -183,9 +185,10 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 {
 int err;
 HRESULT hr;
-dsound *s = glob_dsound;
+dsound *s = drv_opaque;
 WAVEFORMATEX wfx;
 struct audsettings obt_as;
+DSoundConf *conf = s-conf;
 #ifdef DSBTYPE_IN
 const char *typ = ADC;
 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
@@ -212,7 +215,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 bd.dwSize = sizeof (bd);
 bd.lpwfxFormat = wfx;
 #ifdef DSBTYPE_IN
-bd.dwBufferBytes = conf.bufsize_in;
+bd.dwBufferBytes = conf-bufsize_in;
 hr = IDirectSoundCapture_CreateCaptureBuffer (
 s-dsound_capture,
 bd,
@@ -221,7 +224,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 );
 #else
 bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
-bd.dwBufferBytes = conf.bufsize_out;
+bd.dwBufferBytes = conf-bufsize_out;
 hr = IDirectSound_CreateSoundBuffer (
 s-dsound,
 bd,
@@ -271,6 +274,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 );
 }
 hw-samples = bc.dwBufferBytes  hw-info.shift;
+ds-s = s;
 
 #ifdef DEBUG_DSOUND
 dolog (caps %ld, desc %ld\n,
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index e2d89fd..c8b09e2 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -41,7 +41,7 @@
 
 /* #define DEBUG_DSOUND */
 
-static struct {
+typedef struct {
 int lock_retries;
 int restore_retries;
 int getstatus_retries;
@@ -50,33 +50,22 @@ static struct {
 int bufsize_out;
 struct audsettings settings;
 int latency_millis;
-} conf = {
-.lock_retries   = 1,
-.restore_retries= 1,
-.getstatus_retries  = 1,
-.set_primary= 0,
-.bufsize_in = 16384,
-.bufsize_out= 16384,
-.settings.freq  = 44100,
-.settings.nchannels = 2,
-.settings.fmt   = AUD_FMT_S16,
-.latency_millis = 10
-};
+} DSoundConf;
 
 typedef struct {
 LPDIRECTSOUND dsound;
 LPDIRECTSOUNDCAPTURE dsound_capture;
 LPDIRECTSOUNDBUFFER dsound_primary_buffer;
 struct audsettings settings;
+DSoundConf conf;
 } dsound;
 
-static dsound glob_dsound;
-
 typedef struct {
 HWVoiceOut hw;
 LPDIRECTSOUNDBUFFER dsound_buffer;
 DWORD old_pos;
 int first_time;
+dsound *s;
 #ifdef DEBUG_DSOUND
 DWORD old_ppos;
 DWORD played;
@@ -88,6 +77,7 @@ typedef struct {
 HWVoiceIn hw;
 int first_time;
 LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+dsound *s;
 } DSoundVoiceIn;
 
 static void dsound_log_hresult (HRESULT hr)
@@ -281,12 +271,12 @@ static void print_wave_format (WAVEFORMATEX *wfx)
 }
 #endif
 
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
+static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
 {
 HRESULT hr;
 int i;
 
-for (i = 0; i  conf.restore_retries; ++i) {
+for (i = 0; i  s-conf.restore_retries; ++i) {
 hr = IDirectSoundBuffer_Restore (dsb);
 
 switch (hr) {
@@ -311,12 +301,13 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
 #include dsound_template.h
 #undef DSBTYPE_IN
 
-static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
+static int

[Qemu-devel] [PATCH 08/12] ossaudio: do not use global variables

2015-06-01 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/ossaudio.c | 114 +--
 1 file changed, 61 insertions(+), 53 deletions(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 80ac610..d247969 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -38,6 +38,17 @@
 #define USE_DSP_POLICY
 #endif
 
+typedef struct OSSConf {
+int try_mmap;
+int nfrags;
+int fragsize;
+const char *devpath_out;
+const char *devpath_in;
+int debug;
+int exclusive;
+int policy;
+} OSSConf;
+
 typedef struct OSSVoiceOut {
 HWVoiceOut hw;
 void *pcm_buf;
@@ -47,6 +58,7 @@ typedef struct OSSVoiceOut {
 int fragsize;
 int mmapped;
 int pending;
+OSSConf *conf;
 } OSSVoiceOut;
 
 typedef struct OSSVoiceIn {
@@ -55,28 +67,9 @@ typedef struct OSSVoiceIn {
 int fd;
 int nfrags;
 int fragsize;
+OSSConf *conf;
 } OSSVoiceIn;
 
-static struct {
-int try_mmap;
-int nfrags;
-int fragsize;
-const char *devpath_out;
-const char *devpath_in;
-int debug;
-int exclusive;
-int policy;
-} conf = {
-.try_mmap = 0,
-.nfrags = 4,
-.fragsize = 4096,
-.devpath_out = /dev/dsp,
-.devpath_in = /dev/dsp,
-.debug = 0,
-.exclusive = 0,
-.policy = 5
-};
-
 struct oss_params {
 int freq;
 audfmt_e fmt;
@@ -272,18 +265,18 @@ static int oss_get_version (int fd, int *version, const 
char *typ)
 #endif
 
 static int oss_open (int in, struct oss_params *req,
- struct oss_params *obt, int *pfd)
+ struct oss_params *obt, int *pfd, OSSConf* conf)
 {
 int fd;
-int oflags = conf.exclusive ? O_EXCL : 0;
+int oflags = conf-exclusive ? O_EXCL : 0;
 audio_buf_info abinfo;
 int fmt, freq, nchannels;
 int setfragment = 1;
-const char *dspname = in ? conf.devpath_in : conf.devpath_out;
+const char *dspname = in ? conf-devpath_in : conf-devpath_out;
 const char *typ = in ? ADC : DAC;
 
 /* Kludge needed to have working mmap on Linux */
-oflags |= conf.try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
+oflags |= conf-try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
 
 fd = open (dspname, oflags | O_NONBLOCK);
 if (-1 == fd) {
@@ -317,20 +310,20 @@ static int oss_open (int in, struct oss_params *req,
 }
 
 #ifdef USE_DSP_POLICY
-if (conf.policy = 0) {
+if (conf-policy = 0) {
 int version;
 
 if (!oss_get_version (fd, version, typ)) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (OSS version = %#x\n, version);
 }
 
 if (version = 0x04) {
-int policy = conf.policy;
+int policy = conf-policy;
 if (ioctl (fd, SNDCTL_DSP_POLICY, policy)) {
 oss_logerr2 (errno, typ,
  Failed to set timing policy to %d\n,
- conf.policy);
+ conf-policy);
 goto err;
 }
 setfragment = 0;
@@ -434,6 +427,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 struct audio_buf_info abinfo;
 struct count_info cntinfo;
 int bufsize;
+OSSConf *conf = oss-conf;
 
 bufsize = hw-samples  hw-info.shift;
 
@@ -458,7 +452,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 }
 
 if (abinfo.bytes  bufsize) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (warning: Invalid available size, size=%d bufsize=%d\n
please report your OS/audio hw to av1...@comtv.ru\n,
abinfo.bytes, bufsize);
@@ -467,7 +461,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
 }
 
 if (abinfo.bytes  0) {
-if (conf.debug) {
+if (conf-debug) {
 dolog (warning: Invalid available size, size=%d bufsize=%d\n,
abinfo.bytes, bufsize);
 }
@@ -520,18 +514,17 @@ static int oss_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 int fd;
 audfmt_e effective_fmt;
 struct audsettings obt_as;
-
-(void) drv_opaque;
+OSSConf *conf = drv_opaque;
 
 oss-fd = -1;
 
 req.fmt = aud_to_ossfmt (as-fmt, as-endianness);
 req.freq = as-freq;
 req.nchannels = as-nchannels;
-req.fragsize = conf.fragsize;
-req.nfrags = conf.nfrags;
+req.fragsize = conf-fragsize;
+req.nfrags = conf-nfrags;
 
-if (oss_open (0, req, obt, fd)) {
+if (oss_open (0, req, obt, fd, conf)) {
 return -1;
 }
 
@@ -558,7 +551,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 hw-samples = (obt.nfrags * obt.fragsize)  hw-info.shift;
 
 oss-mmapped = 0;
-if (conf.try_mmap) {
+if (conf-try_mmap) {
 oss-pcm_buf = mmap (
 NULL,
 hw-samples  hw

[Qemu-devel] [PATCH 04/12] audio: remove winwave audio driver

2015-06-01 Thread Kővágó, Zoltán
DirectSound should be a superior choice on Windows.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/Makefile.objs  |   1 -
 audio/audio_int.h|   1 -
 audio/winwaveaudio.c | 717 ---
 configure|  11 +-
 4 files changed, 2 insertions(+), 728 deletions(-)
 delete mode 100644 audio/winwaveaudio.c

diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 3c84972..89b61e1 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -5,7 +5,6 @@ common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
-common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
diff --git a/audio/audio_int.h b/audio/audio_int.h
index d593879..92a2f3c 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -210,7 +210,6 @@ extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
 extern struct audio_driver pa_audio_driver;
 extern struct audio_driver spice_audio_driver;
-extern struct audio_driver winwave_audio_driver;
 extern const struct mixeng_volume nominal_volume;
 
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
deleted file mode 100644
index 8dbd145..000
--- a/audio/winwaveaudio.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* public domain */
-
-#include qemu-common.h
-#include sysemu/sysemu.h
-#include audio.h
-
-#define AUDIO_CAP winwave
-#include audio_int.h
-
-#include windows.h
-#include mmsystem.h
-
-#include audio_win_int.h
-
-static struct {
-int dac_headers;
-int dac_samples;
-int adc_headers;
-int adc_samples;
-} conf = {
-.dac_headers = 4,
-.dac_samples = 1024,
-.adc_headers = 4,
-.adc_samples = 1024
-};
-
-typedef struct {
-HWVoiceOut hw;
-HWAVEOUT hwo;
-WAVEHDR *hdrs;
-HANDLE event;
-void *pcm_buf;
-int avail;
-int pending;
-int curhdr;
-int paused;
-CRITICAL_SECTION crit_sect;
-} WaveVoiceOut;
-
-typedef struct {
-HWVoiceIn hw;
-HWAVEIN hwi;
-WAVEHDR *hdrs;
-HANDLE event;
-void *pcm_buf;
-int curhdr;
-int paused;
-int rpos;
-int avail;
-CRITICAL_SECTION crit_sect;
-} WaveVoiceIn;
-
-static void winwave_log_mmresult (MMRESULT mr)
-{
-const char *str = BUG;
-
-switch (mr) {
-case MMSYSERR_NOERROR:
-str = Success;
-break;
-
-case MMSYSERR_INVALHANDLE:
-str = Specified device handle is invalid;
-break;
-
-case MMSYSERR_BADDEVICEID:
-str = Specified device id is out of range;
-break;
-
-case MMSYSERR_NODRIVER:
-str = No device driver is present;
-break;
-
-case MMSYSERR_NOMEM:
-str = Unable to allocate or lock memory;
-break;
-
-case WAVERR_SYNC:
-str = Device is synchronous but waveOutOpen was called 
-without using the WINWAVE_ALLOWSYNC flag;
-break;
-
-case WAVERR_UNPREPARED:
-str = The data block pointed to by the pwh parameter 
-hasn't been prepared;
-break;
-
-case WAVERR_STILLPLAYING:
-str = There are still buffers in the queue;
-break;
-
-default:
-dolog (Reason: Unknown (MMRESULT %#x)\n, mr);
-return;
-}
-
-dolog (Reason: %s\n, str);
-}
-
-static void GCC_FMT_ATTR (2, 3) winwave_logerr (
-MMRESULT mr,
-const char *fmt,
-...
-)
-{
-va_list ap;
-
-va_start (ap, fmt);
-AUD_vlog (AUDIO_CAP, fmt, ap);
-va_end (ap);
-
-AUD_log (NULL,  failed\n);
-winwave_log_mmresult (mr);
-}
-
-static void winwave_anal_close_out (WaveVoiceOut *wave)
-{
-MMRESULT mr;
-
-mr = waveOutClose (wave-hwo);
-if (mr != MMSYSERR_NOERROR) {
-winwave_logerr (mr, waveOutClose);
-}
-wave-hwo = NULL;
-}
-
-static void CALLBACK winwave_callback_out (
-HWAVEOUT hwo,
-UINT msg,
-DWORD_PTR dwInstance,
-DWORD_PTR dwParam1,
-DWORD_PTR dwParam2
-)
-{
-WaveVoiceOut *wave = (WaveVoiceOut *) dwInstance;
-
-switch (msg) {
-case WOM_DONE:
-{
-WAVEHDR *h = (WAVEHDR *) dwParam1;
-if (!h-dwUser) {
-h-dwUser = 1;
-EnterCriticalSection (wave-crit_sect);
-{
-wave-avail += conf.dac_samples;
-}
-LeaveCriticalSection (wave-crit_sect);
-if (wave-hw.poll_mode) {
-if (!SetEvent (wave-event)) {
-dolog (DAC SetEvent failed %lx\n, GetLastError ());
-}
-}
-}
-}
-break;
-
-case WOM_CLOSE:
-case WOM_OPEN:
-break;
-
-default

[Qemu-devel] [PATCH 11/12] paaudio: fix possible resource leak

2015-06-01 Thread Kővágó, Zoltán
qpa_audio_init did not clean up resources properly if the initialization
failed. This hopefully fixes it.

Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/paaudio.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 35e8887..fea6071 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -47,6 +47,8 @@ typedef struct {
 paaudio *g;
 } PAVoiceIn;
 
+static void qpa_audio_fini(void *opaque);
+
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
 va_list ap;
@@ -814,6 +816,8 @@ static void *qpa_audio_init (void)
 {
 paaudio *g = g_malloc(sizeof(paaudio));
 g-conf = glob_conf;
+g-mainloop = NULL;
+g-context = NULL;
 
 g-mainloop = pa_threaded_mainloop_new ();
 if (!g-mainloop) {
@@ -867,7 +871,7 @@ unlock_and_fail:
 pa_threaded_mainloop_unlock (g-mainloop);
 fail:
 AUD_log (AUDIO_CAP, Failed to initialize PA context);
-g_free(g);
+qpa_audio_fini(g);
 return NULL;
 }
 
-- 
2.4.2




[Qemu-devel] [PATCH 06/12] alsaaudio: do not use global variables

2015-06-01 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/alsaaudio.c | 154 +-
 1 file changed, 82 insertions(+), 72 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index eb33bff..d7e181b 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -33,9 +33,29 @@
 #define AUDIO_CAP alsa
 #include audio_int.h
 
+typedef struct ALSAConf {
+int size_in_usec_in;
+int size_in_usec_out;
+const char *pcm_name_in;
+const char *pcm_name_out;
+unsigned int buffer_size_in;
+unsigned int period_size_in;
+unsigned int buffer_size_out;
+unsigned int period_size_out;
+unsigned int threshold;
+
+int buffer_size_in_overridden;
+int period_size_in_overridden;
+
+int buffer_size_out_overridden;
+int period_size_out_overridden;
+int verbose;
+} ALSAConf;
+
 struct pollhlp {
 snd_pcm_t *handle;
 struct pollfd *pfds;
+ALSAConf *conf;
 int count;
 int mask;
 };
@@ -56,30 +76,6 @@ typedef struct ALSAVoiceIn {
 struct pollhlp pollhlp;
 } ALSAVoiceIn;
 
-static struct {
-int size_in_usec_in;
-int size_in_usec_out;
-const char *pcm_name_in;
-const char *pcm_name_out;
-unsigned int buffer_size_in;
-unsigned int period_size_in;
-unsigned int buffer_size_out;
-unsigned int period_size_out;
-unsigned int threshold;
-
-int buffer_size_in_overridden;
-int period_size_in_overridden;
-
-int buffer_size_out_overridden;
-int period_size_out_overridden;
-int verbose;
-} conf = {
-.buffer_size_out = 4096,
-.period_size_out = 1024,
-.pcm_name_out = default,
-.pcm_name_in = default,
-};
-
 struct alsa_params_req {
 int freq;
 snd_pcm_format_t fmt;
@@ -184,6 +180,7 @@ static void alsa_poll_handler (void *opaque)
 snd_pcm_state_t state;
 struct pollhlp *hlp = opaque;
 unsigned short revents;
+ALSAConf *conf = hlp-conf;
 
 count = poll (hlp-pfds, hlp-count, 0);
 if (count  0) {
@@ -205,7 +202,7 @@ static void alsa_poll_handler (void *opaque)
 }
 
 if (!(revents  hlp-mask)) {
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (revents = %d\n, revents);
 }
 return;
@@ -242,6 +239,7 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
 {
 int i, count, err;
 struct pollfd *pfds;
+ALSAConf *conf = hlp-conf;
 
 count = snd_pcm_poll_descriptors_count (handle);
 if (count = 0) {
@@ -270,13 +268,13 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct 
pollhlp *hlp, int mask)
NULL, hlp);
 }
 if (pfds[i].events  POLLOUT) {
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (POLLOUT %d %d\n, i, pfds[i].fd);
 }
 err = qemu_set_fd_handler (pfds[i].fd, NULL,
alsa_poll_handler, hlp);
 }
-if (conf.verbose) {
+if (conf-verbose) {
 dolog (Set handler events=%#x index=%d fd=%d err=%d\n,
pfds[i].events, i, pfds[i].fd, err);
 }
@@ -476,14 +474,15 @@ static void alsa_set_threshold (snd_pcm_t *handle, 
snd_pcm_uframes_t threshold)
 }
 
 static int alsa_open (int in, struct alsa_params_req *req,
-  struct alsa_params_obt *obt, snd_pcm_t **handlep)
+  struct alsa_params_obt *obt, snd_pcm_t **handlep,
+  ALSAConf *conf)
 {
 snd_pcm_t *handle;
 snd_pcm_hw_params_t *hw_params;
 int err;
 int size_in_usec;
 unsigned int freq, nchannels;
-const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
+const char *pcm_name = in ? conf-pcm_name_in : conf-pcm_name_out;
 snd_pcm_uframes_t obt_buffer_size;
 const char *typ = in ? ADC : DAC;
 snd_pcm_format_t obtfmt;
@@ -522,7 +521,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 }
 
 err = snd_pcm_hw_params_set_format (handle, hw_params, req-fmt);
-if (err  0  conf.verbose) {
+if (err  0  conf-verbose) {
 alsa_logerr2 (err, typ, Failed to set format %d\n, req-fmt);
 }
 
@@ -654,7 +653,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 goto err;
 }
 
-if (!in  conf.threshold) {
+if (!in  conf-threshold) {
 snd_pcm_uframes_t threshold;
 int bytes_per_sec;
 
@@ -676,7 +675,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 break;
 }
 
-threshold = (conf.threshold * bytes_per_sec) / 1000;
+threshold = (conf-threshold * bytes_per_sec) / 1000;
 alsa_set_threshold (handle, threshold);
 }
 
@@ -686,7 +685,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
 
 *handlep = handle;
 
-if (conf.verbose 
+if (conf-verbose 
 (obtfmt != req-fmt ||
  obt-nchannels != req-nchannels

[Qemu-devel] [PATCH 07/12] paaudio: do not use global variables

2015-06-01 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán dirty.ice...@gmail.com
---
 audio/paaudio.c | 102 +---
 1 file changed, 52 insertions(+), 50 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 11c2d29..35e8887 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -9,6 +9,19 @@
 #include audio_pt_int.h
 
 typedef struct {
+int samples;
+char *server;
+char *sink;
+char *source;
+} PAConf;
+
+typedef struct {
+PAConf conf;
+pa_threaded_mainloop *mainloop;
+pa_context *context;
+} paaudio;
+
+typedef struct {
 HWVoiceOut hw;
 int done;
 int live;
@@ -17,6 +30,7 @@ typedef struct {
 pa_stream *stream;
 void *pcm_buf;
 struct audio_pt pt;
+paaudio *g;
 } PAVoiceOut;
 
 typedef struct {
@@ -30,21 +44,9 @@ typedef struct {
 struct audio_pt pt;
 const void *read_data;
 size_t read_index, read_length;
+paaudio *g;
 } PAVoiceIn;
 
-typedef struct {
-int samples;
-char *server;
-char *sink;
-char *source;
-pa_threaded_mainloop *mainloop;
-pa_context *context;
-} paaudio;
-
-static paaudio glob_paaudio = {
-.samples = 4096,
-};
-
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
 va_list ap;
@@ -106,7 +108,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
 
 static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int 
*rerror)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = p-g;
 
 pa_threaded_mainloop_lock (g-mainloop);
 
@@ -160,7 +162,7 @@ unlock_and_fail:
 
 static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, 
int *rerror)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = p-g;
 
 pa_threaded_mainloop_lock (g-mainloop);
 
@@ -222,7 +224,7 @@ static void *qpa_thread_out (void *arg)
 }
 }
 
-decr = to_mix = audio_MIN (pa-live, glob_paaudio.samples  2);
+decr = to_mix = audio_MIN (pa-live, pa-g-conf.samples  2);
 rpos = pa-rpos;
 
 if (audio_pt_unlock (pa-pt, AUDIO_FUNC)) {
@@ -314,7 +316,7 @@ static void *qpa_thread_in (void *arg)
 }
 }
 
-incr = to_grab = audio_MIN (pa-dead, glob_paaudio.samples  2);
+incr = to_grab = audio_MIN (pa-dead, pa-g-conf.samples  2);
 wpos = pa-wpos;
 
 if (audio_pt_unlock (pa-pt, AUDIO_FUNC)) {
@@ -430,7 +432,7 @@ static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int 
*endianness)
 
 static void context_state_cb (pa_context *c, void *userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 switch (pa_context_get_state(c)) {
 case PA_CONTEXT_READY:
@@ -449,7 +451,7 @@ static void context_state_cb (pa_context *c, void *userdata)
 
 static void stream_state_cb (pa_stream *s, void * userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 switch (pa_stream_get_state (s)) {
 
@@ -467,23 +469,21 @@ static void stream_state_cb (pa_stream *s, void * 
userdata)
 
 static void stream_request_cb (pa_stream *s, size_t length, void *userdata)
 {
-paaudio *g = glob_paaudio;
+paaudio *g = userdata;
 
 pa_threaded_mainloop_signal (g-mainloop, 0);
 }
 
 static pa_stream *qpa_simple_new (
-const char *server,
+paaudio *g,
 const char *name,
 pa_stream_direction_t dir,
 const char *dev,
-const char *stream_name,
 const pa_sample_spec *ss,
 const pa_channel_map *map,
 const pa_buffer_attr *attr,
 int *rerror)
 {
-paaudio *g = glob_paaudio;
 int r;
 pa_stream *stream;
 
@@ -538,12 +538,11 @@ static int qpa_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 void *drv_opaque)
 {
 int error;
-static pa_sample_spec ss;
-static pa_buffer_attr ba;
+pa_sample_spec ss;
+pa_buffer_attr ba;
 struct audsettings obt_as = *as;
 PAVoiceOut *pa = (PAVoiceOut *) hw;
-
-(void) drv_opaque;
+paaudio *g = pa-g = drv_opaque;
 
 ss.format = audfmt_to_pa (as-fmt, as-endianness);
 ss.channels = as-nchannels;
@@ -561,11 +560,10 @@ static int qpa_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 obt_as.fmt = pa_to_audfmt (ss.format, obt_as.endianness);
 
 pa-stream = qpa_simple_new (
-glob_paaudio.server,
+g,
 qemu,
 PA_STREAM_PLAYBACK,
-glob_paaudio.sink,
-pcm.playback,
+g-conf.sink,
 ss,
 NULL,   /* channel map */
 ba,/* buffering attributes */
@@ -577,7 +575,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 }
 
 audio_pcm_init_info (hw-info, obt_as);
-hw-samples = glob_paaudio.samples;
+hw-samples = g-conf.samples;
 pa-pcm_buf = audio_calloc (AUDIO_FUNC, hw-samples, 1  hw-info.shift);
 pa-rpos = hw-rpos;
 if (!pa-pcm_buf) {
@@ -607,11 +605,10 @@ static int qpa_init_out(HWVoiceOut *hw, struct

  1   2   3   4   5   6   7   >