From 1e98d531f2eef6a331512e89629518c57a832c30 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 20 Nov 2021 22:59:08 -0300 Subject: [PATCH] Fix hijacking of the CD audio filter by VIA AC97 --- src/chipset/via_pipc.c | 3 +++ src/sound/snd_ac97_via.c | 15 ++++++++++----- src/sound/snd_cs423x.c | 4 ++-- src/sound/snd_sb.c | 1 - 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 3829e337c..a2f3dc774 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -824,6 +824,9 @@ pipc_sb_handlers(pipc_t *dev, uint8_t modem) sb_dsp_setirq(&dev->sb->dsp, (irq == 11) ? 10 : irq); sb_dsp_setdma8(&dev->sb->dsp, (dev->ac97_regs[0][0x43] >> 4) & 0x03); + + /* Set up CD audio filter. This might not actually work if VIAUDIO writes to CD volume through AC97. */ + sound_set_cd_audio_filter(sbpro_filter_cd_audio, dev->sb); } if (dev->ac97_regs[0][0x42] & 0x02) { diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index de12edf75..aea9d6ee0 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -87,6 +87,7 @@ ac97_via_log(const char *fmt, ...) static void ac97_via_sgd_process(void *priv); static void ac97_via_update_codec(ac97_via_t *dev); static void ac97_via_speed_changed(void *priv); +static void ac97_via_filter_cd_audio(int channel, double *buffer, void *priv); void @@ -390,8 +391,15 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) *((uint16_t *) &dev->codec_shadow[modem].regs_codec[i][val & 0x7f]) = *((uint16_t *) &dev->sgd_regs[0x80])); /* Update primary audio codec state if that codec was written to. */ - if (!modem && !i) + if (!modem && !i) { ac97_via_update_codec(dev); + + /* Set up CD audio filter if CD volume was written to. Setting it + up at init prevents CD audio from working on other cards, but + this works as the CD channel is muted by default per AC97 spec. */ + if (val == 0x12) + sound_set_cd_audio_filter(ac97_via_filter_cd_audio, dev); + } } } @@ -741,7 +749,7 @@ ac97_via_get_buffer(int32_t *buffer, int len, void *priv) static void -via_ac97_filter_cd_audio(int channel, double *buffer, void *priv) +ac97_via_filter_cd_audio(int channel, double *buffer, void *priv) { ac97_via_t *dev = (ac97_via_t *) priv; double c, volume = channel ? dev->cd_vol_r : dev->cd_vol_l; @@ -806,9 +814,6 @@ ac97_via_init(const device_t *info) /* Set up playback handler. */ sound_add_handler(ac97_via_get_buffer, dev); - /* Set up CD audio filter. */ - sound_set_cd_audio_filter(via_ac97_filter_cd_audio, dev); - return dev; } diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index f3d95828d..c5b349c9e 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -779,9 +779,9 @@ cs423x_init(const device_t *info) /* Initialize ISAPnP. */ dev->pnp_card = isapnp_add_card(NULL, 0, cs423x_pnp_config_changed, NULL, NULL, NULL, dev); - /* Initialize SBPro codec first to get the correct CD audio filter for the default - context, which is SBPro. The WSS codec is initialized later by cs423x_reset */ + /* Initialize SBPro codec. The WSS codec is initialized later by cs423x_reset */ dev->sb = device_add(&sb_pro_compat_device); + sound_set_cd_audio_filter(sbpro_filter_cd_audio, dev->sb); /* CD audio filter for the default context */ /* Initialize RAM, registers and WSS codec. */ cs423x_reset(dev); diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index f52e78c6c..ef0fa626d 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1615,7 +1615,6 @@ sb_pro_compat_init(const device_t *info) sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sbpro, sb); - sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t));