commit 97a219cb75c76fcb6640b6aaf3ec725b734cbc55
parent 866fe953a5d4d25d8b4300922a087aba48a69f95
Author: 790 <790@users.noreply.github.com>
Date: Thu, 6 Jan 2022 17:42:45 +0000
remove temporary ui
Diffstat:
8 files changed, 258 insertions(+), 377 deletions(-)
diff --git a/source/jucePlugin/PluginEditor.cpp b/source/jucePlugin/PluginEditor.cpp
@@ -7,220 +7,13 @@
//==============================================================================
AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudioProcessor &p) :
- AudioProcessorEditor(&p), processorRef(p), m_btSingleMode("Single Mode"), m_btMultiMode("Multi Mode"),
- m_parameterBinding(p),
- m_btLoadFile("Load bank"), m_cmbMidiInput("Midi Input"), m_cmbMidiOutput("Midi Output"),
- m_tempEditor(p)
+ AudioProcessorEditor(&p), processorRef(p), m_parameterBinding(p), m_virusEditor(new VirusEditor(m_parameterBinding, processorRef))
{
ignoreUnused (processorRef);
- juce::PropertiesFile::Options opts;
- opts.applicationName = "DSP56300 Emulator";
- opts.filenameSuffix = ".settings";
- opts.folderName = "DSP56300 Emulator";
- opts.osxLibrarySubFolder = "Application Support/DSP56300 Emulator";
- m_properties = new juce::PropertiesFile(opts);
-
- // Make sure that before the constructor has finished, you've set the
- // editor's size to whatever you need it to be.
- setSize(800, 800);
-
- // Resizable UI
- setResizable(true, true);
- setResizeLimits(800,400,800,1600);
-
- m_btSingleMode.setRadioGroupId(0x3cf);
- m_btMultiMode.setRadioGroupId(0x3cf);
- addAndMakeVisible(m_btSingleMode);
- addAndMakeVisible(m_btMultiMode);
- m_btSingleMode.setTopLeftPosition(0,0);
- m_btSingleMode.setSize(120,30);
- m_btMultiMode.getToggleStateValue().referTo(*processorRef.getController().getParamValue(Virus::Param_PlayMode));
- const auto isMulti = processorRef.getController().isMultiMode();
- m_btSingleMode.setToggleState(!isMulti, juce::dontSendNotification);
- m_btMultiMode.setToggleState(isMulti, juce::dontSendNotification);
- m_btSingleMode.setClickingTogglesState(true);
- m_btMultiMode.setClickingTogglesState(true);
- m_btMultiMode.setTopLeftPosition(m_btSingleMode.getPosition().x + m_btSingleMode.getWidth() + 10, m_btSingleMode.getY());
- m_btMultiMode.setSize(120,30);
-
- addAndMakeVisible(m_btLoadFile);
- m_btLoadFile.setTopLeftPosition(m_btSingleMode.getPosition().x + m_btSingleMode.getWidth() + m_btMultiMode.getWidth() + 10, m_btSingleMode.getY());
- m_btLoadFile.setSize(120, 30);
- m_btLoadFile.onClick = [this]() {
- loadFile();
- };
-
- for (uint8_t pt = 0; pt < 16; pt++)
- {
- m_partSelectors[pt].onClick = [this, pt]() {
-
- juce::PopupMenu selector;
-
- for(uint8_t b=0; b<processorRef.getController().getBankCount(); ++b)
- {
- const auto bank = virusLib::fromArrayIndex(b);
- auto presetNames = processorRef.getController().getSinglePresetNames(bank);
- juce::PopupMenu p;
- for (uint8_t i = 0; i < 128; i++)
- {
- p.addItem(presetNames[i], [this, bank, i, pt] { processorRef.getController().setCurrentPartPreset(pt, bank, i); });
- }
- std::stringstream bankName;
- bankName << "Bank " << static_cast<char>('A' + b);
- selector.addSubMenu(std::string(bankName.str()), p);
- }
- selector.showMenu(juce::PopupMenu::Options());
- };
- m_partSelectors[pt].setSize(m_partSelectors[pt].getWidth() - 48, m_partSelectors[pt].getHeight());
- m_partSelectors[pt].setTopLeftPosition(m_partSelectors[pt].getPosition() + juce::Point(24, 0));
- addAndMakeVisible(m_partSelectors[pt]);
-
- m_prevPatch[pt].setSize(24, m_partSelectors[pt].getHeight());
- m_nextPatch[pt].setSize(24, m_partSelectors[pt].getHeight());
- m_prevPatch[pt].setTopLeftPosition(m_partSelectors[pt].getPosition() - juce::Point(24, 0));
- m_nextPatch[pt].setTopLeftPosition(m_partSelectors[pt].getPosition() + juce::Point(m_partSelectors[pt].getWidth(), 0));
- m_prevPatch[pt].setButtonText("<");
- m_nextPatch[pt].setButtonText(">");
- m_prevPatch[pt].onClick = [this, pt]() {
- processorRef.getController().setCurrentPartPreset(pt, processorRef.getController().getCurrentPartBank(pt),
- std::max(0, processorRef.getController().getCurrentPartProgram(pt) - 1));
- };
- m_nextPatch[pt].onClick = [this, pt]() {
- processorRef.getController().setCurrentPartPreset(pt, processorRef.getController().getCurrentPartBank(pt),
- std::min(127, processorRef.getController().getCurrentPartProgram(pt) + 1));
- };
- addAndMakeVisible(m_prevPatch[pt]);
- addAndMakeVisible(m_nextPatch[pt]);
- }
-
- auto midiIn = m_properties->getValue("midi_input", "");
- auto midiOut = m_properties->getValue("midi_output", "");
- if (midiIn != "")
- {
- processorRef.setMidiInput(midiIn);
- }
- if (midiOut != "")
- {
- processorRef.setMidiOutput(midiOut);
- }
-
- m_cmbMidiInput.setSize(160, 30);
- m_cmbMidiInput.setTopLeftPosition(0, 400);
- m_cmbMidiOutput.setSize(160, 30);
- m_cmbMidiOutput.setTopLeftPosition(164, 400);
- addAndMakeVisible(m_cmbMidiInput);
- addAndMakeVisible(m_cmbMidiOutput);
- m_cmbMidiInput.setTextWhenNoChoicesAvailable("No MIDI Inputs Enabled");
- auto midiInputs = juce::MidiInput::getAvailableDevices();
- juce::StringArray midiInputNames;
- midiInputNames.add(" - Midi In - ");
- auto inIndex = 0;
- for (int i = 0; i < midiInputs.size(); i++)
- {
- const auto input = midiInputs[i];
- if (processorRef.getMidiInput() != nullptr && input.identifier == processorRef.getMidiInput()->getIdentifier())
- {
- inIndex = i + 1;
- }
- midiInputNames.add(input.name);
- }
- m_cmbMidiInput.addItemList(midiInputNames, 1);
- m_cmbMidiInput.setSelectedItemIndex(inIndex, juce::dontSendNotification);
- m_cmbMidiOutput.setTextWhenNoChoicesAvailable("No MIDI Outputs Enabled");
- auto midiOutputs = juce::MidiOutput::getAvailableDevices();
- juce::StringArray midiOutputNames;
- midiOutputNames.add(" - Midi Out - ");
- auto outIndex = 0;
- for (int i = 0; i < midiOutputs.size(); i++)
- {
- const auto output = midiOutputs[i];
- if (processorRef.getMidiOutput() != nullptr && output.identifier == processorRef.getMidiOutput()->getIdentifier())
- {
- outIndex = i+1;
- }
- midiOutputNames.add(output.name);
- }
- m_cmbMidiOutput.addItemList(midiOutputNames, 1);
- m_cmbMidiOutput.setSelectedItemIndex(outIndex, juce::dontSendNotification);
- m_cmbMidiInput.onChange = [this]() { updateMidiInput(m_cmbMidiInput.getSelectedItemIndex()); };
- m_cmbMidiOutput.onChange = [this]() { updateMidiOutput(m_cmbMidiOutput.getSelectedItemIndex()); };
-
- addAndMakeVisible(m_tempEditor);
-
- startTimerHz(5);
-
- m_openEditor.setButtonText("Show Editor");
- m_openEditor.setTopLeftPosition(0, 500);
- auto ctrl =& processorRef.getController();
- m_openEditor.onClick = [this, ctrl]()
- {
- m_virusEditor.reset(new juce::ResizableWindow("VirusEditor", true));
- m_virusEditor->setTopLeftPosition(0, 0);
- m_virusEditor->setUsingNativeTitleBar(true);
- m_virusEditor->setVisible(true);
- m_virusEditor->setResizable(true, false);
- m_virusEditor->setContentOwned(new VirusEditor(m_parameterBinding, *ctrl), true);
- };
- addAndMakeVisible(m_openEditor);
-}
-void AudioPluginAudioProcessorEditor::updateMidiInput(int index)
-{
- auto list = juce::MidiInput::getAvailableDevices();
-
- if (index == 0)
- {
- m_properties->setValue("midi_input", "");
- m_properties->save();
- m_lastInputIndex = index;
- m_cmbMidiInput.setSelectedItemIndex(index, juce::dontSendNotification);
- return;
- }
- index--;
- auto newInput = list[index];
-
- if (!deviceManager.isMidiInputDeviceEnabled(newInput.identifier))
- deviceManager.setMidiInputDeviceEnabled(newInput.identifier, true);
-
- if (!processorRef.setMidiInput(newInput.identifier))
- {
- m_cmbMidiInput.setSelectedItemIndex(0, juce::dontSendNotification);
- m_lastInputIndex = 0;
- return;
- }
-
- m_properties->setValue("midi_input", newInput.identifier);
- m_properties->save();
-
- m_cmbMidiInput.setSelectedItemIndex(index+1, juce::dontSendNotification);
- m_lastInputIndex = index;
-}
-void AudioPluginAudioProcessorEditor::updateMidiOutput(int index)
-{
- auto list = juce::MidiOutput::getAvailableDevices();
-
- if (index == 0)
- {
- m_properties->setValue("midi_output", "");
- m_properties->save();
- m_cmbMidiOutput.setSelectedItemIndex(index, juce::dontSendNotification);
- m_lastOutputIndex = index;
- processorRef.setMidiOutput("");
- return;
- }
- index--;
- auto newOutput = list[index];
- if(!processorRef.setMidiOutput(newOutput.identifier))
- {
- m_cmbMidiOutput.setSelectedItemIndex(0, juce::dontSendNotification);
- m_lastOutputIndex = 0;
- return;
- }
- m_properties->setValue("midi_output", newOutput.identifier);
- m_properties->save();
-
- m_cmbMidiOutput.setSelectedItemIndex(index+1, juce::dontSendNotification);
- m_lastOutputIndex = index;
+ setSize(1377, 800);
+ m_virusEditor->setTopLeftPosition(0, 0);
+ addAndMakeVisible(m_virusEditor);
}
AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor()
@@ -230,36 +23,11 @@ AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor()
//==============================================================================
void AudioPluginAudioProcessorEditor::paint (juce::Graphics& g)
{
- // (Our component is opaque, so we must completely fill the background with a solid colour)
- g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
-
- g.setColour (juce::Colours::white);
- g.setFont (15.0f);
-
- std::string message = "DSP 56300 Emulator\nVersion " + std::string(g_pluginVersionString) + "\n" __DATE__ " " __TIME__;
-
- if(!processorRef.isPluginValid())
- message += "\n\nNo ROM, no sound!\nCopy ROM next to plugin, must end with .bin";
-
- g.drawFittedText(message, getLocalBounds().removeFromLeft(400).removeFromBottom(45), juce::Justification::centred,
- 2);
- g.drawFittedText("To donate: paypal.me/dsp56300", getLocalBounds().removeFromRight(400).removeFromTop(35),
- juce::Justification::centred, 2);
}
void AudioPluginAudioProcessorEditor::timerCallback()
{
// ugly (polling!) way for refreshing presets names as this is temporary ui
- const auto multiMode = processorRef.getController().isMultiMode();
- for (auto pt = 0; pt < 16; pt++)
- {
- bool singlePartOrInMulti = pt == 0 || multiMode;
- m_partSelectors[pt].setVisible(singlePartOrInMulti);
- m_prevPatch[pt].setVisible(singlePartOrInMulti);
- m_nextPatch[pt].setVisible(singlePartOrInMulti);
- if (singlePartOrInMulti)
- m_partSelectors[pt].setButtonText(processorRef.getController().getCurrentPartPresetName(pt));
- }
}
void AudioPluginAudioProcessorEditor::resized()
@@ -268,84 +36,4 @@ void AudioPluginAudioProcessorEditor::resized()
// subcomponents in your editor..
auto area = getLocalBounds();
area.removeFromTop(35);
- m_tempEditor.setBounds(area.removeFromRight(400));
- for (auto pt = 0; pt < 16; pt++)
- {
- m_partSelectors[pt].setBounds(area.removeFromTop(20));
- }
-
- m_openEditor.setBounds(0, 0, 80, 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);
-
- if (!chooser.browseForFileToOpen())
- return;
- bool sentData = false;
- 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().sendSysEx(Virus::SysEx(it, it + 267));
- sentData = true;
- }
- }
- 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().sendSysEx(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().sendSysEx(syx);
- it += 266;
- }
-
- sentData = true;
- }
- }
- }
-
- if (sentData)
- processorRef.getController().onStateLoaded();
}
diff --git a/source/jucePlugin/PluginEditor.h b/source/jucePlugin/PluginEditor.h
@@ -1,6 +1,7 @@
#pragma once
#include "VirusParameterBinding.h"
+#include "ui/VirusEditor.h"
#include "PluginProcessor.h"
#include <juce_audio_devices/juce_audio_devices.h>
//==============================================================================
@@ -16,34 +17,15 @@ public:
void resized() override;
private:
- void updateMidiInput(int index);
- void updateMidiOutput(int index);
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;
VirusParameterBinding m_parameterBinding;
- juce::GenericAudioProcessorEditor m_tempEditor;
- juce::TextButton m_partSelectors[16];
- juce::TextButton m_prevPatch[16];
- juce::TextButton m_nextPatch[16];
- juce::TextButton m_btSingleMode;
- juce::TextButton m_btMultiMode;
- juce::TextButton m_btLoadFile;
- juce::String m_previousPath;
- juce::ComboBox m_cmbMidiInput;
- juce::ComboBox m_cmbMidiOutput;
-
- juce::AudioDeviceManager deviceManager;
- juce::PropertiesFile *m_properties;
- int m_lastInputIndex = 0;
- int m_lastOutputIndex = 0;
// New "real" editor
- juce::TextButton m_openEditor; // temporary until integrated - will be rebased!
- std::unique_ptr<juce::ResizableWindow> m_virusEditor;
+ VirusEditor *m_virusEditor;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAudioProcessorEditor)
diff --git a/source/jucePlugin/VirusParameterBinding.cpp b/source/jucePlugin/VirusParameterBinding.cpp
@@ -1,8 +1,18 @@
#include "VirusParameterBinding.h"
-
+#include "VirusParameter.h"
#include "PluginProcessor.h"
-void VirusParameterBinding::bind(juce::Slider& _slider, Virus::ParameterType _param) const
+void VirusParameterBinding::setPart(uint8_t _part) {
+ m_part = _part;
+
+ for (const auto b : m_bindings)
+ {
+ b->onValueChanged = nullptr;
+ }
+ m_bindings.clear();
+
+}
+void VirusParameterBinding::bind(juce::Slider &_slider, Virus::ParameterType _param)
{
const auto v = m_processor.getController().getParameter(_param, m_part);
if (!v)
@@ -16,7 +26,7 @@ void VirusParameterBinding::bind(juce::Slider& _slider, Virus::ParameterType _pa
_slider.getValueObject().referTo(v->getValueObject());
}
-void VirusParameterBinding::bind(juce::ComboBox& _combo, Virus::ParameterType _param) const
+void VirusParameterBinding::bind(juce::ComboBox& _combo, Virus::ParameterType _param)
{
const auto v = m_processor.getController().getParameter(_param, m_part);
if (!v)
@@ -31,10 +41,12 @@ void VirusParameterBinding::bind(juce::ComboBox& _combo, Virus::ParameterType _p
//v->setValue(_combo.getSelectedId() - 1);
v->getValueObject().getValueSource().setValue(_combo.getSelectedItemIndex());
};
+
v->onValueChanged = [this, &_combo, v]() { _combo.setSelectedItemIndex(v->getValueObject().getValueSource().getValue(), juce::NotificationType::dontSendNotification); };
+ m_bindings.add(v);
}
-void VirusParameterBinding::bind(juce::DrawableButton &_btn, Virus::ParameterType _param) const
+void VirusParameterBinding::bind(juce::DrawableButton &_btn, Virus::ParameterType _param)
{
const auto v = m_processor.getController().getParameter(_param, m_part);
if (!v)
@@ -45,7 +57,7 @@ void VirusParameterBinding::bind(juce::DrawableButton &_btn, Virus::ParameterTyp
_btn.getToggleStateValue().referTo(v->getValueObject());
}
-void VirusParameterBinding::bind(juce::Component &_btn, Virus::ParameterType _param) const
+void VirusParameterBinding::bind(juce::Component &_btn, Virus::ParameterType _param)
{
const auto v = m_processor.getController().getParameter(_param, m_part);
if (!v)
diff --git a/source/jucePlugin/VirusParameterBinding.h b/source/jucePlugin/VirusParameterBinding.h
@@ -1,6 +1,6 @@
#pragma once
#include "VirusController.h"
-
+#include "VirusParameter.h"
namespace juce {
class Value;
}
@@ -14,11 +14,12 @@ public:
{
m_part = _part;
}
-
- void bind(juce::Slider& _control, Virus::ParameterType _param) const;
- void bind(juce::ComboBox &_control, Virus::ParameterType _param) const;
- void bind(juce::DrawableButton &_control, Virus::ParameterType _param) const;
- void bind(juce::Component &_control, Virus::ParameterType _param) const;
+ void setPart(uint8_t _part);
+ void bind(juce::Slider& _control, Virus::ParameterType _param);
+ void bind(juce::ComboBox &_control, Virus::ParameterType _param);
+ void bind(juce::DrawableButton &_control, Virus::ParameterType _param);
+ void bind(juce::Component &_control, Virus::ParameterType _param);
AudioPluginAudioProcessor& m_processor;
uint8_t m_part;
+ juce::Array<Virus::Parameter*> m_bindings;
};
diff --git a/source/jucePlugin/ui/VirusEditor.cpp b/source/jucePlugin/ui/VirusEditor.cpp
@@ -1,6 +1,6 @@
#include "VirusEditor.h"
#include "BinaryData.h"
-
+#include "../version.h"
#include "Virus_ArpEditor.h"
#include "Virus_FxEditor.h"
#include "Virus_LfoEditor.h"
@@ -13,8 +13,8 @@ using namespace juce;
constexpr auto kPanelWidth = 1377;
constexpr auto kPanelHeight = 800;
-VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, Virus::Controller& _controller) :
- m_parameterBinding(_parameterBinding), m_controller(_controller)
+VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) :
+ m_parameterBinding(_parameterBinding), processorRef(_processorRef), m_controller(processorRef.getController()), m_btSingleMode("Single Mode"), m_btMultiMode("Multi Mode")
{
setLookAndFeel(&m_lookAndFeel);
@@ -61,7 +61,7 @@ VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, Virus::Contro
addAndMakeVisible(m_partSelect[pt]);
m_presetNames[pt].setBounds(80, 172 + pt * (36), 136, 16);
- m_presetNames[pt].setButtonText(_controller.getCurrentPartPresetName(pt));
+ m_presetNames[pt].setButtonText(m_controller.getCurrentPartPresetName(pt));
m_presetNames[pt].setColour(0, juce::Colours::white);
m_presetNames[pt].onClick = [this, pt]() {
@@ -106,6 +106,102 @@ VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, Virus::Contro
addAndMakeVisible(m_nextPatch[pt]);
}
m_partSelect[0].setToggleState(true, NotificationType::sendNotification);
+
+ m_btSingleMode.setRadioGroupId(0x3cf);
+ m_btMultiMode.setRadioGroupId(0x3cf);
+ addAndMakeVisible(m_btSingleMode);
+ addAndMakeVisible(m_btMultiMode);
+ m_btSingleMode.setTopLeftPosition(102, 756);
+ m_btSingleMode.setSize(100, 30);
+ m_btMultiMode.getToggleStateValue().referTo(*m_controller.getParamValue(Virus::Param_PlayMode));
+ const auto isMulti = m_controller.isMultiMode();
+ m_btSingleMode.setToggleState(!isMulti, juce::dontSendNotification);
+ m_btMultiMode.setToggleState(isMulti, juce::dontSendNotification);
+ m_btSingleMode.setClickingTogglesState(false);
+ m_btMultiMode.setClickingTogglesState(false);
+ m_btSingleMode.onClick = [this]() { setPlayMode(0); };
+ m_btMultiMode.onClick = [this]() { setPlayMode(1); };
+
+ m_btMultiMode.setTopLeftPosition(m_btSingleMode.getPosition().x + m_btSingleMode.getWidth() + 10,
+ m_btSingleMode.getY());
+ m_btMultiMode.setSize(100, 30);
+
+ juce::PropertiesFile::Options opts;
+ opts.applicationName = "DSP56300 Emulator";
+ opts.filenameSuffix = ".settings";
+ opts.folderName = "DSP56300 Emulator";
+ opts.osxLibrarySubFolder = "Application Support/DSP56300 Emulator";
+ m_properties = new juce::PropertiesFile(opts);
+ auto midiIn = m_properties->getValue("midi_input", "");
+ auto midiOut = m_properties->getValue("midi_output", "");
+ if (midiIn != "")
+ {
+ processorRef.setMidiInput(midiIn);
+ }
+ if (midiOut != "")
+ {
+ processorRef.setMidiOutput(midiOut);
+ }
+
+ m_cmbMidiInput.setSize(160, 30);
+ m_cmbMidiInput.setTopLeftPosition(350, 760);
+ m_cmbMidiOutput.setSize(160, 30);
+ m_cmbMidiOutput.setTopLeftPosition(350+164, 760);
+ addAndMakeVisible(m_cmbMidiInput);
+ addAndMakeVisible(m_cmbMidiOutput);
+ m_cmbMidiInput.setTextWhenNoChoicesAvailable("No MIDI Inputs Enabled");
+ auto midiInputs = juce::MidiInput::getAvailableDevices();
+ juce::StringArray midiInputNames;
+ midiInputNames.add(" - Midi In - ");
+ auto inIndex = 0;
+ for (int i = 0; i < midiInputs.size(); i++)
+ {
+ const auto input = midiInputs[i];
+ if (processorRef.getMidiInput() != nullptr && input.identifier == processorRef.getMidiInput()->getIdentifier())
+ {
+ inIndex = i + 1;
+ }
+ midiInputNames.add(input.name);
+ }
+ m_cmbMidiInput.addItemList(midiInputNames, 1);
+ m_cmbMidiInput.setSelectedItemIndex(inIndex, juce::dontSendNotification);
+ m_cmbMidiOutput.setTextWhenNoChoicesAvailable("No MIDI Outputs Enabled");
+ auto midiOutputs = juce::MidiOutput::getAvailableDevices();
+ juce::StringArray midiOutputNames;
+ midiOutputNames.add(" - Midi Out - ");
+ auto outIndex = 0;
+ for (int i = 0; i < midiOutputs.size(); i++)
+ {
+ const auto output = midiOutputs[i];
+ if (processorRef.getMidiOutput() != nullptr &&
+ output.identifier == processorRef.getMidiOutput()->getIdentifier())
+ {
+ outIndex = i + 1;
+ }
+ midiOutputNames.add(output.name);
+ }
+ m_cmbMidiOutput.addItemList(midiOutputNames, 1);
+ m_cmbMidiOutput.setSelectedItemIndex(outIndex, juce::dontSendNotification);
+ m_cmbMidiInput.onChange = [this]() { updateMidiInput(m_cmbMidiInput.getSelectedItemIndex()); };
+ m_cmbMidiOutput.onChange = [this]() { updateMidiOutput(m_cmbMidiOutput.getSelectedItemIndex()); };
+
+ std::string message =
+ "DSP 56300 Emulator\nVersion " + std::string(g_pluginVersionString) + "\n" __DATE__ " " __TIME__;
+ if (!processorRef.isPluginValid())
+ message += "\n\nNo ROM, no sound!\nCopy ROM next to plugin, must end with .bin";
+ message += "\n\nTo donate: paypal.me/dsp56300";
+ m_version.setText(message, NotificationType::dontSendNotification);
+ m_version.setBounds(94, 2, 220, 150);
+ m_version.setColour(juce::Label::textColourId, juce::Colours::white);
+ m_version.setJustificationType(Justification::centred);
+ addAndMakeVisible(m_version);
+
+ m_patchName.setBounds(410, 48, 362, 36);
+ m_patchName.setJustificationType(Justification::left);
+ m_patchName.setFont(juce::Font(32.0f, juce::Font::bold));
+ m_patchName.setColour(juce::Label::textColourId, juce::Colours::red);
+ addAndMakeVisible(m_patchName);
+
startTimerHz(5);
setSize (kPanelWidth, kPanelHeight);
}
@@ -124,7 +220,72 @@ void VirusEditor::timerCallback()
m_nextPatch[pt].setVisible(singlePartOrInMulti);
if (singlePartOrInMulti)
m_presetNames[pt].setButtonText(m_controller.getCurrentPartPresetName(pt));
+ if (pt == m_parameterBinding.m_part)
+ {
+ m_patchName.setText(m_controller.getCurrentPartPresetName(pt),
+ NotificationType::dontSendNotification);
+ }
}
+
+}
+
+void VirusEditor::updateMidiInput(int index)
+{
+ auto list = juce::MidiInput::getAvailableDevices();
+
+ if (index == 0)
+ {
+ m_properties->setValue("midi_input", "");
+ m_properties->save();
+ m_lastInputIndex = index;
+ m_cmbMidiInput.setSelectedItemIndex(index, juce::dontSendNotification);
+ return;
+ }
+ index--;
+ auto newInput = list[index];
+
+ if (!deviceManager.isMidiInputDeviceEnabled(newInput.identifier))
+ deviceManager.setMidiInputDeviceEnabled(newInput.identifier, true);
+
+ if (!processorRef.setMidiInput(newInput.identifier))
+ {
+ m_cmbMidiInput.setSelectedItemIndex(0, juce::dontSendNotification);
+ m_lastInputIndex = 0;
+ return;
+ }
+
+ m_properties->setValue("midi_input", newInput.identifier);
+ m_properties->save();
+
+ m_cmbMidiInput.setSelectedItemIndex(index + 1, juce::dontSendNotification);
+ m_lastInputIndex = index;
+}
+void VirusEditor::updateMidiOutput(int index)
+{
+ auto list = juce::MidiOutput::getAvailableDevices();
+
+ if (index == 0)
+ {
+ m_properties->setValue("midi_output", "");
+ m_properties->save();
+ m_cmbMidiOutput.setSelectedItemIndex(index, juce::dontSendNotification);
+ m_lastOutputIndex = index;
+ processorRef.setMidiOutput("");
+ return;
+ }
+ index--;
+ auto newOutput = list[index];
+ if (!processorRef.setMidiOutput(newOutput.identifier))
+ {
+ m_cmbMidiOutput.setSelectedItemIndex(0, juce::dontSendNotification);
+ m_lastOutputIndex = 0;
+ return;
+ }
+ m_properties->setValue("midi_output", newOutput.identifier);
+ m_properties->save();
+
+ m_cmbMidiOutput.setSelectedItemIndex(index + 1, juce::dontSendNotification);
+ m_lastOutputIndex = index;
}
void VirusEditor::updatePartsPresetNames()
{
@@ -150,22 +311,35 @@ void VirusEditor::resized()
m_presetButtons.setBounds(statusArea.removeFromRight(188));
applyToSections([this](Component *s) { s->setTopLeftPosition(338, 133); });
}
-void VirusEditor::changePart(uint8_t _part) {
- m_parameterBinding.m_part = _part;
+void VirusEditor::setPlayMode(uint8_t _mode) {
+ m_controller.getParameter(Virus::Param_PlayMode)->setValue(_mode);
+ changePart(0);
+}
+
+void VirusEditor::changePart(uint8_t _part)
+{
+ for (auto &p : m_partSelect)
+ {
+ p.setToggleState(false, juce::dontSendNotification);
+ }
+ m_partSelect[_part].setToggleState(true, juce::dontSendNotification);
+ m_parameterBinding.setPart(_part);
+
removeChildComponent(m_oscEditor.get());
+ removeChildComponent(m_lfoEditor.get());
+ removeChildComponent(m_fxEditor.get());
+ removeChildComponent(m_arpEditor.get());
+
m_oscEditor = std::make_unique<OscEditor>(m_parameterBinding);
addChildComponent(m_oscEditor.get());
- removeChildComponent(m_lfoEditor.get());
m_lfoEditor = std::make_unique<LfoEditor>(m_parameterBinding);
addChildComponent(m_lfoEditor.get());
- removeChildComponent(m_fxEditor.get());
m_fxEditor = std::make_unique<FxEditor>(m_parameterBinding);
addChildComponent(m_fxEditor.get());
- removeChildComponent(m_arpEditor.get());
m_arpEditor = std::make_unique<ArpEditor>(m_parameterBinding);
addChildComponent(m_arpEditor.get());
diff --git a/source/jucePlugin/ui/VirusEditor.h b/source/jucePlugin/ui/VirusEditor.h
@@ -1,6 +1,7 @@
#pragma once
#include <juce_gui_extra/juce_gui_extra.h>
+#include <juce_audio_devices/juce_audio_devices.h>
#include "Virus_Buttons.h"
#include "Virus_LookAndFeel.h"
#include "../VirusController.h"
@@ -14,22 +15,36 @@ class ArpEditor;
class VirusEditor : public juce::Component, private juce::Timer
{
public:
- VirusEditor(VirusParameterBinding& _parameterBinding, Virus::Controller& _controller);
+ VirusEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef);
~VirusEditor() override;
void resized() override;
void changePart(uint8_t _part);
void updatePartsPresetNames();
void loadFile();
+ void setPlayMode(uint8_t _mode);
+
private:
void timerCallback() override;
+ void updateMidiInput(int index);
+ void updateMidiOutput(int index);
+ juce::Label m_version;
+ juce::Label m_patchName;
Buttons::PartSelectButton m_partSelect[16];
juce::Label m_partLabels[16];
juce::TextButton m_presetNames[16];
juce::TextButton m_nextPatch[16];
juce::TextButton m_prevPatch[16];
+ juce::TextButton m_btSingleMode;
+ juce::TextButton m_btMultiMode;
+ juce::ComboBox m_cmbMidiInput;
+ juce::ComboBox m_cmbMidiOutput;
+ juce::AudioDeviceManager deviceManager;
+ juce::PropertiesFile *m_properties;
+ int m_lastInputIndex = 0;
+ int m_lastOutputIndex = 0;
- static constexpr auto kPartGroupId = 0x3FBBA;
+ static constexpr auto kPartGroupId = 0x3FBBC;
struct MainButtons : juce::Component, juce::Value::Listener
{
MainButtons();
@@ -56,6 +71,7 @@ private:
void applyToSections(std::function<void(juce::Component *)>);
VirusParameterBinding& m_parameterBinding;
+ AudioPluginAudioProcessor &processorRef;
Virus::Controller& m_controller;
std::unique_ptr<OscEditor> m_oscEditor;
std::unique_ptr<LfoEditor> m_lfoEditor;
diff --git a/source/jucePlugin/ui/Virus_LfoEditor.cpp b/source/jucePlugin/ui/Virus_LfoEditor.cpp
@@ -27,8 +27,8 @@ LfoEditor::LfoBase::LfoBase(VirusParameterBinding& _parameterBinding, uint8_t _l
{
for (auto *s : {&m_rate, &m_keytrack, &m_amount})
setupRotary(*this, *s);
- addAndMakeVisible(m_subWaveform);
- m_subWaveform.setBounds(8, 123, Buttons::HandleButton::kWidth, Buttons::HandleButton::kHeight);
+ addAndMakeVisible(m_mode);
+ m_mode.setBounds(8, 123, Buttons::HandleButton::kWidth, Buttons::HandleButton::kHeight);
addAndMakeVisible(m_shape);
m_shape.setBounds(10, 37, 84, comboBoxHeight);
@@ -44,12 +44,15 @@ LfoEditor::LfoBase::LfoBase(VirusParameterBinding& _parameterBinding, uint8_t _l
const Virus::ParameterType clock[] = {Virus::Param_Lfo1Clock, Virus::Param_Lfo2Clock, Virus::Param_Lfo3Clock};
const Virus::ParameterType assignDest[] = {Virus::Param_Lfo1AssignDest, Virus::Param_Lfo2AssignDest,
Virus::Param_Lfo3Destination};
+ const Virus::ParameterType lfoModes[] = {Virus::Param_Lfo1Mode, Virus::Param_Lfo2Mode, Virus::Param_Lfo3Mode};
+
_parameterBinding.bind(m_rate, rate[_lfoIndex]);
_parameterBinding.bind(m_keytrack, keytrack[_lfoIndex]);
_parameterBinding.bind(m_amount, amount[_lfoIndex]);
_parameterBinding.bind(m_shape, shapes[_lfoIndex]);
_parameterBinding.bind(m_clock, clock[_lfoIndex]);
_parameterBinding.bind(m_assignDest, assignDest[_lfoIndex]);
+ _parameterBinding.bind(m_mode, lfoModes[_lfoIndex]);
}
LfoEditor::LfoTwoOneShared::LfoTwoOneShared(VirusParameterBinding& _parameterBinding, uint8_t _lfoIndex) : LfoBase(_parameterBinding, _lfoIndex), m_link(false)
@@ -73,7 +76,7 @@ LfoEditor::LfoTwoOneShared::LfoTwoOneShared(VirusParameterBinding& _parameterBin
_parameterBinding.bind(m_phase, _lfoIndex == 0 ? Virus::Param_Lfo1KeyTrigger : Virus::Param_Lfo2Keytrigger);
//parameterBinding.bind(m_amount, Virus::Param_Lfo1AssignAmount);
_parameterBinding.bind(m_envMode, _lfoIndex == 0 ? Virus::Param_Lfo1EnvMode : Virus::Param_Lfo2EnvMode);
- _parameterBinding.bind(m_link, _lfoIndex == 0 ? Virus::Param_Lfo1Mode : Virus::Param_Lfo2Mode);
+ //_parameterBinding.bind(m_link, _lfoIndex == 0 ? Virus::Param_Lfo1Mode : Virus::Param_Lfo2Mode);
//_parameterBinding.bind(m_assignDest, Virus::Param_Lfo1AssignDest);
}
@@ -137,29 +140,34 @@ LfoEditor::ModMatrix::ModMatrix(VirusParameterBinding& _parameterBinding)
setupSlot(4, {{255, 338}}, {320, 314});
setupSlot(5, {{255, 462}}, {320, 439});
- _parameterBinding.bind(m_modMatrix[0]->m_source, Virus::Param_Assign1Source);
- _parameterBinding.bind(m_modMatrix[1]->m_source, Virus::Param_Assign2Source);
- _parameterBinding.bind(m_modMatrix[2]->m_source, Virus::Param_Assign3Source);
+ // slot 0 is assign2, slot 1 is assign3, then 1,4,5,6
+ _parameterBinding.bind(m_modMatrix[0]->m_source, Virus::Param_Assign2Source);
+ _parameterBinding.bind(m_modMatrix[1]->m_source, Virus::Param_Assign3Source);
+ _parameterBinding.bind(m_modMatrix[2]->m_source, Virus::Param_Assign1Source);
_parameterBinding.bind(m_modMatrix[3]->m_source, Virus::Param_Assign4Source);
_parameterBinding.bind(m_modMatrix[4]->m_source, Virus::Param_Assign5Source);
_parameterBinding.bind(m_modMatrix[5]->m_source, Virus::Param_Assign6Source);
- _parameterBinding.bind(m_modMatrix[0]->m_destinations[0]->m_amount, Virus::Param_Assign1Amount);
- _parameterBinding.bind(m_modMatrix[1]->m_destinations[0]->m_amount, Virus::Param_Assign2Amount1);
- //_parameterBinding.bind(m_modMatrix[1]->m_destinations[1]->m_amount, Virus::Param_Assign2Amount2);
- //_parameterBinding.bind(m_modMatrix[1]->m_destinations[2]->m_amount, Virus::Param_Assign2Amount3);
- _parameterBinding.bind(m_modMatrix[2]->m_destinations[0]->m_amount, Virus::Param_Assign3Amount1);
- //_parameterBinding.bind(m_modMatrix[2]->m_destinations[1]->m_amount, Virus::Param_Assign3Amount2);
+ _parameterBinding.bind(m_modMatrix[0]->m_destinations[0]->m_amount, Virus::Param_Assign2Amount1);
+ _parameterBinding.bind(m_modMatrix[0]->m_destinations[1]->m_amount, Virus::Param_Assign2Amount2);
+ _parameterBinding.bind(m_modMatrix[0]->m_destinations[2]->m_amount, Virus::Param_Assign2Amount3);
+
+ _parameterBinding.bind(m_modMatrix[1]->m_destinations[0]->m_amount, Virus::Param_Assign3Amount1);
+ _parameterBinding.bind(m_modMatrix[1]->m_destinations[1]->m_amount, Virus::Param_Assign3Amount2);
+
+ _parameterBinding.bind(m_modMatrix[2]->m_destinations[0]->m_amount, Virus::Param_Assign1Amount);
+
_parameterBinding.bind(m_modMatrix[3]->m_destinations[0]->m_amount, Virus::Param_Assign4Amount);
_parameterBinding.bind(m_modMatrix[4]->m_destinations[0]->m_amount, Virus::Param_Assign5Amount);
_parameterBinding.bind(m_modMatrix[5]->m_destinations[0]->m_amount, Virus::Param_Assign6Amount);
- _parameterBinding.bind(m_modMatrix[0]->m_destinations[0]->m_dest, Virus::Param_Assign1Destination);
- _parameterBinding.bind(m_modMatrix[1]->m_destinations[0]->m_dest, Virus::Param_Assign2Destination1);
- //_parameterBinding.bind(m_modMatrix[1]->m_destinations[1]->m_dest, Virus::Param_Assign2Destination2);
- //_parameterBinding.bind(m_modMatrix[1]->m_destinations[2]->m_dest, Virus::Param_Assign2Destination3);
- _parameterBinding.bind(m_modMatrix[2]->m_destinations[0]->m_dest, Virus::Param_Assign3Destination1);
- //_parameterBinding.bind(m_modMatrix[2]->m_destinations[1]->m_dest, Virus::Param_Assign3Destination2);
+ _parameterBinding.bind(m_modMatrix[0]->m_destinations[0]->m_dest, Virus::Param_Assign2Destination1);
+ _parameterBinding.bind(m_modMatrix[0]->m_destinations[1]->m_dest, Virus::Param_Assign2Destination2);
+ _parameterBinding.bind(m_modMatrix[0]->m_destinations[2]->m_dest, Virus::Param_Assign2Destination3);
+ _parameterBinding.bind(m_modMatrix[1]->m_destinations[0]->m_dest, Virus::Param_Assign3Destination1);
+ _parameterBinding.bind(m_modMatrix[1]->m_destinations[1]->m_dest, Virus::Param_Assign3Destination2);
+
+ _parameterBinding.bind(m_modMatrix[2]->m_destinations[0]->m_dest, Virus::Param_Assign1Destination);
_parameterBinding.bind(m_modMatrix[3]->m_destinations[0]->m_dest, Virus::Param_Assign4Destination);
_parameterBinding.bind(m_modMatrix[4]->m_destinations[0]->m_dest, Virus::Param_Assign5Destination);
_parameterBinding.bind(m_modMatrix[5]->m_destinations[0]->m_dest, Virus::Param_Assign6Destination);
diff --git a/source/jucePlugin/ui/Virus_LfoEditor.h b/source/jucePlugin/ui/Virus_LfoEditor.h
@@ -17,7 +17,7 @@ private:
juce::Slider m_rate;
juce::Slider m_keytrack;
juce::Slider m_amount;
- Buttons::HandleButton m_subWaveform;
+ Buttons::HandleButton m_mode;
juce::ComboBox m_shape, m_clock;
juce::ComboBox m_assignDest;
};