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_init_file(FILE *stream) {}
|
||||||
virtual void VOC_write_block(FILE *stream, int block, Bit32u headerlen,
|
virtual void VOC_write_block(FILE *stream, int block, Bit32u headerlen,
|
||||||
Bit8u header[], Bit32u datalen, Bit8u data[]) {}
|
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) {}
|
Bit8u bits, bx_bool stereo, bx_bool issigned) {}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -483,6 +483,7 @@ void bx_es1370_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
|||||||
Bit8u index, master_vol, dac_vol;
|
Bit8u index, master_vol, dac_vol;
|
||||||
bx_bool set_wave_vol = 0;
|
bx_bool set_wave_vol = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
float tmp_vol;
|
||||||
|
|
||||||
BX_DEBUG(("register write to address 0x%04x - value = 0x%08x", address, value));
|
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) {
|
if (set_wave_vol) {
|
||||||
master_vol = ((0x1f - (BX_ES1370_THIS s.codec_reg[0] & 0x1f)) +
|
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));
|
||||||
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);
|
||||||
(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);
|
|
||||||
BX_ES1370_THIS s.wave_vol = (Bit8u)(255 * tmp_vol);
|
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;
|
issigned = (format >> 1) & 1;
|
||||||
|
|
||||||
// apply wave volume
|
// 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,
|
DEV_soundmod_pcm_apply_volume(buflen, buffer, BX_ES1370_THIS s.wave_vol,
|
||||||
bits, stereo, issigned);
|
bits, stereo, issigned);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ typedef struct {
|
|||||||
Bit32u mempage;
|
Bit32u mempage;
|
||||||
Bit8u codec_index;
|
Bit8u codec_index;
|
||||||
Bit8u codec_reg[BX_ES1370_CODEC_REGS];
|
Bit8u codec_reg[BX_ES1370_CODEC_REGS];
|
||||||
Bit8u wave_vol;
|
Bit16u wave_vol;
|
||||||
Bit32u sctl;
|
Bit32u sctl;
|
||||||
|
|
||||||
int dac1_timer_index;
|
int dac1_timer_index;
|
||||||
|
@ -1426,7 +1426,7 @@ void bx_sb16_c::dsp_sendwavepacket()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// apply wave volume
|
// 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,
|
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);
|
DSP.dma.bits, DSP.dma.stereo, DSP.dma.format & 1);
|
||||||
}
|
}
|
||||||
@ -1628,6 +1628,7 @@ void bx_sb16_c::mixer_writedata(Bit32u value)
|
|||||||
int i;
|
int i;
|
||||||
bx_bool set_wave_vol = 0;
|
bx_bool set_wave_vol = 0;
|
||||||
Bit8u master_vol, dac_vol;
|
Bit8u master_vol, dac_vol;
|
||||||
|
float tmp_vol;
|
||||||
|
|
||||||
// do some action depending on what register was written
|
// do some action depending on what register was written
|
||||||
switch (MIXER.regindex)
|
switch (MIXER.regindex)
|
||||||
@ -1774,10 +1775,14 @@ void bx_sb16_c::mixer_writedata(Bit32u value)
|
|||||||
MIXER.reg[MIXER.regindex] = value;
|
MIXER.reg[MIXER.regindex] = value;
|
||||||
|
|
||||||
if (set_wave_vol) {
|
if (set_wave_vol) {
|
||||||
master_vol = ((MIXER.reg[0x30] >> 3) + (MIXER.reg[0x31] >> 3)) / 2;
|
master_vol = (MIXER.reg[0x30] >> 3);
|
||||||
dac_vol = ((MIXER.reg[0x32] >> 3) + (MIXER.reg[0x33] >> 3)) / 2;
|
dac_vol = (MIXER.reg[0x32] >> 3);
|
||||||
float tmp_vol = (float)master_vol/31.0f*pow(10.0f, (float)(31-dac_vol)*-0.065f);
|
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);
|
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",
|
writelog(BOTHLOG(4), "mixer register %02x set to %02x",
|
||||||
|
@ -200,7 +200,7 @@ private:
|
|||||||
int currentirq;
|
int currentirq;
|
||||||
int currentdma8;
|
int currentdma8;
|
||||||
int currentdma16;
|
int currentdma16;
|
||||||
Bit8u wave_vol;
|
Bit16u wave_vol;
|
||||||
|
|
||||||
// the MPU 401 relevant variables
|
// the MPU 401 relevant variables
|
||||||
struct bx_sb16_mpu_struct {
|
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);
|
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)
|
Bit8u bits, bx_bool stereo, bx_bool issigned)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
Bit8u value8u;
|
Bit8u value8u;
|
||||||
Bit8s value8s;
|
Bit8s value8s;
|
||||||
Bit16u value16u;
|
Bit16u value16u, tmpvol;
|
||||||
Bit16s value16s;
|
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) {
|
if (bits == 16) {
|
||||||
for (i = 0; i < datalen; i += 2) {
|
for (i = 0; i < datalen; i += 2) {
|
||||||
if (issigned) {
|
if (issigned) {
|
||||||
value16s = (Bit16s)(data[i] | (data[i+1] << 8));
|
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] = (Bit8u)(value16s & 0xff);
|
||||||
data[i+1] = (Bit8u)(value16s >> 8);
|
data[i+1] = (Bit8u)(value16s >> 8);
|
||||||
} else {
|
} else {
|
||||||
value16u = data[i] | (data[i+1] << 8);
|
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] = (Bit8u)(value16u & 0xff);
|
||||||
data[i+1] = (Bit8u)(value16u >> 8);
|
data[i+1] = (Bit8u)(value16u >> 8);
|
||||||
}
|
}
|
||||||
|
channel ^= 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < datalen; i++) {
|
for (i = 0; i < datalen; i++) {
|
||||||
if (issigned) {
|
if (issigned) {
|
||||||
value8s = (Bit8s)data[i];
|
value8s = (Bit8s)data[i];
|
||||||
data[i] = (Bit8u)(((Bit16s)value8s * volume) / 256);
|
data[i] = (Bit8u)(((Bit16s)value8s * volumes[channel]) / 256);
|
||||||
} else {
|
} else {
|
||||||
value8u = data[i];
|
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_init_file(FILE *stream);
|
||||||
virtual void VOC_write_block(FILE *stream, int block, Bit32u headerlen,
|
virtual void VOC_write_block(FILE *stream, int block, Bit32u headerlen,
|
||||||
Bit8u header[], Bit32u datalen, Bit8u data[]);
|
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);
|
Bit8u bits, bx_bool stereo, bx_bool issigned);
|
||||||
private:
|
private:
|
||||||
bx_sound_lowlevel_c *soundmod;
|
bx_sound_lowlevel_c *soundmod;
|
||||||
|
Loading…
Reference in New Issue
Block a user