now on insEdit

the final step is to fix pitch linearity
This commit is contained in:
tildearrow 2024-09-21 17:56:37 -05:00
parent d703aa1e97
commit fa0c417976

View file

@ -5862,16 +5862,12 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
}
}
// TODO: fix it all.
void FurnaceGUI::drawInsSID3(DivInstrument* ins)
{
void FurnaceGUI::drawInsSID3(DivInstrument* ins) {
char buffer[100];
char buffer2[100];
if (ImGui::BeginTabItem("SID3"))
{
if (ImGui::BeginTable("sid3Waves",2,0))
{
if (ImGui::BeginTabItem("SID3")) {
if (ImGui::BeginTable("sid3Waves",2,0)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0f);
@ -5903,8 +5899,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
if (ImGui::Button(_("noise"))) { PARAMETER
ins->sid3.noiseOn=!ins->sid3.noiseOn;
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Like in SID2,specific noise LFSR feedback bits config can produce tonal waves.\n"
"Refer to the manual for LFSR bits macro configurations for which frequency calculation is altered\n"
"in a way that makes tonal noise stay in tune."));
@ -5923,17 +5918,14 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
P(CWSliderScalar(_("Special wave"),ImGuiDataType_U8,&ins->sid3.special_wave,&_ZERO,&_SID3_SPECIAL_WAVES,_(sid3SpecialWaveforms[ins->sid3.special_wave%SID3_NUM_SPECIAL_WAVES]))); rightClickable
if(ImGui::Checkbox(_("Wavetable channel"),&ins->sid3.doWavetable))
{
if (ImGui::Checkbox(_("Wavetable channel"),&ins->sid3.doWavetable)) {
PARAMETER;
ins->std.waveMacro.vZoom=-1;
for(int i = 0; i < 256; i++)
{
for (int i=0; i<256; i++) {
ins->std.waveMacro.val[i]=0;
}
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Forces waveform macro to control wavetable index."));
}
@ -5941,8 +5933,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
if (ImGui::Checkbox(_("Inv. left"),&invLeft)) { PARAMETER
ins->sid3.phaseInv^=SID3_INV_SIGNAL_LEFT;
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Invert left channel signal"));
}
ImGui::SameLine();
@ -5950,8 +5941,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
if (ImGui::Checkbox(_("Inv. right"),&invRight)) { PARAMETER
ins->sid3.phaseInv^=SID3_INV_SIGNAL_RIGHT;
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Invert right channel signal"));
}
@ -5966,8 +5956,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
ImVec2 sliderSize=ImVec2(30.0f*dpiScale,256.0*dpiScale);
if (ImGui::BeginTable("SID3EnvParams",6,ImGuiTableFlags_NoHostExtendX))
{
if (ImGui::BeginTable("SID3EnvParams",6,ImGuiTableFlags_NoHostExtendX)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
@ -6007,20 +5996,19 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
ImGui::TableNextColumn();
P(CWVSliderScalar("##Release",sliderSize,ImGuiDataType_U8,&ins->sid3.r,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
ImGui::TableNextColumn();
drawSID3Env(0,(ins->sid3.a == 0 ? (255) : (256-ins->sid3.a)),(ins->sid3.d == 0 ? (255) : (256-ins->sid3.d)),ins->sid3.sr,255-(ins->sid3.r == 255 ? (ins->sid3.r - 1) : ins->sid3.r),255-ins->sid3.s,0,0,0,255,256,255,ImVec2(ImGui::GetContentRegionAvail().x,sliderSize.y),ins->type); //the (ins->sid3.r == 15 ? (ins->sid3.r - 1) : ins->sid3.r) is used so release part never becomes horizontal (which isn't the case with SID3 envelope)
// the (ins->sid3.r==15?(ins->sid3.r-1):ins->sid3.r) is used so release part never becomes horizontal (which isn't the case with SID3 envelope)
drawSID3Env(0,(ins->sid3.a==0?(255):(256-ins->sid3.a)),(ins->sid3.d==0?(255):(256-ins->sid3.d)),ins->sid3.sr,255-(ins->sid3.r==255?(ins->sid3.r-1):ins->sid3.r),255-ins->sid3.s,0,0,0,255,256,255,ImVec2(ImGui::GetContentRegionAvail().x,sliderSize.y),ins->type);
ImGui::EndTable();
}
if(!ins->sid3.doWavetable)
{
if (!ins->sid3.doWavetable) {
strncpy(buffer,macroSID3WaveMixMode(0,(float)ins->sid3.mixMode,NULL).c_str(),40);
P(CWSliderScalar(_("Wave Mix Mode"),ImGuiDataType_U8,&ins->sid3.mixMode,&_ZERO,&_FOUR,buffer));
P(CWSliderScalar(_("Duty"),ImGuiDataType_U16,&ins->sid3.duty,&_ZERO,&_SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE)); rightClickable
P(CWSliderScalar(_("Feedback"),ImGuiDataType_U8,&ins->sid3.feedback,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE));
bool resetDuty=ins->sid3.resetDuty;
if (ImGui::Checkbox(_("Reset duty on new note"),&resetDuty))
{ PARAMETER
if (ImGui::Checkbox(_("Reset duty on new note"),&resetDuty)) { PARAMETER
ins->sid3.resetDuty=resetDuty;
}
if (ImGui::Checkbox(_("Absolute Duty Macro"),&ins->sid3.dutyIsAbs)) {
@ -6061,24 +6049,20 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
ImGui::Separator();
if(!ins->sid3.doWavetable)
{
if (!ins->sid3.doWavetable) {
bool sepNoisePitch=ins->sid3.separateNoisePitch;
if (ImGui::Checkbox(_("Separate noise pitch"),&sepNoisePitch)) { PARAMETER
ins->sid3.separateNoisePitch=sepNoisePitch;
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Make noise pitch independent from other waves' pitch.\nNoise pitch will be controllable via macros."));
}
}
for(int i = 0; i < SID3_NUM_FILTERS; i++)
{
for (int i=0; i<SID3_NUM_FILTERS; i++) {
DivInstrumentSID3::Filter* filt=&ins->sid3.filt[i];
if(filt->enabled)
{
if (filt->enabled) {
ImGui::Separator();
}
@ -6088,8 +6072,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
filt->enabled=enable;
}
if(filt->enabled)
{
if (filt->enabled) {
bool init=filt->init;
snprintf(buffer,100,_("Initialize filter %d"),i+1);
if (ImGui::Checkbox(buffer,&init)) { PARAMETER
@ -6158,17 +6141,14 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
snprintf(buffer,100,_("Change cutoff with pitch##bindcutoff%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindCutoffToNote));
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter cutoff will change with frequency/pitch.\nSee settings below."));
}
if(filt->bindCutoffToNote)
{
if (filt->bindCutoffToNote) {
snprintf(buffer,100,_("Decrease cutoff when pitch increases##decreasecutoff%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindCutoffToNoteDir));
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("If this is enabled,filter cutoff will decrease if you increase the pitch.\n"
"If this is disabled,filter cutoff will increase if you increase the pitch."));
}
@ -6176,38 +6156,32 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
snprintf(buffer2,100,_("%s"),noteNameNormal(filt->bindCutoffToNoteCenter%12,(short)(filt->bindCutoffToNoteCenter / 12)-5));
snprintf(buffer,100,_("Cutoff change center note##bindcutcenternote%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindCutoffToNoteCenter,&_ZERO,&_ONE_HUNDRED_SEVENTY_NINE,buffer2)); rightClickable
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("The center note for cutoff changes. At this note no cutoff change happens.\nAs pitch goes lower or higher,cutoff changes apply."));
}
snprintf(buffer,100,_("Cutoff change strength##bindcutstrength%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindCutoffToNoteStrength,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("How much cutoff changes for given pitch change."));
}
snprintf(buffer,100,_("Scale cutoff only once on new note##bindcutnn%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindCutoffOnNote));
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter cutoff will be changed only once on new note.\nIf this option is disabled,cutoff scaling will be applied\nevery time a pitch change happens."));
}
}
snprintf(buffer,100,_("Change resonance with pitch##bindres%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindResonanceToNote));
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter resonance will change with frequency/pitch.\nSee settings below."));
}
if(filt->bindResonanceToNote)
{
if (filt->bindResonanceToNote) {
snprintf(buffer,100,_("Decrease resonance when pitch increases##decreaseres%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindResonanceToNoteDir));
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("If this is enabled,filter resonance will decrease if you increase the pitch.\n"
"If this is disabled,filter resonance will increase if you increase the pitch."));
}
@ -6215,21 +6189,18 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
snprintf(buffer2,100,_("%s"),noteNameNormal(filt->bindResonanceToNoteCenter%12,(short)(filt->bindResonanceToNoteCenter / 12)-5));
snprintf(buffer,100,_("Resonance change center note##bindrescenternote%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindResonanceToNoteCenter,&_ZERO,&_ONE_HUNDRED_SEVENTY_NINE,buffer2)); rightClickable
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("The center note for resonance changes. At this note no resonance change happens.\nAs pitch goes lower or higher,resonance changes apply."));
}
snprintf(buffer,100,_("Resonance change strength##bindresstrength%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindResonanceToNoteStrength,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("How much resonance changes for given pitch change."));
}
snprintf(buffer,100,_("Scale resonance only once on new note##bindresnn%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindResonanceOnNote));
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter resonance will be changed only once on new note.\nIf this option is disabled,resonance scaling will be applied\nevery time a pitch change happens."));
}
}
@ -6238,8 +6209,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
ImGui::Separator();
if (ImGui::BeginTable("SID3filtmatrix",1))
{
if (ImGui::BeginTable("SID3filtmatrix",1)) {
if (waveGenVisible) ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,250.0f*dpiScale);
ImGui::TableNextRow();
ImGui::TableNextColumn();
@ -6247,16 +6217,14 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
CENTER_TEXT(_("Filters connection matrix"));
ImGui::Text(_("Filters connection matrix"));
if (ImGui::BeginTable("SID3checkboxesmatrix",3 + SID3_NUM_FILTERS))
{
if (ImGui::BeginTable("SID3checkboxesmatrix",3+SID3_NUM_FILTERS)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text(">>");
ImGui::TableNextColumn();
ImGui::Text(_("In"));
for(int i = 0; i < SID3_NUM_FILTERS; i++)
{
for (int i=0; i<SID3_NUM_FILTERS; i++) {
ImGui::TableNextColumn();
ImGui::Text("%d",i+1);
}
@ -6266,8 +6234,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
ImGui::TableNextRow();
for(int i = 0; i < SID3_NUM_FILTERS; i++)
{
for (int i=0; i<SID3_NUM_FILTERS; i++) {
DivInstrumentSID3::Filter* filt=&ins->sid3.filt[i];
ImGui::TableNextRow();
@ -6281,13 +6248,11 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
if (ImGui::Checkbox(buffer,&toInput)) { PARAMETER
filt->mode^=SID3_FILTER_CHANNEL_INPUT;
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Feed signal from channel to filter %d input"),i+1);
}
for(int j = 0; j < SID3_NUM_FILTERS; j++)
{
for (int j=0; j<SID3_NUM_FILTERS; j++) {
ImGui::TableNextColumn();
snprintf(buffer,40,"##filtmatrix%d%d",i+1,j+1);
@ -6295,8 +6260,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
if (ImGui::Checkbox(buffer,&enable)) { PARAMETER
filt->filter_matrix^=(1<<j);
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Feed signal from filter %d output to filter %d input"),j+1,i+1);
}
}
@ -6308,8 +6272,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
if (ImGui::Checkbox(buffer,&toOutput)) { PARAMETER
filt->mode^=SID3_FILTER_OUTPUT;
}
if (ImGui::IsItemHovered())
{
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Feed signal from filter %d output to channel output"),i+1);
}
}
@ -6323,20 +6286,17 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins)
ImGui::EndTabItem();
}
if(!ins->amiga.useSample)
{
if (!ins->amiga.useSample) {
insTabWavetable(ins);
}
insTabSample(ins);
std::vector<FurnaceGUIMacroDesc> macroList;
for(int i = 0; i < SID3_NUM_FILTERS; i++)
{
for (int i=0; i<SID3_NUM_FILTERS; i++) {
snprintf(buffer,40,_("Filter %d macros"),i+1);
if (ImGui::BeginTabItem(buffer))
{
if (ImGui::BeginTabItem(buffer)) {
macroList.push_back(FurnaceGUIMacroDesc(_("Cutoff"),&ins->std.opMacros[i].d2rMacro,ins->sid3.filt[i].absoluteCutoff?0:-65535,65535,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Resonance"),&ins->std.opMacros[i].damMacro,0,255,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Toggle"),&ins->std.opMacros[i].drMacro,0,1,32,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true));
@ -6513,28 +6473,8 @@ void FurnaceGUI::drawInsEdit() {
}
for (DivInstrumentType i: insTypeList) {
if (ImGui::Selectable(insTypes[i][0],insType==i)) {
//DivInstrumentType prevType = ins->type;
ins->type=i;
/* what is this?
//clamp some settings
if(prevType == DIV_INS_SID3)
{
ins->sid3.a = CLAMP(ins->sid3.a, 0, 15);
ins->sid3.d = CLAMP(ins->sid3.a, 0, 15);
ins->sid3.s = CLAMP(ins->sid3.a, 0, 15);
ins->sid3.r = CLAMP(ins->sid3.a, 0, 15);
ins->sid3.duty = CLAMP(ins->sid3.a, 0, 0xfff);
ins->sid3.mixMode = CLAMP(ins->sid3.mixMode, 0, 3);
}
if(prevType == DIV_INS_SID3 || prevType == DIV_INS_SID2)
{
ins->sid3.cut = CLAMP(ins->sid3.cut, 0, 0x7ff);
ins->sid3.res = CLAMP(ins->sid3.res, 0, 0xf);
}*/
// reset macro zoom
ins->std.volMacro.vZoom=-1;
ins->std.dutyMacro.vZoom=-1;