From ae20311e3e6b6345db92bcec9f527c0b92c146f7 Mon Sep 17 00:00:00 2001 From: khokh2001 Date: Wed, 29 Oct 2014 01:36:01 +0900 Subject: opl additive voice volume calculation fix opl additive voice volume calculation fix--- src/i_oplmusic.c | 54 ++++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c index a1e90506..39517e3f 100644 --- a/src/i_oplmusic.c +++ b/src/i_oplmusic.c @@ -508,45 +508,39 @@ static void SetVoiceVolume(opl_voice_t *voice, unsigned int volume) { genmidi_voice_t *opl_voice; unsigned int full_volume; - unsigned int op_volume; - unsigned int reg_volume; - + unsigned int car_volume; + unsigned int mod_volume; + voice->note_volume = volume; - + opl_voice = &voice->current_instr->voices[voice->current_instr_voice]; - + // Multiply note volume and channel volume to get the actual volume. - - full_volume = (volume_mapping_table[voice->note_volume] - * volume_mapping_table[voice->channel->volume] - * volume_mapping_table[current_music_volume]) / (127 * 127); - - // The volume of each instrument can be controlled via GENMIDI: - - op_volume = 0x3f - opl_voice->carrier.level; - + + full_volume = (volume_mapping_table[voice->note_volume] * (2 * (volume_mapping_table[(voice->channel->volume * current_music_volume) / 127] + 1))) >> 9; + // The volume value to use in the register: - - reg_volume = (op_volume * full_volume) / 128; - reg_volume = (0x3f - reg_volume) | opl_voice->carrier.scale; - + car_volume = 0x3f - full_volume; + // Update the volume register(s) if necessary. - - if (reg_volume != voice->reg_volume) + + if (car_volume != voice->reg_volume) { - voice->reg_volume = reg_volume; - - OPL_WriteRegister(OPL_REGS_LEVEL + voice->op2, reg_volume); - + voice->reg_volume = car_volume | (opl_voice->carrier.scale & 0xc0); + + OPL_WriteRegister(OPL_REGS_LEVEL + voice->op2, voice->reg_volume); + // If we are using non-modulated feedback mode, we must set the // volume for both voices. - // Note that the same register volume value is written for - // both voices, always calculated from the carrier's level - // value. - - if ((opl_voice->feedback & 0x01) != 0) + + if ((opl_voice->feedback & 0x01) != 0 && opl_voice->modulator.level != 0x3f) { - OPL_WriteRegister(OPL_REGS_LEVEL + voice->op1, reg_volume); + mod_volume = 0x3f - opl_voice->modulator.level; + if (mod_volume >= car_volume) + { + mod_volume = car_volume; + } + OPL_WriteRegister(OPL_REGS_LEVEL + voice->op1, mod_volume | (opl_voice->modulator.scale & 0xc0)); } } } -- cgit v1.2.3 From 37aae66760717b106acf602c180140096d95d036 Mon Sep 17 00:00:00 2001 From: khokh2001 Date: Wed, 29 Oct 2014 17:03:45 +0900 Subject: opl additive voice volume calculation fix opl additive voice volume calculation fix--- src/i_oplmusic.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c index 39517e3f..128cff18 100644 --- a/src/i_oplmusic.c +++ b/src/i_oplmusic.c @@ -507,6 +507,7 @@ static void SetVoiceInstrument(opl_voice_t *voice, static void SetVoiceVolume(opl_voice_t *voice, unsigned int volume) { genmidi_voice_t *opl_voice; + unsigned int midi_volume; unsigned int full_volume; unsigned int car_volume; unsigned int mod_volume; @@ -517,7 +518,10 @@ static void SetVoiceVolume(opl_voice_t *voice, unsigned int volume) // Multiply note volume and channel volume to get the actual volume. - full_volume = (volume_mapping_table[voice->note_volume] * (2 * (volume_mapping_table[(voice->channel->volume * current_music_volume) / 127] + 1))) >> 9; + midi_volume = 2 * (volume_mapping_table[(voice->channel->volume + * current_music_volume) / 127] + 1); + + full_volume = (volume_mapping_table[voice->note_volume] * midi_volume) >> 9; // The volume value to use in the register: car_volume = 0x3f - full_volume; @@ -540,7 +544,8 @@ static void SetVoiceVolume(opl_voice_t *voice, unsigned int volume) { mod_volume = car_volume; } - OPL_WriteRegister(OPL_REGS_LEVEL + voice->op1, mod_volume | (opl_voice->modulator.scale & 0xc0)); + OPL_WriteRegister(OPL_REGS_LEVEL + voice->op1, + mod_volume | (opl_voice->modulator.scale & 0xc0)); } } } -- cgit v1.2.3