[Top][All Lists]
[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);
- [Qemu-devel] [PATCH 1/2] Introduce AUD_set_volume,
Jan Kiszka <=