mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 01:48:21 -07:00
More AdLib Gold fixes.
This commit is contained in:
@@ -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*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user