Signed-off-by: falkTX <falktx@falktx.com>pull/95/head
@@ -1,8 +1,10 @@ | |||
############################################################################### | |||
if linux_embed | |||
# TODO deal with this later | |||
plugins = [] | |||
plugins = [ | |||
'vitalium', | |||
'swankyamp', | |||
] | |||
else | |||
plugins = [ | |||
'chow', | |||
@@ -5,29 +5,38 @@ plugin_extra_include_dirs = include_directories([ | |||
'thirdparty/optional-lite/include', | |||
]) | |||
plugin_srcs = files([ | |||
'source/BinaryData.cpp', | |||
'source/NewComponent.cpp', | |||
'source/PluginEditor.cpp', | |||
'source/PluginProcessor.cpp', | |||
'source/PresetManager.cpp', | |||
'source/SwankyAmpLAF.cpp', | |||
'source/TooltipsData.cpp', | |||
'source/Utils.cpp', | |||
'source/Components/AmpGroup.cpp', | |||
'source/Components/CabGroup.cpp', | |||
'source/Components/LevelMeter.cpp', | |||
'source/Components/LevelsGroup.cpp', | |||
'source/Components/ParameterGroup.cpp', | |||
'source/Components/PowerAmpGroup.cpp', | |||
'source/Components/PreAmpGroup.cpp', | |||
'source/Components/PresetGroup.cpp', | |||
'source/Components/RButton.cpp', | |||
'source/Components/RSlider.cpp', | |||
'source/Components/RSliderLabel.cpp', | |||
'source/Components/StagingGroup.cpp', | |||
'source/Components/ToneStackGroup.cpp', | |||
]) | |||
if linux_embed | |||
plugin_srcs = files([ | |||
'source/BinaryData.cpp', | |||
'source/PluginProcessor.cpp', | |||
'source/PresetManager.cpp', | |||
'source/Utils.cpp', | |||
]) | |||
else | |||
plugin_srcs = files([ | |||
'source/BinaryData.cpp', | |||
'source/NewComponent.cpp', | |||
'source/PluginEditor.cpp', | |||
'source/PluginProcessor.cpp', | |||
'source/PresetManager.cpp', | |||
'source/SwankyAmpLAF.cpp', | |||
'source/TooltipsData.cpp', | |||
'source/Utils.cpp', | |||
'source/Components/AmpGroup.cpp', | |||
'source/Components/CabGroup.cpp', | |||
'source/Components/LevelMeter.cpp', | |||
'source/Components/LevelsGroup.cpp', | |||
'source/Components/ParameterGroup.cpp', | |||
'source/Components/PowerAmpGroup.cpp', | |||
'source/Components/PreAmpGroup.cpp', | |||
'source/Components/PresetGroup.cpp', | |||
'source/Components/RButton.cpp', | |||
'source/Components/RSlider.cpp', | |||
'source/Components/RSliderLabel.cpp', | |||
'source/Components/StagingGroup.cpp', | |||
'source/Components/ToneStackGroup.cpp', | |||
]) | |||
endif | |||
plugin_name = 'SwankyAmp' | |||
@@ -396,6 +396,7 @@ void SwankyAmpAudioProcessor::processBlock( | |||
} | |||
} | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
bool SwankyAmpAudioProcessor::hasEditor() const | |||
{ | |||
return true; // (change this to false if you choose to not supply an editor) | |||
@@ -405,6 +406,7 @@ AudioProcessorEditor* SwankyAmpAudioProcessor::createEditor() | |||
{ | |||
return new SwankyAmpAudioProcessorEditor(*this, parameters); | |||
} | |||
#endif | |||
void SwankyAmpAudioProcessor::setPresetText(const String& text) | |||
{ | |||
@@ -97,8 +97,10 @@ public: | |||
void processBlock(AudioBuffer<float>&, MidiBuffer&) override; | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
AudioProcessorEditor* createEditor() override; | |||
bool hasEditor() const override; | |||
#endif | |||
const String getName() const override; | |||
@@ -46,17 +46,26 @@ plugin_extra_include_dirs = include_directories([ | |||
'third_party', | |||
]) | |||
plugin_srcs = files([ | |||
'BinaryData.cpp', | |||
'source/unity_build/common.cpp', | |||
'source/unity_build/interface_editor_components.cpp', | |||
'source/unity_build/interface_editor_sections.cpp', | |||
'source/unity_build/interface_editor_sections2.cpp', | |||
'source/unity_build/interface_look_and_feel.cpp', | |||
'source/unity_build/interface_wavetable.cpp', | |||
'source/unity_build/plugin.cpp', | |||
'source/unity_build/synthesis.cpp', | |||
]) | |||
if linux_embed | |||
plugin_srcs = files([ | |||
'BinaryData.cpp', | |||
'source/unity_build/common.cpp', | |||
'source/unity_build/plugin.cpp', | |||
'source/unity_build/synthesis.cpp', | |||
]) | |||
else | |||
plugin_srcs = files([ | |||
'BinaryData.cpp', | |||
'source/unity_build/common.cpp', | |||
'source/unity_build/interface_editor_components.cpp', | |||
'source/unity_build/interface_editor_sections.cpp', | |||
'source/unity_build/interface_editor_sections2.cpp', | |||
'source/unity_build/interface_look_and_feel.cpp', | |||
'source/unity_build/interface_wavetable.cpp', | |||
'source/unity_build/plugin.cpp', | |||
'source/unity_build/synthesis.cpp', | |||
]) | |||
endif | |||
plugin_name = 'vitalium' | |||
plugin_uses_opengl = true | |||
@@ -123,18 +123,24 @@ void MidiManager::processPitchBend(const MidiMessage& midi_message, int sample_p | |||
if (isMpeChannelMasterLowerZone(channel)) { | |||
engine_->setZonedPitchWheel(value, lowerMasterChannel(), lowerMasterChannel() + 1); | |||
engine_->setZonedPitchWheel(value, lowerZoneStartChannel(), lowerZoneEndChannel()); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
listener_->pitchWheelMidiChanged(value); | |||
#endif | |||
} | |||
else if (isMpeChannelMasterUpperZone(channel)) { | |||
engine_->setZonedPitchWheel(value, upperMasterChannel(), upperMasterChannel() + 1); | |||
engine_->setZonedPitchWheel(value, upperZoneStartChannel(), upperZoneEndChannel()); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
listener_->pitchWheelMidiChanged(value); | |||
#endif | |||
} | |||
else if (mpe_enabled_) | |||
engine_->setPitchWheel(value, channel); | |||
else { | |||
engine_->setZonedPitchWheel(value, channel, channel); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
listener_->pitchWheelMidiChanged(value); | |||
#endif | |||
} | |||
} | |||
@@ -234,7 +240,9 @@ void MidiManager::processMidiMessage(const MidiMessage& midi_message, int sample | |||
case kModWheel: { | |||
vital::mono_float percent = (1.0f * midi_message.getControllerValue()) / kControlMax; | |||
engine_->setModWheel(percent, channel); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
listener_->modWheelMidiChanged(percent); | |||
#endif | |||
break; | |||
} | |||
case kAllNotesOff: | |||
@@ -81,9 +81,11 @@ class MidiManager { | |||
public: | |||
virtual ~Listener() { } | |||
virtual void valueChangedThroughMidi(const std::string& name, vital::mono_float value) = 0; | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
virtual void pitchWheelMidiChanged(vital::mono_float value) = 0; | |||
virtual void modWheelMidiChanged(vital::mono_float value) = 0; | |||
virtual void presetChangedThroughMidi(File preset) = 0; | |||
#endif | |||
}; | |||
MidiManager(SynthBase* synth, MidiKeyboardState* keyboard_state, | |||
@@ -114,6 +116,7 @@ class MidiManager { | |||
void setMpeEnabled(bool enabled) { mpe_enabled_ = enabled; } | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
struct PresetLoadedCallback : public CallbackMessage { | |||
PresetLoadedCallback(Listener* lis, File pre) : listener(lis), preset(std::move(pre)) { } | |||
@@ -125,6 +128,7 @@ class MidiManager { | |||
Listener* listener; | |||
File preset; | |||
}; | |||
#endif | |||
protected: | |||
void readMpeMessage(const MidiMessage& message); | |||
@@ -74,11 +74,14 @@ void SynthBase::valueChangedInternal(const std::string& name, vital::mono_float | |||
void SynthBase::valueChangedThroughMidi(const std::string& name, vital::mono_float value) { | |||
controls_[name]->set(value); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
ValueChangedCallback* callback = new ValueChangedCallback(self_reference_, name, value); | |||
setValueNotifyHost(name, value); | |||
callback->post(); | |||
#endif | |||
} | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
void SynthBase::pitchWheelMidiChanged(vital::mono_float value) { | |||
ValueChangedCallback* callback = new ValueChangedCallback(self_reference_, "pitch_wheel", value); | |||
callback->post(); | |||
@@ -88,6 +91,7 @@ void SynthBase::modWheelMidiChanged(vital::mono_float value) { | |||
ValueChangedCallback* callback = new ValueChangedCallback(self_reference_, "mod_wheel", value); | |||
callback->post(); | |||
} | |||
#endif | |||
void SynthBase::pitchWheelGuiChanged(vital::mono_float value) { | |||
engine_->setZonedPitchWheel(value, 0, vital::kNumMidiChannels - 1); | |||
@@ -97,6 +101,7 @@ void SynthBase::modWheelGuiChanged(vital::mono_float value) { | |||
engine_->setModWheelAllChannels(value); | |||
} | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
void SynthBase::presetChangedThroughMidi(File preset) { | |||
SynthGuiInterface* gui_interface = getGuiInterface(); | |||
if (gui_interface) { | |||
@@ -104,6 +109,7 @@ void SynthBase::presetChangedThroughMidi(File preset) { | |||
gui_interface->notifyFresh(); | |||
} | |||
} | |||
#endif | |||
void SynthBase::valueChangedExternal(const std::string& name, vital::mono_float value) { | |||
valueChanged(name, value); | |||
@@ -112,8 +118,10 @@ void SynthBase::valueChangedExternal(const std::string& name, vital::mono_float | |||
else if (name == "pitch_wheel") | |||
engine_->setZonedPitchWheel(value, 0, vital::kNumMidiChannels - 1); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
ValueChangedCallback* callback = new ValueChangedCallback(self_reference_, name, value); | |||
callback->post(); | |||
#endif | |||
} | |||
vital::ModulationConnection* SynthBase::getConnection(const std::string& source, const std::string& destination) { | |||
@@ -371,11 +379,13 @@ bool SynthBase::loadFromFile(File preset, std::string& error) { | |||
setPresetName(preset.getFileNameWithoutExtension()); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
SynthGuiInterface* gui_interface = getGuiInterface(); | |||
if (gui_interface) { | |||
gui_interface->updateFullGui(); | |||
gui_interface->notifyFresh(); | |||
} | |||
#endif | |||
return true; | |||
} | |||
@@ -555,9 +565,11 @@ bool SynthBase::saveToFile(File preset) { | |||
setPresetName(preset.getFileNameWithoutExtension()); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
SynthGuiInterface* gui_interface = getGuiInterface(); | |||
if (gui_interface) | |||
gui_interface->notifyFresh(); | |||
#endif | |||
if (preset.replaceWithText(saveToJson().dump())) { | |||
active_file_ = preset; | |||
@@ -742,6 +754,7 @@ void SynthBase::checkOversampling() { | |||
return engine_->checkOversampling(); | |||
} | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
void SynthBase::ValueChangedCallback::messageCallback() { | |||
if (auto synth_base = listener.lock()) { | |||
SynthGuiInterface* gui_interface = (*synth_base)->getGuiInterface(); | |||
@@ -752,3 +765,4 @@ void SynthBase::ValueChangedCallback::messageCallback() { | |||
} | |||
} | |||
} | |||
#endif |
@@ -50,11 +50,15 @@ class SynthBase : public MidiManager::Listener { | |||
void valueChanged(const std::string& name, vital::mono_float value); | |||
void valueChangedThroughMidi(const std::string& name, vital::mono_float value) override; | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
void pitchWheelMidiChanged(vital::mono_float value) override; | |||
void modWheelMidiChanged(vital::mono_float value) override; | |||
#endif | |||
void pitchWheelGuiChanged(vital::mono_float value); | |||
void modWheelGuiChanged(vital::mono_float value); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
void presetChangedThroughMidi(File preset) override; | |||
#endif | |||
void valueChangedExternal(const std::string& name, vital::mono_float value); | |||
void valueChangedInternal(const std::string& name, vital::mono_float value); | |||
bool connectModulation(const std::string& source, const std::string& destination); | |||
@@ -119,6 +123,7 @@ class SynthBase : public MidiManager::Listener { | |||
virtual void pauseProcessing(bool pause) = 0; | |||
Tuning* getTuning() { return &tuning_; } | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
struct ValueChangedCallback : public CallbackMessage { | |||
ValueChangedCallback(std::shared_ptr<SynthBase*> listener, std::string name, vital::mono_float val) : | |||
listener(listener), control_name(std::move(name)), value(val) { } | |||
@@ -129,11 +134,14 @@ class SynthBase : public MidiManager::Listener { | |||
std::string control_name; | |||
vital::mono_float value; | |||
}; | |||
#endif | |||
protected: | |||
vital::modulation_change createModulationChange(vital::ModulationConnection* connection); | |||
bool isInvalidConnection(const vital::modulation_change& change); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
virtual SynthGuiInterface* getGuiInterface() = 0; | |||
#endif | |||
json saveToJson(); | |||
bool loadFromJson(const json& state); | |||
vital::ModulationConnection* getConnection(const std::string& source, const std::string& destination); | |||
@@ -198,8 +206,10 @@ class HeadlessSynth : public SynthBase { | |||
critical_section_.exit(); | |||
} | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
protected: | |||
virtual SynthGuiInterface* getGuiInterface() override { return nullptr; } | |||
#endif | |||
private: | |||
CriticalSection critical_section_; | |||
@@ -15,7 +15,9 @@ | |||
*/ | |||
#include "synth_plugin.h" | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
#include "synth_editor.h" | |||
#endif | |||
#include "sound_engine.h" | |||
#include "load_save.h" | |||
@@ -42,6 +44,7 @@ SynthPlugin::~SynthPlugin() { | |||
keyboard_state_ = nullptr; | |||
} | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
SynthGuiInterface* SynthPlugin::getGuiInterface() { | |||
AudioProcessorEditor* editor = getActiveEditor(); | |||
if (editor) | |||
@@ -65,6 +68,7 @@ void SynthPlugin::setValueNotifyHost(const std::string& name, vital::mono_float | |||
bridge_lookup_[name]->setValueNotifyHost(plugin_value); | |||
} | |||
} | |||
#endif | |||
const CriticalSection& SynthPlugin::getCriticalSection() { | |||
return getCallbackLock(); | |||
@@ -119,11 +123,15 @@ double SynthPlugin::getTailLengthSeconds() const { | |||
} | |||
const String SynthPlugin::getProgramName(int index) { | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
SynthGuiInterface* editor = getGuiInterface(); | |||
if (editor == nullptr || editor->getSynth() == nullptr) | |||
return ""; | |||
return editor->getSynth()->getPresetName(); | |||
#else | |||
return ""; | |||
#endif | |||
} | |||
void SynthPlugin::prepareToPlay(double sample_rate, int buffer_size) { | |||
@@ -173,6 +181,7 @@ void SynthPlugin::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midi_messa | |||
} | |||
} | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
bool SynthPlugin::hasEditor() const { | |||
return true; | |||
} | |||
@@ -180,6 +189,7 @@ bool SynthPlugin::hasEditor() const { | |||
AudioProcessorEditor* SynthPlugin::createEditor() { | |||
return new SynthEditor(*this); | |||
} | |||
#endif | |||
void SynthPlugin::parameterChanged(std::string name, vital::mono_float value) { | |||
valueChangedExternal(name, value); | |||
@@ -209,13 +219,19 @@ void SynthPlugin::setStateInformation(const void* data, int size_in_bytes) { | |||
} | |||
catch (const json::exception& e) { | |||
std::string error = "There was an error open the preset. Preset file is corrupted."; | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
AlertWindow::showNativeDialogBox("Error opening preset", error, false); | |||
#else | |||
std::cerr << error << std::endl; | |||
#endif | |||
} | |||
pauseProcessing(false); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
SynthGuiInterface* editor = getGuiInterface(); | |||
if (editor) | |||
editor->updateFullGui(); | |||
#endif | |||
} | |||
AudioProcessor* JUCE_CALLTYPE createPluginFilter() { | |||
@@ -30,10 +30,12 @@ class SynthPlugin : public SynthBase, public AudioProcessor, public ValueBridge: | |||
SynthPlugin(); | |||
virtual ~SynthPlugin(); | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
SynthGuiInterface* getGuiInterface() override; | |||
void beginChangeGesture(const std::string& name) override; | |||
void endChangeGesture(const std::string& name) override; | |||
void setValueNotifyHost(const std::string& name, vital::mono_float value) override; | |||
#endif | |||
const CriticalSection& getCriticalSection() override; | |||
void pauseProcessing(bool pause) override; | |||
@@ -41,8 +43,10 @@ class SynthPlugin : public SynthBase, public AudioProcessor, public ValueBridge: | |||
void releaseResources() override; | |||
void processBlock(AudioSampleBuffer&, MidiBuffer&) override; | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
AudioProcessorEditor* createEditor() override; | |||
bool hasEditor() const override; | |||
#endif | |||
const String getName() const override; | |||
bool supportsMPE() const override { return true; } | |||
@@ -14,7 +14,7 @@ | |||
* along with vital. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#if !HEADLESS | |||
#if !HEADLESS && !JUCE_AUDIOPROCESSOR_NO_GUI | |||
#include "border_bounds_constrainer.cpp" | |||
#endif | |||
@@ -22,7 +22,9 @@ | |||
#include "midi_manager.cpp" | |||
#include "tuning.cpp" | |||
#include "startup.cpp" | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
#include "synth_gui_interface.cpp" | |||
#endif | |||
#include "synth_parameters.cpp" | |||
#include "load_save.cpp" | |||
#include "synth_types.cpp" | |||
@@ -14,5 +14,7 @@ | |||
* along with vital. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#if ! JUCE_AUDIOPROCESSOR_NO_GUI | |||
#include "synth_editor.cpp" | |||
#endif | |||
#include "synth_plugin.cpp" |