From b2223ccd0f4869a3540d8be141b0ae686cd3da2e Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 22 Jul 2024 19:08:39 -0500 Subject: [PATCH] implement getGain for a couple chips the ones with log volume --- src/engine/engine.cpp | 7 +++++++ src/engine/engine.h | 3 +++ src/engine/platform/ay.cpp | 5 +++++ src/engine/platform/ay.h | 1 + src/engine/platform/ay8930.cpp | 5 +++++ src/engine/platform/ay8930.h | 1 + src/engine/platform/fmshared_OPN.h | 13 +++++++++++++ src/engine/platform/fmsharedbase.h | 5 +++++ src/engine/platform/opl.cpp | 5 +++++ src/engine/platform/opl.h | 1 + src/engine/platform/opll.cpp | 5 +++++ src/engine/platform/opll.h | 1 + src/engine/platform/pce.cpp | 5 +++++ src/engine/platform/pce.h | 1 + src/engine/platform/sms.cpp | 5 +++++ src/engine/platform/sms.h | 1 + src/gui/gui.cpp | 2 +- 17 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index b8114abbf..3f0fbe7eb 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2330,6 +2330,13 @@ int DivEngine::mapVelocity(int ch, float vel) { return disCont[dispatchOfChan[ch]].dispatch->mapVelocity(dispatchChanOfChan[ch],vel); } +float DivEngine::getGain(int ch, int vol) { + if (ch<0) return 0; + if (ch>=chans) return 0; + if (disCont[dispatchOfChan[ch]].dispatch==NULL) return 0; + return disCont[dispatchOfChan[ch]].dispatch->getGain(dispatchChanOfChan[ch],vol); +} + unsigned char DivEngine::getOrder() { return prevOrder; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 08a4845c2..e4da99f91 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -927,6 +927,9 @@ class DivEngine { // map MIDI velocity to volume int mapVelocity(int ch, float vel); + // map volume to gain + float getGain(int ch, int vol); + // get current order unsigned char getOrder(); diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 4d57d022f..75d3a48bd 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -801,6 +801,11 @@ int DivPlatformAY8910::mapVelocity(int ch, float vel) { return round(15.0*pow(vel,0.33)); } +float DivPlatformAY8910::getGain(int ch, int vol) { + if (vol==0) return 0; + return 1.0/pow(10.0,(float)(15-vol)*2.0/20.0); +} + unsigned char* DivPlatformAY8910::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 49641c328..8b64b5405 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -144,6 +144,7 @@ class DivPlatformAY8910: public DivDispatch { void* getChanState(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); int mapVelocity(int ch, float vel); + float getGain(int ch, int vol); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void setCore(unsigned char core); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 334bb5295..250581bf9 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -792,6 +792,11 @@ int DivPlatformAY8930::mapVelocity(int ch, float vel) { return round(31.0*pow(vel,0.22)); } +float DivPlatformAY8930::getGain(int ch, int vol) { + if (vol==0) return 0; + return 1.0/pow(10.0,(float)(31-vol)*1.5/20.0); +} + unsigned char* DivPlatformAY8930::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 7087a246b..828c0c306 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -138,6 +138,7 @@ class DivPlatformAY8930: public DivDispatch { void* getChanState(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); int mapVelocity(int ch, float vel); + float getGain(int ch, int vol); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/fmshared_OPN.h b/src/engine/platform/fmshared_OPN.h index 57170e51d..d7ba70418 100644 --- a/src/engine/platform/fmshared_OPN.h +++ b/src/engine/platform/fmshared_OPN.h @@ -198,6 +198,19 @@ class DivPlatformOPN: public DivPlatformFMBase { if (ch>=psgChanOffs) return round(15.0*pow(vel,0.33)); return DivPlatformFMBase::mapVelocity(ch,vel); } + virtual float getGain(int ch, int vol) { + if (vol==0) return 0; + if (ch==csmChan) return 1; + if (ch==adpcmBChanOffs) return (float)vol/255.0; + if (ch>=adpcmAChanOffs) { + return 1.0/pow(10.0,(float)(31-vol)*0.75/20.0); + } + if (ch>=psgChanOffs) { + return 1.0/pow(10.0,(float)(15-vol)*1.5/20.0); + } + return DivPlatformFMBase::getGain(ch,vol); + } + }; #endif diff --git a/src/engine/platform/fmsharedbase.h b/src/engine/platform/fmsharedbase.h index 3f5db9229..ca5b52775 100644 --- a/src/engine/platform/fmsharedbase.h +++ b/src/engine/platform/fmsharedbase.h @@ -136,6 +136,11 @@ class DivPlatformFMBase: public DivDispatch { return CLAMP(round(128.0-(56.0-log2(vel*127.0)*8.0)),0,127); } + virtual float getGain(int ch, int vol) { + if (vol==0) return 0; + return 1.0/pow(10.0,(float)(127-vol)*0.75/20.0); + } + bool getLegacyAlwaysSetVolume() { return true; } diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 77eabbf1e..bdf690644 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -2140,6 +2140,11 @@ int DivPlatformOPL::mapVelocity(int ch, float vel) { return CLAMP(round(64.0-(56.0-log2(vel*127.0)*8.0)),0,63); } +float DivPlatformOPL::getGain(int ch, int vol) { + if (vol==0) return 0; + return 1.0/pow(10.0,(float)(63-vol)*0.75/20.0); +} + unsigned char* DivPlatformOPL::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/opl.h b/src/engine/platform/opl.h index e76aae834..327389c1f 100644 --- a/src/engine/platform/opl.h +++ b/src/engine/platform/opl.h @@ -154,6 +154,7 @@ class DivPlatformOPL: public DivDispatch { DivChannelPair getPaired(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); int mapVelocity(int ch, float vel); + float getGain(int ch, int vol); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index c231b749b..fb3461622 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -1026,6 +1026,11 @@ int DivPlatformOPLL::mapVelocity(int ch, float vel) { return CLAMP(round(16.0-(14.0-log2(vel*127.0)*2.0)),0,15); } +float DivPlatformOPLL::getGain(int ch, int vol) { + if (vol==0) return 0; + return 1.0/pow(10.0,(float)(15-vol)*3.0/20.0); +} + unsigned char* DivPlatformOPLL::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/opll.h b/src/engine/platform/opll.h index efa75fa51..b1f6e56ac 100644 --- a/src/engine/platform/opll.h +++ b/src/engine/platform/opll.h @@ -99,6 +99,7 @@ class DivPlatformOPLL: public DivDispatch { DivMacroInt* getChanMacroInt(int ch); DivDispatchOscBuffer* getOscBuffer(int chan); int mapVelocity(int ch, float vel); + float getGain(int ch, int vol); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index dbc4fec46..d65271a3b 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -575,6 +575,11 @@ int DivPlatformPCE::mapVelocity(int ch, float vel) { return round(31.0*pow(vel,0.22)); } +float DivPlatformPCE::getGain(int ch, int vol) { + if (vol==0) return 0; + return 1.0/pow(10.0,(float)(31-vol)*3.0/20.0); +} + unsigned char* DivPlatformPCE::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 18ce23331..725d1c232 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -90,6 +90,7 @@ class DivPlatformPCE: public DivDispatch { DivSamplePos getSamplePos(int ch); DivDispatchOscBuffer* getOscBuffer(int chan); int mapVelocity(int ch, float vel); + float getGain(int ch, int vol); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 27693e7cb..7be834bda 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -466,6 +466,11 @@ int DivPlatformSMS::mapVelocity(int ch, float vel) { return round(15.0*pow(vel,0.33)); } +float DivPlatformSMS::getGain(int ch, int vol) { + if (vol==0) return 0; + return 1.0/pow(10.0,(float)(15-vol)*2.0/20.0); +} + unsigned char* DivPlatformSMS::getRegisterPool() { return regPool; } diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index d2d0c901f..58efd06e5 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -80,6 +80,7 @@ class DivPlatformSMS: public DivDispatch { unsigned short getPan(int chan); DivDispatchOscBuffer* getOscBuffer(int chan); int mapVelocity(int ch, float vel); + float getGain(int ch, int vol); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 0444b33ab..156e26eab 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4680,7 +4680,7 @@ bool FurnaceGUI::loop() { if (maxVol<1 || p->data[cursor.y][3]>maxVol) { info=fmt::sprintf(_("Set volume: %d (%.2X, INVALID!)"),p->data[cursor.y][3],p->data[cursor.y][3]); } else { - float realVol=e->mapVelocity(cursor.xCoarse,(float)p->data[cursor.y][3]/(float)maxVol); + float realVol=e->getGain(cursor.xCoarse,p->data[cursor.y][3]); info=fmt::sprintf(_("Set volume: %d (%.2X, %d%%)"),p->data[cursor.y][3],p->data[cursor.y][3],(int)(realVol*100.0f/(float)maxVol)); } hasInfo=true;