implement more MIDI stuff
This commit is contained in:
parent
a08f7507fd
commit
052dcb2576
|
@ -251,7 +251,7 @@ class DivEngine {
|
|||
size_t totalProcessed;
|
||||
|
||||
// MIDI stuff
|
||||
std::function<int(const TAMidiMessage&)> midiCallback=[](const TAMidiMessage&) -> int {return -1;};
|
||||
std::function<int(const TAMidiMessage&)> midiCallback=[](const TAMidiMessage&) -> int {return -2;};
|
||||
|
||||
DivSystem systemFromFile(unsigned char val);
|
||||
unsigned char systemToFile(DivSystem val);
|
||||
|
|
186
src/gui/gui.cpp
186
src/gui/gui.cpp
|
@ -805,6 +805,64 @@ void FurnaceGUI::noteInput(int num, int key, int vol) {
|
|||
curNibble=false;
|
||||
}
|
||||
|
||||
void FurnaceGUI::valueInput(int num, bool direct, int target) {
|
||||
DivPattern* pat=e->song.pat[cursor.xCoarse].getPattern(e->song.orders.ord[cursor.xCoarse][e->getOrder()],true);
|
||||
prepareUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
if (target==-1) target=cursor.xFine+1;
|
||||
if (direct) {
|
||||
pat->data[cursor.y][target]=num&0xff;
|
||||
} else {
|
||||
if (pat->data[cursor.y][target]==-1) pat->data[cursor.y][target]=0;
|
||||
pat->data[cursor.y][target]=((pat->data[cursor.y][target]<<4)|num)&0xff;
|
||||
}
|
||||
if (cursor.xFine==1) { // instrument
|
||||
if (pat->data[cursor.y][target]>=(int)e->song.ins.size()) {
|
||||
pat->data[cursor.y][target]&=0x0f;
|
||||
if (pat->data[cursor.y][target]>=(int)e->song.ins.size()) {
|
||||
pat->data[cursor.y][target]=(int)e->song.ins.size()-1;
|
||||
}
|
||||
}
|
||||
makeUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
if (direct) {
|
||||
curNibble=false;
|
||||
} else {
|
||||
if (e->song.ins.size()<16) {
|
||||
curNibble=false;
|
||||
editAdvance();
|
||||
} else {
|
||||
curNibble=!curNibble;
|
||||
if (!curNibble) editAdvance();
|
||||
}
|
||||
}
|
||||
} else if (cursor.xFine==2) {
|
||||
if (curNibble) {
|
||||
if (pat->data[cursor.y][target]>e->getMaxVolumeChan(cursor.xCoarse)) pat->data[cursor.y][target]=e->getMaxVolumeChan(cursor.xCoarse);
|
||||
} else {
|
||||
pat->data[cursor.y][target]&=15;
|
||||
}
|
||||
makeUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
if (direct) {
|
||||
curNibble=false;
|
||||
} else {
|
||||
if (e->getMaxVolumeChan(cursor.xCoarse)<16) {
|
||||
curNibble=false;
|
||||
editAdvance();
|
||||
} else {
|
||||
curNibble=!curNibble;
|
||||
if (!curNibble) editAdvance();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
makeUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
if (direct) {
|
||||
curNibble=false;
|
||||
} else {
|
||||
curNibble=!curNibble;
|
||||
if (!curNibble) editAdvance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::keyDown(SDL_Event& ev) {
|
||||
if (ImGuiFileDialog::Instance()->IsOpened()) return;
|
||||
if (aboutOpen) return;
|
||||
|
@ -879,44 +937,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
} else if (edit) { // value
|
||||
try {
|
||||
int num=valueKeys.at(ev.key.keysym.sym);
|
||||
DivPattern* pat=e->song.pat[cursor.xCoarse].getPattern(e->song.orders.ord[cursor.xCoarse][e->getOrder()],true);
|
||||
prepareUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
if (pat->data[cursor.y][cursor.xFine+1]==-1) pat->data[cursor.y][cursor.xFine+1]=0;
|
||||
pat->data[cursor.y][cursor.xFine+1]=((pat->data[cursor.y][cursor.xFine+1]<<4)|num)&0xff;
|
||||
if (cursor.xFine==1) { // instrument
|
||||
if (pat->data[cursor.y][cursor.xFine+1]>=(int)e->song.ins.size()) {
|
||||
pat->data[cursor.y][cursor.xFine+1]&=0x0f;
|
||||
if (pat->data[cursor.y][cursor.xFine+1]>=(int)e->song.ins.size()) {
|
||||
pat->data[cursor.y][cursor.xFine+1]=(int)e->song.ins.size()-1;
|
||||
}
|
||||
}
|
||||
makeUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
if (e->song.ins.size()<16) {
|
||||
curNibble=false;
|
||||
editAdvance();
|
||||
} else {
|
||||
curNibble=!curNibble;
|
||||
if (!curNibble) editAdvance();
|
||||
}
|
||||
} else if (cursor.xFine==2) {
|
||||
if (curNibble) {
|
||||
if (pat->data[cursor.y][cursor.xFine+1]>e->getMaxVolumeChan(cursor.xCoarse)) pat->data[cursor.y][cursor.xFine+1]=e->getMaxVolumeChan(cursor.xCoarse);
|
||||
} else {
|
||||
pat->data[cursor.y][cursor.xFine+1]&=15;
|
||||
}
|
||||
makeUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
if (e->getMaxVolumeChan(cursor.xCoarse)<16) {
|
||||
curNibble=false;
|
||||
editAdvance();
|
||||
} else {
|
||||
curNibble=!curNibble;
|
||||
if (!curNibble) editAdvance();
|
||||
}
|
||||
} else {
|
||||
makeUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
curNibble=!curNibble;
|
||||
if (!curNibble) editAdvance();
|
||||
}
|
||||
valueInput(num);
|
||||
} catch (std::out_of_range& e) {
|
||||
}
|
||||
}
|
||||
|
@ -1931,7 +1952,7 @@ bool FurnaceGUI::loop() {
|
|||
midiMap.binds[learning].type=msg.type>>4;
|
||||
midiMap.binds[learning].channel=msg.type&15;
|
||||
midiMap.binds[learning].data1=msg.data[0];
|
||||
switch (msg.type>>4) {
|
||||
switch (msg.type&0xf0) {
|
||||
case TA_MIDI_NOTE_OFF:
|
||||
case TA_MIDI_NOTE_ON:
|
||||
case TA_MIDI_AFTERTOUCH:
|
||||
|
@ -1951,13 +1972,36 @@ bool FurnaceGUI::loop() {
|
|||
doAction(action);
|
||||
} else switch (msg.type&0xf0) {
|
||||
case TA_MIDI_NOTE_ON:
|
||||
if (edit && msg.data[1]!=0) {
|
||||
if (midiMap.valueInputStyle==0 || midiMap.valueInputStyle>3 || cursor.xFine==0) {
|
||||
if (midiMap.noteInput && edit && msg.data[1]!=0) {
|
||||
noteInput(
|
||||
msg.data[0]-12,
|
||||
0,
|
||||
midiMap.volInput?((int)(pow((double)msg.data[2]/127.0,midiMap.volExp)*127.0)):-1
|
||||
midiMap.volInput?((int)(pow((double)msg.data[1]/127.0,midiMap.volExp)*127.0)):-1
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (edit && msg.data[1]!=0) {
|
||||
switch (midiMap.valueInputStyle) {
|
||||
case 1: {
|
||||
int val=msg.data[0]%24;
|
||||
if (val<16) {
|
||||
valueInput(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
valueInput(msg.data[0]&15);
|
||||
break;
|
||||
case 3:
|
||||
int val=altValues[msg.data[0]%24];
|
||||
if (val>=0) {
|
||||
valueInput(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TA_MIDI_PROGRAM:
|
||||
if (midiMap.programChange) {
|
||||
|
@ -1965,6 +2009,64 @@ bool FurnaceGUI::loop() {
|
|||
if (curIns>=(int)e->song.ins.size()) curIns=e->song.ins.size()-1;
|
||||
}
|
||||
break;
|
||||
case TA_MIDI_CONTROL:
|
||||
bool gchanged=false;
|
||||
if (msg.data[0]==midiMap.valueInputControlMSB) {
|
||||
midiMap.valueInputCurMSB=msg.data[1];
|
||||
gchanged=true;
|
||||
}
|
||||
if (msg.data[0]==midiMap.valueInputControlLSB) {
|
||||
midiMap.valueInputCurLSB=msg.data[1];
|
||||
gchanged=true;
|
||||
}
|
||||
if (msg.data[0]==midiMap.valueInputControlSingle) {
|
||||
midiMap.valueInputCurSingle=msg.data[1];
|
||||
gchanged=true;
|
||||
}
|
||||
if (gchanged && cursor.xFine>0) {
|
||||
switch (midiMap.valueInputStyle) {
|
||||
case 4: // dual CC
|
||||
valueInput(((midiMap.valueInputCurMSB>>3)<<4)|(midiMap.valueInputCurLSB>>3),true);
|
||||
break;
|
||||
case 5: // 14-bit
|
||||
valueInput((midiMap.valueInputCurMSB<<1)|(midiMap.valueInputCurLSB>>6),true);
|
||||
break;
|
||||
case 6: // single CC
|
||||
valueInput((midiMap.valueInputCurSingle*255)/127,true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<18; i++) {
|
||||
bool changed=false;
|
||||
if (midiMap.valueInputSpecificStyle[i]!=0) {
|
||||
if (msg.data[0]==midiMap.valueInputSpecificMSB[i]) {
|
||||
changed=true;
|
||||
midiMap.valueInputCurMSBS[i]=msg.data[1];
|
||||
}
|
||||
if (msg.data[0]==midiMap.valueInputSpecificLSB[i]) {
|
||||
changed=true;
|
||||
midiMap.valueInputCurLSBS[i]=msg.data[1];
|
||||
}
|
||||
if (msg.data[0]==midiMap.valueInputSpecificSingle[i]) {
|
||||
changed=true;
|
||||
midiMap.valueInputCurSingleS[i]=msg.data[1];
|
||||
}
|
||||
|
||||
if (changed) switch (midiMap.valueInputStyle) {
|
||||
case 1: // dual CC
|
||||
valueInput(((midiMap.valueInputCurMSBS[i]>>3)<<4)|(midiMap.valueInputCurLSBS[i]>>3),true,i+2);
|
||||
break;
|
||||
case 2: // 14-bit
|
||||
valueInput((midiMap.valueInputCurMSBS[i]<<1)|(midiMap.valueInputCurLSBS[i]>>6),true,i+2);
|
||||
break;
|
||||
case 3: // single CC
|
||||
valueInput((midiMap.valueInputCurSingleS[i]*255)/127,true,i+2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2734,6 +2836,8 @@ bool FurnaceGUI::init() {
|
|||
midiQueue.push(msg);
|
||||
midiLock.unlock();
|
||||
e->setMidiBaseChan(cursor.xCoarse);
|
||||
if (midiMap.valueInputStyle!=0 && cursor.xFine!=0 && edit) return -2;
|
||||
if (!midiMap.noteInput) return -2;
|
||||
if (learning!=-1) return -2;
|
||||
if (midiMap.at(msg)) return -2;
|
||||
return curIns;
|
||||
|
|
|
@ -539,11 +539,27 @@ struct MIDIMap {
|
|||
//
|
||||
// 4: use dual CC for value input (nibble)
|
||||
// 5: use 14-bit CC for value input (MSB/LSB)
|
||||
// 6: use single CC for value input (may be imprecise)
|
||||
int valueInputStyle;
|
||||
int valueInputControlMSB; // on 4
|
||||
int valueInputControlLSB; // on 4
|
||||
int valueInputControlSingle;
|
||||
|
||||
// 0: disabled
|
||||
// 1: use dual CC (nibble)
|
||||
// 2: use 14-bit CC (MSB/LSB)
|
||||
// 3: use single CC (may be imprecise)
|
||||
int valueInputSpecificStyle[18];
|
||||
int valueInputSpecificMSB[18];
|
||||
int valueInputSpecificLSB[18];
|
||||
int valueInputSpecificSingle[18];
|
||||
float volExp;
|
||||
|
||||
int valueInputCurMSB, valueInputCurLSB, valueInputCurSingle;
|
||||
int valueInputCurMSBS[18];
|
||||
int valueInputCurLSBS[18];
|
||||
int valueInputCurSingleS[18];
|
||||
|
||||
void compile();
|
||||
void deinit();
|
||||
int at(const TAMidiMessage& where);
|
||||
|
@ -560,7 +576,19 @@ struct MIDIMap {
|
|||
midiClock(false),
|
||||
midiTimeCode(false),
|
||||
valueInputStyle(1),
|
||||
volExp(1.0f) {}
|
||||
volExp(1.0f),
|
||||
valueInputCurMSB(0),
|
||||
valueInputCurLSB(0),
|
||||
valueInputCurSingle(0) {
|
||||
memset(valueInputSpecificStyle,0,18*sizeof(int));
|
||||
memset(valueInputSpecificMSB,0,18*sizeof(int));
|
||||
memset(valueInputSpecificLSB,0,18*sizeof(int));
|
||||
memset(valueInputSpecificSingle,0,18*sizeof(int));
|
||||
|
||||
memset(valueInputCurMSBS,0,18*sizeof(int));
|
||||
memset(valueInputCurLSBS,0,18*sizeof(int));
|
||||
memset(valueInputCurSingleS,0,18*sizeof(int));
|
||||
}
|
||||
};
|
||||
|
||||
struct Particle {
|
||||
|
@ -983,6 +1011,7 @@ class FurnaceGUI {
|
|||
void doRedo();
|
||||
void editOptions(bool topMenu);
|
||||
void noteInput(int num, int key, int vol=-1);
|
||||
void valueInput(int num, bool direct=false, int target=-1);
|
||||
|
||||
void doUndoSample();
|
||||
void doRedoSample();
|
||||
|
|
|
@ -66,6 +66,10 @@ const char* pitchLabel[11]={
|
|||
"1/6", "1/5", "1/4", "1/3", "1/2", "1x", "2x", "3x", "4x", "5x", "6x"
|
||||
};
|
||||
|
||||
const int altValues[24]={
|
||||
0, 10, 1, 11, 2, 3, 12, 4, 13, 5, 14, 6, 7, 15, 8, -1, 9, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
const char* insTypes[DIV_INS_MAX]={
|
||||
"Standard",
|
||||
"FM (4-operator)",
|
||||
|
|
|
@ -28,3 +28,4 @@ extern const char* sampleDepths[17];
|
|||
extern const char* resampleStrats[];
|
||||
extern const int availableSystems[];
|
||||
extern const char* guiActions[][2];
|
||||
extern const int altValues[24];
|
|
@ -62,6 +62,14 @@ int MIDIMap::at(const TAMidiMessage& where) {
|
|||
x=std::stof(optionValueS); \
|
||||
}
|
||||
|
||||
#define UNDERSTAND_ARRAY_OPTION(x,yMax) if (optionNameS==#x) { \
|
||||
if (optionIndex<0 || optionIndex>=yMax) { \
|
||||
logW("MIDI map array option %d out of range (0-%d) at line %d: %s\n",optionIndex,yMax,curLine,line); \
|
||||
break; \
|
||||
} \
|
||||
x[optionIndex]=std::stoi(optionValueS); \
|
||||
}
|
||||
|
||||
bool MIDIMap::read(String path) {
|
||||
char line[4096];
|
||||
int curLine=1;
|
||||
|
@ -77,6 +85,37 @@ bool MIDIMap::read(String path) {
|
|||
while (fgets(line,4096,f)) {
|
||||
char* nlPos=strrchr(line,'\n');
|
||||
if (nlPos!=NULL) *nlPos=0;
|
||||
if (strstr(line,"aOption")==line) {
|
||||
char optionName[256];
|
||||
int optionIndex=-1;
|
||||
char optionValue[256];
|
||||
String optionNameS, optionValueS;
|
||||
|
||||
int result=sscanf(line,"aOption %255s %d %255s",optionName,&optionIndex,optionValue);
|
||||
if (result!=3) {
|
||||
logW("MIDI map garbage data at line %d: %s\n",curLine,line);
|
||||
break;
|
||||
}
|
||||
|
||||
optionNameS=optionName;
|
||||
optionValueS=optionValue;
|
||||
|
||||
try {
|
||||
UNDERSTAND_ARRAY_OPTION(valueInputSpecificStyle,18) else
|
||||
UNDERSTAND_ARRAY_OPTION(valueInputSpecificMSB,18) else
|
||||
UNDERSTAND_ARRAY_OPTION(valueInputSpecificLSB,18) else
|
||||
UNDERSTAND_ARRAY_OPTION(valueInputSpecificSingle,18) else {
|
||||
logW("MIDI map unknown array option %s at line %d: %s\n",optionName,curLine,line);
|
||||
}
|
||||
} catch (std::out_of_range& e) {
|
||||
logW("MIDI map invalid value %s for array option %s at line %d: %s\n",optionValue,optionName,curLine,line);
|
||||
} catch (std::invalid_argument& e) {
|
||||
logW("MIDI map invalid value %s for array option %s at line %d: %s\n",optionValue,optionName,curLine,line);
|
||||
}
|
||||
|
||||
curLine++;
|
||||
continue;
|
||||
}
|
||||
if (strstr(line,"option")==line) {
|
||||
char optionName[256];
|
||||
char optionValue[256];
|
||||
|
@ -102,6 +141,7 @@ bool MIDIMap::read(String path) {
|
|||
UNDERSTAND_OPTION(valueInputStyle) else
|
||||
UNDERSTAND_OPTION(valueInputControlMSB) else
|
||||
UNDERSTAND_OPTION(valueInputControlLSB) else
|
||||
UNDERSTAND_OPTION(valueInputControlSingle) else
|
||||
UNDERSTAND_FLOAT_OPTION(volExp) else {
|
||||
logW("MIDI map unknown option %s at line %d: %s\n",optionName,curLine,line);
|
||||
}
|
||||
|
@ -146,6 +186,7 @@ bool MIDIMap::read(String path) {
|
|||
|
||||
#define WRITE_OPTION(x) fprintf(f,"option " #x " %d\n",x);
|
||||
#define WRITE_FLOAT_OPTION(x) fprintf(f,"option " #x " %f\n",x);
|
||||
#define WRITE_ARRAY_OPTION(x,y) fprintf(f,"aOption " #x " %d %d\n",y,x[y]);
|
||||
|
||||
bool MIDIMap::write(String path) {
|
||||
FILE* f=fopen(path.c_str(),"wb");
|
||||
|
@ -165,8 +206,16 @@ bool MIDIMap::write(String path) {
|
|||
WRITE_OPTION(valueInputStyle);
|
||||
WRITE_OPTION(valueInputControlMSB);
|
||||
WRITE_OPTION(valueInputControlLSB);
|
||||
WRITE_OPTION(valueInputControlSingle);
|
||||
WRITE_FLOAT_OPTION(volExp);
|
||||
|
||||
for (int i=0; i<18; i++) {
|
||||
WRITE_ARRAY_OPTION(valueInputSpecificStyle,i);
|
||||
WRITE_ARRAY_OPTION(valueInputSpecificMSB,i);
|
||||
WRITE_ARRAY_OPTION(valueInputSpecificLSB,i);
|
||||
WRITE_ARRAY_OPTION(valueInputSpecificSingle,i);
|
||||
}
|
||||
|
||||
for (MIDIBind& i: binds) {
|
||||
if (fprintf(f,"%d %d %d %d %s\n",i.type,i.channel,i.data1,i.data2,guiActions[i.action][0])<0) {
|
||||
logW("did not write MIDI mapping entirely! %s\n",strerror(errno));
|
||||
|
|
|
@ -87,7 +87,15 @@ const char* valueInputStyles[]={
|
|||
"Raw (note number is value)",
|
||||
"Two octaves alternate (lower keys are 0-9, upper keys are A-F)",
|
||||
"Use dual control change (one for each nibble)",
|
||||
"Use 14-bit control change"
|
||||
"Use 14-bit control change",
|
||||
"Use single control change (imprecise)"
|
||||
};
|
||||
|
||||
const char* valueSInputStyles[]={
|
||||
"Disabled/custom",
|
||||
"Use dual control change (one for each nibble)",
|
||||
"Use 14-bit control change",
|
||||
"Use single control change (imprecise)"
|
||||
};
|
||||
|
||||
const char* messageTypes[]={
|
||||
|
@ -113,6 +121,27 @@ const char* messageChannels[]={
|
|||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "Any"
|
||||
};
|
||||
|
||||
const char* specificControls[18]={
|
||||
"Instrument",
|
||||
"Volume",
|
||||
"Effect 1 type",
|
||||
"Effect 1 value",
|
||||
"Effect 2 type",
|
||||
"Effect 2 value",
|
||||
"Effect 3 type",
|
||||
"Effect 3 value",
|
||||
"Effect 4 type",
|
||||
"Effect 4 value",
|
||||
"Effect 5 type",
|
||||
"Effect 5 value",
|
||||
"Effect 6 type",
|
||||
"Effect 6 value",
|
||||
"Effect 7 type",
|
||||
"Effect 7 value",
|
||||
"Effect 8 type",
|
||||
"Effect 8 value"
|
||||
};
|
||||
|
||||
#define SAMPLE_RATE_SELECTABLE(x) \
|
||||
if (ImGui::Selectable(#x,settings.audioRate==x)) { \
|
||||
settings.audioRate=x; \
|
||||
|
@ -370,8 +399,14 @@ void FurnaceGUI::drawSettings() {
|
|||
ImGui::Checkbox("Program change is instrument selection",&midiMap.programChange);
|
||||
ImGui::Checkbox("Listen to MIDI clock",&midiMap.midiClock);
|
||||
ImGui::Checkbox("Listen to MIDI time code",&midiMap.midiTimeCode);
|
||||
ImGui::Combo("Value input style",&midiMap.valueInputStyle,valueInputStyles,6);
|
||||
ImGui::Combo("Value input style",&midiMap.valueInputStyle,valueInputStyles,7);
|
||||
if (midiMap.valueInputStyle>3) {
|
||||
if (midiMap.valueInputStyle==6) {
|
||||
if (ImGui::InputInt("Control##valueCCS",&midiMap.valueInputControlSingle,1,16)) {
|
||||
if (midiMap.valueInputControlSingle<0) midiMap.valueInputControlSingle=0;
|
||||
if (midiMap.valueInputControlSingle>127) midiMap.valueInputControlSingle=127;
|
||||
}
|
||||
} else {
|
||||
if (ImGui::InputInt((midiMap.valueInputStyle==4)?"CC of upper nibble##valueCC1":"MSB CC##valueCC1",&midiMap.valueInputControlMSB,1,16)) {
|
||||
if (midiMap.valueInputControlMSB<0) midiMap.valueInputControlMSB=0;
|
||||
if (midiMap.valueInputControlMSB>127) midiMap.valueInputControlMSB=127;
|
||||
|
@ -381,6 +416,34 @@ void FurnaceGUI::drawSettings() {
|
|||
if (midiMap.valueInputControlLSB>127) midiMap.valueInputControlLSB=127;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ImGui::TreeNode("Per-column control change")) {
|
||||
for (int i=0; i<18; i++) {
|
||||
ImGui::PushID(i);
|
||||
ImGui::Combo(specificControls[i],&midiMap.valueInputSpecificStyle[i],valueSInputStyles,4);
|
||||
if (midiMap.valueInputSpecificStyle[i]>0) {
|
||||
ImGui::Indent();
|
||||
if (midiMap.valueInputSpecificStyle[i]==3) {
|
||||
if (ImGui::InputInt("Control##valueCCS",&midiMap.valueInputSpecificSingle[i],1,16)) {
|
||||
if (midiMap.valueInputSpecificSingle[i]<0) midiMap.valueInputSpecificSingle[i]=0;
|
||||
if (midiMap.valueInputSpecificSingle[i]>127) midiMap.valueInputSpecificSingle[i]=127;
|
||||
}
|
||||
} else {
|
||||
if (ImGui::InputInt((midiMap.valueInputSpecificStyle[i]==4)?"CC of upper nibble##valueCC1":"MSB CC##valueCC1",&midiMap.valueInputSpecificMSB[i],1,16)) {
|
||||
if (midiMap.valueInputSpecificMSB[i]<0) midiMap.valueInputSpecificMSB[i]=0;
|
||||
if (midiMap.valueInputSpecificMSB[i]>127) midiMap.valueInputSpecificMSB[i]=127;
|
||||
}
|
||||
if (ImGui::InputInt((midiMap.valueInputSpecificStyle[i]==4)?"CC of lower nibble##valueCC2":"LSB CC##valueCC2",&midiMap.valueInputSpecificLSB[i],1,16)) {
|
||||
if (midiMap.valueInputSpecificLSB[i]<0) midiMap.valueInputSpecificLSB[i]=0;
|
||||
if (midiMap.valueInputSpecificLSB[i]>127) midiMap.valueInputSpecificLSB[i]=127;
|
||||
}
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue