qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/2] Introduce AUD_set_volume


From: Jan Kiszka
Subject: [Qemu-devel] [PATCH 1/2] Introduce AUD_set_volume
Date: Sun, 27 Apr 2008 13:26:48 +0200
User-agent: Thunderbird 2.0.0.12 (X11/20080226)

This patch adds volume and mute control to the AUD interface and cleans
up the related code.

As Andrzej suggested, per-voice volume control is dropped in favor of
two global volumes: PCM input and output. Those two should be easier
mappable on real mixer support. But for now the pre-existing soft-mixer
infrastructure is used.

Partly derived from VirtualBox's mixer support - but cleaner and without
calculation errors. :)

Signed-off-by: Jan Kiszka <address@hidden>
---
 audio/alsaaudio.c       |    2 +-
 audio/audio.c           |   39 +++++++++++++++++++++++++++++++++++----
 audio/audio.h           |    8 ++++++++
 audio/audio_int.h       |    5 ++---
 audio/audio_template.h  |    1 -
 audio/dsoundaudio.c     |    4 ++--
 audio/esdaudio.c        |    2 +-
 audio/fmodaudio.c       |    4 ++--
 audio/mixeng.c          |    2 --
 audio/mixeng_template.h |   14 ++------------
 audio/ossaudio.c        |    2 +-
 11 files changed, 54 insertions(+), 29 deletions(-)

Index: b/audio/audio.c
===================================================================
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -111,14 +111,25 @@ static struct {
 
 static AudioState glob_audio_state;
 
-volume_t nominal_volume = {
+volume_t pcm_out_volume = {
     0,
 #ifdef FLOAT_MIXENG
     1.0,
     1.0
 #else
-    UINT_MAX,
-    UINT_MAX
+    INT_MAX,
+    INT_MAX
+#endif
+};
+
+volume_t pcm_in_volume = {
+    0,
+#ifdef FLOAT_MIXENG
+    1.0,
+    1.0
+#else
+    INT_MAX,
+    INT_MAX
 #endif
 };
 
@@ -1040,7 +1051,7 @@ int audio_pcm_sw_write (SWVoiceOut *sw, 
     swlim = ((int64_t) dead << 32) / sw->ratio;
     swlim = audio_MIN (swlim, samples);
     if (swlim) {
-        sw->conv (sw->buf, buf, swlim, &sw->vol);
+        sw->conv (sw->buf, buf, swlim, &pcm_out_volume);
     }
 
     while (swlim) {
@@ -1955,3 +1966,23 @@ void AUD_del_capture (CaptureVoiceOut *c
         }
     }
 }
+
+void AUD_set_volume (audmixerctl_t mt, int mute, uint8_t lvol, uint8_t rvol)
+{
+    volume_t *vol;
+
+    switch (mt) {
+    case AUD_MIXER_PCM_OUT:
+        vol  = &pcm_out_volume;
+        break;
+    case AUD_MIXER_LINE_IN:
+        vol  = &pcm_in_volume;
+        break;
+    default:
+        return;
+    }
+
+    vol->mute = mute;
+    vol->l = (((int64_t)lvol) * 0x100000000) / 0xff;
+    vol->r = (((int64_t)rvol) * 0x100000000) / 0xff;
+}
Index: b/audio/audio.h
===================================================================
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -56,6 +56,12 @@ typedef enum {
     AUD_CNOTIFY_DISABLE
 } audcnotification_e;
 
+typedef enum
+{
+    AUD_MIXER_PCM_OUT,
+    AUD_MIXER_LINE_IN
+} audmixerctl_t;
+
 struct audio_capture_ops {
     void (*notify) (void *opaque, audcnotification_e cmd);
     void (*capture) (void *opaque, void *buf, int size);
@@ -141,6 +147,8 @@ int  AUD_is_active_in (SWVoiceIn *sw);
 void     AUD_init_time_stamp_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
 uint64_t AUD_get_elapsed_usec_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
 
+void AUD_set_volume (audmixerctl_t mt, int mute, uint8_t lvol, uint8_t rvol);
+
 static inline void *advance (void *p, int incr)
 {
     uint8_t *d = p;
Index: b/audio/audio_int.h
===================================================================
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -114,7 +114,6 @@ struct SWVoiceOut {
     int empty;
     HWVoiceOut *hw;
     char *name;
-    volume_t vol;
     struct audio_callback callback;
     LIST_ENTRY (SWVoiceOut) entries;
 };
@@ -129,7 +128,6 @@ struct SWVoiceIn {
     f_sample *clip;
     HWVoiceIn *hw;
     char *name;
-    volume_t vol;
     struct audio_callback callback;
     LIST_ENTRY (SWVoiceIn) entries;
 };
@@ -203,7 +201,8 @@ extern struct audio_driver alsa_audio_dr
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
 extern struct audio_driver esd_audio_driver;
-extern volume_t nominal_volume;
+extern volume_t pcm_out_volume;
+extern volume_t pcm_in_volume;
 
 void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as);
 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int 
len);
Index: b/audio/audio_template.h
===================================================================
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -491,7 +491,6 @@ SW *glue (AUD_open_, TYPE) (
     }
 
     if (sw) {
-        sw->vol = nominal_volume;
         sw->callback.fn = callback_fn;
         sw->callback.opaque = callback_opaque;
 
Index: b/audio/mixeng.c
===================================================================
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -28,8 +28,6 @@
 #define AUDIO_CAP "mixeng"
 #include "audio_int.h"
 
-#define NOVOL
-
 /* 8 bit */
 #define ENDIAN_CONVERSION natural
 #define ENDIAN_CONVERT(v) (v)
Index: b/audio/ossaudio.c
===================================================================
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -680,7 +680,7 @@ static int oss_run_in (HWVoiceIn *hw)
                 }
                 read_samples += nread >> hwshift;
                 hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift,
-                          &nominal_volume);
+                          &pcm_in_volume);
             }
 
             if (bufs[i].len - nread) {
Index: b/audio/mixeng_template.h
===================================================================
--- a/audio/mixeng_template.h
+++ b/audio/mixeng_template.h
@@ -31,15 +31,11 @@
 #define HALF (IN_MAX >> 1)
 #endif
 
-#ifdef NOVOL
-#define VOL(a, b) a
-#else
 #ifdef FLOAT_MIXENG
 #define VOL(a, b) ((a) * (b))
 #else
 #define VOL(a, b) ((a) * (b)) >> 32
 #endif
-#endif
 
 #define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
 
@@ -113,14 +109,11 @@ static void glue (glue (conv_, ET), _to_
 {
     st_sample_t *out = dst;
     IN_T *in = (IN_T *) src;
-#ifndef NOVOL
+
     if (vol->mute) {
         mixeng_clear (dst, samples);
         return;
     }
-#else
-    (void) vol;
-#endif
     while (samples--) {
         out->l = VOL (glue (conv_, ET) (*in++), vol->l);
         out->r = VOL (glue (conv_, ET) (*in++), vol->r);
@@ -133,14 +126,11 @@ static void glue (glue (conv_, ET), _to_
 {
     st_sample_t *out = dst;
     IN_T *in = (IN_T *) src;
-#ifndef NOVOL
+
     if (vol->mute) {
         mixeng_clear (dst, samples);
         return;
     }
-#else
-    (void) vol;
-#endif
     while (samples--) {
         out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
         out->r = out->l;
Index: b/audio/alsaaudio.c
===================================================================
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -902,7 +902,7 @@ static int alsa_run_in (HWVoiceIn *hw)
                 }
             }
 
-            hw->conv (dst, src, nread, &nominal_volume);
+            hw->conv (dst, src, nread, &pcm_in_volume);
 
             src = advance (src, nread << hwshift);
             dst += nread;
Index: b/audio/dsoundaudio.c
===================================================================
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -927,11 +927,11 @@ static int dsound_run_in (HWVoiceIn *hw)
     decr = len1 + len2;
 
     if (p1 && len1) {
-        hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
+        hw->conv (hw->conv_buf + hw->wpos, p1, len1, &pcm_in_volume);
     }
 
     if (p2 && len2) {
-        hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
+        hw->conv (hw->conv_buf, p2, len2, &pcm_in_volume);
     }
 
     dsound_unlock_in (dscb, p1, p2, blen1, blen2);
Index: b/audio/esdaudio.c
===================================================================
--- a/audio/esdaudio.c
+++ b/audio/esdaudio.c
@@ -368,7 +368,7 @@ static void *qesd_thread_in (void *arg)
             }
 
             hw->conv (hw->conv_buf + wpos, buf, nread >> hw->info.shift,
-                      &nominal_volume);
+                      &pcm_in_volume);
             wpos = (wpos + chunk) % hw->samples;
             to_grab -= chunk;
         }
Index: b/audio/fmodaudio.c
===================================================================
--- a/audio/fmodaudio.c
+++ b/audio/fmodaudio.c
@@ -502,10 +502,10 @@ static int fmod_run_in (HWVoiceIn *hw)
     decr = len1 + len2;
 
     if (p1 && blen1) {
-        hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
+        hw->conv (hw->conv_buf + hw->wpos, p1, len1, &pcm_in_volume);
     }
     if (p2 && len2) {
-        hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
+        hw->conv (hw->conv_buf, p2, len2, &pcm_in_volume);
     }
 
     fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]