From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Jq51x-00006v-Gw for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:26:53 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Jq51w-0008W2-1A for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:26:52 -0400 Received: from [199.232.76.173] (port=48233 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Jq51v-0008Vl-Lw for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:26:51 -0400 Received: from fmmailgate01.web.de ([217.72.192.221]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Jq51u-0002Z2-Nu for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:26:51 -0400 Received: from smtp07.web.de (fmsmtp07.dlan.cinetic.de [172.20.5.215]) by fmmailgate01.web.de (Postfix) with ESMTP id 1A082DCF757A for ; Sun, 27 Apr 2008 13:26:48 +0200 (CEST) Received: from [88.64.4.240] (helo=[192.168.1.198]) by smtp07.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.109 #226) id 1Jq51r-0007Ue-00 for qemu-devel@nongnu.org; Sun, 27 Apr 2008 13:26:47 +0200 Message-ID: <481462F8.3050806@web.de> Date: Sun, 27 Apr 2008 13:26:48 +0200 From: Jan Kiszka MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Sender: jan.kiszka@web.de Subject: [Qemu-devel] [PATCH 1/2] Introduce AUD_set_volume Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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 --- 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);