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)); }