start working on ADSR macro mode
This commit is contained in:
parent
2cebd75236
commit
a979bc244d
|
@ -437,6 +437,12 @@ notes:
|
||||||
- the entire instrument is stored, regardless of instrument type.
|
- the entire instrument is stored, regardless of instrument type.
|
||||||
- the macro range varies depending on the instrument type.
|
- the macro range varies depending on the instrument type.
|
||||||
- "macro open" indicates whether the macro is collapsed or not in the instrument editor.
|
- "macro open" indicates whether the macro is collapsed or not in the instrument editor.
|
||||||
|
- as of format version 120, bit 1-2 indicates macro mode:
|
||||||
|
- 0: sequence (normal)
|
||||||
|
- 1: ADSR
|
||||||
|
- 2: LFO
|
||||||
|
- 3: ADSR+LFO
|
||||||
|
- see sub-section for information on how to interpret parameters.
|
||||||
- FM operator order is:
|
- FM operator order is:
|
||||||
- 1/3/2/4 (internal order) for OPN, OPM, OPZ and OPL 4-op
|
- 1/3/2/4 (internal order) for OPN, OPM, OPZ and OPL 4-op
|
||||||
- 1/2/?/? (? = unused) for OPL 2-op and OPLL
|
- 1/2/?/? (? = unused) for OPL 2-op and OPLL
|
||||||
|
@ -1024,6 +1030,33 @@ size | description
|
||||||
1 | KSR macro delay
|
1 | KSR macro delay
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## interpreting macro mode values
|
||||||
|
|
||||||
|
- sequence (normal): I think this is obvious...
|
||||||
|
- ADSR:
|
||||||
|
- `val[0]`: bottom
|
||||||
|
- `val[1]`: top
|
||||||
|
- `val[2]`: attack
|
||||||
|
- `val[3]`: hold time
|
||||||
|
- `val[4]`: decay
|
||||||
|
- `val[5]`: sustain level
|
||||||
|
- `val[6]`: sustain hold time
|
||||||
|
- `val[7]`: decay 2
|
||||||
|
- `val[8]`: release
|
||||||
|
- LFO:
|
||||||
|
- `val[9]`: bottom
|
||||||
|
- `val[10]`: top
|
||||||
|
- `val[11]`: speed
|
||||||
|
- `val[12]`: waveform
|
||||||
|
- 0: triangle
|
||||||
|
- 1: sine
|
||||||
|
- 2: saw
|
||||||
|
- 3: pulse
|
||||||
|
- `val[13]`: phase
|
||||||
|
- `val[14]`: loop
|
||||||
|
- `val[15]`: global (not sure how will I implement this)
|
||||||
|
- for ADSR+LFO just interpret both ADSR and LFO params.
|
||||||
|
|
||||||
# wavetable
|
# wavetable
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev119"
|
#define DIV_VERSION "dev120"
|
||||||
#define DIV_ENGINE_VERSION 119
|
#define DIV_ENGINE_VERSION 120
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
|
|
@ -177,7 +177,7 @@ struct DivInstrumentMacro {
|
||||||
String name;
|
String name;
|
||||||
int val[256];
|
int val[256];
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
bool open;
|
unsigned char open;
|
||||||
unsigned char len, delay, speed, loop, rel;
|
unsigned char len, delay, speed, loop, rel;
|
||||||
|
|
||||||
// the following variables are used by the GUI and not saved in the file
|
// the following variables are used by the GUI and not saved in the file
|
||||||
|
|
|
@ -21,9 +21,20 @@
|
||||||
#include "instrument.h"
|
#include "instrument.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
|
||||||
|
#define ADSR_LOW source.val[0]
|
||||||
|
#define ADSR_HIGH source.val[1]
|
||||||
|
#define ADSR_AR source.val[2]
|
||||||
|
#define ADSR_HT source.val[3]
|
||||||
|
#define ADSR_DR source.val[4]
|
||||||
|
#define ADSR_SL source.val[5]
|
||||||
|
#define ADSR_ST source.val[6]
|
||||||
|
#define ADSR_SR source.val[7]
|
||||||
|
#define ADSR_RR source.val[8]
|
||||||
|
|
||||||
void DivMacroStruct::prepare(DivInstrumentMacro& source, DivEngine* e) {
|
void DivMacroStruct::prepare(DivInstrumentMacro& source, DivEngine* e) {
|
||||||
has=had=actualHad=will=true;
|
has=had=actualHad=will=true;
|
||||||
mode=source.mode;
|
mode=source.mode;
|
||||||
|
type=(source.open>>1)&3;
|
||||||
linger=(source.name=="vol" && e->song.volMacroLinger);
|
linger=(source.name=="vol" && e->song.volMacroLinger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +64,9 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic
|
||||||
}
|
}
|
||||||
actualHad=has;
|
actualHad=has;
|
||||||
had=actualHad;
|
had=actualHad;
|
||||||
|
|
||||||
if (has) {
|
if (has) {
|
||||||
|
if (type==0) { // sequence
|
||||||
lastPos=pos;
|
lastPos=pos;
|
||||||
val=source.val[pos++];
|
val=source.val[pos++];
|
||||||
if (pos>source.rel && !released) {
|
if (pos>source.rel && !released) {
|
||||||
|
@ -73,6 +86,50 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (type==1 || type==3) { // ADSR
|
||||||
|
if (released && lastPos<3) lastPos=3;
|
||||||
|
switch (lastPos) {
|
||||||
|
case 0: // attack
|
||||||
|
pos+=ADSR_AR;
|
||||||
|
if (pos>255) {
|
||||||
|
pos=255;
|
||||||
|
lastPos=1;
|
||||||
|
delay=ADSR_HT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: // decay
|
||||||
|
pos-=ADSR_DR;
|
||||||
|
if (pos<=ADSR_SL) {
|
||||||
|
pos=ADSR_SL;
|
||||||
|
lastPos=2;
|
||||||
|
delay=ADSR_ST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // sustain
|
||||||
|
pos-=ADSR_SR;
|
||||||
|
if (pos<0) {
|
||||||
|
pos=0;
|
||||||
|
lastPos=4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // release
|
||||||
|
pos-=ADSR_RR;
|
||||||
|
if (pos<0) {
|
||||||
|
pos=0;
|
||||||
|
lastPos=4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: // end
|
||||||
|
pos=0;
|
||||||
|
if (!linger) has=false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
val=ADSR_LOW+((pos+(ADSR_HIGH-ADSR_LOW)*pos)>>8);
|
||||||
|
}
|
||||||
|
if (type==2 || type==3) { // LFO
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivMacroInt::next() {
|
void DivMacroInt::next() {
|
||||||
|
|
|
@ -28,10 +28,10 @@ struct DivMacroStruct {
|
||||||
int pos, lastPos, delay;
|
int pos, lastPos, delay;
|
||||||
int val;
|
int val;
|
||||||
bool has, had, actualHad, finished, will, linger, began;
|
bool has, had, actualHad, finished, will, linger, began;
|
||||||
unsigned int mode;
|
unsigned int mode, type;
|
||||||
void doMacro(DivInstrumentMacro& source, bool released, bool tick);
|
void doMacro(DivInstrumentMacro& source, bool released, bool tick);
|
||||||
void init() {
|
void init() {
|
||||||
pos=lastPos=mode=delay=0;
|
pos=lastPos=mode=type=delay=0;
|
||||||
has=had=actualHad=will=false;
|
has=had=actualHad=will=false;
|
||||||
linger=false;
|
linger=false;
|
||||||
began=true;
|
began=true;
|
||||||
|
@ -51,7 +51,8 @@ struct DivMacroStruct {
|
||||||
will(false),
|
will(false),
|
||||||
linger(false),
|
linger(false),
|
||||||
began(true),
|
began(true),
|
||||||
mode(0) {}
|
mode(0),
|
||||||
|
type(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DivMacroInt {
|
class DivMacroInt {
|
||||||
|
|
|
@ -203,6 +203,13 @@ enum FMParams {
|
||||||
#define FM_NAME(x) fmParamNames[settings.fmNames][x]
|
#define FM_NAME(x) fmParamNames[settings.fmNames][x]
|
||||||
#define FM_SHORT_NAME(x) fmParamShortNames[settings.fmNames][x]
|
#define FM_SHORT_NAME(x) fmParamShortNames[settings.fmNames][x]
|
||||||
|
|
||||||
|
const char* macroTypeLabels[4]={
|
||||||
|
ICON_FA_BAR_CHART "##IMacroType",
|
||||||
|
ICON_FA_AREA_CHART "##IMacroType",
|
||||||
|
ICON_FA_LINE_CHART "##IMacroType",
|
||||||
|
ICON_FA_SIGN_OUT "##IMacroType"
|
||||||
|
};
|
||||||
|
|
||||||
const char* fmOperatorBits[5]={
|
const char* fmOperatorBits[5]={
|
||||||
"op1", "op2", "op3", "op4", NULL
|
"op1", "op2", "op3", "op4", NULL
|
||||||
};
|
};
|
||||||
|
@ -1326,10 +1333,11 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%s",i.displayName);
|
ImGui::Text("%s",i.displayName);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SmallButton(i.macro->open?(ICON_FA_CHEVRON_UP "##IMacroOpen"):(ICON_FA_CHEVRON_DOWN "##IMacroOpen"))) {
|
if (ImGui::SmallButton((i.macro->open&1)?(ICON_FA_CHEVRON_UP "##IMacroOpen"):(ICON_FA_CHEVRON_DOWN "##IMacroOpen"))) {
|
||||||
i.macro->open=!i.macro->open;
|
i.macro->open^=1;
|
||||||
}
|
}
|
||||||
if (i.macro->open) {
|
if (i.macro->open&1) {
|
||||||
|
if ((i.macro->open&6)==0) {
|
||||||
ImGui::SetNextItemWidth(lenAvail);
|
ImGui::SetNextItemWidth(lenAvail);
|
||||||
int macroLen=i.macro->len;
|
int macroLen=i.macro->len;
|
||||||
if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { MARK_MODIFIED
|
if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { MARK_MODIFIED
|
||||||
|
@ -1337,11 +1345,32 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
if (macroLen>255) macroLen=255;
|
if (macroLen>255) macroLen=255;
|
||||||
i.macro->len=macroLen;
|
i.macro->len=macroLen;
|
||||||
}
|
}
|
||||||
if (ImGui::Button(ICON_FA_BAR_CHART "##IMacroType")) {
|
}
|
||||||
|
if (ImGui::Button(macroTypeLabels[(i.macro->open>>1)&3])) {
|
||||||
|
i.macro->open+=2;
|
||||||
|
if (i.macro->open>=8) {
|
||||||
|
i.macro->open-=8;
|
||||||
|
}
|
||||||
|
PARAMETER;
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("Coming soon!");
|
switch (i.macro->open&6) {
|
||||||
|
case 0:
|
||||||
|
ImGui::SetTooltip("Macro type: Sequence");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ImGui::SetTooltip("Macro type: ADSR");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ImGui::SetTooltip("Macro type: LFO");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
ImGui::SetTooltip("Macro type: ADSR+LFO");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ImGui::SetTooltip("Macro type: What's going on here?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Button(ICON_FA_ELLIPSIS_H "##IMacroSet");
|
ImGui::Button(ICON_FA_ELLIPSIS_H "##IMacroSet");
|
||||||
|
@ -1372,6 +1401,7 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
|
|
||||||
// macro area
|
// macro area
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
if ((i.macro->open&6)==0) {
|
||||||
for (int j=0; j<256; j++) {
|
for (int j=0; j<256; j++) {
|
||||||
bit30Indicator[j]=0;
|
bit30Indicator[j]=0;
|
||||||
if (j+macroDragScroll>=i.macro->len) {
|
if (j+macroDragScroll>=i.macro->len) {
|
||||||
|
@ -1429,11 +1459,11 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.isBitfield) {
|
if (i.isBitfield) {
|
||||||
PlotBitfield("##IMacro",asInt,totalFit,0,i.bitfieldBits,i.max,ImVec2(availableWidth,(i.macro->open)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),doHighlight);
|
PlotBitfield("##IMacro",asInt,totalFit,0,i.bitfieldBits,i.max,ImVec2(availableWidth,(i.macro->open&1)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),doHighlight);
|
||||||
} else {
|
} else {
|
||||||
PlotCustom("##IMacro",asFloat,totalFit,macroDragScroll,NULL,i.min+i.macro->vScroll,i.min+i.macro->vScroll+i.macro->vZoom,ImVec2(availableWidth,(i.macro->open)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),i.color,i.macro->len-macroDragScroll,i.hoverFunc,i.hoverFuncUser,i.blockMode,i.macro->open?genericGuide:NULL,doHighlight);
|
PlotCustom("##IMacro",asFloat,totalFit,macroDragScroll,NULL,i.min+i.macro->vScroll,i.min+i.macro->vScroll+i.macro->vZoom,ImVec2(availableWidth,(i.macro->open&1)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),i.color,i.macro->len-macroDragScroll,i.hoverFunc,i.hoverFuncUser,i.blockMode,(i.macro->open&1)?genericGuide:NULL,doHighlight);
|
||||||
}
|
}
|
||||||
if (i.macro->open && (ImGui::IsItemClicked(ImGuiMouseButton_Left) || ImGui::IsItemClicked(ImGuiMouseButton_Right))) {
|
if ((i.macro->open&1) && (ImGui::IsItemClicked(ImGuiMouseButton_Left) || ImGui::IsItemClicked(ImGuiMouseButton_Right))) {
|
||||||
macroDragStart=ImGui::GetItemRectMin();
|
macroDragStart=ImGui::GetItemRectMin();
|
||||||
macroDragAreaSize=ImVec2(availableWidth,i.height*dpiScale);
|
macroDragAreaSize=ImVec2(availableWidth,i.height*dpiScale);
|
||||||
if (i.isBitfield) {
|
if (i.isBitfield) {
|
||||||
|
@ -1458,7 +1488,7 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
lastMacroDesc=i;
|
lastMacroDesc=i;
|
||||||
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
|
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
|
||||||
}
|
}
|
||||||
if (i.macro->open) {
|
if ((i.macro->open&1)) {
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
if (ctrlWheeling) {
|
if (ctrlWheeling) {
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
|
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
|
||||||
|
@ -1570,6 +1600,114 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
} else {
|
||||||
|
if (i.macro->open&2) {
|
||||||
|
if (ImGui::BeginTable("MacroADSR",4)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.3);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.3);
|
||||||
|
//ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch,0.4);
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Bottom");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (ImGui::InputInt("##MABottom",&i.macro->val[0],1,16)) { PARAMETER
|
||||||
|
if (i.macro->val[0]<i.min) i.macro->val[0]=i.min;
|
||||||
|
if (i.macro->val[0]>i.max) i.macro->val[0]=i.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Top");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (ImGui::InputInt("##MATop",&i.macro->val[1],1,16)) { PARAMETER
|
||||||
|
if (i.macro->val[1]<i.min) i.macro->val[1]=i.min;
|
||||||
|
if (i.macro->val[1]>i.max) i.macro->val[1]=i.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("the envelope goes here");*/
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Attack");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##MAAR",&i.macro->val[2],0,255)) { PARAMETER
|
||||||
|
if (i.macro->val[2]<0) i.macro->val[2]=0;
|
||||||
|
if (i.macro->val[2]>255) i.macro->val[2]=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Sustain");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##MASL",&i.macro->val[5],0,255)) { PARAMETER
|
||||||
|
if (i.macro->val[5]<0) i.macro->val[5]=0;
|
||||||
|
if (i.macro->val[5]>255) i.macro->val[5]=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Hold");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##MAHT",&i.macro->val[3],0,255)) { PARAMETER
|
||||||
|
if (i.macro->val[3]<0) i.macro->val[3]=0;
|
||||||
|
if (i.macro->val[3]>255) i.macro->val[3]=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("SusTime");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##MAST",&i.macro->val[6],0,255)) { PARAMETER
|
||||||
|
if (i.macro->val[6]<0) i.macro->val[6]=0;
|
||||||
|
if (i.macro->val[6]>255) i.macro->val[6]=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Decay");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##MADR",&i.macro->val[4],0,255)) { PARAMETER
|
||||||
|
if (i.macro->val[4]<0) i.macro->val[4]=0;
|
||||||
|
if (i.macro->val[4]>255) i.macro->val[4]=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("SusDecay");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##MASR",&i.macro->val[7],0,255)) { PARAMETER
|
||||||
|
if (i.macro->val[7]<0) i.macro->val[7]=0;
|
||||||
|
if (i.macro->val[7]>255) i.macro->val[7]=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Release");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##MARR",&i.macro->val[8],0,255)) { PARAMETER
|
||||||
|
if (i.macro->val[8]<0) i.macro->val[8]=0;
|
||||||
|
if (i.macro->val[8]>255) i.macro->val[8]=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i.macro->open&4) {
|
||||||
|
ImGui::Text("LFO...");
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue