All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@web.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 1/2] Introduce AUD_set_volume
Date: Sun, 27 Apr 2008 13:26:48 +0200	[thread overview]
Message-ID: <481462F8.3050806@web.de> (raw)

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 <jan.kiszka@web.de>
---
 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	other threads:[~2008-04-27 11:26 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-27 11:26 Jan Kiszka [this message]
2008-04-27 18:35 ` [Qemu-devel] [PATCH 1/2] Introduce AUD_set_volume malc
2008-05-02  2:08   ` andrzej zaborowski
2008-05-02  7:41     ` Jan Kiszka
2008-05-02 10:12       ` andrzej zaborowski
2008-05-02 10:55         ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=481462F8.3050806@web.de \
    --to=jan.kiszka@web.de \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.