Allow hw/audio drivers to pass raw DB values to audio/ drivers
cover Allow hw/audio drivers to pass raw DB values to audio/ drivers
This patch series introduces the ability for virtual audio drivers to pass information about guest-chosen DB values to backend audio drivers.
For now, supported virtual driver is hda-codec, and backend is pulseaudio, as they both support DB values.
Without these patches, emulated Windows has a very short range of hearable sound, as range in the guest is much smaller than in Pulseaudio.
Yaroslav Isakov (3):
Allow audio driver to pass DB value to underlying drivers Pass raw DB values from hda-codec.c to audio driver If raw DB values are known, use them in paaudio
audio/audio.c | 15 +++++++++++++-- audio/audio.h | 6 ++++-- audio/mixeng.h | 6 ++++-- audio/paaudio.c | 9 +++++++-- hw/audio/ac97.c | 4 ++-- hw/audio/hda-codec-common.h | 2 +- hw/audio/hda-codec.c | 12 ++++++++++-- hw/audio/lm4549.c | 2 +- hw/audio/wm8750.c | 18 ++++++++++++------ hw/display/xlnx_dp.c | 3 ++- hw/usb/dev-audio.c | 6 ++++-- 11 files changed, 60 insertions(+), 23 deletions(-)
Signature · 1 line
2.18.1
PATCH 1/3 Allow audio driver to pass DB value to underlying drivers
--- audio/audio.c | 15 +++++++++++++-- audio/audio.h | 6 ++++-- audio/mixeng.h | 6 ++++-- hw/audio/ac97.c | 4 ++-- hw/audio/hda-codec-common.h | 2 +- hw/audio/hda-codec.c | 8 ++++++-- hw/audio/lm4549.c | 2 +- hw/audio/wm8750.c | 18 ++++++++++++------ hw/display/xlnx_dp.c | 3 ++- hw/usb/dev-audio.c | 6 ++++-- 10 files changed, 49 insertions(+), 21 deletions(-)
audio/audio.c +13 -2
@@ -146,6 +146,9 @@ const struct mixeng_volume nominal_volume = { .r = 1ULL << 32, .l = 1ULL << 32, #endif + .db_known = false, + .r_db = 0, + .l_db =0 };#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
@@ -2089,7 +2092,8 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque) } } -void AUD_set_volume_out (SWVoiceOut *sw,int mute,uint8_t lvol,uint8_t rvol) +void AUD_set_volume_out (SWVoiceOut *sw,int mute,uint8_t lvol,uint8_t rvol, +bool db_known,double lvol_db,double rvol_db) {if (sw) {HWVoiceOut *hw = sw->hw;
@@ -2097,6 +2101,9 @@ void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol) sw->vol.mute = mute; sw->vol.l = nominal_volume.l * lvol /255 ; sw->vol.r = nominal_volume.r * rvol /255 ; + sw->vol.db_known = db_known; + sw->vol.l_db = lvol_db; + sw->vol.r_db = rvol_db;if (hw->pcm_ops->ctl_out) { hw->pcm_ops->ctl_out (hw,VOICE_VOLUME , sw);
@@ -2104,7 +2111,8 @@ void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol) } } -void AUD_set_volume_in (SWVoiceIn *sw,int mute,uint8_t lvol,uint8_t rvol) +void AUD_set_volume_in (SWVoiceIn *sw,int mute,uint8_t lvol,uint8_t rvol, +bool db_known,double lvol_db,double rvol_db) {if (sw) {HWVoiceIn *hw = sw->hw;
@@ -2112,6 +2120,9 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol) sw->vol.mute = mute; sw->vol.l = nominal_volume.l * lvol /255 ; sw->vol.r = nominal_volume.r * rvol /255 ; + sw->vol.db_known = db_known; + sw->vol.l_db = lvol_db; + sw->vol.r_db = rvol_db;if (hw->pcm_ops->ctl_in) { hw->pcm_ops->ctl_in (hw,VOICE_VOLUME , sw);
audio/audio.h +4 -2
@@ -117,8 +117,10 @@ int AUD_is_active_out (SWVoiceOut *sw);void AUD_init_time_stamp_out (SWVoiceOut *sw,QEMUAudioTimeStamp *ts);uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw,QEMUAudioTimeStamp *ts); -void AUD_set_volume_out (SWVoiceOut *sw,int mute,uint8_t lvol,uint8_t rvol); -void AUD_set_volume_in (SWVoiceIn *sw,int mute,uint8_t lvol,uint8_t rvol); +void AUD_set_volume_out (SWVoiceOut *sw,int mute,uint8_t lvol,uint8_t rvol, +bool db_known,double lvol_db,double rvol_db); +void AUD_set_volume_in (SWVoiceIn *sw,int mute,uint8_t lvol,uint8_t rvol, +bool db_known,double lvol_db,double rvol_db); SWVoiceIn *AUD_open_in ( QEMUSoundCard *card,
audio/mixeng.h +4 -2
@@ -27,10 +27,12 @@#ifdef FLOAT_MIXENG typedef float mixeng_real ; -struct mixeng_volume {int mute;mixeng_real r;mixeng_real l; }; +struct mixeng_volume {int mute;mixeng_real r;mixeng_real l; +bool db_known;double r_db;double l_db; };struct st_sample {mixeng_real l;mixeng_real r; };#else -struct mixeng_volume {int mute;int64_t r;int64_t l; }; +struct mixeng_volume {int mute;int64_t r;int64_t l; +bool db_known;double r_db;double l_db;};struct st_sample {int64_t l;int64_t r; };#endif
hw/audio/ac97.c +2 -2
@@ -470,7 +470,7 @@ static void update_combined_volume_out (AC97LinkState *s) lvol = (lvol * plvol) /255 ; rvol = (rvol * prvol) /255 ; -AUD_set_volume_out (s->voice_po, mute, lvol, rvol); +AUD_set_volume_out (s->voice_po, mute, lvol, rvol, false,0 ,0 ); }static void update_volume_in (AC97LinkState *s)
@@ -481,7 +481,7 @@ static void update_volume_in (AC97LinkState *s)get_volume (mixer_load (s, AC97_Record_Gain_Mute),0x0f ,0 , &mute, &lvol, &rvol); -AUD_set_volume_in (s->voice_pi, mute, lvol, rvol); +AUD_set_volume_in (s->voice_pi, mute, lvol, rvol, false,0 ,0 ); }static void set_volume (AC97LinkState *s,int index,uint32_t val)
hw/audio/hda-codec-common.h +1 -1
@@ -32,7 +32,7 @@ (AC_AMPCAP_MUTE | \ (QEMU_HDA_AMP_STEPS <<AC_AMPCAP_OFFSET_SHIFT ) | \ (QEMU_HDA_AMP_STEPS <<AC_AMPCAP_NUM_STEPS_SHIFT ) | \ - (3 << AC_AMPCAP_STEP_SIZE_SHIFT)) + (QEMU_HDA_AMP_STEP_SIZE << AC_AMPCAP_STEP_SIZE_SHIFT))#else #define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x11)#define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x21)
hw/audio/hda-codec.c +6 -2
@@ -119,6 +119,8 @@ static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as) 0x1fc /* 16 -> 96 kHz */)#define QEMU_HDA_AMP_NONE (0)#define QEMU_HDA_AMP_STEPS 0x4a +#define QEMU_HDA_AMP_STEP_SIZE 3 +#define QEMU_HDA_AMP_DB_OF_STEP ((QEMU_HDA_AMP_STEP_SIZE + 1) * 0.25)#define PARAM mixemu#define HDA_MIXER
@@ -451,9 +453,11 @@ static void hda_audio_set_amp(HDAAudioStream *st)return ; }if (st->output) { -AUD_set_volume_out (st->voice.out, muted, left, right); +AUD_set_volume_out (st->voice.out, muted, left, right, + false,0 ,0 ); }else { -AUD_set_volume_in (st->voice.in, muted, left, right); +AUD_set_volume_in (st->voice.in, muted, left, right, + false,0 ,0 ); } }
hw/audio/lm4549.c +1 -1
@@ -304,7 +304,7 @@ void lm4549_init(lm4549_state *s, lm4549_callback data_req_cb, void* opaque) &as ); -AUD_set_volume_out (s->voice,0 ,255 ,255 ); +AUD_set_volume_out (s->voice,0 ,255 ,255 , false,0 ,0 ); s->voice_is_active =0 ;
hw/audio/wm8750.c +12 -6
@@ -144,30 +144,36 @@ static void wm8750_vol_update(WM8750State *s)AUD_set_volume_in (s->adc_voice[0 ], s->mute, s->inmute[0 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[0 ]), - s->inmute[1 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[1 ])); + s->inmute[1 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[1 ]), + false,0 ,0 );AUD_set_volume_in (s->adc_voice[1 ], s->mute, s->inmute[0 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[0 ]), - s->inmute[1 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[1 ])); + s->inmute[1 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[1 ]), + false,0 ,0 );AUD_set_volume_in (s->adc_voice[2 ], s->mute, s->inmute[0 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[0 ]), - s->inmute[1 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[1 ])); + s->inmute[1 ] ?0 :WM8750_INVOL_TRANSFORM (s->invol[1 ]), + false,0 ,0 );/* FIXME: multiply all volumes by s->outvol[0], s->outvol[1] */ /* Speaker: LOUT2VOL ROUT2VOL */ AUD_set_volume_out (s->dac_voice[0 ], s->mute, s->outmute[0 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[4 ]), - s->outmute[1 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[5 ])); + s->outmute[1 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[5 ]), + false,0 ,0 );/* Headphone: LOUT1VOL ROUT1VOL */ AUD_set_volume_out (s->dac_voice[1 ], s->mute, s->outmute[0 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[2 ]), - s->outmute[1 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[3 ])); + s->outmute[1 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[3 ]), + false,0 ,0 );/* MONOOUT: MONOVOL MONOVOL */ AUD_set_volume_out (s->dac_voice[2 ], s->mute, s->outmute[0 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[6 ]), - s->outmute[1 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[6 ])); + s->outmute[1 ] ?0 :WM8750_OUTVOL_TRANSFORM (s->outvol[6 ]), + false,0 ,0 ); }static void wm8750_set_format (WM8750State *s)
hw/display/xlnx_dp.c +2 -1
@@ -1271,7 +1271,8 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp) s, xlnx_dp_audio_callback, &as); -AUD_set_volume_out (s->amixer_output_stream,0 ,255 ,255 ); +AUD_set_volume_out (s->amixer_output_stream,0 ,255 ,255 , + false,0 ,0 );xlnx_dp_audio_activate (s); }
hw/usb/dev-audio.c +4 -2
@@ -500,7 +500,8 @@ static int usb_audio_set_control(USBAudioState *s, uint8_t attrib, s->out.mute, s->out.vol[0], s->out.vol[1]); }AUD_set_volume_out (s->out.voice, s->out.mute, - s->out.vol[0 ], s->out.vol[1 ]); + s->out.vol[0 ], s->out.vol[1 ], + false,0 ,0 ); }return ret;
@@ -653,7 +654,8 @@ static void usb_audio_realize(USBDevice *dev, Error **errp) s->out.voice =AUD_open_out (&s->card, s->out.voice,TYPE_USB_AUDIO , s, output_callback, &s->out.as); -AUD_set_volume_out (s->out.voice, s->out.mute, s->out.vol[0 ], s->out.vol[1 ]); +AUD_set_volume_out (s->out.voice, s->out.mute, s->out.vol[0 ], s->out.vol[1 ], + false,0 ,0 );AUD_set_active_out (s->out.voice,0 ); }
Signature · 1 line
2.18.1
PATCH 2/3 Pass raw DB values from hda-codec.c to audio driver
In reply to Yaroslav Isakov--- hw/audio/hda-codec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
hw/audio/hda-codec.c +6 -2
@@ -437,6 +437,7 @@ static void hda_audio_set_amp(HDAAudioStream *st) {bool muted;uint32_t left, right; +double left_db, right_db;if (st->node ==NULL ) {return ;
@@ -446,6 +447,9 @@ static void hda_audio_set_amp(HDAAudioStream *st) left = st->mute_left ?0 : st->gain_left; right = st->mute_right ?0 : st->gain_right; + left_db = ((int64_t )left -QEMU_HDA_AMP_STEPS ) *QEMU_HDA_AMP_DB_OF_STEP ; + right_db = ((int64_t )right -QEMU_HDA_AMP_STEPS ) *QEMU_HDA_AMP_DB_OF_STEP ; + left = left *255 /QEMU_HDA_AMP_STEPS ; right = right *255 /QEMU_HDA_AMP_STEPS ;
@@ -454,10 +458,10 @@ static void hda_audio_set_amp(HDAAudioStream *st) }if (st->output) {AUD_set_volume_out (st->voice.out, muted, left, right, - false,0 ,0 ); + true, left_db, right_db); }else {AUD_set_volume_in (st->voice.in, muted, left, right, - false,0 ,0 ); + true, left_db, right_db); } }
Signature · 1 line
2.18.1
Re: [Qemu-devel] [PATCH 2/3] Pass raw DB values from hda-codec.c to audio driver
Sorry, lost cover letter and first patch, resending them
пт, 21 дек. 2018 г. в 21:57, Yaroslav Isakov <[email protected]>:
Quoted 44 lines
Signed-off-by Yaroslav Isakov <[email protected]>--- hw/audio/hda-codec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)hw/audio/hda-codec.c +6
-3@@ -437,6 +437,7 @@ static void hda_audio_set_amp(HDAAudioStream *st) {bool muted;uint32_t left, right; +double left_db, right_db;if (st->node ==NULL ) {return ;@@ -446,6 +447,9 @@ static void hda_audio_set_amp(HDAAudioStream *st) left = st->mute_left ?0 : st->gain_left; right = st->mute_right ?0 : st->gain_right; + left_db = ((int64_t )left -QEMU_HDA_AMP_STEPS ) *QEMU_HDA_AMP_DB_OF_STEP ; + right_db = ((int64_t )right -QEMU_HDA_AMP_STEPS ) *QEMU_HDA_AMP_DB_OF_STEP ; + left = left *255 /QEMU_HDA_AMP_STEPS ; right = right *255 /QEMU_HDA_AMP_STEPS ;@@ -454,10 +458,10 @@ static void hda_audio_set_amp(HDAAudioStream *st) }if (st->output) {AUD_set_volume_out (st->voice.out, muted, left, right, - false,0 ,0 ); + true, left_db, right_db); }else {AUD_set_volume_in (st->voice.in, muted, left, right, - false,0 ,0 ); + true, left_db, right_db); } } --2.18.1
PATCH 3/3 If raw DB values are known, use them in paaudio
In reply to Yaroslav Isakov--- audio/paaudio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
audio/paaudio.c +7 -2
@@ -724,8 +724,13 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)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 ; +if (sw->vol.db_known) { + v.values[0 ] =pa_sw_volume_from_dB (sw->vol.l_db); + v.values[1 ] =pa_sw_volume_from_dB (sw->vol.r_db); + }else { + 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);
Signature · 1 line
2.18.1
Patchew URL: https://patchew.org/QEMU/[email protected]/
Patchew URL: https://patchew.org/QEMU/[email protected]/
Hi,
This series seems to have some coding style problems. See output below for more information:
Message-id: [email protected]
Type: series
Subject: [Qemu-devel] [PATCH 0/3] Allow hw/audio drivers to pass raw DB values to audio/ drivers
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 Switched to a new branch 'test'
a581faa If raw DB values are known, use them in paaudio de78230 Pass raw DB values from hda-codec.c to audio driver 4bbc16a Allow audio driver to pass DB value to underlying drivers
=== OUTPUT BEGIN ===
Checking PATCH 1/3: Allow audio driver to pass DB value to underlying drivers...
ERROR: space required after that ';' (ctx:VxV)
#95: FILE: audio/mixeng.h:35:
+ bool db_known; double r_db; double l_db;};
^total: 1 errors, 0 warnings, 193 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
Checking PATCH 2/3: Pass raw DB values from hda-codec.c to audio driver... Checking PATCH 3/3: If raw DB values are known, use them in paaudio...
ERROR: line over 90 characters
#23: FILE: audio/paaudio.c:731:
+ v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX;
ERROR: line over 90 characters
#24: FILE: audio/paaudio.c:732:
+ v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX;
total: 2 errors, 0 warnings, 15 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/[email protected]/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to [email protected]