Add an option to round volumes up when applying linear scaling

This is secretly a FamiTracker compatibility mode, but it's useful
in many other contexts. With upwards rounding, if both the channel
and the macro volume are positive, then the computed result is
also positive, ie, it will never become 0, which is silent on many
chips.

Still needs UI changes to expose the setting, and save/load work
to persist it to file.
This commit is contained in:
Zeta 2023-11-14 03:27:03 -05:00
parent bb1cbbc403
commit 36804d7c9b
2 changed files with 4 additions and 2 deletions

View file

@ -782,7 +782,7 @@ class DivDispatch {
#define NOTE_FNUM_BLOCK(x,bits) parent->calcBaseFreqFNumBlock(chipClock,CHIP_FREQBASE,x,bits)
// this is for volume scaling calculation.
#define VOL_SCALE_LINEAR(x,y,range) (((x)*(y))/(range))
#define VOL_SCALE_LINEAR(x,y,range) ((parent->song.ceilVolumeScaling)?((((x)*(y))+(range-1))/(range)):(((x)*(y))/(range)))
#define VOL_SCALE_LOG(x,y,range) (CLAMP(((x)+(y))-(range),0,(range)))
#define VOL_SCALE_LINEAR_BROKEN(x,y,range) ((parent->song.newVolumeScaling)?(VOL_SCALE_LINEAR(x,y,range)):(VOL_SCALE_LOG(x,y,range)))
#define VOL_SCALE_LOG_BROKEN(x,y,range) ((parent->song.newVolumeScaling)?(VOL_SCALE_LOG(x,y,range)):(VOL_SCALE_LINEAR(x,y,range)))

View file

@ -379,6 +379,7 @@ struct DivSong {
bool preNoteNoEffect;
bool oldDPCM;
bool resetArpPhaseOnNewNote;
bool ceilVolumeScaling;
std::vector<DivInstrument*> ins;
std::vector<DivWavetable*> wave;
@ -500,7 +501,8 @@ struct DivSong {
brokenFMOff(false),
preNoteNoEffect(false),
oldDPCM(false),
resetArpPhaseOnNewNote(false) {
resetArpPhaseOnNewNote(false),
ceilVolumeScaling(false) { // DEBUG: before accepting PR, set this to false! (zeta hasn't touched the UI yet)
for (int i=0; i<DIV_MAX_CHIPS; i++) {
system[i]=DIV_SYSTEM_NULL;
systemVol[i]=1.0;