MIDI output improvements
This commit is contained in:
parent
c27c650c11
commit
122694d7c9
|
@ -3683,6 +3683,8 @@ bool DivEngine::initAudioBackend() {
|
||||||
clampSamples=getConfInt("clampSamples",0);
|
clampSamples=getConfInt("clampSamples",0);
|
||||||
lowLatency=getConfInt("lowLatency",0);
|
lowLatency=getConfInt("lowLatency",0);
|
||||||
metroVol=(float)(getConfInt("metroVol",100))/100.0f;
|
metroVol=(float)(getConfInt("metroVol",100))/100.0f;
|
||||||
|
midiOutClock=getConfInt("midiOutClock",0);
|
||||||
|
midiOutMode=getConfInt("midiOutMode",DIV_MIDI_MODE_NOTE);
|
||||||
if (metroVol<0.0f) metroVol=0.0f;
|
if (metroVol<0.0f) metroVol=0.0f;
|
||||||
if (metroVol>2.0f) metroVol=2.0f;
|
if (metroVol>2.0f) metroVol=2.0f;
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,12 @@ enum DivHaltPositions {
|
||||||
DIV_HALT_BREAKPOINT
|
DIV_HALT_BREAKPOINT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DivMIDIModes {
|
||||||
|
DIV_MIDI_MODE_OFF=0,
|
||||||
|
DIV_MIDI_MODE_NOTE,
|
||||||
|
DIV_MIDI_MODE_LIGHT_SHOW
|
||||||
|
};
|
||||||
|
|
||||||
struct DivChannelState {
|
struct DivChannelState {
|
||||||
std::vector<DivDelayedCommand> delayed;
|
std::vector<DivDelayedCommand> delayed;
|
||||||
int note, oldNote, lastIns, pitch, portaSpeed, portaNote;
|
int note, oldNote, lastIns, pitch, portaSpeed, portaNote;
|
||||||
|
@ -340,6 +346,8 @@ class DivEngine {
|
||||||
bool lowLatency;
|
bool lowLatency;
|
||||||
bool systemsRegistered;
|
bool systemsRegistered;
|
||||||
bool hasLoadedSomething;
|
bool hasLoadedSomething;
|
||||||
|
bool midiOutClock;
|
||||||
|
int midiOutMode;
|
||||||
int softLockCount;
|
int softLockCount;
|
||||||
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed;
|
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed;
|
||||||
size_t curSubSongIndex;
|
size_t curSubSongIndex;
|
||||||
|
@ -1008,6 +1016,8 @@ class DivEngine {
|
||||||
lowLatency(false),
|
lowLatency(false),
|
||||||
systemsRegistered(false),
|
systemsRegistered(false),
|
||||||
hasLoadedSomething(false),
|
hasLoadedSomething(false),
|
||||||
|
midiOutClock(false),
|
||||||
|
midiOutMode(DIV_MIDI_MODE_NOTE),
|
||||||
softLockCount(0),
|
softLockCount(0),
|
||||||
subticks(0),
|
subticks(0),
|
||||||
ticks(0),
|
ticks(0),
|
||||||
|
|
|
@ -257,6 +257,7 @@ int DivEngine::dispatchCmd(DivCommand c) {
|
||||||
|
|
||||||
if (output) if (!skipping && output->midiOut!=NULL) {
|
if (output) if (!skipping && output->midiOut!=NULL) {
|
||||||
if (output->midiOut->isDeviceOpen()) {
|
if (output->midiOut->isDeviceOpen()) {
|
||||||
|
if (midiOutMode==DIV_MIDI_MODE_NOTE) {
|
||||||
int scaledVol=(chan[c.chan].volume*127)/MAX(1,chan[c.chan].volMax);
|
int scaledVol=(chan[c.chan].volume*127)/MAX(1,chan[c.chan].volMax);
|
||||||
if (scaledVol<0) scaledVol=0;
|
if (scaledVol<0) scaledVol=0;
|
||||||
if (scaledVol>127) scaledVol=127;
|
if (scaledVol>127) scaledVol=127;
|
||||||
|
@ -301,11 +302,37 @@ int DivEngine::dispatchCmd(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_PANNING: {
|
||||||
|
int pan=convertPanSplitToLinearLR(c.value,c.value2,127);
|
||||||
|
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x0a,pan));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_HINT_PORTA: {
|
||||||
|
if (c.value2>0) {
|
||||||
|
if (c.value<=0 || c.value>=255) break;
|
||||||
|
//output->midiOut->send(TAMidiMessage(0x80|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||||
|
int target=c.value+12;
|
||||||
|
if (target<0) target=0;
|
||||||
|
if (target>127) target=127;
|
||||||
|
|
||||||
|
if (chan[c.chan].curMidiNote>=0) {
|
||||||
|
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x54,chan[c.chan].curMidiNote));
|
||||||
|
}
|
||||||
|
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x05,1/*MIN(0x7f,c.value2/4)*/));
|
||||||
|
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x41,0x7f));
|
||||||
|
|
||||||
|
output->midiOut->send(TAMidiMessage(0x90|(c.chan&15),target,scaledVol));
|
||||||
|
} else {
|
||||||
|
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x41,0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.chan=dispatchChanOfChan[c.dis];
|
c.chan=dispatchChanOfChan[c.dis];
|
||||||
|
|
||||||
|
@ -1055,11 +1082,6 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
||||||
cycles++;
|
cycles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIDI clock
|
|
||||||
if (output) if (!skipping && output->midiOut!=NULL) {
|
|
||||||
//output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pendingNotes.empty()) {
|
if (!pendingNotes.empty()) {
|
||||||
bool isOn[DIV_MAX_CHANS];
|
bool isOn[DIV_MAX_CHANS];
|
||||||
memset(isOn,0,DIV_MAX_CHANS*sizeof(bool));
|
memset(isOn,0,DIV_MAX_CHANS*sizeof(bool));
|
||||||
|
@ -1106,6 +1128,12 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
||||||
if (!freelance) {
|
if (!freelance) {
|
||||||
if (--subticks<=0) {
|
if (--subticks<=0) {
|
||||||
subticks=tickMult;
|
subticks=tickMult;
|
||||||
|
|
||||||
|
// MIDI clock
|
||||||
|
if (output) if (!skipping && output->midiOut!=NULL && midiOutClock) {
|
||||||
|
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
|
||||||
|
}
|
||||||
|
|
||||||
if (stepPlay!=1) {
|
if (stepPlay!=1) {
|
||||||
tempoAccum+=curSubSong->virtualTempoN;
|
tempoAccum+=curSubSong->virtualTempoN;
|
||||||
while (tempoAccum>=curSubSong->virtualTempoD) {
|
while (tempoAccum>=curSubSong->virtualTempoD) {
|
||||||
|
|
|
@ -1195,6 +1195,8 @@ class FurnaceGUI {
|
||||||
int channelFeedbackStyle;
|
int channelFeedbackStyle;
|
||||||
int channelFont;
|
int channelFont;
|
||||||
int channelTextCenter;
|
int channelTextCenter;
|
||||||
|
int midiOutClock;
|
||||||
|
int midiOutMode;
|
||||||
int maxRecentFile;
|
int maxRecentFile;
|
||||||
unsigned int maxUndoSteps;
|
unsigned int maxUndoSteps;
|
||||||
String mainFontPath;
|
String mainFontPath;
|
||||||
|
@ -1318,6 +1320,8 @@ class FurnaceGUI {
|
||||||
channelFeedbackStyle(1),
|
channelFeedbackStyle(1),
|
||||||
channelFont(1),
|
channelFont(1),
|
||||||
channelTextCenter(1),
|
channelTextCenter(1),
|
||||||
|
midiOutClock(0),
|
||||||
|
midiOutMode(1),
|
||||||
maxRecentFile(10),
|
maxRecentFile(10),
|
||||||
maxUndoSteps(100),
|
maxUndoSteps(100),
|
||||||
mainFontPath(""),
|
mainFontPath(""),
|
||||||
|
|
|
@ -955,6 +955,26 @@ void FurnaceGUI::drawSettings() {
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
if (ImGui::TreeNode("MIDI output settings")) {
|
||||||
|
ImGui::Text("Output mode:");
|
||||||
|
if (ImGui::RadioButton("Off (use for TX81Z)",settings.midiOutMode==0)) {
|
||||||
|
settings.midiOutMode=0;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("Melodic",settings.midiOutMode==1)) {
|
||||||
|
settings.midiOutMode=1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (ImGui::RadioButton("Light Show (use for Launchpad)",settings.midiOutMode==2)) {
|
||||||
|
settings.midiOutMode=2;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
bool midiOutClockB=settings.midiOutClock;
|
||||||
|
if (ImGui::Checkbox("Send MIDI clock",&midiOutClockB)) {
|
||||||
|
settings.midiOutClock=midiOutClockB;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2314,6 +2334,8 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.channelFont=e->getConfInt("channelFont",1);
|
settings.channelFont=e->getConfInt("channelFont",1);
|
||||||
settings.channelTextCenter=e->getConfInt("channelTextCenter",1);
|
settings.channelTextCenter=e->getConfInt("channelTextCenter",1);
|
||||||
settings.maxRecentFile=e->getConfInt("maxRecentFile",10);
|
settings.maxRecentFile=e->getConfInt("maxRecentFile",10);
|
||||||
|
settings.midiOutClock=e->getConfInt("midiOutClock",0);
|
||||||
|
settings.midiOutMode=e->getConfInt("midiOutMode",1);
|
||||||
|
|
||||||
clampSetting(settings.mainFontSize,2,96);
|
clampSetting(settings.mainFontSize,2,96);
|
||||||
clampSetting(settings.patFontSize,2,96);
|
clampSetting(settings.patFontSize,2,96);
|
||||||
|
@ -2415,6 +2437,8 @@ void FurnaceGUI::syncSettings() {
|
||||||
clampSetting(settings.channelFont,0,1);
|
clampSetting(settings.channelFont,0,1);
|
||||||
clampSetting(settings.channelTextCenter,0,1);
|
clampSetting(settings.channelTextCenter,0,1);
|
||||||
clampSetting(settings.maxRecentFile,0,30);
|
clampSetting(settings.maxRecentFile,0,30);
|
||||||
|
clampSetting(settings.midiOutClock,0,1);
|
||||||
|
clampSetting(settings.midiOutMode,0,2);
|
||||||
|
|
||||||
settings.initialSys=e->decodeSysDesc(e->getConfString("initialSys",""));
|
settings.initialSys=e->decodeSysDesc(e->getConfString("initialSys",""));
|
||||||
if (settings.initialSys.size()<4) {
|
if (settings.initialSys.size()<4) {
|
||||||
|
@ -2572,6 +2596,8 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("channelFont",settings.channelFont);
|
e->setConf("channelFont",settings.channelFont);
|
||||||
e->setConf("channelTextCenter",settings.channelTextCenter);
|
e->setConf("channelTextCenter",settings.channelTextCenter);
|
||||||
e->setConf("maxRecentFile",settings.maxRecentFile);
|
e->setConf("maxRecentFile",settings.maxRecentFile);
|
||||||
|
e->setConf("midiOutClock",settings.midiOutClock);
|
||||||
|
e->setConf("midiOutMode",settings.midiOutMode);
|
||||||
|
|
||||||
// colors
|
// colors
|
||||||
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
||||||
|
|
Loading…
Reference in a new issue