]> Git Repo - qemu.git/blobdiff - audio/paaudio.c
qdev: Set the object property's description to the qdev property's.
[qemu.git] / audio / paaudio.c
index 6f50c1ce0cc0afda02781a6cc571887ce7737397..90ff24500b1016b652dc2cd4074821f49d80c24b 100644 (file)
@@ -56,6 +56,26 @@ static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
     AUD_log (AUDIO_CAP, "Reason: %s\n", pa_strerror (err));
 }
 
+#ifndef PA_CONTEXT_IS_GOOD
+static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
+{
+    return
+        x == PA_CONTEXT_CONNECTING ||
+        x == PA_CONTEXT_AUTHORIZING ||
+        x == PA_CONTEXT_SETTING_NAME ||
+        x == PA_CONTEXT_READY;
+}
+#endif
+
+#ifndef PA_STREAM_IS_GOOD
+static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
+{
+    return
+        x == PA_STREAM_CREATING ||
+        x == PA_STREAM_READY;
+}
+#endif
+
 #define CHECK_SUCCESS_GOTO(c, rerror, expression, label)        \
     do {                                                        \
         if (!(expression)) {                                    \
@@ -481,12 +501,16 @@ static pa_stream *qpa_simple_new (
     if (dir == PA_STREAM_PLAYBACK) {
         r = pa_stream_connect_playback (stream, dev, attr,
                                         PA_STREAM_INTERPOLATE_TIMING
+#ifdef PA_STREAM_ADJUST_LATENCY
                                         |PA_STREAM_ADJUST_LATENCY
+#endif
                                         |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
     } else {
         r = pa_stream_connect_record (stream, dev, attr,
                                       PA_STREAM_INTERPOLATE_TIMING
+#ifdef PA_STREAM_ADJUST_LATENCY
                                       |PA_STREAM_ADJUST_LATENCY
+#endif
                                       |PA_STREAM_AUTO_TIMING_UPDATE);
     }
 
@@ -505,8 +529,7 @@ fail:
         pa_stream_unref (stream);
     }
 
-    qpa_logerr (pa_context_errno (g->context),
-                "stream_new() failed\n");
+    *rerror = pa_context_errno (g->context);
 
     return NULL;
 }
@@ -524,11 +547,11 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
     ss.rate = as->freq;
 
     /*
-     * qemu audio tick runs at 250 Hz (by default), so processing
-     * data chunks worth 4 ms of sound should be a good fit.
+     * qemu audio tick runs at 100 Hz (by default), so processing
+     * data chunks worth 10 ms of sound should be a good fit.
      */
-    ba.tlength = pa_usec_to_bytes (4 * 1000, &ss);
-    ba.minreq = pa_usec_to_bytes (2 * 1000, &ss);
+    ba.tlength = pa_usec_to_bytes (10 * 1000, &ss);
+    ba.minreq = pa_usec_to_bytes (5 * 1000, &ss);
     ba.maxlength = -1;
     ba.prebuf = -1;
 
@@ -677,15 +700,107 @@ static void qpa_fini_in (HWVoiceIn *hw)
 
 static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 {
-    (void) hw;
-    (void) cmd;
+    PAVoiceOut *pa = (PAVoiceOut *) hw;
+    pa_operation *op;
+    pa_cvolume v;
+    paaudio *g = &glob_paaudio;
+
+#ifdef PA_CHECK_VERSION    /* macro is present in 0.9.16+ */
+    pa_cvolume_init (&v);  /* function is present in 0.9.13+ */
+#endif
+
+    switch (cmd) {
+    case VOICE_VOLUME:
+        {
+            SWVoiceOut *sw;
+            va_list ap;
+
+            va_start (ap, cmd);
+            sw = va_arg (ap, SWVoiceOut *);
+            va_end (ap);
+
+            v.channels = 2;
+            v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX;
+            v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX;
+
+            pa_threaded_mainloop_lock (g->mainloop);
+
+            op = pa_context_set_sink_input_volume (g->context,
+                pa_stream_get_index (pa->stream),
+                &v, NULL, NULL);
+            if (!op)
+                qpa_logerr (pa_context_errno (g->context),
+                            "set_sink_input_volume() failed\n");
+            else
+                pa_operation_unref (op);
+
+            op = pa_context_set_sink_input_mute (g->context,
+                pa_stream_get_index (pa->stream),
+               sw->vol.mute, NULL, NULL);
+            if (!op) {
+                qpa_logerr (pa_context_errno (g->context),
+                            "set_sink_input_mute() failed\n");
+            } else {
+                pa_operation_unref (op);
+            }
+
+            pa_threaded_mainloop_unlock (g->mainloop);
+        }
+    }
     return 0;
 }
 
 static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
 {
-    (void) hw;
-    (void) cmd;
+    PAVoiceIn *pa = (PAVoiceIn *) hw;
+    pa_operation *op;
+    pa_cvolume v;
+    paaudio *g = &glob_paaudio;
+
+#ifdef PA_CHECK_VERSION
+    pa_cvolume_init (&v);
+#endif
+
+    switch (cmd) {
+    case VOICE_VOLUME:
+        {
+            SWVoiceIn *sw;
+            va_list ap;
+
+            va_start (ap, cmd);
+            sw = va_arg (ap, SWVoiceIn *);
+            va_end (ap);
+
+            v.channels = 2;
+            v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX;
+            v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX;
+
+            pa_threaded_mainloop_lock (g->mainloop);
+
+            /* FIXME: use the upcoming "set_source_output_{volume,mute}" */
+            op = pa_context_set_source_volume_by_index (g->context,
+                pa_stream_get_device_index (pa->stream),
+                &v, NULL, NULL);
+            if (!op) {
+                qpa_logerr (pa_context_errno (g->context),
+                            "set_source_volume() failed\n");
+            } else {
+                pa_operation_unref(op);
+            }
+
+            op = pa_context_set_source_mute_by_index (g->context,
+                pa_stream_get_index (pa->stream),
+                sw->vol.mute, NULL, NULL);
+            if (!op) {
+                qpa_logerr (pa_context_errno (g->context),
+                            "set_source_mute() failed\n");
+            } else {
+                pa_operation_unref (op);
+            }
+
+            pa_threaded_mainloop_unlock (g->mainloop);
+        }
+    }
     return 0;
 }
 
@@ -822,5 +937,6 @@ struct audio_driver pa_audio_driver = {
     .max_voices_out = INT_MAX,
     .max_voices_in  = INT_MAX,
     .voice_size_out = sizeof (PAVoiceOut),
-    .voice_size_in  = sizeof (PAVoiceIn)
+    .voice_size_in  = sizeof (PAVoiceIn),
+    .ctl_caps       = VOICE_VOLUME_CAP
 };
This page took 0.029923 seconds and 4 git commands to generate.