Moved OPL2 and OPL3 to a new 49716 Hz source so resampling is no longer needed, also fixed SB OPL and PC Speaker filtering (OPL was being downsampled to the selected DSP sample rate, which is incorrect, and the PC Speaker filter was using the wrong filter index in some liens).

This commit is contained in:
OBattler
2024-03-01 06:52:48 +01:00
parent 71ecdc1b55
commit e0d80aefb4
18 changed files with 683 additions and 193 deletions

View File

@@ -185,10 +185,6 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv)
double out_mono = 0.0;
double out_l = 0.0;
double out_r = 0.0;
const int32_t *opl_buf = NULL;
if (sb->opl_enabled)
opl_buf = sb->opl.update(sb->opl.priv);
sb_dsp_update(&sb->dsp);
@@ -200,17 +196,12 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv)
out_l = 0.0;
out_r = 0.0;
if (sb->opl_enabled)
out_mono = ((double) opl_buf[c]) * 0.7171630859375;
if (sb->cms_enabled) {
out_l += sb->cms.buffer[c];
out_r += sb->cms.buffer[c + 1];
}
out_l += out_mono;
out_r += out_mono;
if (((sb->opl_enabled) || (sb->cms_enabled)) && sb->mixer_enabled) {
if (sb->cms_enabled && sb->mixer_enabled) {
out_l *= mixer->fm;
out_r *= mixer->fm;
}
@@ -234,17 +225,55 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv)
buffer[c + 1] += (int32_t) out_r;
}
sb->pos = 0;
if (sb->opl_enabled)
sb->opl.reset_buffer(sb->opl.priv);
sb->dsp.pos = 0;
if (sb->cms_enabled)
sb->cms.pos = 0;
}
static void
sb_get_music_buffer_sb2(int32_t *buffer, int len, void *priv)
{
sb_t *sb = (sb_t *) priv;
const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2;
double out_mono = 0.0;
double out_l = 0.0;
double out_r = 0.0;
const int32_t *opl_buf = NULL;
if (!sb->opl_enabled)
return;
opl_buf = sb->opl.update(sb->opl.priv);
for (int c = 0; c < len * 2; c += 2) {
out_mono = 0.0;
out_l = 0.0;
out_r = 0.0;
if (sb->opl_enabled)
out_mono = ((double) opl_buf[c]) * 0.7171630859375;
out_l += out_mono;
out_r += out_mono;
if (sb->mixer_enabled) {
out_l *= mixer->fm;
out_r *= mixer->fm;
}
if (sb->mixer_enabled) {
out_l *= mixer->master;
out_r *= mixer->master;
}
buffer[c] += (int32_t) out_l;
buffer[c + 1] += (int32_t) out_r;
}
sb->opl.reset_buffer(sb->opl.priv);
}
static void
sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv)
{
@@ -253,10 +282,10 @@ sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv)
double c;
if (sb->mixer_enabled) {
c = ((sb_iir(1, 0, *buffer) / 1.3) * mixer->cd) / 3.0;
c = ((sb_iir(2, 0, *buffer) / 1.3) * mixer->cd) / 3.0;
*buffer = c * mixer->master;
} else {
c = (((sb_iir(1, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0;
c = (((sb_iir(2, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0;
*buffer = c;
}
}
@@ -268,16 +297,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv)
const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro;
double out_l = 0.0;
double out_r = 0.0;
const int32_t *opl_buf = NULL;
const int32_t *opl2_buf = NULL;
if (sb->opl_enabled) {
if (sb->dsp.sb_type == SBPRO) {
opl_buf = sb->opl.update(sb->opl.priv);
opl2_buf = sb->opl2.update(sb->opl2.priv);
} else
opl_buf = sb->opl.update(sb->opl.priv);
}
sb_dsp_update(&sb->dsp);
@@ -285,21 +304,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv)
out_l = 0.0;
out_r = 0.0;
if (sb->opl_enabled) {
if (sb->dsp.sb_type == SBPRO) {
/* Two chips for LEFT and RIGHT channels.
Each chip stores data into the LEFT channel only (no sample alternating.) */
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375;
} 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);
}
}
}
/* TODO: Implement the stereo switch on the mixer instead of on the dsp? */
if (mixer->output_filter) {
out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9;
@@ -317,15 +321,57 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv)
buffer[c + 1] += (int32_t) out_r;
}
sb->pos = 0;
sb->dsp.pos = 0;
}
if (sb->opl_enabled) {
sb->opl.reset_buffer(sb->opl.priv);
if (sb->dsp.sb_type == SBPRO)
sb->opl2.reset_buffer(sb->opl2.priv);
void
sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
{
sb_t *sb = (sb_t *) priv;
const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro;
double out_l = 0.0;
double out_r = 0.0;
const int32_t *opl_buf = NULL;
const int32_t *opl2_buf = NULL;
if (!sb->opl_enabled)
return;
if (sb->dsp.sb_type == SBPRO) {
opl_buf = sb->opl.update(sb->opl.priv);
opl2_buf = sb->opl2.update(sb->opl2.priv);
} else
opl_buf = sb->opl.update(sb->opl.priv);
sb_dsp_update(&sb->dsp);
for (int c = 0; c < len * 2; c += 2) {
out_l = 0.0;
out_r = 0.0;
if (sb->dsp.sb_type == SBPRO) {
/* Two chips for LEFT and RIGHT channels.
Each chip stores data into the LEFT channel only (no sample alternating.) */
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375;
} 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);
}
/* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */
out_l *= mixer->master_l;
out_r *= mixer->master_r;
buffer[c] += (int32_t) out_l;
buffer[c + 1] += (int32_t) out_r;
}
sb->dsp.pos = 0;
sb->opl.reset_buffer(sb->opl.priv);
if (sb->dsp.sb_type == SBPRO)
sb->opl2.reset_buffer(sb->opl2.priv);
}
void
@@ -338,7 +384,7 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv)
double master = channel ? mixer->master_r : mixer->master_l;
if (mixer->output_filter)
c = (sb_iir(1, channel, *buffer) * cd) / 3.9;
c = (sb_iir(2, channel, *buffer) * cd) / 3.9;
else
c = (*buffer * cd) / 3.0;
*buffer = c * master;
@@ -349,21 +395,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
{
sb_t *sb = (sb_t *) priv;
const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
int dsp_rec_pos = sb->dsp.record_pos_write;
int c_emu8k = 0;
int c_record;
int32_t in_l;
int32_t in_r;
double out_l = 0.0;
double out_r = 0.0;
double bass_treble;
const int32_t *opl_buf = NULL;
if (sb->opl_enabled)
opl_buf = sb->opl.update(sb->opl.priv);
if (sb->dsp.sb_type > SB16)
emu8k_update(&sb->emu8k);
sb_dsp_update(&sb->dsp);
@@ -371,25 +405,6 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
out_l = 0.0;
out_r = 0.0;
if (sb->dsp.sb_type > SB16)
c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2);
if (sb->opl_enabled) {
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->dsp.sb_type > SB16) {
out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l);
out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r);
}
/* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */
in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r)
: 0;
in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r)
: 0;
if (mixer->output_filter) {
/* We divide by 3 to get the volume down to normal. */
out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0;
@@ -440,8 +455,100 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
out_r = (out_l *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble));
}
buffer[c] += (int32_t) (out_l * mixer->output_gain_L);
buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R);
}
sb->dsp.pos = 0;
}
static void
sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
{
sb_t *sb = (sb_t *) priv;
const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
int dsp_rec_pos = sb->dsp.record_pos_write;
int c_emu8k = 0;
int c_record;
int32_t in_l;
int32_t in_r;
double out_l = 0.0;
double out_r = 0.0;
double bass_treble;
const int32_t *opl_buf = NULL;
if (sb->opl_enabled)
opl_buf = sb->opl.update(sb->opl.priv);
if (sb->dsp.sb_type > SB16)
emu8k_update(&sb->emu8k);
for (int c = 0; c < len * 2; c += 2) {
out_l = 0.0;
out_r = 0.0;
if (sb->dsp.sb_type > SB16)
c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2);
if (sb->opl_enabled) {
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->dsp.sb_type > SB16) {
out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l);
out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r);
}
/* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */
in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r)
: 0;
in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r)
: 0;
out_l *= mixer->master_l;
out_r *= mixer->master_r;
/* This is not exactly how one does bass/treble controls, but the end result is like it.
A better implementation would reduce the CPU usage. */
if (mixer->bass_l != 8) {
bass_treble = sb_bass_treble_4bits[mixer->bass_l];
if (mixer->bass_l > 8)
out_l += (low_iir(1, 0, out_l) * bass_treble);
else if (mixer->bass_l < 8)
out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble));
}
if (mixer->bass_r != 8) {
bass_treble = sb_bass_treble_4bits[mixer->bass_r];
if (mixer->bass_r > 8)
out_r += (low_iir(1, 1, out_r) * bass_treble);
else if (mixer->bass_r < 8)
out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble));
}
if (mixer->treble_l != 8) {
bass_treble = sb_bass_treble_4bits[mixer->treble_l];
if (mixer->treble_l > 8)
out_l += (high_iir(1, 0, out_l) * bass_treble);
else if (mixer->treble_l < 8)
out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble));
}
if (mixer->treble_r != 8) {
bass_treble = sb_bass_treble_4bits[mixer->treble_r];
if (mixer->treble_r > 8)
out_r += (high_iir(1, 1, out_r) * bass_treble);
else if (mixer->treble_r < 8)
out_r = (out_l *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble));
}
if (sb->dsp.sb_enable_i) {
c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / SOUND_FREQ);
c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ);
in_l <<= mixer->input_gain_L;
in_r <<= mixer->input_gain_R;
@@ -467,13 +574,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
sb->dsp.record_pos_write += ((len * sb->dsp.sb_freq) / 24000);
sb->dsp.record_pos_write &= 0xffff;
sb->pos = 0;
if (sb->opl_enabled)
sb->opl.reset_buffer(sb->opl.priv);
sb->dsp.pos = 0;
if (sb->dsp.sb_type > SB16)
sb->emu8k.pos = 0;
}
@@ -492,7 +595,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv)
double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L);
if (mixer->output_filter)
c = (low_fir_sb16(1, channel, *buffer) * cd) / 3.0;
c = (low_fir_sb16(2, channel, *buffer) * cd) / 3.0;
else
c = ((*buffer) * cd) / 3.0;
c *= master;
@@ -503,18 +606,18 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv)
bass_treble = sb_bass_treble_4bits[bass];
if (bass > 8)
c += (low_iir(1, channel, c) * bass_treble);
c += (low_iir(2, channel, c) * bass_treble);
else if (bass < 8)
c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble));
c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble));
}
if (treble != 8) {
bass_treble = sb_bass_treble_4bits[treble];
if (treble > 8)
c += (high_iir(1, channel, c) * bass_treble);
c += (high_iir(2, channel, c) * bass_treble);
else if (treble < 8)
c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble));
c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble));
}
*buffer = c * output_gain;
@@ -534,7 +637,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv)
double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L);
if (mixer->output_filter)
c = (low_fir_sb16(2, channel, *buffer) * spk) / 3.0;
c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0;
else
c = ((*buffer) * spk) / 3.0;
c *= master;
@@ -545,18 +648,18 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv)
bass_treble = sb_bass_treble_4bits[bass];
if (bass > 8)
c += (low_iir(2, channel, c) * bass_treble);
c += (low_iir(3, channel, c) * bass_treble);
else if (bass < 8)
c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble));
c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble));
}
if (treble != 8) {
bass_treble = sb_bass_treble_4bits[treble];
if (treble > 8)
c += (high_iir(2, channel, c) * bass_treble);
c += (high_iir(3, channel, c) * bass_treble);
else if (treble < 8)
c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble));
c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble));
}
*buffer = c * output_gain;
@@ -1706,6 +1809,7 @@ sb_1_init(UNUSED(const device_t *info))
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -1731,6 +1835,8 @@ sb_1_init(UNUSED(const device_t *info))
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
if (device_get_config_int("receive_input"))
@@ -1754,6 +1860,7 @@ sb_15_init(UNUSED(const device_t *info))
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -1781,6 +1888,8 @@ sb_15_init(UNUSED(const device_t *info))
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
if (device_get_config_int("receive_input"))
@@ -1802,6 +1911,7 @@ sb_mcv_init(UNUSED(const device_t *info))
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, 0);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -1809,6 +1919,8 @@ sb_mcv_init(UNUSED(const device_t *info))
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
/* I/O handlers activated in sb_mcv_write */
@@ -1847,6 +1959,7 @@ sb_2_init(UNUSED(const device_t *info))
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -1890,6 +2003,8 @@ sb_2_init(UNUSED(const device_t *info))
} else
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
if (device_get_config_int("receive_input"))
@@ -1939,6 +2054,7 @@ sb_pro_v1_init(UNUSED(const device_t *info))
sb->opl2.set_do_cycles(sb->opl2.priv, 0);
}
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -1970,6 +2086,8 @@ sb_pro_v1_init(UNUSED(const device_t *info))
sb_ct1345_mixer_write, NULL, NULL,
sb);
sound_add_handler(sb_get_buffer_sbpro, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sbpro, sb);
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
if (device_get_config_int("receive_input"))
@@ -1995,6 +2113,7 @@ sb_pro_v2_init(UNUSED(const device_t *info))
if (sb->opl_enabled)
fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -2022,6 +2141,8 @@ sb_pro_v2_init(UNUSED(const device_t *info))
sb_ct1345_mixer_write, NULL, NULL,
sb);
sound_add_handler(sb_get_buffer_sbpro, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sbpro, sb);
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
if (device_get_config_int("receive_input"))
@@ -2044,11 +2165,14 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
sb->opl_enabled = 1;
fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
sb_ct1345_mixer_reset(sb);
sb->mixer_enabled = 1;
sound_add_handler(sb_get_buffer_sbpro, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sbpro, sb);
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
/* I/O handlers activated in sb_pro_mcv_write */
@@ -2070,11 +2194,14 @@ sb_pro_compat_init(UNUSED(const device_t *info))
fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
sb_ct1345_mixer_reset(sb);
sb->mixer_enabled = 1;
sound_add_handler(sb_get_buffer_sbpro, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sbpro, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
@@ -2097,6 +2224,7 @@ sb_16_init(UNUSED(const device_t *info))
if (sb->opl_enabled)
fm_driver_get(info->local, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, (info->local != FM_YMF289B));
sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -2126,6 +2254,12 @@ sb_16_init(UNUSED(const device_t *info))
io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
sb_ct1745_mixer_write, NULL, NULL, sb);
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
if (sb->opl_enabled) {
if (info->local == FM_YMF289B)
sound_add_handler(sb_get_music_buffer_sb16_awe32, sb);
else
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
}
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
@@ -2157,6 +2291,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info))
sb->opl_enabled = 1;
fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setdma16_supported(&sb->dsp, 1);
sb_dsp_setdma16_enabled(&sb->dsp, 1);
@@ -2165,6 +2300,8 @@ sb_16_reply_mca_init(UNUSED(const device_t *info))
sb->mixer_enabled = 1;
sb->mixer_sb16.output_filter = 1;
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
@@ -2207,6 +2344,8 @@ sb_16_pnp_init(UNUSED(const device_t *info))
sb->mixer_enabled = 1;
sb->mixer_sb16.output_filter = 1;
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
@@ -2225,6 +2364,7 @@ sb_16_pnp_init(UNUSED(const device_t *info))
isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_setaddr(&sb->dsp, 0);
sb_dsp_setirq(&sb->dsp, 0);
sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED);
@@ -2262,6 +2402,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
sb->opl_enabled = 1;
fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb);
/* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */
sb_dsp_setdma16_supported(&sb->dsp, info->local != 0);
@@ -2270,6 +2411,8 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
sb->mixer_enabled = 1;
sb->mixer_sb16.output_filter = 1;
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
@@ -2340,6 +2483,7 @@ sb_16_compat_init(const device_t *info)
fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setdma16_supported(&sb->dsp, 1);
sb_dsp_setdma16_enabled(&sb->dsp, 1);
@@ -2347,6 +2491,8 @@ sb_16_compat_init(const device_t *info)
sb->mixer_enabled = 1;
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
@@ -2411,6 +2557,7 @@ sb_awe32_init(UNUSED(const device_t *info))
if (sb->opl_enabled)
fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
@@ -2440,6 +2587,8 @@ sb_awe32_init(UNUSED(const device_t *info))
io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
sb_ct1745_mixer_write, NULL, NULL, sb);
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
@@ -2482,9 +2631,12 @@ sb_awe32_pnp_init(const device_t *info)
sb_dsp_setdma16_supported(&sb->dsp, 1);
sb_ct1745_mixer_reset(sb);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb->mixer_enabled = 1;
sb->mixer_sb16.output_filter = 1;
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);