Added volume control support per channel for stereo samples
TODO: do the same for mono samples (requires data doubling in emulation)
This commit is contained in:
parent
15ab8d32c2
commit
acd0fe11b5
@ -358,7 +358,7 @@ public:
|
||||
virtual void VOC_init_file(FILE *stream) {}
|
||||
virtual void VOC_write_block(FILE *stream, int block, Bit32u headerlen,
|
||||
Bit8u header[], Bit32u datalen, Bit8u data[]) {}
|
||||
virtual void pcm_apply_volume(Bit32u datalen, Bit8u data[], Bit8u volume,
|
||||
virtual void pcm_apply_volume(Bit32u datalen, Bit8u data[], Bit16u volume,
|
||||
Bit8u bits, bx_bool stereo, bx_bool issigned) {}
|
||||
};
|
||||
#endif
|
||||
|
@ -483,6 +483,7 @@ void bx_es1370_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
Bit8u index, master_vol, dac_vol;
|
||||
bx_bool set_wave_vol = 0;
|
||||
unsigned i;
|
||||
float tmp_vol;
|
||||
|
||||
BX_DEBUG(("register write to address 0x%04x - value = 0x%08x", address, value));
|
||||
|
||||
@ -563,12 +564,14 @@ void bx_es1370_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
}
|
||||
|
||||
if (set_wave_vol) {
|
||||
master_vol = ((0x1f - (BX_ES1370_THIS s.codec_reg[0] & 0x1f)) +
|
||||
(0x1f - (BX_ES1370_THIS s.codec_reg[1] & 0x1f))) / 2;
|
||||
dac_vol = ((0x1f - (BX_ES1370_THIS s.codec_reg[2] & 0x1f)) +
|
||||
(0x1f - (BX_ES1370_THIS s.codec_reg[3] & 0x1f))) / 2;
|
||||
float tmp_vol = (float)master_vol/31.0f*pow(10.0f, (float)(31-dac_vol)*-0.065f);
|
||||
master_vol = (0x1f - (BX_ES1370_THIS s.codec_reg[0] & 0x1f));
|
||||
dac_vol = (0x1f - (BX_ES1370_THIS s.codec_reg[2] & 0x1f));
|
||||
tmp_vol = (float)master_vol/31.0f*pow(10.0f, (float)(31-dac_vol)*-0.065f);
|
||||
BX_ES1370_THIS s.wave_vol = (Bit8u)(255 * tmp_vol);
|
||||
master_vol = (0x1f - (BX_ES1370_THIS s.codec_reg[1] & 0x1f));
|
||||
dac_vol = (0x1f - (BX_ES1370_THIS s.codec_reg[3] & 0x1f));
|
||||
tmp_vol = (float)master_vol/31.0f*pow(10.0f, (float)(31-dac_vol)*-0.065f);
|
||||
BX_ES1370_THIS s.wave_vol |= ((Bit8u)(255 * tmp_vol) << 8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -830,7 +833,7 @@ void bx_es1370_c::sendwavepacket(unsigned channel, Bit32u buflen, Bit8u *buffer)
|
||||
issigned = (format >> 1) & 1;
|
||||
|
||||
// apply wave volume
|
||||
if (BX_ES1370_THIS s.wave_vol != 255) {
|
||||
if (BX_ES1370_THIS s.wave_vol != 0xffff) {
|
||||
DEV_soundmod_pcm_apply_volume(buflen, buffer, BX_ES1370_THIS s.wave_vol,
|
||||
bits, stereo, issigned);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ typedef struct {
|
||||
Bit32u mempage;
|
||||
Bit8u codec_index;
|
||||
Bit8u codec_reg[BX_ES1370_CODEC_REGS];
|
||||
Bit8u wave_vol;
|
||||
Bit16u wave_vol;
|
||||
Bit32u sctl;
|
||||
|
||||
int dac1_timer_index;
|
||||
|
@ -1426,7 +1426,7 @@ void bx_sb16_c::dsp_sendwavepacket()
|
||||
return;
|
||||
|
||||
// apply wave volume
|
||||
if (BX_SB16_THIS wave_vol != 255) {
|
||||
if (BX_SB16_THIS wave_vol != 0xffff) {
|
||||
DEV_soundmod_pcm_apply_volume(DSP.dma.chunkindex, DSP.dma.chunk, BX_SB16_THIS wave_vol,
|
||||
DSP.dma.bits, DSP.dma.stereo, DSP.dma.format & 1);
|
||||
}
|
||||
@ -1628,6 +1628,7 @@ void bx_sb16_c::mixer_writedata(Bit32u value)
|
||||
int i;
|
||||
bx_bool set_wave_vol = 0;
|
||||
Bit8u master_vol, dac_vol;
|
||||
float tmp_vol;
|
||||
|
||||
// do some action depending on what register was written
|
||||
switch (MIXER.regindex)
|
||||
@ -1774,10 +1775,14 @@ void bx_sb16_c::mixer_writedata(Bit32u value)
|
||||
MIXER.reg[MIXER.regindex] = value;
|
||||
|
||||
if (set_wave_vol) {
|
||||
master_vol = ((MIXER.reg[0x30] >> 3) + (MIXER.reg[0x31] >> 3)) / 2;
|
||||
dac_vol = ((MIXER.reg[0x32] >> 3) + (MIXER.reg[0x33] >> 3)) / 2;
|
||||
float tmp_vol = (float)master_vol/31.0f*pow(10.0f, (float)(31-dac_vol)*-0.065f);
|
||||
master_vol = (MIXER.reg[0x30] >> 3);
|
||||
dac_vol = (MIXER.reg[0x32] >> 3);
|
||||
tmp_vol = (float)master_vol/31.0f*pow(10.0f, (float)(31-dac_vol)*-0.065f);
|
||||
BX_SB16_THIS wave_vol = (Bit8u)(255 * tmp_vol);
|
||||
master_vol = (MIXER.reg[0x31] >> 3);
|
||||
dac_vol = (MIXER.reg[0x33] >> 3);
|
||||
tmp_vol = (float)master_vol/31.0f*pow(10.0f, (float)(31-dac_vol)*-0.065f);
|
||||
BX_SB16_THIS wave_vol |= ((Bit8u)(255 * tmp_vol) << 8);
|
||||
}
|
||||
|
||||
writelog(BOTHLOG(4), "mixer register %02x set to %02x",
|
||||
|
@ -200,7 +200,7 @@ private:
|
||||
int currentirq;
|
||||
int currentdma8;
|
||||
int currentdma16;
|
||||
Bit8u wave_vol;
|
||||
Bit16u wave_vol;
|
||||
|
||||
// the MPU 401 relevant variables
|
||||
struct bx_sb16_mpu_struct {
|
||||
|
@ -267,39 +267,49 @@ void bx_soundmod_ctl_c::VOC_write_block(FILE *stream, int block,
|
||||
fwrite(data, 1, datalen, stream);
|
||||
}
|
||||
|
||||
void bx_soundmod_ctl_c::pcm_apply_volume(Bit32u datalen, Bit8u data[], Bit8u volume,
|
||||
void bx_soundmod_ctl_c::pcm_apply_volume(Bit32u datalen, Bit8u data[], Bit16u volume,
|
||||
Bit8u bits, bx_bool stereo, bx_bool issigned)
|
||||
{
|
||||
unsigned i;
|
||||
Bit8u value8u;
|
||||
Bit8s value8s;
|
||||
Bit16u value16u;
|
||||
Bit16u value16u, tmpvol;
|
||||
Bit16s value16s;
|
||||
Bit8u volumes[2], channel = 0;
|
||||
|
||||
if (stereo) {
|
||||
volumes[0] = (Bit8u)(volume & 0xff);
|
||||
volumes[1] = (Bit8u)(volume >> 8);
|
||||
} else {
|
||||
tmpvol = ((volume & 0xff) + (volume >> 8)) / 2;
|
||||
volumes[0] = volumes[1] = (Bit8u)tmpvol;
|
||||
}
|
||||
|
||||
UNUSED(stereo); // TODO
|
||||
if (bits == 16) {
|
||||
for (i = 0; i < datalen; i += 2) {
|
||||
if (issigned) {
|
||||
value16s = (Bit16s)(data[i] | (data[i+1] << 8));
|
||||
value16s = (Bit16s)((Bit32s)value16s * volume / 256);
|
||||
value16s = (Bit16s)((Bit32s)value16s * volumes[channel] / 256);
|
||||
data[i] = (Bit8u)(value16s & 0xff);
|
||||
data[i+1] = (Bit8u)(value16s >> 8);
|
||||
} else {
|
||||
value16u = data[i] | (data[i+1] << 8);
|
||||
value16u = (Bit16u)((Bit32u)value16u * volume / 256);
|
||||
value16u = (Bit16u)((Bit32u)value16u * volumes[channel] / 256);
|
||||
data[i] = (Bit8u)(value16u & 0xff);
|
||||
data[i+1] = (Bit8u)(value16u >> 8);
|
||||
}
|
||||
channel ^= 1;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < datalen; i++) {
|
||||
if (issigned) {
|
||||
value8s = (Bit8s)data[i];
|
||||
data[i] = (Bit8u)(((Bit16s)value8s * volume) / 256);
|
||||
data[i] = (Bit8u)(((Bit16s)value8s * volumes[channel]) / 256);
|
||||
} else {
|
||||
value8u = data[i];
|
||||
data[i] = (Bit8u)(((Bit16u)value8u * volume) / 256);
|
||||
data[i] = (Bit8u)(((Bit16u)value8u * volumes[channel]) / 256);
|
||||
}
|
||||
channel ^= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
virtual void VOC_init_file(FILE *stream);
|
||||
virtual void VOC_write_block(FILE *stream, int block, Bit32u headerlen,
|
||||
Bit8u header[], Bit32u datalen, Bit8u data[]);
|
||||
virtual void pcm_apply_volume(Bit32u datalen, Bit8u data[], Bit8u volume,
|
||||
virtual void pcm_apply_volume(Bit32u datalen, Bit8u data[], Bit16u volume,
|
||||
Bit8u bits, bx_bool stereo, bx_bool issigned);
|
||||
private:
|
||||
bx_sound_lowlevel_c *soundmod;
|
||||
|
Loading…
Reference in New Issue
Block a user