diff --git a/src/include/86box/snd_ym7128.h b/src/include/86box/snd_ym7128.h index a0796b1fa..f0657425f 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; - int16_t prev_l; - int16_t prev_r; + int16_t filter_dat[2]; + int16_t prev_l[2]; + int16_t prev_r[2]; - int16_t delay_buffer[2400]; - int delay_pos; + int16_t delay_buffer[2][2400]; + int delay_pos[2]; 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 len); +void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len); #endif /*SOUND_YM7128_H*/ diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index f708b6967..0181db72e 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -82,6 +82,7 @@ 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]; @@ -788,25 +789,25 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) adgold_update(adgold); for (c = 0; c < len * 2; c += 2) { - adgold->opl_buffer[c] = ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; - adgold->opl_buffer[c + 1] = ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; + 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; } if (adgold->surround_enabled) - ym7128_apply(&adgold->ym7128, adgold->opl_buffer, len); + ym7128_apply(&adgold->ym7128, adgold->samp_buffer, 0, len); switch (adgold->adgold_38x_regs[0x8] & 6) { case 0: for (c = 0; c < len * 2; c++) - adgold->opl_buffer[c] = 0; + adgold->samp_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]; + adgold->samp_buffer[c + 1] = adgold->samp_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]; + adgold->samp_buffer[c] = adgold->samp_buffer[c + 1]; break; case 6: /*Left and right channels*/ break; @@ -818,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->opl_buffer[c] = adgold->opl_buffer[c + 1] = ((int32_t) adgold->opl_buffer[c] + (int32_t) adgold->opl_buffer[c + 1]) / 2; + adgold->samp_buffer[c] = adgold->samp_buffer[c + 1] = ((int32_t) adgold->samp_buffer[c] + (int32_t) adgold->samp_buffer[c + 1]) / 2; break; case 0x08: /*Linear stereo*/ break; @@ -826,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->opl_buffer[c] += adgold_pseudo_stereo_iir(0, adgold->opl_buffer[c]); + adgold->samp_buffer[c] += adgold_pseudo_stereo_iir(0, adgold->samp_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]; + int16_t l = adgold->samp_buffer[c]; + int16_t r = adgold->samp_buffer[c + 1]; - adgold->opl_buffer[c] += (r / 3) + ((l * 2) / 3); - adgold->opl_buffer[c + 1] += (l / 3) + ((r * 2) / 3); + adgold->samp_buffer[c] += (r / 3) + ((l * 2) / 3); + adgold->samp_buffer[c + 1] += (l / 3) + ((r * 2) / 3); } break; @@ -850,7 +851,7 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) int32_t highpass; /*Output is deliberately halved to avoid clipping*/ - temp = ((int32_t) adgold->opl_buffer[c] * adgold->vol_l) >> 18; + 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); if (adgold->bass > 6) @@ -867,7 +868,7 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) temp = 32767; buffer[c] += temp; - temp = ((int32_t) adgold->opl_buffer[c + 1] * adgold->vol_r) >> 18; + 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) @@ -902,7 +903,7 @@ adgold_get_music_buffer(int32_t *buffer, int len, void *priv) } if (adgold->surround_enabled) - ym7128_apply(&adgold->ym7128, adgold->opl_buffer, len); + ym7128_apply(&adgold->ym7128, adgold->opl_buffer, 1, len); switch (adgold->adgold_38x_regs[0x8] & 6) { case 0: @@ -959,7 +960,7 @@ adgold_get_music_buffer(int32_t *buffer, int len, void *priv) int32_t highpass; /*Output is deliberately halved to avoid clipping*/ - temp = ((int32_t) adgold->opl_buffer[c] * adgold->vol_l) >> 18; + 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) @@ -976,7 +977,7 @@ adgold_get_music_buffer(int32_t *buffer, int len, void *priv) temp = 32767; buffer[c] += temp; - temp = ((int32_t) adgold->opl_buffer[c + 1] * adgold->vol_r) >> 18; + 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); if (adgold->bass > 6) diff --git a/src/sound/snd_ym7128.c b/src/sound/snd_ym7128.c index 59e5691e9..08b33f414 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 - offset) < 0) ? ym7128->delay_buffer[(ym7128->delay_pos - offset) + 2400] : ym7128->delay_buffer[ym7128->delay_pos - offset]) +#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]) void -ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len) +ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, 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 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 * ym7128->c1) >> 11); + filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat[i] * ym7128->c1) >> 11); filter_out = (filter_out * ym7128->vc) >> 16; samp = (samp * ym7128->vm) >> 16; samp += filter_out; - ym7128->delay_buffer[ym7128->delay_pos] = samp; + ym7128->delay_buffer[i][ym7128->delay_pos[i]] = 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 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) / 2; - buffer[c + 1] += (samp_r + (int32_t) ym7128->prev_r) / 2; + 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 + 2] += samp_l; buffer[c + 3] += samp_r; - ym7128->delay_pos++; - if (ym7128->delay_pos >= 2400) - ym7128->delay_pos = 0; + ym7128->delay_pos[i]++; + if (ym7128->delay_pos[i] >= 2400) + ym7128->delay_pos[i] = 0; - ym7128->filter_dat = filter_temp; - ym7128->prev_l = samp_l; - ym7128->prev_r = samp_r; + ym7128->filter_dat[i] = filter_temp; + ym7128->prev_l[i] = samp_l; + ym7128->prev_r[i] = samp_r; } }