diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-04-18 10:05:58 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-04-18 10:06:09 -0500 |
commit | 51006bbc45bc74977ae538190a53df2af534acb9 (patch) | |
tree | 6fd11943a51b242e657e50d51651833090c201c2 /hw | |
parent | 25b9e14e78bf9790cdee12d57c45898e86866a24 (diff) | |
parent | 6e7a7f3d9bc2031b4c93c05400b18775ba1b1f55 (diff) | |
download | qemu-51006bbc45bc74977ae538190a53df2af534acb9.tar.gz qemu-51006bbc45bc74977ae538190a53df2af534acb9.tar.bz2 qemu-51006bbc45bc74977ae538190a53df2af534acb9.zip |
Merge remote-tracking branch 'origin/master' into staging
* origin/master:
Allow controlling volume with PulseAudio backend
configure: pa_simple is not needed anymore
Do not use pa_simple PulseAudio API
audio/spice: add support for volume control
hw/ac97: add support for volume control
hw/ac97: the volume mask is not only 0x1f
hw/ac97: remove USE_MIXER code
audio: don't apply volume effect if backend has VOICE_VOLUME_CAP
audio: add VOICE_VOLUME ctl
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ac97.c | 139 |
1 files changed, 49 insertions, 90 deletions
@@ -118,7 +118,6 @@ enum { #define EACS_VRA 1 #define EACS_VRM 8 -#define VOL_MASK 0x1f #define MUTE_SHIFT 15 #define REC_MASK 7 @@ -437,83 +436,55 @@ static void reset_voices (AC97LinkState *s, uint8_t active[LAST_INDEX]) AUD_set_active_in (s->voice_mc, active[MC_INDEX]); } -#ifdef USE_MIXER -static void set_volume (AC97LinkState *s, int index, - audmixerctl_t mt, uint32_t val) +static void get_volume (uint16_t vol, uint16_t mask, int inverse, + int *mute, uint8_t *lvol, uint8_t *rvol) { - int mute = (val >> MUTE_SHIFT) & 1; - uint8_t rvol = VOL_MASK - (val & VOL_MASK); - uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK); - rvol = 255 * rvol / VOL_MASK; - lvol = 255 * lvol / VOL_MASK; - -#ifdef SOFT_VOLUME - if (index == AC97_Master_Volume_Mute) { - AUD_set_volume_out (s->voice_po, mute, lvol, rvol); - } - else { - AUD_set_volume (mt, &mute, &lvol, &rvol); - } -#else - AUD_set_volume (mt, &mute, &lvol, &rvol); -#endif + *mute = (vol >> MUTE_SHIFT) & 1; + *rvol = (255 * (vol & mask)) / mask; + *lvol = (255 * ((vol >> 8) & mask)) / mask; - rvol = VOL_MASK - ((VOL_MASK * rvol) / 255); - lvol = VOL_MASK - ((VOL_MASK * lvol) / 255); - mixer_store (s, index, val); + if (inverse) { + *rvol = 255 - *rvol; + *lvol = 255 - *lvol; + } } -static audrecsource_t ac97_to_aud_record_source (uint8_t i) +static void update_combined_volume_out (AC97LinkState *s) { - switch (i) { - case REC_MIC: - return AUD_REC_MIC; - - case REC_CD: - return AUD_REC_CD; + uint8_t lvol, rvol, plvol, prvol; + int mute, pmute; - case REC_VIDEO: - return AUD_REC_VIDEO; + get_volume (mixer_load (s, AC97_Master_Volume_Mute), 0x3f, 1, + &mute, &lvol, &rvol); + /* FIXME: should be 1f according to spec */ + get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x3f, 1, + &pmute, &plvol, &prvol); - case REC_AUX: - return AUD_REC_AUX; + mute = mute | pmute; + lvol = (lvol * plvol) / 255; + rvol = (rvol * prvol) / 255; - case REC_LINE_IN: - return AUD_REC_LINE_IN; - - case REC_PHONE: - return AUD_REC_PHONE; - - default: - dolog ("Unknown record source %d, using MIC\n", i); - return AUD_REC_MIC; - } + AUD_set_volume_out (s->voice_po, mute, lvol, rvol); } -static uint8_t aud_to_ac97_record_source (audrecsource_t rs) +static void update_volume_in (AC97LinkState *s) { - switch (rs) { - case AUD_REC_MIC: - return REC_MIC; - - case AUD_REC_CD: - return REC_CD; - - case AUD_REC_VIDEO: - return REC_VIDEO; - - case AUD_REC_AUX: - return REC_AUX; + uint8_t lvol, rvol; + int mute; - case AUD_REC_LINE_IN: - return REC_LINE_IN; + get_volume (mixer_load (s, AC97_Record_Gain_Mute), 0x0f, 0, + &mute, &lvol, &rvol); - case AUD_REC_PHONE: - return REC_PHONE; + AUD_set_volume_in (s->voice_pi, mute, lvol, rvol); +} - default: - dolog ("Unknown audio recording source %d using MIC\n", rs); - return REC_MIC; +static void set_volume (AC97LinkState *s, int index, uint32_t val) +{ + mixer_store (s, index, val); + if (index == AC97_Master_Volume_Mute || index == AC97_PCM_Out_Volume_Mute) { + update_combined_volume_out (s); + } else if (index == AC97_Record_Gain_Mute) { + update_volume_in (s); } } @@ -521,14 +492,8 @@ static void record_select (AC97LinkState *s, uint32_t val) { uint8_t rs = val & REC_MASK; uint8_t ls = (val >> 8) & REC_MASK; - audrecsource_t ars = ac97_to_aud_record_source (rs); - audrecsource_t als = ac97_to_aud_record_source (ls); - AUD_set_record_source (&als, &ars); - rs = aud_to_ac97_record_source (ars); - ls = aud_to_ac97_record_source (als); mixer_store (s, AC97_Record_Select, rs | (ls << 8)); } -#endif static void mixer_reset (AC97LinkState *s) { @@ -564,12 +529,11 @@ static void mixer_reset (AC97LinkState *s) mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80); mixer_store (s, AC97_MIC_ADC_Rate , 0xbb80); -#ifdef USE_MIXER record_select (s, 0); - set_volume (s, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME , 0x8000); - set_volume (s, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM , 0x8808); - set_volume (s, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808); -#endif + set_volume (s, AC97_Master_Volume_Mute, 0x8000); + set_volume (s, AC97_PCM_Out_Volume_Mute, 0x8808); + set_volume (s, AC97_Line_In_Volume_Mute, 0x8808); + reset_voices (s, active); } @@ -628,20 +592,15 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val) val |= mixer_load (s, index) & 0xf; mixer_store (s, index, val); break; -#ifdef USE_MIXER - case AC97_Master_Volume_Mute: - set_volume (s, index, AUD_MIXER_VOLUME, val); - break; case AC97_PCM_Out_Volume_Mute: - set_volume (s, index, AUD_MIXER_PCM, val); - break; + case AC97_Master_Volume_Mute: + case AC97_Record_Gain_Mute: case AC97_Line_In_Volume_Mute: - set_volume (s, index, AUD_MIXER_LINE_IN, val); + set_volume (s, index, val); break; case AC97_Record_Select: record_select (s, val); break; -#endif case AC97_Vendor_ID1: case AC97_Vendor_ID2: dolog ("Attempt to write vendor ID to %#x\n", val); @@ -1194,14 +1153,14 @@ static int ac97_post_load (void *opaque, int version_id) uint8_t active[LAST_INDEX]; AC97LinkState *s = opaque; -#ifdef USE_MIXER record_select (s, mixer_load (s, AC97_Record_Select)); -#define V_(a, b) set_volume (s, a, b, mixer_load (s, a)) - V_ (AC97_Master_Volume_Mute, AUD_MIXER_VOLUME); - V_ (AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM); - V_ (AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN); -#undef V_ -#endif + set_volume (s, AC97_Master_Volume_Mute, + mixer_load (s, AC97_Master_Volume_Mute)); + set_volume (s, AC97_PCM_Out_Volume_Mute, + mixer_load (s, AC97_PCM_Out_Volume_Mute)); + set_volume (s, AC97_Line_In_Volume_Mute, + mixer_load (s, AC97_Line_In_Volume_Mute)); + active[PI_INDEX] = !!(s->bm_regs[PI_INDEX].cr & CR_RPBM); active[PO_INDEX] = !!(s->bm_regs[PO_INDEX].cr & CR_RPBM); active[MC_INDEX] = !!(s->bm_regs[MC_INDEX].cr & CR_RPBM); |