commit 0258ec91f2468e00ebdf52783e9da066ec882f22
parent ab6b739bbb458228284a7d4d45dc0e9fad8ecedf
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Mon, 29 Jul 2024 11:32:18 +0200
n2x juce plugin basics
Diffstat:
8 files changed, 200 insertions(+), 0 deletions(-)
diff --git a/source/nord/n2x/CMakeLists.txt b/source/nord/n2x/CMakeLists.txt
@@ -2,3 +2,7 @@ cmake_minimum_required(VERSION 3.15)
add_subdirectory(n2xLib)
add_subdirectory(n2xTestConsole)
+
+if(${CMAKE_PROJECT_NAME}_BUILD_JUCEPLUGIN)
+ add_subdirectory(n2xJucePlugin)
+endif()
diff --git a/source/nord/n2x/n2xJucePlugin/CMakeLists.txt b/source/nord/n2x/n2xJucePlugin/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(n2xJucePlugin VERSION ${CMAKE_PROJECT_VERSION})
+
+set(SOURCES
+ n2xController.cpp n2xController.h
+ n2xPatchManager.cpp n2xPatchManager.h
+ n2xPluginProcessor.cpp n2xPluginProcessor.h
+ parameterDescriptions_n2x.json
+)
+
+# https://forum.juce.com/t/help-needed-using-binarydata-with-cmake-juce-6/40486
+# "This might be because the BinaryData files are generated during the build, so the IDE may not be able to find them until the build has been run once (and even then, some IDEs might need a bit of a nudge to re-index the binary directory…)"
+SET(ASSETS "parameterDescriptions_n2x.json")
+
+juce_add_binary_data(n2xJucePlugin_BinaryData SOURCES ${ASSETS})
+
+createJucePlugin(n2xJucePlugin "NodalRed" TRUE "Tn2x" n2xJucePlugin_BinaryData n2xLib)
diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.cpp b/source/nord/n2x/n2xJucePlugin/n2xController.cpp
@@ -0,0 +1,71 @@
+#include "n2xController.h"
+
+#include <fstream>
+
+#include "BinaryData.h"
+#include "n2xPluginProcessor.h"
+
+#include "synthLib/os.h"
+
+#include "dsp56kEmu/logging.h"
+
+namespace
+{
+}
+
+Controller::Controller(AudioPluginAudioProcessor& _p) : pluginLib::Controller(_p, loadParameterDescriptions())
+{
+ registerParams(_p);
+}
+
+Controller::~Controller() = default;
+
+const char* findEmbeddedResource(const std::string& _filename, uint32_t& _size)
+{
+ for(size_t i=0; i<BinaryData::namedResourceListSize; ++i)
+ {
+ if (BinaryData::originalFilenames[i] != _filename)
+ continue;
+
+ int size = 0;
+ const auto res = BinaryData::getNamedResource(BinaryData::namedResourceList[i], size);
+ _size = static_cast<uint32_t>(size);
+ return res;
+ }
+ return nullptr;
+}
+
+std::string Controller::loadParameterDescriptions()
+{
+ const auto name = "parameterDescriptions_n2x.json";
+ const auto path = synthLib::getModulePath() + name;
+
+ const std::ifstream f(path.c_str(), std::ios::in);
+ if(f.is_open())
+ {
+ std::stringstream buf;
+ buf << f.rdbuf();
+ return buf.str();
+ }
+
+ uint32_t size;
+ const auto res = findEmbeddedResource(name, size);
+ if(res)
+ return {res, size};
+ return {};
+}
+
+bool Controller::parseSysexMessage(const pluginLib::SysEx& _msg, synthLib::MidiEventSource)
+{
+ return false;
+}
+
+bool Controller::parseControllerMessage(const synthLib::SMidiEvent&)
+{
+ // TODO
+ return false;
+}
+
+void Controller::sendParameterChange(const pluginLib::Parameter& _parameter, const uint8_t _value)
+{
+}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.h b/source/nord/n2x/n2xJucePlugin/n2xController.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "jucePluginLib/controller.h"
+
+class AudioPluginAudioProcessor;
+
+class Controller : public pluginLib::Controller
+{
+public:
+ Controller(AudioPluginAudioProcessor&);
+ ~Controller() override;
+
+private:
+ static std::string loadParameterDescriptions();
+
+ void onStateLoaded() override
+ {
+ }
+
+ uint8_t getPartCount() override
+ {
+ return 4;
+ }
+
+ bool parseSysexMessage(const pluginLib::SysEx&, synthLib::MidiEventSource) override;
+ bool parseControllerMessage(const synthLib::SMidiEvent&) override;
+ void sendParameterChange(const pluginLib::Parameter& _parameter, uint8_t _value) override;
+};
diff --git a/source/nord/n2x/n2xJucePlugin/n2xPatchManager.cpp b/source/nord/n2x/n2xJucePlugin/n2xPatchManager.cpp
diff --git a/source/nord/n2x/n2xJucePlugin/n2xPatchManager.h b/source/nord/n2x/n2xJucePlugin/n2xPatchManager.h
diff --git a/source/nord/n2x/n2xJucePlugin/n2xPluginProcessor.cpp b/source/nord/n2x/n2xJucePlugin/n2xPluginProcessor.cpp
@@ -0,0 +1,62 @@
+#include "n2xPluginProcessor.h"
+
+#include <juce_audio_processors/juce_audio_processors.h>
+#include <juce_audio_devices/juce_audio_devices.h>
+
+#include "n2xController.h"
+
+#include "jucePluginLib/processor.h"
+
+#include "n2xLib/n2xdevice.h"
+
+class Controller;
+
+namespace
+{
+ juce::PropertiesFile::Options getOptions()
+ {
+ juce::PropertiesFile::Options opts;
+ opts.applicationName = "DSP56300EmulatorNodalRed";
+ opts.filenameSuffix = ".settings";
+ opts.folderName = "DSP56300EmulatorNodalRed";
+ opts.osxLibrarySubFolder = "Application Support/DSP56300EmulatorNodalRed";
+ return opts;
+ }
+}
+
+//==============================================================================
+AudioPluginAudioProcessor::AudioPluginAudioProcessor() :
+ Processor(BusesProperties()
+ .withOutput("Out AB", juce::AudioChannelSet::stereo(), true)
+ .withOutput("Out CD", juce::AudioChannelSet::stereo(), true)
+ , getOptions(), pluginLib::Processor::Properties{JucePlugin_Name, JucePlugin_IsSynth, JucePlugin_WantsMidiInput, JucePlugin_ProducesMidiOutput, JucePlugin_IsMidiEffect})
+{
+ getController();
+ const auto latencyBlocks = getConfig().getIntValue("latencyBlocks", static_cast<int>(getPlugin().getLatencyBlocks()));
+ Processor::setLatencyBlocks(latencyBlocks);
+}
+
+AudioPluginAudioProcessor::~AudioPluginAudioProcessor()
+{
+ destroyEditorState();
+}
+
+jucePluginEditorLib::PluginEditorState* AudioPluginAudioProcessor::createEditorState()
+{
+ return nullptr;
+}
+
+synthLib::Device* AudioPluginAudioProcessor::createDevice()
+{
+ return new n2x::Device();
+}
+
+pluginLib::Controller* AudioPluginAudioProcessor::createController()
+{
+ return new Controller(*this);
+}
+
+juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
+{
+ return new AudioPluginAudioProcessor();
+}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xPluginProcessor.h b/source/nord/n2x/n2xJucePlugin/n2xPluginProcessor.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "jucePluginEditorLib/pluginProcessor.h"
+
+class AudioPluginAudioProcessor : public jucePluginEditorLib::Processor
+{
+public:
+ AudioPluginAudioProcessor();
+ ~AudioPluginAudioProcessor() override;
+
+ jucePluginEditorLib::PluginEditorState* createEditorState() override;
+ synthLib::Device* createDevice() override;
+ pluginLib::Controller* createController() override;
+
+private:
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioPluginAudioProcessor)
+};