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
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
Sorry for a mess, forgot to add maintainer. Gerd, please, take a look at these patches.
пт, 21 дек. 2018 г. в 22:40, Yaroslav Isakov <[email protected]>:
Quoted 31 lines
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 fromhda-codec.cto audio driver If raw DB values are known, use them in paaudioaudio/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(-)--
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'
8eb6105 If raw DB values are known, use them in paaudio 5d986ae Pass raw DB values from hda-codec.c to audio driver 80db359 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]
Quoted 8 lines · Yaroslav Isakov
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.
It's more useful to add support for converting db values to linear values, so it'll work properly with all backends not only pulse.
cheers,
Gerd