diff --git a/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.cpp b/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.cpp index a5a75e2c..633f9085 100644 --- a/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.cpp +++ b/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.cpp @@ -6,7 +6,10 @@ #include "variable_block_adapter.hpp" #include #include -#include +#include "reaper_vst3_interfaces.h" +#include "reaper_integration.hpp" + +#include #define DEFAULT_OSC_PORT 8000 @@ -45,7 +48,13 @@ using namespace ear::plugin; //============================================================================== EarBinauralMonitoringAudioProcessor::EarBinauralMonitoringAudioProcessor() - : AudioProcessor(_getBusProperties()) { + : AudioProcessor(BusesProperties() + .withInput("Input", + AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), + true) + .withOutput("Output", + AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), + true)) { dataFileManager.onSelectedDataFileChange( [this](ear::plugin::DataFileManager::DataFile const& df) { @@ -198,17 +207,6 @@ void EarBinauralMonitoringAudioProcessor::timerCallback() { processor_->setIsPlaying(false); } -//============================================================================== -juce::AudioProcessor::BusesProperties -EarBinauralMonitoringAudioProcessor::_getBusProperties() { - auto ret = BusesProperties().withInput( - "Input", AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), true); - ret = ret.withOutput("Left Ear", AudioChannelSet::mono(), true); - ret = ret.withOutput("Right Ear", AudioChannelSet::mono(), true); - ret = ret.withOutput("(Unused)", AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS-2), true); - return ret; -} - void EarBinauralMonitoringAudioProcessor::restartBearProcessor( bool onlyOnConfigChange) { std::lock_guard lock(processorMutex_); @@ -329,23 +327,10 @@ void EarBinauralMonitoringAudioProcessor::releaseResources() { bool EarBinauralMonitoringAudioProcessor::isBusesLayoutSupported( const BusesLayout& layouts) const { - // Must accept default config specified in ctor - - if(layouts.inputBuses.size() != 1) - return false; - if (layouts.inputBuses[0] != - AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS)) - return false; - - if(layouts.outputBuses.size() != 3) - return false; - if(layouts.outputBuses[0] != AudioChannelSet::mono()) - return false; - if(layouts.outputBuses[1] != AudioChannelSet::mono()) - return false; - if (layouts.outputBuses[2] != - AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS - 2)) - return false; + auto i = layouts.getMainInputChannels(); + if (i != numDawChannels_) return false; + auto o = layouts.getMainOutputChannels(); + if (o != numDawChannels_) return false; return true; } @@ -526,6 +511,23 @@ void EarBinauralMonitoringAudioProcessor::setStateInformation(const void* data, } } +void EarBinauralMonitoringAudioProcessor::setIHostApplication( + Steinberg::FUnknown* unknown) { + auto reaperHost = dynamic_cast(unknown); + VST3ClientExtensions::setIHostApplication(unknown); + if (reaperHost) { + numDawChannels_ = DetermineChannelCount(reaperHost); + auto retI = setChannelLayoutOfBus( + true, 0, AudioChannelSet::discreteChannels(numDawChannels_)); + auto retO = setChannelLayoutOfBus( + false, 0, AudioChannelSet::discreteChannels(numDawChannels_)); + assert(retI && retO); + backend_ = std::make_unique( + nullptr, numDawChannels_); + connector_->setListenerOrientationInstance(backend_->listenerOrientation); + } +} + //============================================================================== // This creates new instances of the plugin.. AudioProcessor* JUCE_CALLTYPE createPluginFilter() { diff --git a/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.hpp b/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.hpp index 311b042e..df2537a2 100644 --- a/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.hpp +++ b/ear-production-suite-plugins/plugins/binaural_monitoring/src/binaural_monitoring_plugin_processor.hpp @@ -12,6 +12,8 @@ #include "bear_data_files.hpp" #include "orientation_osc.hpp" +#include + namespace ear { namespace plugin { namespace ui { @@ -26,7 +28,8 @@ class BinauralMonitoringAudioProcessor; class EarBinauralMonitoringAudioProcessor : private AudioProcessorParameter::Listener, Timer, - public AudioProcessor { + public AudioProcessor, + public VST3ClientExtensions { public: EarBinauralMonitoringAudioProcessor(); ~EarBinauralMonitoringAudioProcessor(); @@ -59,6 +62,8 @@ class EarBinauralMonitoringAudioProcessor void getStateInformation(MemoryBlock& destData) override; void setStateInformation(const void* data, int sizeInBytes) override; + void setIHostApplication(Steinberg::FUnknown* unknown) override; + std::weak_ptr getLevelMeter() { return levelMeter_; }; @@ -93,8 +98,6 @@ class EarBinauralMonitoringAudioProcessor void timerCallback() override; private: - BusesProperties _getBusProperties(); - AudioParameterBool* bypass_; AudioParameterFloat* yaw_; AudioParameterFloat* pitch_; @@ -119,6 +122,7 @@ class EarBinauralMonitoringAudioProcessor int samplerate_{48000}; int blocksize_{512}; + int numDawChannels_{MAX_DAW_CHANNELS}; std::shared_ptr levelMeter_; diff --git a/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.cpp b/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.cpp index 3e5200ae..a791e4a8 100644 --- a/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.cpp +++ b/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.cpp @@ -2,7 +2,10 @@ #include "monitoring_plugin_editor.hpp" #include "variable_block_adapter.hpp" -#include +#include "reaper_vst3_interfaces.h" +#include "reaper_integration.hpp" + +#include namespace ear { namespace plugin { @@ -52,27 +55,36 @@ ear::Layout const& layout() { } } -juce::AudioProcessor::BusesProperties -EarMonitoringAudioProcessor::_getBusProperties() { - numOutputChannels_ = layout().channelNames().size(); - auto ret = BusesProperties().withInput( - "Input", AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), true); - for (const std::string& name : layout().channelNames()) { - ret = ret.withOutput(name, AudioChannelSet::mono(), true); - } - ret = ret.withOutput( - "(Unused)", - AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS - numOutputChannels_), - true); - return ret; +void EarMonitoringAudioProcessor::setIHostApplication( + Steinberg::FUnknown* unknown) { + auto reaperHost = dynamic_cast(unknown); + VST3ClientExtensions::setIHostApplication(unknown); + if (reaperHost) { + numDawChannels_ = DetermineChannelCount(reaperHost); + auto retI = setChannelLayoutOfBus( + true, 0, AudioChannelSet::discreteChannels(numDawChannels_)); + auto retO = setChannelLayoutOfBus( + false, 0, AudioChannelSet::discreteChannels(numDawChannels_)); + assert(retI && retO); + backend_ = std::make_unique( + nullptr, layout(), numDawChannels_); + } } //============================================================================== EarMonitoringAudioProcessor::EarMonitoringAudioProcessor() - : AudioProcessor(_getBusProperties()) { + : AudioProcessor( + BusesProperties() + .withInput("Input", + AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), + true) + .withOutput("Output", + AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), + true)) { auto speakerLayout = layout(); + numOutputChannels_ = speakerLayout.channels().size(); backend_ = std::make_unique( - nullptr, speakerLayout, MAX_DAW_CHANNELS); + nullptr, speakerLayout, numDawChannels_); levelMeter_ = std::make_shared(0, 0); ProcessorConfig newConfig{getTotalNumInputChannels(), getTotalNumOutputChannels(), 512, @@ -131,24 +143,11 @@ void EarMonitoringAudioProcessor::releaseResources() { bool EarMonitoringAudioProcessor::isBusesLayoutSupported( const BusesLayout& layouts) const { - // Must accept default config specified in ctor - - if(layouts.inputBuses.size() != 1) + auto i = layouts.getMainInputChannels(); + if (i != numDawChannels_) return false; - if (layouts.inputBuses[0] != - AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS)) - return false; - - auto outputBusCount = layouts.outputBuses.size(); - auto expectedOutputBusCount = numOutputChannels_ + 1; - if(outputBusCount != expectedOutputBusCount) - return false; - for(int i = 0; i < numOutputChannels_; ++i) { - if(layouts.outputBuses[i] != AudioChannelSet::mono()) - return false; - } - if (layouts.outputBuses[numOutputChannels_] != - AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS - numOutputChannels_)) + auto o = layouts.getMainOutputChannels(); + if (o != numDawChannels_) return false; return true; diff --git a/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.hpp b/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.hpp index b6ac47c6..563e716d 100644 --- a/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.hpp +++ b/ear-production-suite-plugins/plugins/monitoring/src/monitoring_plugin_processor.hpp @@ -6,6 +6,7 @@ #include #include "components/level_meter_calculator.hpp" +#include namespace ear { namespace plugin { @@ -33,7 +34,8 @@ inline bool operator!=(ProcessorConfig const& lhs, ProcessorConfig const rhs) { return !(lhs == rhs); } -class EarMonitoringAudioProcessor : public AudioProcessor { +class EarMonitoringAudioProcessor : public AudioProcessor, + public VST3ClientExtensions { public: EarMonitoringAudioProcessor(); ~EarMonitoringAudioProcessor(); @@ -70,15 +72,17 @@ class EarMonitoringAudioProcessor : public AudioProcessor { return levelMeter_; }; + void setIHostApplication(Steinberg::FUnknown* unknown) override; + private: - BusesProperties _getBusProperties(); void configureProcessor(const ProcessorConfig& config); ProcessorConfig processorConfig_{}; std::unique_ptr backend_; std::unique_ptr processor_; int samplerate_; - int numOutputChannels_; + int numDawChannels_{MAX_DAW_CHANNELS}; + int numOutputChannels_{0}; std::shared_ptr levelMeter_; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EarMonitoringAudioProcessor) diff --git a/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.cpp b/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.cpp index 55d164f4..f63c103e 100644 --- a/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.cpp +++ b/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.cpp @@ -2,13 +2,16 @@ #include "scene_plugin_editor.hpp" #include #include "programme_store_adm_serializer.hpp" -#include #include #include "scene_backend.hpp" #include "metadata_event_dispatcher.hpp" #include "pending_store.hpp" #include "restored_pending_store.hpp" -#include +#include "reaper_vst3_interfaces.h" +#include "reaper_integration.hpp" + +#include +#include SceneAudioProcessor::SceneAudioProcessor() : AudioProcessor( @@ -35,7 +38,7 @@ SceneAudioProcessor::SceneAudioProcessor() } levelMeter_ = std::make_shared( - MAX_DAW_CHANNELS, samplerate_); + numDawChannels_, samplerate_); samplesSocket = new SamplesSender(); samplesSocket->open(); @@ -122,18 +125,9 @@ void SceneAudioProcessor::releaseResources() {} bool SceneAudioProcessor::isBusesLayoutSupported( const BusesLayout& layouts) const { - // Must accept default config specified in ctor - - if(layouts.inputBuses.size() != 1) - return false; - if (layouts.inputBuses[0] != - AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS)) - return false; - - if(layouts.outputBuses.size() != 0) - return false; + auto i = layouts.getMainInputChannels(); + return i == numDawChannels_; - return true; } void SceneAudioProcessor::processBlock(AudioBuffer& buffer, @@ -162,9 +156,12 @@ void SceneAudioProcessor::processBlock(AudioBuffer& buffer, int bufferChannels = buffer.getNumChannels(); int bufferSamplesPerChannel = buffer.getNumSamples(); + // TODO: We could do with a better system than sending channels of blanks, + // but at least this way we don't need to worry about DAW channel limits + // and routings in to the Scene. for (int sample = 0; sample < bufferSamplesPerChannel; ++sample) { for (int channel = 0; channel < numChannels; ++channel) { - curSample = buffer.getSample(channel, sample); + curSample = channel < bufferChannels? buffer.getSample(channel, sample) : 0.f; assert(msgPosOffset + sampleSize <= msg_size); memcpy(msgPosPtr + msgPosOffset, &curSample, sampleSize); msgPosOffset += sampleSize; @@ -212,7 +209,7 @@ void SceneAudioProcessor::doSampleRateChecks() { auto curSampleRate = static_cast(getSampleRate()); if (samplerate_ != curSampleRate) { samplerate_ = curSampleRate; - levelMeter_->setup(MAX_DAW_CHANNELS, samplerate_); + levelMeter_->setup(numDawChannels_, samplerate_); } } @@ -264,7 +261,7 @@ void SceneAudioProcessor::incomingMessage(std::shared_ptr msg) { future.get(); } else if (cmd == commandSocket->Command::GetConfig) { - uint8_t numChannels = MAX_DAW_CHANNELS; + uint8_t numChannels = numDawChannels_; uint32_t sampleRate = samplerate_; commandSocket->sendInfo(numChannels, samplerate_); @@ -296,6 +293,18 @@ void SceneAudioProcessor::setupBackend() { } } +void SceneAudioProcessor::setIHostApplication(Steinberg::FUnknown* unknown) { + auto reaperHost = dynamic_cast(unknown); + VST3ClientExtensions::setIHostApplication(unknown); + if (reaperHost) { + numDawChannels_ = DetermineChannelCount(reaperHost); + auto ret = setChannelLayoutOfBus( + true, 0, AudioChannelSet::discreteChannels(numDawChannels_)); + assert(ret); + levelMeter_->setup(numDawChannels_, samplerate_); + } +} + ear::plugin::Metadata &SceneAudioProcessor::metadata() { return metadata_; } diff --git a/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.hpp b/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.hpp index a82b7b25..ca7c8d35 100644 --- a/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.hpp +++ b/ear-production-suite-plugins/plugins/scene/src/scene_plugin_processor.hpp @@ -10,6 +10,7 @@ #include "ui_event_dispatcher.hpp" #include "communication/metadata_thread.hpp" #include "auto_mode_controller.hpp" +#include namespace ear { namespace plugin { @@ -22,7 +23,7 @@ class RestoredPendingStore; } // namespace plugin } // namespace ear -class SceneAudioProcessor : public AudioProcessor { +class SceneAudioProcessor : public AudioProcessor, public VST3ClientExtensions { public: SceneAudioProcessor(); ~SceneAudioProcessor(); @@ -62,6 +63,8 @@ class SceneAudioProcessor : public AudioProcessor { void setupBackend(); + void setIHostApplication(Steinberg::FUnknown* unknown) override; + ear::plugin::Metadata& metadata(); private: @@ -83,6 +86,7 @@ class SceneAudioProcessor : public AudioProcessor { SamplesSender* samplesSocket; bool sendSamplesToExtension{false}; uint32_t samplerate_{0}; + int numDawChannels_{MAX_DAW_CHANNELS}; std::shared_ptr levelMeter_; std::unique_ptr backendSetupTimer_; diff --git a/reaper-adm-export-source-plugin/src/CMakeLists.txt b/reaper-adm-export-source-plugin/src/CMakeLists.txt index 3d7283b6..380a3a2f 100644 --- a/reaper-adm-export-source-plugin/src/CMakeLists.txt +++ b/reaper-adm-export-source-plugin/src/CMakeLists.txt @@ -47,8 +47,9 @@ target_link_libraries(adm_export_source_VST3 PRIVATE target_include_directories(adm_export_source_VST3 PRIVATE + ${CMAKE_SOURCE_DIR}/ear-production-suite-plugins/lib/include $ - $ + $ ) target_compile_definitions(adm_export_source_VST3 diff --git a/reaper-adm-export-source-plugin/src/PluginProcessor.cpp b/reaper-adm-export-source-plugin/src/PluginProcessor.cpp index fee9cad7..b62c5f26 100644 --- a/reaper-adm-export-source-plugin/src/PluginProcessor.cpp +++ b/reaper-adm-export-source-plugin/src/PluginProcessor.cpp @@ -1,14 +1,15 @@ #include "PluginEditor.h" #include "PluginProcessor.h" #include -#include #include +#include "reaper_vst3_interfaces.h" +#include "reaper_integration.hpp" + AdmStemPluginAudioProcessor::AdmStemPluginAudioProcessor() #ifndef JucePlugin_PreferredChannelConfigurations : AudioProcessor (BusesProperties() .withInput("Input", AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), true) - .withOutput("Output", AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), true) ) #endif { @@ -331,23 +332,10 @@ void AdmStemPluginAudioProcessor::processBlock (AudioBuffer& buffer, Midi #endif ScopedNoDenormals noDenormals; - auto totalNumInputChannels = getTotalNumInputChannels(); - auto totalNumOutputChannels = getTotalNumOutputChannels(); - - // In case we have more outputs than inputs, this code clears any output - // channels that didn't contain input data, (because these aren't - // guaranteed to be empty - they may contain garbage). - // This is here to avoid people getting screaming feedback - // when they first compile a plugin, but obviously you don't need to keep - // this code if your algorithm always overwrites all the output channels. - for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i) - buffer.clear (i, 0, buffer.getNumSamples()); - - // This is the place where you'd normally do the guts of your plugin's - // audio processing... if (sendSamples) { size_t sampleSize = sizeof(float); + auto totalNumInputChannels = getTotalNumInputChannels(); uint8_t numChannels = numChnsParam->get(); size_t msg_size = buffer.getNumSamples() * numChannels * sampleSize; // Samples auto msg = std::make_shared(msg_size); @@ -384,21 +372,21 @@ void AdmStemPluginAudioProcessor::processBlock (AudioBuffer& buffer, Midi #ifndef JucePlugin_PreferredChannelConfigurations bool AdmStemPluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const { - if (layouts.getMainOutputChannelSet() == AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS) && - layouts.getMainInputChannelSet() == AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS)) { - return true; - } - return false; + auto i = layouts.getMainInputChannels(); + return i == numDawChannels_; } #endif -void AdmStemPluginAudioProcessor::numChannelsChanged(){ - //auto busIn = this->getBus(true, 0)->getCurrentLayout().getDescription(); - auto busChIn = this->getBus(true, 0)->getNumberOfChannels(); - //auto busOut = this->getBus(false, 0)->getCurrentLayout().getDescription(); - auto busChOut = this->getBus(false, 0)->getNumberOfChannels(); - - // TODO - do we actually need to do anything here? We used to warn if being fed less than the expected width of the ADM essense - would be a nice feature. +void AdmStemPluginAudioProcessor::setIHostApplication(Steinberg::FUnknown* unknown) +{ + auto reaperHost = dynamic_cast(unknown); + VST3ClientExtensions::setIHostApplication(unknown); + if (reaperHost) { + numDawChannels_ = DetermineChannelCount(reaperHost); + auto retI = setChannelLayoutOfBus( + true, 0, AudioChannelSet::discreteChannels(numDawChannels_)); + assert(retI); + } } AdmStemPluginAudioProcessorEditor* AdmStemPluginAudioProcessor::editor(){ diff --git a/reaper-adm-export-source-plugin/src/PluginProcessor.h b/reaper-adm-export-source-plugin/src/PluginProcessor.h index 6bacd934..9ccb5207 100644 --- a/reaper-adm-export-source-plugin/src/PluginProcessor.h +++ b/reaper-adm-export-source-plugin/src/PluginProcessor.h @@ -15,6 +15,7 @@ #include "PluginProcessorUtils.h" #include #include +#include #define TRACK_STATE 0 #define DEBUG_PARAMS 0 @@ -27,7 +28,8 @@ class AdmStemPluginAudioProcessorEditor; -class AdmStemPluginAudioProcessor : public AudioProcessor +class AdmStemPluginAudioProcessor : public AudioProcessor, + public VST3ClientExtensions { public: AdmStemPluginAudioProcessor(); @@ -57,7 +59,6 @@ class AdmStemPluginAudioProcessor : public AudioProcessor void setCurrentProgram (int index) override; const String getProgramName (int index) override; void changeProgramName (int index, const String& newName) override; - void numChannelsChanged() override; void getStateInformation (MemoryBlock& destData) override; void setStateInformation (const void* data, int sizeInBytes) override; @@ -79,9 +80,13 @@ class AdmStemPluginAudioProcessor : public AudioProcessor void incomingMessage(std::shared_ptr msg); + void setIHostApplication(Steinberg::FUnknown* unknown) override; + private: AdmStemPluginAudioProcessorEditor* editor(); + int numDawChannels_{ MAX_DAW_CHANNELS }; + int calcNumChannels(); void updateNumChnsParam(bool force = false); void updateAdmParameters(bool force = false);