More AdLib Gold fixes.

This commit is contained in:
OBattler
2025-09-23 20:46:24 +02:00
parent a87bcd410e
commit 087a005664
3 changed files with 36 additions and 35 deletions

View File

@@ -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*/

View File

@@ -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)

View File

@@ -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;
}
}