From d37669a8f092e74445e09e4b80a3bb59f3466b10 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 15 Dec 2023 16:46:34 -0500 Subject: [PATCH 1/4] remove su_memory.fur --- demos/specs2/su_memory.fur | Bin 20220 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 demos/specs2/su_memory.fur diff --git a/demos/specs2/su_memory.fur b/demos/specs2/su_memory.fur deleted file mode 100644 index ff030dbe7922c992f8447b41a508520e0c7f02de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20220 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 From 99dd85bcb4b008c4341708590150a62a50ad1407 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 16 Dec 2023 19:37:14 -0500 Subject: [PATCH 2/4] MIDI velocity mapping, part 1 --- src/engine/platform/ay.cpp | 4 ++++ src/engine/platform/ay.h | 1 + src/engine/platform/ay8930.cpp | 4 ++++ src/engine/platform/ay8930.h | 1 + src/engine/platform/fmsharedbase.h | 14 ++++++++++++++ src/engine/platform/pce.cpp | 4 ++++ src/engine/platform/pce.h | 1 + src/engine/platform/sms.cpp | 4 ++++ src/engine/platform/sms.h | 1 + src/engine/platform/t6w28.cpp | 4 ++++ src/engine/platform/t6w28.h | 1 + src/engine/playback.cpp | 4 ++-- 12 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 9928372cc..faf5b7a04 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -719,6 +719,10 @@ DivDispatchOscBuffer* DivPlatformAY8910::getOscBuffer(int ch) { return oscBuf[ch]; } +int DivPlatformAY8910::mapVelocity(int ch, unsigned char vel) { + return round(15.0*pow(((double)vel/127.0),0.33)); +} + unsigned char* DivPlatformAY8910::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 354557fda..86d527947 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -131,6 +131,7 @@ class DivPlatformAY8910: public DivDispatch { int dispatch(DivCommand c); void* getChanState(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); + int mapVelocity(int ch, unsigned char vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void flushWrites(); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index a337a2a31..022b36412 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -718,6 +718,10 @@ DivDispatchOscBuffer* DivPlatformAY8930::getOscBuffer(int ch) { return oscBuf[ch]; } +int DivPlatformAY8930::mapVelocity(int ch, unsigned char vel) { + return round(31.0*pow(((double)vel/127.0),0.22)); +} + unsigned char* DivPlatformAY8930::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index ba2f9abea..c8b0f724a 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -132,6 +132,7 @@ class DivPlatformAY8930: public DivDispatch { int dispatch(DivCommand c); void* getChanState(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); + int mapVelocity(int ch, unsigned char vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/fmsharedbase.h b/src/engine/platform/fmsharedbase.h index e458904eb..db420b408 100644 --- a/src/engine/platform/fmsharedbase.h +++ b/src/engine/platform/fmsharedbase.h @@ -121,6 +121,20 @@ class DivPlatformFMBase: public DivDispatch { } } } + + virtual int mapVelocity(int ch, unsigned char vel) { + // -0.75dB per step + // -6: 64: 8 + // -12: 32: 16 + // -18: 16: 24 + // -24: 8: 32 + // -30: 4: 40 + // -36: 2: 48 + // -42: 1: 56 + if (vel==0) return 0; + if (vel==127) return 127; + return CLAMP(round(128.0-(56.0-log2(vel)*8.0)),0,127); + } friend void putDispatchChan(void*,int,int); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 037a1cd69..d2e0ca6d7 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -539,6 +539,10 @@ DivDispatchOscBuffer* DivPlatformPCE::getOscBuffer(int ch) { return oscBuf[ch]; } +int DivPlatformPCE::mapVelocity(int ch, unsigned char vel) { + return round(31.0*pow(((double)vel/127.0),0.22)); +} + unsigned char* DivPlatformPCE::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index c2649eb05..26e13adda 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -86,6 +86,7 @@ class DivPlatformPCE: public DivDispatch { DivChannelModeHints getModeHints(int chan); DivSamplePos getSamplePos(int ch); DivDispatchOscBuffer* getOscBuffer(int chan); + int mapVelocity(int ch, unsigned char vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 7aa0455ca..db18055fe 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -462,6 +462,10 @@ DivDispatchOscBuffer* DivPlatformSMS::getOscBuffer(int ch) { return oscBuf[ch]; } +int DivPlatformSMS::mapVelocity(int ch, unsigned char vel) { + return round(15.0*pow(((double)vel/127.0),0.33)); +} + unsigned char* DivPlatformSMS::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index 5eaf204ba..d89658462 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -79,6 +79,7 @@ class DivPlatformSMS: public DivDispatch { DivMacroInt* getChanMacroInt(int ch); unsigned short getPan(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); + int mapVelocity(int ch, unsigned char vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index f2dfe7120..7460c2ecc 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -308,6 +308,10 @@ DivDispatchOscBuffer* DivPlatformT6W28::getOscBuffer(int ch) { return oscBuf[ch]; } +int DivPlatformT6W28::mapVelocity(int ch, unsigned char vel) { + return round(15.0*pow(((double)vel/127.0),0.33)); +} + unsigned char* DivPlatformT6W28::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/t6w28.h b/src/engine/platform/t6w28.h index 5e69c6268..ccb89b76d 100644 --- a/src/engine/platform/t6w28.h +++ b/src/engine/platform/t6w28.h @@ -65,6 +65,7 @@ class DivPlatformT6W28: public DivDispatch { DivMacroInt* getChanMacroInt(int ch); unsigned short getPan(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); + int mapVelocity(int ch, unsigned char vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index d2a0db179..0c024d78d 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1372,8 +1372,8 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { } if (note.on) { dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,note.channel,note.ins,1)); - if (note.volume>=0) { - int mappedVol=disCont[dispatchOfChan[note.channel]].dispatch->mapVelocity(note.channel,note.volume); + if (note.volume>=0 && !disCont[dispatchOfChan[note.channel]].dispatch->isVolGlobal()) { + int mappedVol=disCont[dispatchOfChan[note.channel]].dispatch->mapVelocity(dispatchChanOfChan[note.channel],note.volume); logV("dispatching volume (%d -> %d)",note.volume,mappedVol); dispatchCmd(DivCommand(DIV_CMD_VOLUME,note.channel,mappedVol)); } From 51b385a1ef9b95dea9c16794e65d3acec574043a Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 16 Dec 2023 19:52:37 -0500 Subject: [PATCH 3/4] apply volExp on velocity input - PLEASE READ DivDispatch::mapVelocity() now takes a float instead of an unsigned char --- src/engine/dispatch.h | 4 ++-- src/engine/engine.cpp | 4 ++++ src/engine/engine.h | 5 +++++ src/engine/platform/abstract.cpp | 4 ++-- src/engine/platform/ay.cpp | 4 ++-- src/engine/platform/ay.h | 2 +- src/engine/platform/ay8930.cpp | 4 ++-- src/engine/platform/ay8930.h | 2 +- src/engine/platform/fmsharedbase.h | 4 ++-- src/engine/platform/pce.cpp | 4 ++-- src/engine/platform/pce.h | 2 +- src/engine/platform/sms.cpp | 4 ++-- src/engine/platform/sms.h | 2 +- src/engine/platform/t6w28.cpp | 4 ++-- src/engine/platform/t6w28.h | 2 +- src/engine/playback.cpp | 3 ++- src/gui/gui.h | 2 +- src/gui/settings.cpp | 7 ++++++- 18 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 6dcb6171e..5860a3736 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -594,10 +594,10 @@ class DivDispatch { /** * map MIDI velocity (from 0 to 127) to chip volume. * @param ch the chip channel. -1 means N/A. - * @param vel input velocity. + * @param vel input velocity, from 0.0 to 1.0. * @return output volume. */ - virtual int mapVelocity(int ch, unsigned char vel); + virtual int mapVelocity(int ch, float vel); /** * get the lowest note in a portamento. diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index fc999fcd9..f8af13d80 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3385,6 +3385,10 @@ void DivEngine::setMidiDirect(bool value) { midiIsDirect=value; } +void DivEngine::setMidiVolExp(float value) { + midiVolExp=value; +} + void DivEngine::setMidiCallback(std::function what) { midiCallback=what; } diff --git a/src/engine/engine.h b/src/engine/engine.h index db8cb7b34..fe0cd0991 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -423,6 +423,7 @@ class DivEngine { bool midiOutProgramChange; int midiOutMode; int midiOutTimeRate; + float midiVolExp; int softLockCount; int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed, elapsedBars, elapsedBeats, curSpeed; size_t curSubSongIndex; @@ -1184,6 +1185,9 @@ class DivEngine { // set MIDI direct channel map void setMidiDirect(bool value); + // set MIDI volume curve exponent + void setMidiVolExp(float value); + // set MIDI input callback // if the specified function returns -2, note feedback will be inhibited. void setMidiCallback(std::function what); @@ -1261,6 +1265,7 @@ class DivEngine { midiOutProgramChange(false), midiOutMode(DIV_MIDI_MODE_NOTE), midiOutTimeRate(0), + midiVolExp(2.0f), // General MIDI standard softLockCount(0), subticks(0), ticks(0), diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index aaa27a494..9886dae37 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -102,9 +102,9 @@ bool DivDispatch::isVolGlobal() { return false; } -int DivDispatch::mapVelocity(int ch, unsigned char vel) { +int DivDispatch::mapVelocity(int ch, float vel) { const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0)))); - return (vel*volMax)/127; + return round(vel*volMax); } int DivDispatch::getPortaFloor(int ch) { diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index faf5b7a04..f8c5bde9e 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -719,8 +719,8 @@ DivDispatchOscBuffer* DivPlatformAY8910::getOscBuffer(int ch) { return oscBuf[ch]; } -int DivPlatformAY8910::mapVelocity(int ch, unsigned char vel) { - return round(15.0*pow(((double)vel/127.0),0.33)); +int DivPlatformAY8910::mapVelocity(int ch, float vel) { + return round(15.0*pow(vel,0.33)); } unsigned char* DivPlatformAY8910::getRegisterPool() { diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 86d527947..642ae59cf 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -131,7 +131,7 @@ class DivPlatformAY8910: public DivDispatch { int dispatch(DivCommand c); void* getChanState(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); - int mapVelocity(int ch, unsigned char vel); + int mapVelocity(int ch, float vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void flushWrites(); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 022b36412..2199d5ccd 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -718,8 +718,8 @@ DivDispatchOscBuffer* DivPlatformAY8930::getOscBuffer(int ch) { return oscBuf[ch]; } -int DivPlatformAY8930::mapVelocity(int ch, unsigned char vel) { - return round(31.0*pow(((double)vel/127.0),0.22)); +int DivPlatformAY8930::mapVelocity(int ch, float vel) { + return round(31.0*pow(vel,0.22)); } unsigned char* DivPlatformAY8930::getRegisterPool() { diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index c8b0f724a..64f8e9318 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -132,7 +132,7 @@ class DivPlatformAY8930: public DivDispatch { int dispatch(DivCommand c); void* getChanState(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); - int mapVelocity(int ch, unsigned char vel); + int mapVelocity(int ch, float vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/fmsharedbase.h b/src/engine/platform/fmsharedbase.h index db420b408..3a12f96e6 100644 --- a/src/engine/platform/fmsharedbase.h +++ b/src/engine/platform/fmsharedbase.h @@ -122,7 +122,7 @@ class DivPlatformFMBase: public DivDispatch { } } - virtual int mapVelocity(int ch, unsigned char vel) { + virtual int mapVelocity(int ch, float vel) { // -0.75dB per step // -6: 64: 8 // -12: 32: 16 @@ -133,7 +133,7 @@ class DivPlatformFMBase: public DivDispatch { // -42: 1: 56 if (vel==0) return 0; if (vel==127) return 127; - return CLAMP(round(128.0-(56.0-log2(vel)*8.0)),0,127); + return CLAMP(round(128.0-(56.0-log2(vel*127.0)*8.0)),0,127); } friend void putDispatchChan(void*,int,int); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index d2e0ca6d7..1cff48278 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -539,8 +539,8 @@ DivDispatchOscBuffer* DivPlatformPCE::getOscBuffer(int ch) { return oscBuf[ch]; } -int DivPlatformPCE::mapVelocity(int ch, unsigned char vel) { - return round(31.0*pow(((double)vel/127.0),0.22)); +int DivPlatformPCE::mapVelocity(int ch, float vel) { + return round(31.0*pow(vel,0.22)); } unsigned char* DivPlatformPCE::getRegisterPool() { diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 26e13adda..591c94cef 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -86,7 +86,7 @@ class DivPlatformPCE: public DivDispatch { DivChannelModeHints getModeHints(int chan); DivSamplePos getSamplePos(int ch); DivDispatchOscBuffer* getOscBuffer(int chan); - int mapVelocity(int ch, unsigned char vel); + int mapVelocity(int ch, float vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index db18055fe..0b5e6183e 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -462,8 +462,8 @@ DivDispatchOscBuffer* DivPlatformSMS::getOscBuffer(int ch) { return oscBuf[ch]; } -int DivPlatformSMS::mapVelocity(int ch, unsigned char vel) { - return round(15.0*pow(((double)vel/127.0),0.33)); +int DivPlatformSMS::mapVelocity(int ch, float vel) { + return round(15.0*pow(vel,0.33)); } unsigned char* DivPlatformSMS::getRegisterPool() { diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index d89658462..092010a56 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -79,7 +79,7 @@ class DivPlatformSMS: public DivDispatch { DivMacroInt* getChanMacroInt(int ch); unsigned short getPan(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); - int mapVelocity(int ch, unsigned char vel); + int mapVelocity(int ch, float vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index 7460c2ecc..8fd0cb2ee 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -308,8 +308,8 @@ DivDispatchOscBuffer* DivPlatformT6W28::getOscBuffer(int ch) { return oscBuf[ch]; } -int DivPlatformT6W28::mapVelocity(int ch, unsigned char vel) { - return round(15.0*pow(((double)vel/127.0),0.33)); +int DivPlatformT6W28::mapVelocity(int ch, float vel) { + return round(15.0*pow(vel,0.33)); } unsigned char* DivPlatformT6W28::getRegisterPool() { diff --git a/src/engine/platform/t6w28.h b/src/engine/platform/t6w28.h index ccb89b76d..eae0f92f9 100644 --- a/src/engine/platform/t6w28.h +++ b/src/engine/platform/t6w28.h @@ -65,7 +65,7 @@ class DivPlatformT6W28: public DivDispatch { DivMacroInt* getChanMacroInt(int ch); unsigned short getPan(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); - int mapVelocity(int ch, unsigned char vel); + int mapVelocity(int ch, float vel); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 0c024d78d..19fedebe4 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1373,7 +1373,8 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { if (note.on) { dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,note.channel,note.ins,1)); if (note.volume>=0 && !disCont[dispatchOfChan[note.channel]].dispatch->isVolGlobal()) { - int mappedVol=disCont[dispatchOfChan[note.channel]].dispatch->mapVelocity(dispatchChanOfChan[note.channel],note.volume); + float curvedVol=pow((float)note.volume/127.0f,midiVolExp); + int mappedVol=disCont[dispatchOfChan[note.channel]].dispatch->mapVelocity(dispatchChanOfChan[note.channel],curvedVol); logV("dispatching volume (%d -> %d)",note.volume,mappedVol); dispatchCmd(DivCommand(DIV_CMD_VOLUME,note.channel,mappedVol)); } diff --git a/src/gui/gui.h b/src/gui/gui.h index b379ee743..f754a073d 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1003,7 +1003,7 @@ struct MIDIMap { valueInputControlMSB(0), valueInputControlLSB(0), valueInputControlSingle(0), - volExp(1.0f), + volExp(2.0f), valueInputCurMSB(0), valueInputCurLSB(0), valueInputCurSingle(0) { diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 381c2eb9e..dbf1a9661 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -1139,7 +1139,10 @@ void FurnaceGUI::drawSettings() { // TODO //ImGui::Checkbox("Use raw velocity value (don't map from linear to log)",&midiMap.rawVolume); //ImGui::Checkbox("Polyphonic/chord input",&midiMap.polyInput); - if (ImGui::Checkbox("Map MIDI channels to direct channels",&midiMap.directChannel)) settingsChanged=true; + if (ImGui::Checkbox("Map MIDI channels to direct channels",&midiMap.directChannel)) { + e->setMidiDirect(midiMap.directChannel); + settingsChanged=true; + } if (ImGui::Checkbox("Map Yamaha FM voice data to instruments",&midiMap.yamahaFMResponse)) settingsChanged=true; if (ImGui::Checkbox("Program change is instrument selection",&midiMap.programChange)) settingsChanged=true; //ImGui::Checkbox("Listen to MIDI clock",&midiMap.midiClock); @@ -1198,6 +1201,7 @@ void FurnaceGUI::drawSettings() { if (ImGui::SliderFloat("Volume curve",&midiMap.volExp,0.01,8.0,"%.2f")) { if (midiMap.volExp<0.01) midiMap.volExp=0.01; if (midiMap.volExp>8.0) midiMap.volExp=8.0; + e->setMidiVolExp(midiMap.volExp); settingsChanged=true; } rightClickable float curve[128]; @@ -4025,6 +4029,7 @@ void FurnaceGUI::syncSettings() { midiMap.compile(); e->setMidiDirect(midiMap.directChannel); + e->setMidiVolExp(midiMap.volExp); e->setMetronomeVol(((float)settings.metroVol)/100.0f); e->setSamplePreviewVol(((float)settings.sampleVol)/100.0f); } From 87fc98780041256304ef54cd097d13c7b29aa318 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 17 Dec 2023 03:47:52 -0500 Subject: [PATCH 4/4] remove debug message --- src/engine/playback.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 19fedebe4..59c93cf8a 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1375,7 +1375,6 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { if (note.volume>=0 && !disCont[dispatchOfChan[note.channel]].dispatch->isVolGlobal()) { float curvedVol=pow((float)note.volume/127.0f,midiVolExp); int mappedVol=disCont[dispatchOfChan[note.channel]].dispatch->mapVelocity(dispatchChanOfChan[note.channel],curvedVol); - logV("dispatching volume (%d -> %d)",note.volume,mappedVol); dispatchCmd(DivCommand(DIV_CMD_VOLUME,note.channel,mappedVol)); } dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,note.channel,note.note));