commit dfafe64487eca9327bd32a9ff000af8ecab46dac
parent 25d85521fdcb1c3147372637393a9e98e5d4cfd8
Author: dsp56300 <87139854+dsp56300@users.noreply.github.com>
Date: Mon, 4 Oct 2021 10:04:48 +0200
Merge pull request #27 from 790/midibanks
Add midi/syx bank loading
Diffstat:
4 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/source/jucePlugin/PluginEditor.cpp b/source/jucePlugin/PluginEditor.cpp
@@ -6,6 +6,7 @@
//==============================================================================
AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudioProcessor &p) :
AudioProcessorEditor(&p), processorRef(p), m_btSingleMode("Single Mode"), m_btMultiMode("Multi Mode"),
+ m_btLoadFile("Load bank"),
m_tempEditor(p)
{
ignoreUnused (processorRef);
@@ -33,6 +34,13 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi
m_btMultiMode.setTopLeftPosition(m_btSingleMode.getPosition().x + m_btSingleMode.getWidth() + 10, 0);
m_btMultiMode.setSize(120,30);
+ addAndMakeVisible(m_btLoadFile);
+ m_btLoadFile.setTopLeftPosition(m_btSingleMode.getPosition().x + m_btSingleMode.getWidth() + m_btMultiMode.getWidth() + 10, 0);
+ m_btLoadFile.setSize(120, 30);
+ m_btLoadFile.onClick = [this]() {
+ loadFile();
+ };
+
for (auto pt = 0; pt < 16; pt++)
{
m_partSelectors[pt].onClick = [this, pt]() {
@@ -110,3 +118,69 @@ void AudioPluginAudioProcessorEditor::resized()
m_partSelectors[pt].setBounds(area.removeFromTop(20));
}
}
+
+void AudioPluginAudioProcessorEditor::loadFile() {
+ juce::FileChooser chooser("Choose syx/midi banks to import",
+ m_previousPath.isEmpty() ? juce::File::getSpecialLocation(juce::File::currentApplicationFile).getParentDirectory() : m_previousPath,
+ "*.syx,*.mid,*.midi",
+ true);
+ const bool result = chooser.browseForFileToOpen();
+ if (result)
+ {
+ const auto result = chooser.getResult();
+ m_previousPath = result.getParentDirectory().getFullPathName();
+ const auto ext = result.getFileExtension().toLowerCase();
+ if (ext == ".syx")
+ {
+ juce::MemoryBlock data;
+ result.loadFileAsData(data);
+ for (auto it = data.begin(); it != data.end(); it += 267)
+ {
+ if ((it + 267) < data.end())
+ {
+ processorRef.getController().parseMessage(Virus::SysEx(it, it + 267));
+ }
+ }
+ m_btLoadFile.setButtonText("Loaded");
+ }
+ else if (ext == ".mid" || ext == ".midi")
+ {
+ juce::MemoryBlock data;
+ if (!result.loadFileAsData(data))
+ {
+ return;
+ }
+ const uint8_t *ptr = (uint8_t *)data.getData();
+ const auto end = ptr + data.getSize();
+
+ for (auto it = ptr; it < end; it += 1)
+ {
+ if ((uint8_t)*it == (uint8_t)0xf0 && (it+267) < end)
+ {
+ if ((uint8_t) *(it + 1) == (uint8_t)0x00)
+ {
+ auto syx = Virus::SysEx(it, it + 267);
+ syx[7] = 0x01; // force to bank a
+ syx[266] = 0xf7;
+ processorRef.getController().parseMessage(syx);
+
+ it += 266;
+ }
+ else // some midi files have two bytes after the 0xf0
+ {
+ auto syx = Virus::SysEx();
+ syx.push_back(0xf0);
+ for (auto i = it + 3; i < it + 3 + 266; i++)
+ {
+ syx.push_back((uint8_t)*i);
+ }
+ syx[7] = 0x01; // force to bank a
+ syx[266] = 0xf7;
+ processorRef.getController().parseMessage(syx);
+ it += 266;
+ }
+ }
+ }
+ }
+ }
+}
+\ No newline at end of file
diff --git a/source/jucePlugin/PluginEditor.h b/source/jucePlugin/PluginEditor.h
@@ -15,6 +15,7 @@ public:
private:
void timerCallback() override;
+ void loadFile();
// This reference is provided as a quick way for your editor to
// access the processor object that created it.
AudioPluginAudioProcessor& processorRef;
@@ -25,6 +26,8 @@ private:
juce::TextButton m_btSingleMode;
juce::TextButton m_btMultiMode;
+ juce::TextButton m_btLoadFile;
+ juce::String m_previousPath;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAudioProcessorEditor)
};
diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp
@@ -86,7 +86,7 @@ namespace Virus
}
else if (i == 5)
{
- if (msg[i] != m_deviceId)
+ if (msg[i] != m_deviceId && msg[i] != 0x10)
return; // not intended to this device!
}
else if (i == 6)
diff --git a/source/jucePlugin/VirusController.h b/source/jucePlugin/VirusController.h
@@ -36,6 +36,7 @@ namespace Virus
void setCurrentPartPreset(uint8_t part, uint8_t bank, uint8_t prg);
juce::String getCurrentPartPresetName(uint8_t part);
uint32_t getBankCount() const { return static_cast<uint32_t>(m_singles.size()); }
+ void parseMessage(const SysEx &);
private:
void timerCallback() override;
@@ -89,7 +90,6 @@ namespace Virus
static inline uint8_t copyData(const SysEx &src, int startPos, uint8_t *dst);
template <typename T> juce::String parseAsciiText(const T &, int startPos) const;
- void parseMessage(const SysEx &);
void parseSingle(const SysEx &);
void parseMulti(const SysEx &);
void parseParamChange(const SysEx &);