From 6ca6afedd55c4df7c4963c32393e3a3ac2eaab35 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Sep 2025 00:44:01 +0200 Subject: [PATCH] AdLib Gold: Everything now outputs to the same 48k source in order to avoid noise caused by the YM7128's resampling which is currently tailored to that frequency. --- src/include/86box/filters.h | 142 +++++++++++++------------- src/include/86box/snd_opl.h | 5 + src/include/86box/snd_opl_nuked.h | 4 +- src/include/86box/snd_ym7128.h | 12 +-- src/sound/snd_adlibgold.c | 160 ++++++------------------------ src/sound/snd_opl.c | 70 +++++++------ src/sound/snd_opl_nuked.c | 108 ++++++++++++++------ src/sound/snd_opl_ymfm.cpp | 87 ++++++++-------- src/sound/snd_ym7128.c | 24 ++--- 9 files changed, 291 insertions(+), 321 deletions(-) diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index 3e20fa653..572137ef0 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -5,7 +5,7 @@ /* fc=150Hz */ static inline float -adgold_highpass_iir(int c, int i, float NewSample) +adgold_highpass_iir(int i, float NewSample) { float ACoef[NCoef + 1] = { 0.98657437157334349000, @@ -19,76 +19,6 @@ adgold_highpass_iir(int c, int i, float NewSample) 0.97261396931534050000 }; - static float y[2][2][NCoef + 1]; /* output samples */ - static float x[2][2][NCoef + 1]; /* input samples */ - int n; - - /* shift the old samples */ - for (n = NCoef; n > 0; n--) { - x[c][i][n] = x[c][i][n - 1]; - y[c][i][n] = y[c][i][n - 1]; - } - - /* Calculate the new output */ - x[c][i][0] = NewSample; - y[c][i][0] = ACoef[0] * x[c][i][0]; - for (n = 1; n <= NCoef; n++) - y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n]; - - return y[c][i][0]; -} - -/* fc=150Hz */ -static inline float -adgold_lowpass_iir(int c, int i, float NewSample) -{ - float ACoef[NCoef + 1] = { - 0.00009159473951071446, - 0.00018318947902142891, - 0.00009159473951071446 - }; - - float BCoef[NCoef + 1] = { - 1.00000000000000000000, - -1.97223372919526560000, - 0.97261396931306277000 - }; - - static float y[2][2][NCoef + 1]; /* output samples */ - static float x[2][2][NCoef + 1]; /* input samples */ - int n; - - /* shift the old samples */ - for (n = NCoef; n > 0; n--) { - x[c][i][n] = x[c][i][n - 1]; - y[c][i][n] = y[c][i][n - 1]; - } - - /* Calculate the new output */ - x[c][i][0] = NewSample; - y[c][i][0] = ACoef[0] * x[c][i][0]; - for (n = 1; n <= NCoef; n++) - y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n]; - - return y[c][i][0]; -} - -/* fc=56Hz */ -static inline float -adgold_pseudo_stereo_iir(int i, float NewSample) -{ - float ACoef[NCoef + 1] = { - 0.00001409030866231767, - 0.00002818061732463533, - 0.00001409030866231767 - }; - - float BCoef[NCoef + 1] = { - 1.00000000000000000000, - -1.98733021473466760000, - 0.98738361004063568000 - }; - static float y[2][NCoef + 1]; /* output samples */ static float x[2][NCoef + 1]; /* input samples */ int n; @@ -108,6 +38,76 @@ adgold_pseudo_stereo_iir(int i, float NewSample) return y[i][0]; } +/* fc=150Hz */ +static inline float +adgold_lowpass_iir(int i, float NewSample) +{ + float ACoef[NCoef + 1] = { + 0.00009159473951071446, + 0.00018318947902142891, + 0.00009159473951071446 + }; + + float BCoef[NCoef + 1] = { + 1.00000000000000000000, + -1.97223372919526560000, + 0.97261396931306277000 + }; + + static float y[2][NCoef + 1]; /* output samples */ + static float x[2][NCoef + 1]; /* input samples */ + int n; + + /* shift the old samples */ + for (n = NCoef; n > 0; n--) { + x[i][n] = x[i][n - 1]; + y[i][n] = y[i][n - 1]; + } + + /* Calculate the new output */ + x[i][0] = NewSample; + y[i][0] = ACoef[0] * x[i][0]; + for (n = 1; n <= NCoef; n++) + y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; + + return y[i][0]; +} + +/* fc=56Hz */ +static inline float +adgold_pseudo_stereo_iir(float NewSample) +{ + float ACoef[NCoef + 1] = { + 0.00001409030866231767, + 0.00002818061732463533, + 0.00001409030866231767 + }; + + float BCoef[NCoef + 1] = { + 1.00000000000000000000, + -1.98733021473466760000, + 0.98738361004063568000 + }; + + static float y[NCoef + 1]; /* output samples */ + static float x[NCoef + 1]; /* input samples */ + int n; + + /* shift the old samples */ + for (n = NCoef; n > 0; n--) { + x[n] = x[n - 1]; + y[n] = y[n - 1]; + } + + /* Calculate the new output */ + x[0] = NewSample; + y[0] = ACoef[0] * x[0]; + for (n = 1; n <= NCoef; n++) + y[0] += ACoef[n] * x[n] - BCoef[n] * y[n]; + + return y[0]; +} + /* fc=3.2kHz - probably incorrect */ static inline float dss_iir(float NewSample) diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 62c62e965..fbc66a1c2 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -49,6 +49,9 @@ enum fm_type { FM_MAX = 26 }; +#define FM_TYPE_MASK 255 +#define FM_FORCE_48K 256 + enum fm_driver { FM_DRV_NUKED = 0, FM_DRV_YMFM = 1, @@ -65,9 +68,11 @@ typedef struct fm_drv_t { void (*generate)(void *priv, int32_t *data, uint32_t num_samples); /* daughterboard only. */ } fm_drv_t; +extern uint8_t fm_driver_get_ex(int chip_id, fm_drv_t *drv, int is_48k); extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv); extern const fm_drv_t nuked_opl_drv; +extern const fm_drv_t nuked_opl_drv_48k; extern const fm_drv_t ymfm_drv; extern const fm_drv_t esfmu_opl_drv; extern const fm_drv_t ymfm_opl2board_drv; diff --git a/src/include/86box/snd_opl_nuked.h b/src/include/86box/snd_opl_nuked.h index 0b203fe31..9fdbe16c4 100644 --- a/src/include/86box/snd_opl_nuked.h +++ b/src/include/86box/snd_opl_nuked.h @@ -147,7 +147,7 @@ struct _opl3_chip { typedef struct { opl3_chip opl; int8_t flags; - int8_t pad; + int8_t is_48k; uint16_t port; uint8_t status; @@ -159,6 +159,8 @@ typedef struct { int pos; int32_t buffer[MUSICBUFLEN * 2]; + + int32_t *(*update)(void *priv); } nuked_drv_t; enum { diff --git a/src/include/86box/snd_ym7128.h b/src/include/86box/snd_ym7128.h index f0657425f..a0796b1fa 100644 --- a/src/include/86box/snd_ym7128.h +++ b/src/include/86box/snd_ym7128.h @@ -19,18 +19,18 @@ typedef struct ym7128_t { int c1; int t[9]; - int16_t filter_dat[2]; - int16_t prev_l[2]; - int16_t prev_r[2]; + int16_t filter_dat; + int16_t prev_l; + int16_t prev_r; - int16_t delay_buffer[2][2400]; - int delay_pos[2]; + int16_t delay_buffer[2400]; + int delay_pos; int16_t last_samp; } ym7128_t; void ym7128_init(ym7128_t *ym7128); void ym7128_write(ym7128_t *ym7128, uint8_t val); -void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len); +void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len); #endif /*SOUND_YM7128_H*/ diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index f8c89c554..87243e8d9 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -82,8 +82,6 @@ typedef struct adgold_t { int treble; int bass; - int16_t samp_buffer[SOUNDBUFLEN * 2]; - int16_t opl_buffer[MUSICBUFLEN * 2]; int16_t mma_buffer[2][SOUNDBUFLEN]; int pos; @@ -779,30 +777,37 @@ static void adgold_get_buffer(int32_t *buffer, int len, void *priv) { adgold_t *adgold = (adgold_t *) priv; + int16_t *adgold_buffer = malloc(sizeof(int16_t) * len * 2); + if (adgold_buffer == NULL) + fatal("adgold_buffer = NULL"); + int c; + int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); adgold_update(adgold); for (c = 0; c < len * 2; c += 2) { - adgold->samp_buffer[c] = ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; - adgold->samp_buffer[c + 1] = ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; + adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2; + adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; + adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2; + adgold_buffer[c + 1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; } if (adgold->surround_enabled) - ym7128_apply(&adgold->ym7128, adgold->samp_buffer, 0, len); + ym7128_apply(&adgold->ym7128, adgold_buffer, len); switch (adgold->adgold_38x_regs[0x8] & 6) { case 0: for (c = 0; c < len * 2; c++) - adgold->samp_buffer[c] = 0; + adgold_buffer[c] = 0; break; case 2: /*Left channel only*/ for (c = 0; c < len * 2; c += 2) - adgold->samp_buffer[c + 1] = adgold->samp_buffer[c]; + adgold_buffer[c + 1] = adgold_buffer[c]; break; case 4: /*Right channel only*/ for (c = 0; c < len * 2; c += 2) - adgold->samp_buffer[c] = adgold->samp_buffer[c + 1]; + adgold_buffer[c] = adgold_buffer[c + 1]; break; case 6: /*Left and right channels*/ break; @@ -814,7 +819,7 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) switch (adgold->adgold_38x_regs[0x8] & 0x18) { case 0x00: /*Forced mono*/ for (c = 0; c < len * 2; c += 2) - adgold->samp_buffer[c] = adgold->samp_buffer[c + 1] = ((int32_t) adgold->samp_buffer[c] + (int32_t) adgold->samp_buffer[c + 1]) / 2; + adgold_buffer[c] = adgold_buffer[c + 1] = ((int32_t) adgold_buffer[c] + (int32_t) adgold_buffer[c + 1]) / 2; break; case 0x08: /*Linear stereo*/ break; @@ -822,17 +827,17 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) /*Filter left channel, leave right channel unchanged*/ /*Filter cutoff is largely a guess*/ for (c = 0; c < len * 2; c += 2) - adgold->samp_buffer[c] += adgold_pseudo_stereo_iir(0, adgold->samp_buffer[c]); + adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]); break; case 0x18: /*Spatial stereo*/ /*Quite probably wrong, I only have the diagram in the TDA8425 datasheet and a very vague understanding of how op-amps work to go on*/ for (c = 0; c < len * 2; c += 2) { - int16_t l = adgold->samp_buffer[c]; - int16_t r = adgold->samp_buffer[c + 1]; + int16_t l = adgold_buffer[c]; + int16_t r = adgold_buffer[c + 1]; - adgold->samp_buffer[c] += (r / 3) + ((l * 2) / 3); - adgold->samp_buffer[c + 1] += (l / 3) + ((r * 2) / 3); + adgold_buffer[c] += (r / 3) + ((l * 2) / 3); + adgold_buffer[c + 1] += (l / 3) + ((r * 2) / 3); } break; @@ -846,9 +851,9 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) int32_t highpass; /*Output is deliberately halved to avoid clipping*/ - temp = ((int32_t) adgold->samp_buffer[c] * adgold->vol_l) >> 17; - lowpass = adgold_lowpass_iir(0, 0, temp); - highpass = adgold_highpass_iir(0, 0, temp); + temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17; + lowpass = adgold_lowpass_iir(0, temp); + highpass = adgold_highpass_iir(0, temp); if (adgold->bass > 6) temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; else if (adgold->bass < 6) @@ -863,118 +868,9 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) temp = 32767; buffer[c] += temp; - temp = ((int32_t) adgold->samp_buffer[c + 1] * adgold->vol_r) >> 17; - lowpass = adgold_lowpass_iir(0, 1, temp); - highpass = adgold_highpass_iir(0, 1, temp); - if (adgold->bass > 6) - temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; - else if (adgold->bass < 6) - temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); - if (adgold->treble > 6) - temp += (highpass * treble_attenuation[adgold->treble]) >> 14; - else if (adgold->treble < 6) - temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); - if (temp < -32768) - temp = -32768; - if (temp > 32767) - temp = 32767; - buffer[c + 1] += temp; - } - - adgold->pos = 0; -} - -static void -adgold_get_music_buffer(int32_t *buffer, int len, void *priv) -{ - adgold_t *adgold = (adgold_t *) priv; - int c; - - const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); - - for (c = 0; c < len * 2; c += 2) { - adgold->opl_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2; - adgold->opl_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2; - } - - if (adgold->surround_enabled) - ym7128_apply(&adgold->ym7128, adgold->opl_buffer, 1, len); - - switch (adgold->adgold_38x_regs[0x8] & 6) { - case 0: - for (c = 0; c < len * 2; c++) - adgold->opl_buffer[c] = 0; - break; - case 2: /*Left channel only*/ - for (c = 0; c < len * 2; c += 2) - adgold->opl_buffer[c + 1] = adgold->opl_buffer[c]; - break; - case 4: /*Right channel only*/ - for (c = 0; c < len * 2; c += 2) - adgold->opl_buffer[c] = adgold->opl_buffer[c + 1]; - break; - case 6: /*Left and right channels*/ - break; - - default: - break; - } - - switch (adgold->adgold_38x_regs[0x8] & 0x18) { - case 0x00: /*Forced mono*/ - for (c = 0; c < len * 2; c += 2) - adgold->opl_buffer[c] = adgold->opl_buffer[c + 1] = ((int32_t) adgold->opl_buffer[c] + (int32_t) adgold->opl_buffer[c + 1]) / 2; - break; - case 0x08: /*Linear stereo*/ - break; - case 0x10: /*Pseudo stereo*/ - /*Filter left channel, leave right channel unchanged*/ - /*Filter cutoff is largely a guess*/ - for (c = 0; c < len * 2; c += 2) - adgold->opl_buffer[c] += adgold_pseudo_stereo_iir(1, adgold->opl_buffer[c]); - break; - case 0x18: /*Spatial stereo*/ - /*Quite probably wrong, I only have the diagram in the TDA8425 datasheet - and a very vague understanding of how op-amps work to go on*/ - for (c = 0; c < len * 2; c += 2) { - int16_t l = adgold->opl_buffer[c]; - int16_t r = adgold->opl_buffer[c + 1]; - - adgold->opl_buffer[c] += (r / 3) + ((l * 2) / 3); - adgold->opl_buffer[c + 1] += (l / 3) + ((r * 2) / 3); - } - break; - - default: - break; - } - - for (c = 0; c < len * 2; c += 2) { - int32_t temp; - int32_t lowpass; - int32_t highpass; - - /*Output is deliberately halved to avoid clipping*/ - temp = ((int32_t) adgold->opl_buffer[c] * adgold->vol_l) >> 17; - lowpass = adgold_lowpass_iir(1, 0, temp); - highpass = adgold_highpass_iir(1, 0, temp); - if (adgold->bass > 6) - temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; - else if (adgold->bass < 6) - temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); - if (adgold->treble > 6) - temp += (highpass * treble_attenuation[adgold->treble]) >> 14; - else if (adgold->treble < 6) - temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); - if (temp < -32768) - temp = -32768; - if (temp > 32767) - temp = 32767; - buffer[c] += temp; - - temp = ((int32_t) adgold->opl_buffer[c + 1] * adgold->vol_r) >> 17; - lowpass = adgold_lowpass_iir(1, 1, temp); - highpass = adgold_highpass_iir(1, 1, temp); + temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17; + lowpass = adgold_lowpass_iir(1, temp); + highpass = adgold_highpass_iir(1, temp); if (adgold->bass > 6) temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; else if (adgold->bass < 6) @@ -991,6 +887,9 @@ adgold_get_music_buffer(int32_t *buffer, int len, void *priv) } adgold->opl.reset_buffer(adgold->opl.priv); + adgold->pos = 0; + + free(adgold_buffer); } static void @@ -1058,7 +957,7 @@ adgold_init(UNUSED(const device_t *info)) adgold->surround_enabled = device_get_config_int("surround"); adgold->gameport_enabled = device_get_config_int("gameport"); - fm_driver_get(FM_YMF289B, &adgold->opl); + fm_driver_get_ex(FM_YMF262, &adgold->opl, 1); if (adgold->surround_enabled) ym7128_init(&adgold->ym7128); @@ -1149,7 +1048,6 @@ adgold_init(UNUSED(const device_t *info)) timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1); sound_add_handler(adgold_get_buffer, adgold); - music_add_handler(adgold_get_music_buffer, adgold); sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 1ee687f1e..6bbd634a7 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -36,150 +36,152 @@ static uint32_t fm_dev_inst[FM_DRV_MAX][FM_MAX]; uint8_t -fm_driver_get(int chip_id, fm_drv_t *drv) +fm_driver_get_ex(int chip_id, fm_drv_t *drv, int is_48k) { + void *flag_48k = is_48k ? ((void *) FM_FORCE_48K) : NULL; + switch (chip_id) { case FM_YM2149: /* SSG */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2149_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2149_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM3526: /* OPL */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym3526_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym3526_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_Y8950: /* MSX-Audio (OPL with ADPCM) */ *drv = ymfm_drv; - drv->priv = device_add_inst(&y8950_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&y8950_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM3812: /* OPL2 */ if (fm_driver == FM_DRV_NUKED) { - *drv = nuked_opl_drv; - drv->priv = device_add_inst(&ym3812_nuked_device, fm_dev_inst[fm_driver][chip_id]++); + *drv = is_48k ? nuked_opl_drv_48k : nuked_opl_drv; + drv->priv = device_add_inst_params(&ym3812_nuked_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); } else { *drv = ymfm_drv; - drv->priv = device_add_inst(&ym3812_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym3812_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); } break; case FM_YMF262: /* OPL3 */ if (fm_driver == FM_DRV_NUKED) { - *drv = nuked_opl_drv; - drv->priv = device_add_inst(&ymf262_nuked_device, fm_dev_inst[fm_driver][chip_id]++); + *drv = is_48k ? nuked_opl_drv_48k : nuked_opl_drv; + drv->priv = device_add_inst_params(&ymf262_nuked_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); } else { *drv = ymfm_drv; - drv->priv = device_add_inst(&ymf262_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ymf262_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); } break; case FM_YMF289B: /* OPL3-L */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ymf289b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ymf289b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YMF278B: /* OPL4 */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2413: /* OPLL */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2413_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2413_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2423: /* OPLL-X */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2423_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2423_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YMF281: /* OPLLP */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ymf281_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ymf281_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_DS1001: /* Konami VRC7 MMC */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ds1001_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ds1001_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2151: /* OPM */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2151_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2151_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2203: /* OPN */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2203_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2203_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2608: /* OPNA */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2608_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2608_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YMF288: /* OPN3L */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ymf288_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ymf288_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2610: /* OPNB */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2610_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2610_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2610B: /* OPNB2 */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2610b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2610b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2612: /* OPN2 */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2612_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2612_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM3438: /* OPN2C */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym3438_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym3438_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YMF276: /* OPN2L */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ymf276_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ymf276_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM2164: /* OPP */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2164_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2164_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_YM3806: /* OPQ */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym3806_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym3806_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; #if 0 case FM_YMF271: /* OPX */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ymf271_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ymf271_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; #endif case FM_YM2414: /* OPZ */ *drv = ymfm_drv; - drv->priv = device_add_inst(&ym2414_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym2414_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; case FM_ESFM: *drv = esfmu_opl_drv; - drv->priv = device_add_inst(&esfm_esfmu_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&esfm_esfmu_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; #ifdef USE_LIBSERIALPORT case FM_OPL2BOARD: *drv = ymfm_opl2board_drv; - drv->priv = device_add_inst(&ym_opl2board_device, fm_dev_inst[fm_driver][chip_id]++); + drv->priv = device_add_inst_params(&ym_opl2board_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k); break; #endif @@ -189,3 +191,9 @@ fm_driver_get(int chip_id, fm_drv_t *drv) return 1; }; + +uint8_t +fm_driver_get(int chip_id, fm_drv_t *drv) +{ + return fm_driver_get_ex(chip_id, drv, 0); +} diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 60f5ed2a6..a69b2e758 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -1460,6 +1460,15 @@ OPL3_GenerateStream(opl3_chip *chip, int32_t *sndptr, uint32_t numsamples) } } +void +OPL3_GenerateResampledStream(opl3_chip *chip, int32_t *sndptr, uint32_t numsamples) +{ + for (uint_fast32_t i = 0; i < numsamples; i++) { + OPL3_GenerateResampled(chip, sndptr); + sndptr += 2; + } +} + static void nuked_timer_tick(nuked_drv_t *dev, int tmr) { @@ -1525,32 +1534,6 @@ nuked_drv_set_do_cycles(void *priv, int8_t do_cycles) dev->flags &= ~FLAG_CYCLES; } -static void * -nuked_drv_init(const device_t *info) -{ - nuked_drv_t *dev = (nuked_drv_t *) calloc(1, sizeof(nuked_drv_t)); - dev->flags = FLAG_CYCLES; - if (info->local == FM_YMF262) - dev->flags |= FLAG_OPL3; - else - dev->status = 0x06; - - /* Initialize the NukedOPL object. */ - OPL3_Reset(&dev->opl, FREQ_49716); - - timer_add(&dev->timers[0], nuked_timer_1, dev, 0); - timer_add(&dev->timers[1], nuked_timer_2, dev, 0); - - return dev; -} - -static void -nuked_drv_close(void *priv) -{ - nuked_drv_t *dev = (nuked_drv_t *) priv; - free(dev); -} - static int32_t * nuked_drv_update(void *priv) { @@ -1560,8 +1543,8 @@ nuked_drv_update(void *priv) return dev->buffer; OPL3_GenerateStream(&dev->opl, - &dev->buffer[dev->pos * 2], - music_pos_global - dev->pos); + &dev->buffer[dev->pos * 2], + music_pos_global - dev->pos); for (; dev->pos < music_pos_global; dev->pos++) { dev->buffer[dev->pos * 2] /= 2; @@ -1571,6 +1554,26 @@ nuked_drv_update(void *priv) return dev->buffer; } +static int32_t * +nuked_drv_update_48k(void *priv) +{ + nuked_drv_t *dev = (nuked_drv_t *) priv; + + if (dev->pos >= sound_pos_global) + return dev->buffer; + + OPL3_GenerateResampledStream(&dev->opl, + &dev->buffer[dev->pos * 2], + sound_pos_global - dev->pos); + + for (; dev->pos < sound_pos_global; dev->pos++) { + dev->buffer[dev->pos * 2] /= 2; + dev->buffer[(dev->pos * 2) + 1] /= 2; + } + + return dev->buffer; +} + static uint8_t nuked_drv_read(uint16_t port, void *priv) { @@ -1579,7 +1582,7 @@ nuked_drv_read(uint16_t port, void *priv) if (dev->flags & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); - nuked_drv_update(dev); + dev->update(dev); uint8_t ret = 0xff; @@ -1598,7 +1601,8 @@ static void nuked_drv_write(uint16_t port, uint8_t val, void *priv) { nuked_drv_t *dev = (nuked_drv_t *) priv; - nuked_drv_update(dev); + + dev->update(dev); if ((port & 0x0001) == 0x0001) { OPL3_WriteRegBuffered(&dev->opl, dev->port, val); @@ -1649,6 +1653,40 @@ nuked_drv_reset_buffer(void *priv) dev->pos = 0; } +static void +nuked_drv_close(void *priv) +{ + nuked_drv_t *dev = (nuked_drv_t *) priv; + free(dev); +} + +static void * +nuked_drv_init(const device_t *info) +{ + nuked_drv_t *dev = (nuked_drv_t *) calloc(1, sizeof(nuked_drv_t)); + dev->flags = FLAG_CYCLES; + if ((info->local & FM_TYPE_MASK) == FM_YMF262) + dev->flags |= FLAG_OPL3; + else + dev->status = 0x06; + + dev->is_48k = !!(info->local & FM_FORCE_48K); + + /* Initialize the NukedOPL object. */ + if (dev->is_48k) { + dev->update = nuked_drv_update_48k; + OPL3_Reset(&dev->opl, FREQ_48000); + } else { + dev->update = nuked_drv_update; + OPL3_Reset(&dev->opl, FREQ_49716); + } + + timer_add(&dev->timers[0], nuked_timer_1, dev, 0); + timer_add(&dev->timers[1], nuked_timer_2, dev, 0); + + return dev; +} + const device_t ym3812_nuked_device = { .name = "Yamaha YM3812 OPL2 (NUKED)", .internal_name = "ym3812_nuked", @@ -1686,3 +1724,13 @@ const fm_drv_t nuked_opl_drv = { .priv = NULL, .generate = NULL, }; + +const fm_drv_t nuked_opl_drv_48k = { + .read = &nuked_drv_read, + .write = &nuked_drv_write, + .update = &nuked_drv_update_48k, + .reset_buffer = &nuked_drv_reset_buffer, + .set_do_cycles = &nuked_drv_set_do_cycles, + .priv = NULL, + .generate = NULL, +}; diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 815b6cb4b..37363aa74 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -56,11 +56,12 @@ enum { class YMFMChipBase { public: - YMFMChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate) + YMFMChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate, int is_48k) : m_buf_pos(0) , m_flags(0) , m_type(type) , m_samplerate(samplerate) + , m_48k(is_48k) { memset(m_buffer, 0, sizeof(m_buffer)); } @@ -74,11 +75,13 @@ public: void set_do_cycles(int8_t do_cycles) { do_cycles ? m_flags |= FLAG_CYCLES : m_flags &= ~FLAG_CYCLES; } int32_t *buffer() const { return (int32_t *) m_buffer; } void reset_buffer() { m_buf_pos = 0; } + int is_48k() const { return m_48k; } virtual uint32_t sample_rate() const = 0; virtual void write(uint16_t addr, uint8_t data) = 0; virtual void generate(int32_t *data, uint32_t num_samples) = 0; + virtual void generate_resampled(int32_t *data, uint32_t num_samples) = 0; virtual int32_t *update() = 0; virtual uint8_t read(uint16_t addr) = 0; virtual void set_clock(uint32_t clock) = 0; @@ -90,17 +93,19 @@ protected: int8_t m_flags; fm_type m_type; uint32_t m_samplerate; + int m_48k; }; template class YMFMChip : public YMFMChipBase, public ymfm::ymfm_interface { public: - YMFMChip(uint32_t clock, fm_type type, uint32_t samplerate) - : YMFMChipBase(clock, type, samplerate) + YMFMChip(uint32_t clock, fm_type type, uint32_t samplerate, int m_48k) + : YMFMChipBase(clock, type, samplerate, m_48k) , m_chip(*this) , m_clock(clock) , m_samplerate(samplerate) , m_samplecnt(0) + , m_48k(0) { memset(m_samples, 0, sizeof(m_samples)); memset(m_oldsamples, 0, sizeof(m_oldsamples)); @@ -109,7 +114,10 @@ public: m_subtract[0] = 80.0; m_subtract[1] = 320.0; m_type = type; - m_buf_pos_global = (samplerate == FREQ_49716) ? &music_pos_global : &wavetable_pos_global; + if (m_48k) + m_buf_pos_global = &sound_pos_global; + else + m_buf_pos_global = (samplerate == FREQ_49716) ? &music_pos_global : &wavetable_pos_global; if (m_type == FM_YMF278B) { if (rom_load_linear("roms/sound/yamaha/yrw801.rom", 0, 0x200000, 0, m_yrw801) == 0) { @@ -176,14 +184,8 @@ public: } } -#if 0 virtual void generate_resampled(int32_t *data, uint32_t num_samples) override { - if ((m_samplerate == FREQ_49716) || (m_samplerate == FREQ_44100)) { - generate(data, num_samples); - return; - } - for (uint32_t i = 0; i < num_samples; i++) { while (m_samplecnt >= m_rateratio) { m_oldsamples[0] = m_samples[0]; @@ -217,14 +219,16 @@ public: m_samplecnt += 1 << RSM_FRAC; } } -#endif virtual int32_t *update() override { if (m_buf_pos >= *m_buf_pos_global) return m_buffer; - generate(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos); + if (m_48k) + generate_resampled(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos); + else + generate(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos); for (; m_buf_pos < *m_buf_pos_global; m_buf_pos++) { m_buffer[m_buf_pos * 2] /= 2; @@ -287,6 +291,8 @@ private: int32_t m_samplecnt; int32_t m_oldsamples[2]; int32_t m_samples[2]; + + int m_48k; }; extern "C" { @@ -325,127 +331,128 @@ static void * ymfm_drv_init(const device_t *info) { YMFMChipBase *fm; + int is_48k = !!(info->local & FM_FORCE_48K); - switch (info->local) { + switch (info->local & FM_TYPE_MASK) { case FM_YM2149: /* OPL */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2149, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2149, FREQ_49716, is_48k); break; case FM_YM3526: /* OPL */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3526, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3526, FREQ_49716, is_48k); break; case FM_Y8950: /* MSX-Audio (OPL with ADPCM) */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_Y8950, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_Y8950, FREQ_49716, is_48k); break; default: case FM_YM3812: /* OPL2 */ - fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, FREQ_49716, is_48k); break; case FM_YMF262: /* OPL3 */ - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF262, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF262, FREQ_49716, is_48k); break; case FM_YMF289B: /* OPL3-L */ /* According to the datasheet, we should be using 33868800, but YMFM appears to cheat and does it using the same values as the YMF262. */ - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, FREQ_49716, is_48k); break; case FM_YMF278B: /* OPL4 */ - fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, FREQ_44100); + fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, FREQ_44100, is_48k); break; case FM_YM2413: /* OPLL */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2413, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2413, FREQ_49716, is_48k); break; case FM_YM2423: /* OPLL-X */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2423, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2423, FREQ_49716, is_48k); break; case FM_YMF281: /* OPLLP */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF281, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF281, FREQ_49716, is_48k); break; case FM_DS1001: /* Konami VRC7 MMC */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_DS1001, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_DS1001, FREQ_49716, is_48k); break; case FM_YM2151: /* OPM */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2151, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2151, FREQ_49716, is_48k); break; case FM_YM2203: /* OPN */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2203, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2203, FREQ_49716, is_48k); break; case FM_YM2608: /* OPNA */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2608, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2608, FREQ_49716, is_48k); break; case FM_YMF288: /* OPN3L */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF288, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF288, FREQ_49716, is_48k); break; case FM_YM2610: /* OPNB */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2610, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2610, FREQ_49716, is_48k); break; case FM_YM2610B: /* OPNB2 */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2610B, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2610B, FREQ_49716, is_48k); break; case FM_YM2612: /* OPN2 */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2612, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2612, FREQ_49716, is_48k); break; case FM_YM3438: /* OPN2C */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3438, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3438, FREQ_49716, is_48k); break; case FM_YMF276: /* OPN2L */ // TODO: Check function call, rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF276, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF276, FREQ_49716, is_48k); break; case FM_YM2164: /* OPP */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2164, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2164, FREQ_49716, is_48k); break; case FM_YM3806: /* OPQ */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3806, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3806, FREQ_49716, is_48k); break; #if 0 case FM_YMF271: /* OPX */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF271, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF271, FREQ_49716, is_48k); break; #endif case FM_YM2414: /* OPZ */ // TODO: Check rates and frequency - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2414, FREQ_49716); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2414, FREQ_49716, is_48k); break; } @@ -523,8 +530,10 @@ ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples) { YMFMChipBase *drv = (YMFMChipBase *) priv; - // drv->generate_resampled(data, num_samples); - drv->generate(data, num_samples); + if (drv->is_48k()) + drv->generate_resampled(data, num_samples); + else + drv->generate(data, num_samples); } const device_t ym2149_ymfm_device = { diff --git a/src/sound/snd_ym7128.c b/src/sound/snd_ym7128.c index 08b33f414..59e5691e9 100644 --- a/src/sound/snd_ym7128.c +++ b/src/sound/snd_ym7128.c @@ -111,10 +111,10 @@ ym7128_write(ym7128_t *ym7128, uint8_t val) ym7128->a0 = new_a0; } -#define GET_DELAY_SAMPLE(ym7128, offset) (((ym7128->delay_pos[i] - offset) < 0) ? ym7128->delay_buffer[i][(ym7128->delay_pos[i] - offset) + 2400] : ym7128->delay_buffer[i][ym7128->delay_pos[i] - offset]) +#define GET_DELAY_SAMPLE(ym7128, offset) (((ym7128->delay_pos - offset) < 0) ? ym7128->delay_buffer[(ym7128->delay_pos - offset) + 2400] : ym7128->delay_buffer[ym7128->delay_pos - offset]) void -ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len) +ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len) { for (int c = 0; c < len * 2; c += 4) { /*YM7128 samples a mono stream at ~24 kHz, so downsample*/ @@ -125,13 +125,13 @@ ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len) int32_t samp_r = 0; filter_temp = GET_DELAY_SAMPLE(ym7128, ym7128->t[0]); - filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat[i] * ym7128->c1) >> 11); + filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat * ym7128->c1) >> 11); filter_out = (filter_out * ym7128->vc) >> 16; samp = (samp * ym7128->vm) >> 16; samp += filter_out; - ym7128->delay_buffer[i][ym7128->delay_pos[i]] = samp; + ym7128->delay_buffer[ym7128->delay_pos] = samp; for (uint8_t d = 0; d < 8; d++) { samp_l += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d + 1]) * ym7128->gl[d]) >> 16; @@ -141,17 +141,17 @@ ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len) samp_l = (samp_l * ym7128->vl * 2) >> 16; samp_r = (samp_r * ym7128->vr * 2) >> 16; - buffer[c] += (samp_l + (int32_t) ym7128->prev_l[i]) / 2; - buffer[c + 1] += (samp_r + (int32_t) ym7128->prev_r[i]) / 2; + buffer[c] += (samp_l + (int32_t) ym7128->prev_l) / 2; + buffer[c + 1] += (samp_r + (int32_t) ym7128->prev_r) / 2; buffer[c + 2] += samp_l; buffer[c + 3] += samp_r; - ym7128->delay_pos[i]++; - if (ym7128->delay_pos[i] >= 2400) - ym7128->delay_pos[i] = 0; + ym7128->delay_pos++; + if (ym7128->delay_pos >= 2400) + ym7128->delay_pos = 0; - ym7128->filter_dat[i] = filter_temp; - ym7128->prev_l[i] = samp_l; - ym7128->prev_r[i] = samp_r; + ym7128->filter_dat = filter_temp; + ym7128->prev_l = samp_l; + ym7128->prev_r = samp_r; } }