OPTiMC: Fix OPL volume mixing
Windows driver operates the chip in WSS mode so AUX2 volume filtering for OPL playback is required
This commit is contained in:
@@ -66,6 +66,7 @@ extern void ad1848_write(uint16_t addr, uint8_t val, void *priv);
|
||||
extern void ad1848_update(ad1848_t *ad1848);
|
||||
extern void ad1848_speed_changed(ad1848_t *ad1848);
|
||||
extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv);
|
||||
extern void ad1848_filter_aux2(void* priv, double* out_l, double* out_r);
|
||||
|
||||
extern void ad1848_init(ad1848_t *ad1848, uint8_t type);
|
||||
|
||||
|
@@ -147,6 +147,9 @@ typedef struct sb_t {
|
||||
pnp_rom[512];
|
||||
|
||||
uint16_t opl_pnp_addr;
|
||||
|
||||
void *opl_mixer;
|
||||
void (*opl_mix)(void*, double*, double*);
|
||||
} sb_t;
|
||||
|
||||
extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p);
|
||||
|
@@ -599,6 +599,24 @@ ad1848_filter_cd_audio(int channel, double *buffer, void *priv)
|
||||
*buffer = c;
|
||||
}
|
||||
|
||||
void
|
||||
ad1848_filter_aux2(void* priv, double* out_l, double* out_r)
|
||||
{
|
||||
ad1848_t *ad1848 = (ad1848_t *) priv;
|
||||
|
||||
if (ad1848->regs[4] & 0x80) {
|
||||
*out_l = 0.0;
|
||||
} else {
|
||||
*out_l = ((*out_l) * ad1848_vols_5bits_aux_gain[ad1848->regs[4] & 0x1f]) / 65536.0;
|
||||
}
|
||||
|
||||
if (ad1848->regs[5] & 0x80) {
|
||||
*out_r = 0.0;
|
||||
} else {
|
||||
*out_r = ((*out_r) * ad1848_vols_5bits_aux_gain[ad1848->regs[5] & 0x1f]) / 65536.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ad1848_init(ad1848_t *ad1848, uint8_t type)
|
||||
{
|
||||
|
@@ -70,6 +70,16 @@ typedef struct optimc_t {
|
||||
uint8_t regs[6];
|
||||
} optimc_t, opti_82c929_t;
|
||||
|
||||
static void
|
||||
optimc_filter_opl(void* priv, double* out_l, double* out_r)
|
||||
{
|
||||
optimc_t *optimc = (optimc_t *) priv;
|
||||
|
||||
if (optimc->cur_wss_enabled) {
|
||||
ad1848_filter_aux2((void*)&optimc->ad1848, out_l, out_r);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
optimc_wss_read(uint16_t addr, void *priv)
|
||||
{
|
||||
@@ -372,6 +382,9 @@ optimc_init(const device_t *info)
|
||||
sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma);
|
||||
sb_ct1345_mixer_reset(optimc->sb);
|
||||
|
||||
optimc->sb->opl_mixer = optimc;
|
||||
optimc->sb->opl_mix = optimc_filter_opl;
|
||||
|
||||
optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262;
|
||||
fm_driver_get(optimc->fm_type, &optimc->sb->opl);
|
||||
io_sethandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv);
|
||||
|
@@ -290,6 +290,9 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *p)
|
||||
} else {
|
||||
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
|
||||
out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375;
|
||||
if (sb->opl_mix && sb->opl_mixer) {
|
||||
sb->opl_mix(sb->opl_mixer, &out_l, &out_r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user