Merge branch 'master' into feature/esfm

This commit is contained in:
Kagamiin~ 2023-12-17 08:31:16 -03:00
commit 13e45cfce2
19 changed files with 62 additions and 9 deletions

View file

@ -599,10 +599,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.

View file

@ -3391,6 +3391,10 @@ void DivEngine::setMidiDirect(bool value) {
midiIsDirect=value;
}
void DivEngine::setMidiVolExp(float value) {
midiVolExp=value;
}
void DivEngine::setMidiCallback(std::function<int(const TAMidiMessage&)> what) {
midiCallback=what;
}

View file

@ -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<int(const TAMidiMessage&)> 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),

View file

@ -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) {

View file

@ -719,6 +719,10 @@ DivDispatchOscBuffer* DivPlatformAY8910::getOscBuffer(int ch) {
return oscBuf[ch];
}
int DivPlatformAY8910::mapVelocity(int ch, float vel) {
return round(15.0*pow(vel,0.33));
}
unsigned char* DivPlatformAY8910::getRegisterPool() {
return regPool;
}

View file

@ -131,6 +131,7 @@ class DivPlatformAY8910: public DivDispatch {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivDispatchOscBuffer* getOscBuffer(int chan);
int mapVelocity(int ch, float vel);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void flushWrites();

View file

@ -718,6 +718,10 @@ DivDispatchOscBuffer* DivPlatformAY8930::getOscBuffer(int ch) {
return oscBuf[ch];
}
int DivPlatformAY8930::mapVelocity(int ch, float vel) {
return round(31.0*pow(vel,0.22));
}
unsigned char* DivPlatformAY8930::getRegisterPool() {
return regPool;
}

View file

@ -132,6 +132,7 @@ class DivPlatformAY8930: public DivDispatch {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivDispatchOscBuffer* getOscBuffer(int chan);
int mapVelocity(int ch, float vel);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();

View file

@ -121,6 +121,20 @@ class DivPlatformFMBase: public DivDispatch {
}
}
}
virtual int mapVelocity(int ch, float 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*127.0)*8.0)),0,127);
}
friend void putDispatchChan(void*,int,int);

View file

@ -539,6 +539,10 @@ DivDispatchOscBuffer* DivPlatformPCE::getOscBuffer(int ch) {
return oscBuf[ch];
}
int DivPlatformPCE::mapVelocity(int ch, float vel) {
return round(31.0*pow(vel,0.22));
}
unsigned char* DivPlatformPCE::getRegisterPool() {
return regPool;
}

View file

@ -86,6 +86,7 @@ class DivPlatformPCE: public DivDispatch {
DivChannelModeHints getModeHints(int chan);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
int mapVelocity(int ch, float vel);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();

View file

@ -462,6 +462,10 @@ DivDispatchOscBuffer* DivPlatformSMS::getOscBuffer(int ch) {
return oscBuf[ch];
}
int DivPlatformSMS::mapVelocity(int ch, float vel) {
return round(15.0*pow(vel,0.33));
}
unsigned char* DivPlatformSMS::getRegisterPool() {
return regPool;
}

View file

@ -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, float vel);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();

View file

@ -308,6 +308,10 @@ DivDispatchOscBuffer* DivPlatformT6W28::getOscBuffer(int ch) {
return oscBuf[ch];
}
int DivPlatformT6W28::mapVelocity(int ch, float vel) {
return round(15.0*pow(vel,0.33));
}
unsigned char* DivPlatformT6W28::getRegisterPool() {
return regPool;
}

View file

@ -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, float vel);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();

View file

@ -1378,9 +1378,9 @@ 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);
logV("dispatching volume (%d -> %d)",note.volume,mappedVol);
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);
dispatchCmd(DivCommand(DIV_CMD_VOLUME,note.channel,mappedVol));
}
dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,note.channel,note.note));