commit 3b8936105eacc1593a2593ab742a306213f42c73
parent f2fb41db86f780b47d0e3d312e60247587e89181
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Tue, 15 Mar 2022 21:38:37 +0100
add load/save preset functionality
Diffstat:
4 files changed, 135 insertions(+), 36 deletions(-)
diff --git a/source/jucePlugin/genericUI/assets/VirusC.json b/source/jucePlugin/genericUI/assets/VirusC.json
@@ -21,7 +21,7 @@
"name" : "singleLabel",
"label" : {
"text" : "SINGLE",
- "textHeight" : "16",
+ "textHeight" : "18",
"color" : "EBEBEBFF",
"alignH" : "R",
"alignV" : "C",
@@ -76,7 +76,7 @@
"name" : "multiLabel",
"label" : {
"text" : "MULTI",
- "textHeight" : "16",
+ "textHeight" : "18",
"color" : "EBEBEBFF",
"alignH" : "L",
"alignV" : "C",
@@ -2064,7 +2064,7 @@
"y" : "761",
"width" : "140",
"height" : "140",
- "texture" : "Gen_140x140_x2",
+ "texture" : "GenRed_140x140_x2",
"tileSizeX" : "140",
"tileSizeY" : "140"
}
@@ -2249,7 +2249,7 @@
"y" : "90,5",
"width" : "140",
"height" : "140",
- "texture" : "Gen_140x140_x2",
+ "texture" : "GenPol_140x140_x2",
"tileSizeX" : "140",
"tileSizeY" : "140"
}
@@ -2266,7 +2266,7 @@
"y" : "90,5",
"width" : "140",
"height" : "140",
- "texture" : "Gen_140x140_x2",
+ "texture" : "GenRed_140x140_x2",
"tileSizeX" : "140",
"tileSizeY" : "140"
}
@@ -2283,7 +2283,7 @@
"y" : "329,5",
"width" : "140",
"height" : "140",
- "texture" : "Gen_140x140_x2",
+ "texture" : "GenRed_140x140_x2",
"tileSizeX" : "140",
"tileSizeY" : "140"
}
@@ -2300,7 +2300,7 @@
"y" : "329,5",
"width" : "140",
"height" : "140",
- "texture" : "Gen_140x140_x2",
+ "texture" : "GenRed_140x140_x2",
"tileSizeX" : "140",
"tileSizeY" : "140"
}
@@ -2334,7 +2334,7 @@
"y" : "764",
"width" : "140",
"height" : "140",
- "texture" : "Gen_140x140_x2",
+ "texture" : "GenRed_140x140_x2",
"tileSizeX" : "140",
"tileSizeY" : "140"
}
@@ -2664,7 +2664,7 @@
"y" : "327",
"width" : "140",
"height" : "140",
- "texture" : "Gen_140x140_x2",
+ "texture" : "GenPol_140x140_x2",
"tileSizeX" : "140",
"tileSizeY" : "140"
}
@@ -5616,11 +5616,7 @@
"x" : "954,88",
"y" : "1116",
"width" : "124,2466",
- "height" : "36",
- "tooltip" : "Select an additional physical Midi Input device for "
- },
- "parameterAttachment" : {
- "parameter" : "Category1"
+ "height" : "36"
}
},
{
@@ -5634,9 +5630,6 @@
"y" : "1116",
"width" : "124,2466",
"height" : "36"
- },
- "parameterAttachment" : {
- "parameter" : "Category1"
}
}
]
@@ -5671,7 +5664,7 @@
"color" : "FF7180FF",
"x" : "74",
"y" : "1543",
- "width" : "730",
+ "width" : "627,718",
"height" : "45"
}
},
diff --git a/source/jucePlugin/genericUI/assets/assets.cmake b/source/jucePlugin/genericUI/assets/assets.cmake
@@ -1,29 +1,29 @@
set(ASSETS_VirusC
- ${CMAKE_CURRENT_LIST_DIR}/VC_x2_N.png
- ${CMAKE_CURRENT_LIST_DIR}/presest_btn_select_86x60_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/OSC_282x52_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/LFO_282x52_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/FX_282x52_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/ARP_2034x1238_x2.png
${CMAKE_CURRENT_LIST_DIR}/ARP_282x52_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/multi_btn_select_72x72_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/Mult_36x36_x2i.png
- ${CMAKE_CURRENT_LIST_DIR}/OSC_2034x1238_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/arp_72x37_X2.png
+ ${CMAKE_CURRENT_LIST_DIR}/arpall_104x432_X2.png
+ ${CMAKE_CURRENT_LIST_DIR}/env_pol_100x68_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/FX_2034x1238_x2_D.png
+ ${CMAKE_CURRENT_LIST_DIR}/FX_282x52_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/FX_reverbOverlay.png
${CMAKE_CURRENT_LIST_DIR}/Gen_140x140_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/sync2_108x100_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/GenPol_140x140_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/GenRed_140x140_x2.png
${CMAKE_CURRENT_LIST_DIR}/handle_72x94_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/env_pol_100x68_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/link_horizon_48x72_x2.png
${CMAKE_CURRENT_LIST_DIR}/LFO_2034x1238_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/LFO_282x52_x2.png
${CMAKE_CURRENT_LIST_DIR}/lfo_btn_46x76_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/link_horizon_48x72_x2.png
${CMAKE_CURRENT_LIST_DIR}/link_vert_72x48_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/GenPol_140x140_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/FX_2034x1238_x2_D.png
- ${CMAKE_CURRENT_LIST_DIR}/GenRed_140x140_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/FX_reverbOverlay.png
- ${CMAKE_CURRENT_LIST_DIR}/ARP_2034x1238_x2.png
- ${CMAKE_CURRENT_LIST_DIR}/arpall_104x432_X2.png
- ${CMAKE_CURRENT_LIST_DIR}/arp_72x37_X2.png
+ ${CMAKE_CURRENT_LIST_DIR}/Mult_36x36_x2i.png
+ ${CMAKE_CURRENT_LIST_DIR}/multi_btn_select_72x72_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/OSC_2034x1238_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/OSC_282x52_x2.png
${CMAKE_CURRENT_LIST_DIR}/Pres_2034x1238_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/presest_btn_select_86x60_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/sync2_108x100_x2.png
+ ${CMAKE_CURRENT_LIST_DIR}/VC_x2_N.png
${CMAKE_CURRENT_LIST_DIR}/VirusC.json
)
diff --git a/source/jucePlugin/ui3/VirusEditor.cpp b/source/jucePlugin/ui3/VirusEditor.cpp
@@ -49,6 +49,11 @@ namespace genericVirusUI
versionInfo->setText(message, juce::dontSendNotification);
}
+ auto* presetSave = findComponentT<juce::Button>("PresetSave");
+ presetSave->onClick = [this] { savePreset(); };
+
+ auto* presetLoad = findComponentT<juce::Button>("PresetLoad");
+ presetLoad->onClick = [this] { loadPreset(); };
}
void VirusEditor::onProgramChange()
@@ -138,6 +143,102 @@ namespace genericVirusUI
m_playModeMulti->setToggleState(getController().isMultiMode(), juce::dontSendNotification);
}
+ void VirusEditor::savePreset()
+ {
+ const auto path = getController().getConfig()->getValue("virus_bank_dir", "");
+ m_fileChooser = std::make_unique<juce::FileChooser>(
+ "Save preset as syx",
+ m_previousPath.isEmpty()
+ ? (path.isEmpty() ? juce::File::getSpecialLocation(juce::File::currentApplicationFile).getParentDirectory() : juce::File(path))
+ : m_previousPath,
+ "*.syx", true);
+
+ constexpr auto flags = juce::FileBrowserComponent::saveMode | juce::FileBrowserComponent::FileChooserFlags::canSelectFiles;
+
+ auto onFileChooser = [this](const juce::FileChooser& chooser)
+ {
+ if (chooser.getResults().isEmpty())
+ return;
+
+ const auto result = chooser.getResult();
+ m_previousPath = result.getParentDirectory().getFullPathName();
+ const auto ext = result.getFileExtension().toLowerCase();
+ const uint8_t syxHeader[9] = { 0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x01, 0x00 };
+ constexpr uint8_t syxEof[1] = { 0xF7 };
+ uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8];
+ uint8_t data[256];
+ for (int i = 0; i < 256; i++)
+ {
+ const auto param = getController().getParamValue(getController().getCurrentPart(), i < 128 ? 0 : 1, i & 127);
+
+ data[i] = param ? static_cast<int>(param->getValue()) : 0;
+ cs += data[i];
+ }
+ cs = cs & 0x7f;
+
+ result.deleteFile();
+ result.create();
+ result.appendData(syxHeader, 9);
+ result.appendData(data, 256);
+ result.appendData(&cs, 1);
+ result.appendData(syxEof, 1);
+ };
+ m_fileChooser->launchAsync(flags, onFileChooser);
+ }
+
+ void VirusEditor::loadPreset()
+ {
+ m_fileChooser = std::make_unique<juce::FileChooser>(
+ "Choose syx/midi banks to import",
+ m_previousPath.isEmpty()
+ ? juce::File::getSpecialLocation(juce::File::currentApplicationFile).getParentDirectory()
+ : m_previousPath,
+ "*.syx,*.mid,*.midi", true);
+
+ constexpr auto flags = juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::FileChooserFlags::canSelectFiles;
+
+ const std::function onFileChooser = [this](const juce::FileChooser& chooser)
+ {
+ if (chooser.getResults().isEmpty())
+ return;
+
+ const auto result = chooser.getResult();
+ m_previousPath = result.getParentDirectory().getFullPathName();
+ const auto ext = result.getFileExtension().toLowerCase();
+
+ std::vector<Patch> patches;
+ ::PatchBrowser::loadBankFile(patches, nullptr, result);
+
+ if (patches.empty())
+ return;
+
+ if (patches.size() == 1)
+ {
+ // load to edit buffer of current part
+ auto data = patches.front().sysex;
+ data[7] = virusLib::toMidiByte(virusLib::BankNumber::EditBuffer);
+ if (getController().isMultiMode())
+ data[8] = getController().getCurrentPart();
+ else
+ data[8] = virusLib::SINGLE;
+ getController().sendSysEx(data);
+ }
+ else
+ {
+ // load to bank A
+ for (const auto& p : patches)
+ {
+ auto data = p.sysex;
+ data[7] = virusLib::toMidiByte(virusLib::BankNumber::A);
+ getController().sendSysEx(data);
+ }
+ }
+
+ getController().onStateLoaded();
+ };
+ m_fileChooser->launchAsync(flags, onFileChooser);
+ }
+
void VirusEditor::setPlayMode(uint8_t _playMode)
{
getController().getParameter(Virus::Param_PlayMode)->setValue(_playMode);
diff --git a/source/jucePlugin/ui3/VirusEditor.h b/source/jucePlugin/ui3/VirusEditor.h
@@ -32,6 +32,8 @@ namespace genericVirusUI
void updatePresetName() const;
void updatePlayModeButtons() const;
+ void savePreset();
+ void loadPreset();
void setPlayMode(uint8_t _playMode);
@@ -48,5 +50,8 @@ namespace genericVirusUI
juce::TooltipWindow m_tooltipWindow;
PatchBrowser m_patchBrowser;
+
+ std::unique_ptr<juce::FileChooser> m_fileChooser;
+ juce::String m_previousPath;
};
}