| @@ -75,15 +75,19 @@ AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForName (const String& name) | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| void FilterGraph::addPlugin (const PluginDescription& desc, Point<double> p) | |||||
| void FilterGraph::addPlugin (const PluginDescription& desc, Point<double> pos) | |||||
| { | { | ||||
| formatManager.createPluginInstanceAsync (desc, | formatManager.createPluginInstanceAsync (desc, | ||||
| graph.getSampleRate(), | graph.getSampleRate(), | ||||
| graph.getBlockSize(), | graph.getBlockSize(), | ||||
| new AsyncCallback (*this, p)); | |||||
| [this, pos] (std::unique_ptr<AudioPluginInstance> instance, const String& error) | |||||
| { | |||||
| addPluginCallback (std::move (instance), error, pos); | |||||
| }); | |||||
| } | } | ||||
| void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String& error, Point<double> pos) | |||||
| void FilterGraph::addPluginCallback (std::unique_ptr<AudioPluginInstance> instance, | |||||
| const String& error, Point<double> pos) | |||||
| { | { | ||||
| if (instance == nullptr) | if (instance == nullptr) | ||||
| { | { | ||||
| @@ -95,7 +99,7 @@ void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String | |||||
| { | { | ||||
| instance->enableAllBuses(); | instance->enableAllBuses(); | ||||
| if (auto node = graph.addNode (instance)) | |||||
| if (auto node = graph.addNode (std::move (instance))) | |||||
| { | { | ||||
| node->properties.set ("x", pos.x); | node->properties.set ("x", pos.x); | ||||
| node->properties.set ("y", pos.y); | node->properties.set ("y", pos.y); | ||||
| @@ -256,8 +260,8 @@ void FilterGraph::setLastDocumentOpened (const File& file) | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| static void readBusLayoutFromXml (AudioProcessor::BusesLayout& busesLayout, AudioProcessor* plugin, | |||||
| const XmlElement& xml, const bool isInput) | |||||
| static void readBusLayoutFromXml (AudioProcessor::BusesLayout& busesLayout, AudioProcessor& plugin, | |||||
| const XmlElement& xml, bool isInput) | |||||
| { | { | ||||
| auto& targetBuses = (isInput ? busesLayout.inputBuses | auto& targetBuses = (isInput ? busesLayout.inputBuses | ||||
| : busesLayout.outputBuses); | : busesLayout.outputBuses); | ||||
| @@ -272,12 +276,12 @@ static void readBusLayoutFromXml (AudioProcessor::BusesLayout& busesLayout, Audi | |||||
| // the number of buses on busesLayout may not be in sync with the plugin after adding buses | // the number of buses on busesLayout may not be in sync with the plugin after adding buses | ||||
| // because adding an input bus could also add an output bus | // because adding an input bus could also add an output bus | ||||
| for (int actualIdx = plugin->getBusCount (isInput) - 1; actualIdx < busIdx; ++actualIdx) | |||||
| if (! plugin->addBus (isInput)) | |||||
| for (int actualIdx = plugin.getBusCount (isInput) - 1; actualIdx < busIdx; ++actualIdx) | |||||
| if (! plugin.addBus (isInput)) | |||||
| return; | return; | ||||
| for (int actualIdx = targetBuses.size() - 1; actualIdx < busIdx; ++actualIdx) | for (int actualIdx = targetBuses.size() - 1; actualIdx < busIdx; ++actualIdx) | ||||
| targetBuses.add (plugin->getChannelLayoutOfBus (isInput, busIdx)); | |||||
| targetBuses.add (plugin.getChannelLayoutOfBus (isInput, busIdx)); | |||||
| auto layout = e->getStringAttribute ("layout"); | auto layout = e->getStringAttribute ("layout"); | ||||
| @@ -289,7 +293,7 @@ static void readBusLayoutFromXml (AudioProcessor::BusesLayout& busesLayout, Audi | |||||
| // if the plugin has more buses than specified in the xml, then try to remove them! | // if the plugin has more buses than specified in the xml, then try to remove them! | ||||
| while (maxNumBuses < targetBuses.size()) | while (maxNumBuses < targetBuses.size()) | ||||
| { | { | ||||
| if (! plugin->removeBus (isInput)) | |||||
| if (! plugin.removeBus (isInput)) | |||||
| return; | return; | ||||
| targetBuses.removeLast(); | targetBuses.removeLast(); | ||||
| @@ -374,20 +378,20 @@ void FilterGraph::createNodeFromXml (const XmlElement& xml) | |||||
| String errorMessage; | String errorMessage; | ||||
| if (auto* instance = formatManager.createPluginInstance (pd, graph.getSampleRate(), | |||||
| graph.getBlockSize(), errorMessage)) | |||||
| if (auto instance = formatManager.createPluginInstance (pd, graph.getSampleRate(), | |||||
| graph.getBlockSize(), errorMessage)) | |||||
| { | { | ||||
| if (auto* layoutEntity = xml.getChildByName ("LAYOUT")) | if (auto* layoutEntity = xml.getChildByName ("LAYOUT")) | ||||
| { | { | ||||
| auto layout = instance->getBusesLayout(); | auto layout = instance->getBusesLayout(); | ||||
| readBusLayoutFromXml (layout, instance, *layoutEntity, true); | |||||
| readBusLayoutFromXml (layout, instance, *layoutEntity, false); | |||||
| readBusLayoutFromXml (layout, *instance, *layoutEntity, true); | |||||
| readBusLayoutFromXml (layout, *instance, *layoutEntity, false); | |||||
| instance->setBusesLayout (layout); | instance->setBusesLayout (layout); | ||||
| } | } | ||||
| if (auto node = graph.addNode (instance, NodeID ((uint32) xml.getIntAttribute ("uid")))) | |||||
| if (auto node = graph.addNode (std::move (instance), NodeID ((uint32) xml.getIntAttribute ("uid")))) | |||||
| { | { | ||||
| if (auto* state = xml.getChildByName ("STATE")) | if (auto* state = xml.getChildByName ("STATE")) | ||||
| { | { | ||||
| @@ -84,23 +84,6 @@ public: | |||||
| AudioProcessorGraph graph; | AudioProcessorGraph graph; | ||||
| private: | private: | ||||
| //============================================================================== | |||||
| struct AsyncCallback : public AudioPluginFormat::InstantiationCompletionCallback | |||||
| { | |||||
| AsyncCallback(FilterGraph& g, Point<double> pos) : owner(g), position(pos) | |||||
| {} | |||||
| void completionCallback(AudioPluginInstance* instance, const String& error) override | |||||
| { | |||||
| owner.addFilterCallback(instance, error, position); | |||||
| } | |||||
| FilterGraph& owner; | |||||
| Point<double> position; | |||||
| JUCE_DECLARE_NON_COPYABLE (AsyncCallback) | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| AudioPluginFormatManager& formatManager; | AudioPluginFormatManager& formatManager; | ||||
| OwnedArray<PluginWindow> activePluginWindows; | OwnedArray<PluginWindow> activePluginWindows; | ||||
| @@ -108,8 +91,8 @@ private: | |||||
| NodeID lastUID; | NodeID lastUID; | ||||
| NodeID getNextUID() noexcept; | NodeID getNextUID() noexcept; | ||||
| void createNodeFromXml (const XmlElement& xml); | |||||
| void addFilterCallback (AudioPluginInstance*, const String& error, Point<double>); | |||||
| void createNodeFromXml (const XmlElement&); | |||||
| void addPluginCallback (std::unique_ptr<AudioPluginInstance>, const String& error, Point<double>); | |||||
| void changeListenerCallback (ChangeBroadcaster*) override; | void changeListenerCallback (ChangeBroadcaster*) override; | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterGraph) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterGraph) | ||||
| @@ -64,10 +64,8 @@ public: | |||||
| bool isBusesLayoutSupported (const BusesLayout& layout) const override | bool isBusesLayoutSupported (const BusesLayout& layout) const override | ||||
| { | { | ||||
| if (! isGenerator) | if (! isGenerator) | ||||
| { | |||||
| if (layout.getMainOutputChannelSet() != channelSet) | if (layout.getMainOutputChannelSet() != channelSet) | ||||
| return false; | return false; | ||||
| } | |||||
| if (layout.getMainInputChannelSet() != channelSet) | if (layout.getMainInputChannelSet() != channelSet) | ||||
| return false; | return false; | ||||
| @@ -130,7 +128,7 @@ private: | |||||
| class SineWaveSynth : public InternalPlugin | class SineWaveSynth : public InternalPlugin | ||||
| { | { | ||||
| public: | public: | ||||
| SineWaveSynth (const PluginDescription& descr) : InternalPlugin (descr) | |||||
| SineWaveSynth (const PluginDescription& descr) : InternalPlugin (descr) | |||||
| { | { | ||||
| const int numVoices = 8; | const int numVoices = 8; | ||||
| @@ -174,22 +172,17 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| class SineWaveSound : public SynthesiserSound | |||||
| struct SineWaveSound : public SynthesiserSound | |||||
| { | { | ||||
| public: | |||||
| SineWaveSound() {} | |||||
| SineWaveSound() = default; | |||||
| bool appliesToNote (int /*midiNoteNumber*/) override { return true; } | bool appliesToNote (int /*midiNoteNumber*/) override { return true; } | ||||
| bool appliesToChannel (int /*midiChannel*/) override { return true; } | bool appliesToChannel (int /*midiChannel*/) override { return true; } | ||||
| }; | }; | ||||
| class SineWaveVoice : public SynthesiserVoice | |||||
| struct SineWaveVoice : public SynthesiserVoice | |||||
| { | { | ||||
| public: | |||||
| SineWaveVoice() | |||||
| : currentAngle (0), angleDelta (0), level (0), tailOff (0) | |||||
| { | |||||
| } | |||||
| SineWaveVoice() = default; | |||||
| bool canPlaySound (SynthesiserSound* sound) override | bool canPlaySound (SynthesiserSound* sound) override | ||||
| { | { | ||||
| @@ -287,7 +280,7 @@ private: | |||||
| using SynthesiserVoice::renderNextBlock; | using SynthesiserVoice::renderNextBlock; | ||||
| private: | private: | ||||
| double currentAngle, angleDelta, level, tailOff; | |||||
| double currentAngle = 0, angleDelta = 0, level = 0, tailOff = 0; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -366,28 +359,27 @@ InternalPluginFormat::InternalPluginFormat() | |||||
| } | } | ||||
| } | } | ||||
| AudioPluginInstance* InternalPluginFormat::createInstance (const String& name) | |||||
| std::unique_ptr<AudioPluginInstance> InternalPluginFormat::createInstance (const String& name) | |||||
| { | { | ||||
| if (name == audioOutDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); | |||||
| if (name == audioInDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); | |||||
| if (name == midiInDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); | |||||
| if (name == audioOutDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); | |||||
| if (name == audioInDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); | |||||
| if (name == midiInDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); | |||||
| if (name == SineWaveSynth::getIdentifier()) return new SineWaveSynth (SineWaveSynth::getPluginDescription()); | |||||
| if (name == ReverbFilter::getIdentifier()) return new ReverbFilter (ReverbFilter::getPluginDescription()); | |||||
| if (name == SineWaveSynth::getIdentifier()) return std::make_unique<SineWaveSynth> (SineWaveSynth::getPluginDescription()); | |||||
| if (name == ReverbFilter::getIdentifier()) return std::make_unique<ReverbFilter> (ReverbFilter::getPluginDescription()); | |||||
| return nullptr; | |||||
| return {}; | |||||
| } | } | ||||
| void InternalPluginFormat::createPluginInstance (const PluginDescription& desc, | void InternalPluginFormat::createPluginInstance (const PluginDescription& desc, | ||||
| double /*initialSampleRate*/, | |||||
| int /*initialBufferSize*/, | |||||
| void* userData, | |||||
| double /*initialSampleRate*/, int /*initialBufferSize*/, | |||||
| PluginCreationCallback callback) | PluginCreationCallback callback) | ||||
| { | { | ||||
| auto* p = createInstance (desc.name); | |||||
| callback (userData, p, p == nullptr ? NEEDS_TRANS ("Invalid internal filter name") : String()); | |||||
| if (auto p = createInstance (desc.name)) | |||||
| callback (std::move (p), {}); | |||||
| else | |||||
| callback (nullptr, NEEDS_TRANS ("Invalid internal plugin name")); | |||||
| } | } | ||||
| bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | ||||
| @@ -57,9 +57,11 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| void createPluginInstance (const PluginDescription&, double initialSampleRate, int initialBufferSize, | |||||
| void* userData, PluginCreationCallback) override; | |||||
| AudioPluginInstance* createInstance (const String& name); | |||||
| void createPluginInstance (const PluginDescription&, | |||||
| double initialSampleRate, int initialBufferSize, | |||||
| PluginCreationCallback) override; | |||||
| std::unique_ptr<AudioPluginInstance> createInstance (const String& name); | |||||
| bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | ||||
| }; | }; | ||||
| @@ -27,188 +27,83 @@ | |||||
| namespace juce | namespace juce | ||||
| { | { | ||||
| namespace AudioPluginFormatHelpers | |||||
| { | |||||
| struct CallbackInvoker | |||||
| { | |||||
| struct InvokeOnMessageThread : public CallbackMessage | |||||
| { | |||||
| InvokeOnMessageThread (AudioPluginInstance* inInstance, const String& inError, | |||||
| AudioPluginFormat::InstantiationCompletionCallback* inCompletion, | |||||
| CallbackInvoker* invoker) | |||||
| : instance (inInstance), error (inError), compCallback (inCompletion), owner (invoker) | |||||
| {} | |||||
| void messageCallback() override { compCallback->completionCallback (instance.release(), error); } | |||||
| //============================================================================== | |||||
| std::unique_ptr<AudioPluginInstance> instance; | |||||
| String error; | |||||
| std::unique_ptr<AudioPluginFormat::InstantiationCompletionCallback> compCallback; | |||||
| std::unique_ptr<CallbackInvoker> owner; | |||||
| }; | |||||
| //============================================================================== | |||||
| CallbackInvoker (AudioPluginFormat::InstantiationCompletionCallback* cc) : completion (cc) | |||||
| {} | |||||
| void completionCallback (AudioPluginInstance* instance, const String& error) | |||||
| { | |||||
| (new InvokeOnMessageThread (instance, error, completion, this))->post(); | |||||
| } | |||||
| static void staticCompletionCallback (void* userData, AudioPluginInstance* instance, const String& error) | |||||
| { | |||||
| reinterpret_cast<CallbackInvoker*> (userData)->completionCallback (instance, error); | |||||
| } | |||||
| //============================================================================== | |||||
| AudioPluginFormat::InstantiationCompletionCallback* completion; | |||||
| }; | |||||
| } | |||||
| AudioPluginFormat::AudioPluginFormat() noexcept {} | AudioPluginFormat::AudioPluginFormat() noexcept {} | ||||
| AudioPluginFormat::~AudioPluginFormat() {} | AudioPluginFormat::~AudioPluginFormat() {} | ||||
| AudioPluginInstance* AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize) | |||||
| std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize) | |||||
| { | { | ||||
| String errorMessage; | String errorMessage; | ||||
| return createInstanceFromDescription (desc, initialSampleRate, initialBufferSize, errorMessage); | return createInstanceFromDescription (desc, initialSampleRate, initialBufferSize, errorMessage); | ||||
| } | } | ||||
| //============================================================================== | |||||
| struct EventSignaler : public AudioPluginFormat::InstantiationCompletionCallback | |||||
| { | |||||
| EventSignaler (WaitableEvent& inEvent, AudioPluginInstance*& inInstance, String& inErrorMessage) | |||||
| : event (inEvent), outInstance (inInstance), outErrorMessage (inErrorMessage) | |||||
| {} | |||||
| void completionCallback (AudioPluginInstance* newInstance, const String& result) override | |||||
| { | |||||
| outInstance = newInstance; | |||||
| outErrorMessage = result; | |||||
| event.signal(); | |||||
| } | |||||
| static void staticCompletionCallback (void* userData, AudioPluginInstance* pluginInstance, const String& error) | |||||
| { | |||||
| reinterpret_cast<EventSignaler*> (userData)->completionCallback (pluginInstance, error); | |||||
| } | |||||
| WaitableEvent& event; | |||||
| AudioPluginInstance*& outInstance; | |||||
| String& outErrorMessage; | |||||
| JUCE_DECLARE_NON_COPYABLE (EventSignaler) | |||||
| }; | |||||
| AudioPluginInstance* AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| String& errorMessage) | |||||
| std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| String& errorMessage) | |||||
| { | { | ||||
| if (MessageManager::getInstance()->isThisTheMessageThread() | if (MessageManager::getInstance()->isThisTheMessageThread() | ||||
| && requiresUnblockedMessageThreadDuringCreation(desc)) | |||||
| && requiresUnblockedMessageThreadDuringCreation (desc)) | |||||
| { | { | ||||
| errorMessage = NEEDS_TRANS ("This plug-in cannot be instantiated synchronously"); | errorMessage = NEEDS_TRANS ("This plug-in cannot be instantiated synchronously"); | ||||
| return nullptr; | |||||
| return {}; | |||||
| } | } | ||||
| WaitableEvent waitForCreation; | |||||
| AudioPluginInstance* instance = nullptr; | |||||
| WaitableEvent finishedSignal; | |||||
| std::unique_ptr<AudioPluginInstance> instance; | |||||
| std::unique_ptr<EventSignaler> eventSignaler (new EventSignaler (waitForCreation, instance, errorMessage)); | |||||
| auto callback = [&] (std::unique_ptr<AudioPluginInstance> p, const String& error) | |||||
| { | |||||
| errorMessage = error; | |||||
| instance = std::move (p); | |||||
| finishedSignal.signal(); | |||||
| }; | |||||
| if (! MessageManager::getInstance()->isThisTheMessageThread()) | if (! MessageManager::getInstance()->isThisTheMessageThread()) | ||||
| createPluginInstanceAsync (desc, initialSampleRate, initialBufferSize, eventSignaler.release()); | |||||
| createPluginInstanceAsync (desc, initialSampleRate, initialBufferSize, std::move (callback)); | |||||
| else | else | ||||
| createPluginInstance (desc, initialSampleRate, initialBufferSize, | |||||
| eventSignaler.get(), EventSignaler::staticCompletionCallback); | |||||
| waitForCreation.wait(); | |||||
| createPluginInstance (desc, initialSampleRate, initialBufferSize, std::move (callback)); | |||||
| finishedSignal.wait(); | |||||
| return instance; | return instance; | ||||
| } | } | ||||
| void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description, | void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description, | ||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| AudioPluginFormat::InstantiationCompletionCallback* callback) | |||||
| double initialSampleRate, int initialBufferSize, | |||||
| PluginCreationCallback callback) | |||||
| { | { | ||||
| jassert (callback != nullptr); | |||||
| if (MessageManager::getInstance()->isThisTheMessageThread()) | if (MessageManager::getInstance()->isThisTheMessageThread()) | ||||
| { | { | ||||
| createPluginInstanceOnMessageThread (description, initialSampleRate, initialBufferSize, callback); | |||||
| createPluginInstance (description, initialSampleRate, initialBufferSize, std::move (callback)); | |||||
| return; | return; | ||||
| } | } | ||||
| //============================================================================== | |||||
| struct InvokeOnMessageThread : public CallbackMessage | struct InvokeOnMessageThread : public CallbackMessage | ||||
| { | { | ||||
| InvokeOnMessageThread (AudioPluginFormat* myself, | |||||
| const PluginDescription& descriptionParam, | |||||
| double initialSampleRateParam, | |||||
| int initialBufferSizeParam, | |||||
| AudioPluginFormat::InstantiationCompletionCallback* callbackParam) | |||||
| : owner (myself), descr (descriptionParam), sampleRate (initialSampleRateParam), | |||||
| bufferSize (initialBufferSizeParam), call (callbackParam) | |||||
| {} | |||||
| InvokeOnMessageThread (AudioPluginFormat& f, const PluginDescription& d, | |||||
| double sr, int size, PluginCreationCallback call) | |||||
| : format (f), desc (d), sampleRate (sr), bufferSize (size), | |||||
| callbackToUse (std::move (call)) | |||||
| { | |||||
| post(); | |||||
| } | |||||
| void messageCallback() override | void messageCallback() override | ||||
| { | { | ||||
| owner->createPluginInstanceOnMessageThread (descr, sampleRate, bufferSize, call); | |||||
| format.createPluginInstance (desc, sampleRate, bufferSize, std::move (callbackToUse)); | |||||
| } | } | ||||
| AudioPluginFormat* owner; | |||||
| PluginDescription descr; | |||||
| AudioPluginFormat& format; | |||||
| PluginDescription desc; | |||||
| double sampleRate; | double sampleRate; | ||||
| int bufferSize; | int bufferSize; | ||||
| AudioPluginFormat::InstantiationCompletionCallback* call; | |||||
| }; | |||||
| (new InvokeOnMessageThread (this, description, initialSampleRate, initialBufferSize, callback))->post(); | |||||
| } | |||||
| void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| std::function<void(AudioPluginInstance*, const String&)> f) | |||||
| { | |||||
| struct CallbackInvoker : public AudioPluginFormat::InstantiationCompletionCallback | |||||
| { | |||||
| CallbackInvoker (std::function<void(AudioPluginInstance*, const String&)> inCompletion) | |||||
| : completion (inCompletion) | |||||
| {} | |||||
| void completionCallback (AudioPluginInstance* instance, const String& error) override | |||||
| { | |||||
| completion (instance, error); | |||||
| } | |||||
| std::function<void(AudioPluginInstance*, const String&)> completion; | |||||
| PluginCreationCallback callbackToUse; | |||||
| }; | }; | ||||
| createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, new CallbackInvoker (f)); | |||||
| } | |||||
| void AudioPluginFormat::createPluginInstanceOnMessageThread (const PluginDescription& description, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| AudioPluginFormat::InstantiationCompletionCallback* callback) | |||||
| { | |||||
| jassert (callback != nullptr); | |||||
| JUCE_ASSERT_MESSAGE_THREAD | |||||
| //============================================================================== | |||||
| //============================================================================== | |||||
| AudioPluginFormatHelpers::CallbackInvoker* completion = new AudioPluginFormatHelpers::CallbackInvoker (callback); | |||||
| createPluginInstance (description, initialSampleRate, initialBufferSize, completion, | |||||
| AudioPluginFormatHelpers::CallbackInvoker::staticCompletionCallback); | |||||
| new InvokeOnMessageThread (*this, description, initialSampleRate, initialBufferSize, std::move (callback)); | |||||
| } | } | ||||
| } // namespace juce | } // namespace juce | ||||
| @@ -38,17 +38,6 @@ namespace juce | |||||
| class JUCE_API AudioPluginFormat | class JUCE_API AudioPluginFormat | ||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | |||||
| /** Structure used for callbacks when instantiation is completed. */ | |||||
| struct JUCE_API InstantiationCompletionCallback | |||||
| { | |||||
| virtual ~InstantiationCompletionCallback() = default; | |||||
| virtual void completionCallback (AudioPluginInstance* instance, const String& error) = 0; | |||||
| JUCE_LEAK_DETECTOR (InstantiationCompletionCallback) | |||||
| }; | |||||
| //============================================================================== | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| virtual ~AudioPluginFormat(); | virtual ~AudioPluginFormat(); | ||||
| @@ -73,32 +62,30 @@ public: | |||||
| /** Tries to recreate a type from a previously generated PluginDescription. | /** Tries to recreate a type from a previously generated PluginDescription. | ||||
| @see AudioPluginFormatManager::createInstance | @see AudioPluginFormatManager::createInstance | ||||
| */ | */ | ||||
| AudioPluginInstance* createInstanceFromDescription (const PluginDescription&, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize); | |||||
| std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize); | |||||
| /** Same as above but with the possibility of returning an error message. | /** Same as above but with the possibility of returning an error message. | ||||
| @see AudioPluginFormatManager::createInstance | @see AudioPluginFormatManager::createInstance | ||||
| */ | */ | ||||
| AudioPluginInstance* createInstanceFromDescription (const PluginDescription&, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| String& errorMessage); | |||||
| std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| String& errorMessage); | |||||
| /** Tries to recreate a type from a previously generated PluginDescription. | |||||
| /** A callback lambda that is passed to createPluginInstanceAsync() */ | |||||
| using PluginCreationCallback = std::function<void(std::unique_ptr<AudioPluginInstance>, const String&)>; | |||||
| @see AudioPluginFormatManager::createInstanceAsync | |||||
| /** Tries to recreate a type from a previously generated PluginDescription. | |||||
| When the plugin has been created, it will be passed to the caller via an | |||||
| asynchronous call to the PluginCreationCallback lambda that was provided. | |||||
| @see AudioPluginFormatManager::createPluginInstanceAsync | |||||
| */ | */ | ||||
| void createPluginInstanceAsync (const PluginDescription& description, | void createPluginInstanceAsync (const PluginDescription& description, | ||||
| double initialSampleRate, | double initialSampleRate, | ||||
| int initialBufferSize, | int initialBufferSize, | ||||
| InstantiationCompletionCallback* completionCallback); | |||||
| void createPluginInstanceAsync (const PluginDescription& description, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| std::function<void(AudioPluginInstance*, const String&)> completionCallback); | |||||
| PluginCreationCallback); | |||||
| /** Should do a quick check to see if this file or directory might be a plugin of | /** Should do a quick check to see if this file or directory might be a plugin of | ||||
| this format. | this format. | ||||
| @@ -151,22 +138,15 @@ protected: | |||||
| AudioPluginFormat() noexcept; | AudioPluginFormat() noexcept; | ||||
| using PluginCreationCallback = void (*) (void*, AudioPluginInstance*, const String&); | |||||
| /** Implementors must override this function. This is guaranteed to be called on | /** Implementors must override this function. This is guaranteed to be called on | ||||
| the message thread. You may call the callback on any thread. | the message thread. You may call the callback on any thread. | ||||
| */ | */ | ||||
| virtual void createPluginInstance (const PluginDescription&, double initialSampleRate, | virtual void createPluginInstance (const PluginDescription&, double initialSampleRate, | ||||
| int initialBufferSize, void* userData, | |||||
| PluginCreationCallback) = 0; | |||||
| int initialBufferSize, PluginCreationCallback) = 0; | |||||
| virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept = 0; | virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept = 0; | ||||
| private: | private: | ||||
| /** @internal */ | |||||
| void createPluginInstanceOnMessageThread (const PluginDescription&, double rate, int size, | |||||
| AudioPluginFormat::InstantiationCompletionCallback*); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat) | ||||
| }; | }; | ||||
| @@ -27,37 +27,6 @@ | |||||
| namespace juce | namespace juce | ||||
| { | { | ||||
| namespace PluginFormatManagerHelpers | |||||
| { | |||||
| struct ErrorCallbackOnMessageThread : public CallbackMessage | |||||
| { | |||||
| ErrorCallbackOnMessageThread (const String& inError, | |||||
| AudioPluginFormat::InstantiationCompletionCallback* c) | |||||
| : error (inError), callback (c) | |||||
| { | |||||
| } | |||||
| void messageCallback() override { callback->completionCallback (nullptr, error); } | |||||
| String error; | |||||
| std::unique_ptr<AudioPluginFormat::InstantiationCompletionCallback> callback; | |||||
| }; | |||||
| struct ErrorLambdaOnMessageThread : public CallbackMessage | |||||
| { | |||||
| ErrorLambdaOnMessageThread (const String& inError, | |||||
| std::function<void(AudioPluginInstance*, const String&)> f) | |||||
| : error (inError), lambda (f) | |||||
| { | |||||
| } | |||||
| void messageCallback() override { lambda (nullptr, error); } | |||||
| String error; | |||||
| std::function<void(AudioPluginInstance*, const String&)> lambda; | |||||
| }; | |||||
| } | |||||
| AudioPluginFormatManager::AudioPluginFormatManager() {} | AudioPluginFormatManager::AudioPluginFormatManager() {} | ||||
| AudioPluginFormatManager::~AudioPluginFormatManager() {} | AudioPluginFormatManager::~AudioPluginFormatManager() {} | ||||
| @@ -120,39 +89,40 @@ void AudioPluginFormatManager::addFormat (AudioPluginFormat* format) | |||||
| formats.add (format); | formats.add (format); | ||||
| } | } | ||||
| AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const PluginDescription& description, double rate, | |||||
| int blockSize, String& errorMessage) const | |||||
| std::unique_ptr<AudioPluginInstance> AudioPluginFormatManager::createPluginInstance (const PluginDescription& description, | |||||
| double rate, int blockSize, | |||||
| String& errorMessage) const | |||||
| { | { | ||||
| if (auto* format = findFormatForDescription (description, errorMessage)) | if (auto* format = findFormatForDescription (description, errorMessage)) | ||||
| return format->createInstanceFromDescription (description, rate, blockSize, errorMessage); | return format->createInstanceFromDescription (description, rate, blockSize, errorMessage); | ||||
| return nullptr; | |||||
| return {}; | |||||
| } | } | ||||
| void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description, | void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description, | ||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| AudioPluginFormat::InstantiationCompletionCallback* callback) | |||||
| double initialSampleRate, int initialBufferSize, | |||||
| AudioPluginFormat::PluginCreationCallback callback) | |||||
| { | { | ||||
| String error; | String error; | ||||
| if (auto* format = findFormatForDescription (description, error)) | if (auto* format = findFormatForDescription (description, error)) | ||||
| return format->createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, callback); | |||||
| return format->createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, std::move (callback)); | |||||
| (new PluginFormatManagerHelpers::ErrorCallbackOnMessageThread (error, callback))->post(); | |||||
| } | |||||
| struct DeliverError : public CallbackMessage | |||||
| { | |||||
| DeliverError (AudioPluginFormat::PluginCreationCallback c, const String& e) | |||||
| : call (std::move (c)), error (e) | |||||
| { | |||||
| post(); | |||||
| } | |||||
| void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| std::function<void(AudioPluginInstance*, const String&)> f) | |||||
| { | |||||
| String error; | |||||
| void messageCallback() override { call (nullptr, error); } | |||||
| if (auto* format = findFormatForDescription (description, error)) | |||||
| return format->createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, f); | |||||
| AudioPluginFormat::PluginCreationCallback call; | |||||
| String error; | |||||
| }; | |||||
| (new PluginFormatManagerHelpers::ErrorLambdaOnMessageThread (error, f))->post(); | |||||
| new DeliverError (std::move (callback), error); | |||||
| } | } | ||||
| AudioPluginFormat* AudioPluginFormatManager::findFormatForDescription (const PluginDescription& description, | AudioPluginFormat* AudioPluginFormatManager::findFormatForDescription (const PluginDescription& description, | ||||
| @@ -167,7 +137,7 @@ AudioPluginFormat* AudioPluginFormatManager::findFormatForDescription (const Plu | |||||
| errorMessage = NEEDS_TRANS ("No compatible plug-in format exists for this plug-in"); | errorMessage = NEEDS_TRANS ("No compatible plug-in format exists for this plug-in"); | ||||
| return nullptr; | |||||
| return {}; | |||||
| } | } | ||||
| bool AudioPluginFormatManager::doesPluginStillExist (const PluginDescription& description) const | bool AudioPluginFormatManager::doesPluginStillExist (const PluginDescription& description) const | ||||
| @@ -45,30 +45,25 @@ public: | |||||
| ~AudioPluginFormatManager(); | ~AudioPluginFormatManager(); | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Adds any formats that it knows about, e.g. VST. | |||||
| */ | |||||
| /** Adds the set of available standard formats, e.g. VST. */ | |||||
| void addDefaultFormats(); | void addDefaultFormats(); | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the number of types of format that are available. | /** Returns the number of types of format that are available. | ||||
| Use getFormat() to get one of them. | Use getFormat() to get one of them. | ||||
| */ | */ | ||||
| int getNumFormats(); | int getNumFormats(); | ||||
| /** Returns one of the available formats. | /** Returns one of the available formats. | ||||
| @see getNumFormats | @see getNumFormats | ||||
| */ | */ | ||||
| AudioPluginFormat* getFormat (int index); | AudioPluginFormat* getFormat (int index); | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Adds a format to the list. | /** Adds a format to the list. | ||||
| The object passed in will be owned and deleted by the manager. | The object passed in will be owned and deleted by the manager. | ||||
| */ | */ | ||||
| void addFormat (AudioPluginFormat* format); | |||||
| void addFormat (AudioPluginFormat*); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Tries to load the type for this description, by trying all the formats | /** Tries to load the type for this description, by trying all the formats | ||||
| @@ -84,10 +79,9 @@ public: | |||||
| thread other than the message thread and without blocking the message | thread other than the message thread and without blocking the message | ||||
| thread. | thread. | ||||
| */ | */ | ||||
| AudioPluginInstance* createPluginInstance (const PluginDescription& description, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| String& errorMessage) const; | |||||
| std::unique_ptr<AudioPluginInstance> createPluginInstance (const PluginDescription& description, | |||||
| double initialSampleRate, int initialBufferSize, | |||||
| String& errorMessage) const; | |||||
| /** Tries to asynchronously load the type for this description, by trying | /** Tries to asynchronously load the type for this description, by trying | ||||
| all the formats that this manager knows about. | all the formats that this manager knows about. | ||||
| @@ -112,24 +106,16 @@ public: | |||||
| from an auxiliary thread. | from an auxiliary thread. | ||||
| */ | */ | ||||
| void createPluginInstanceAsync (const PluginDescription& description, | void createPluginInstanceAsync (const PluginDescription& description, | ||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| AudioPluginFormat::InstantiationCompletionCallback* callback); | |||||
| void createPluginInstanceAsync (const PluginDescription& description, | |||||
| double initialSampleRate, | |||||
| int initialBufferSize, | |||||
| std::function<void(AudioPluginInstance*, const String&)> completionCallback); | |||||
| double initialSampleRate, int initialBufferSize, | |||||
| AudioPluginFormat::PluginCreationCallback callback); | |||||
| /** Checks that the file or component for this plugin actually still exists. | /** Checks that the file or component for this plugin actually still exists. | ||||
| (This won't try to load the plugin) | (This won't try to load the plugin) | ||||
| */ | */ | ||||
| bool doesPluginStillExist (const PluginDescription& description) const; | |||||
| bool doesPluginStillExist (const PluginDescription&) const; | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| //@internal | |||||
| AudioPluginFormat* findFormatForDescription (const PluginDescription&, String& errorMessage) const; | AudioPluginFormat* findFormatForDescription (const PluginDescription&, String& errorMessage) const; | ||||
| OwnedArray<AudioPluginFormat> formats; | OwnedArray<AudioPluginFormat> formats; | ||||
| @@ -57,7 +57,7 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| void createPluginInstance (const PluginDescription&, | void createPluginInstance (const PluginDescription&, | ||||
| double initialSampleRate, int initialBufferSize, | double initialSampleRate, int initialBufferSize, | ||||
| void* userData, PluginCreationCallback) override; | |||||
| PluginCreationCallback) override; | |||||
| bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | ||||
| @@ -2637,9 +2637,9 @@ void AudioUnitPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& | |||||
| try | try | ||||
| { | { | ||||
| std::unique_ptr<AudioPluginInstance> createdInstance (createInstanceFromDescription (desc, 44100.0, 512)); | |||||
| auto createdInstance = createInstanceFromDescription (desc, 44100.0, 512); | |||||
| if (AudioUnitPluginInstance* auInstance = dynamic_cast<AudioUnitPluginInstance*> (createdInstance.get())) | |||||
| if (auto auInstance = dynamic_cast<AudioUnitPluginInstance*> (createdInstance.get())) | |||||
| results.add (new PluginDescription (auInstance->getPluginDescription())); | results.add (new PluginDescription (auInstance->getPluginDescription())); | ||||
| } | } | ||||
| catch (...) | catch (...) | ||||
| @@ -2650,13 +2650,12 @@ void AudioUnitPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& | |||||
| void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | ||||
| double rate, int blockSize, | double rate, int blockSize, | ||||
| void* userData, PluginCreationCallback callback) | |||||
| PluginCreationCallback callback) | |||||
| { | { | ||||
| using namespace AudioUnitFormatHelpers; | using namespace AudioUnitFormatHelpers; | ||||
| if (fileMightContainThisPluginType (desc.fileOrIdentifier)) | if (fileMightContainThisPluginType (desc.fileOrIdentifier)) | ||||
| { | { | ||||
| String pluginName, version, manufacturer; | String pluginName, version, manufacturer; | ||||
| AudioComponentDescription componentDesc; | AudioComponentDescription componentDesc; | ||||
| AudioComponent auComponent; | AudioComponent auComponent; | ||||
| @@ -2665,19 +2664,19 @@ void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| if ((! getComponentDescFromIdentifier (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer)) | if ((! getComponentDescFromIdentifier (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer)) | ||||
| && (! getComponentDescFromFile (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer))) | && (! getComponentDescFromFile (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer))) | ||||
| { | { | ||||
| callback (userData, nullptr, errMessage); | |||||
| callback (nullptr, errMessage); | |||||
| return; | return; | ||||
| } | } | ||||
| if ((auComponent = AudioComponentFindNext (nullptr, &componentDesc)) == nullptr) | if ((auComponent = AudioComponentFindNext (nullptr, &componentDesc)) == nullptr) | ||||
| { | { | ||||
| callback (userData, nullptr, errMessage); | |||||
| callback (nullptr, errMessage); | |||||
| return; | return; | ||||
| } | } | ||||
| if (AudioComponentGetDescription (auComponent, &componentDesc) != noErr) | if (AudioComponentGetDescription (auComponent, &componentDesc) != noErr) | ||||
| { | { | ||||
| callback (userData, nullptr, errMessage); | |||||
| callback (nullptr, errMessage); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -2688,9 +2687,9 @@ void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| #endif | #endif | ||||
| AUAsyncInitializationCallback (double inSampleRate, int inFramesPerBuffer, | AUAsyncInitializationCallback (double inSampleRate, int inFramesPerBuffer, | ||||
| void* inUserData, PluginCreationCallback inOriginalCallback) | |||||
| PluginCreationCallback inOriginalCallback) | |||||
| : sampleRate (inSampleRate), framesPerBuffer (inFramesPerBuffer), | : sampleRate (inSampleRate), framesPerBuffer (inFramesPerBuffer), | ||||
| passUserData (inUserData), originalCallback (inOriginalCallback) | |||||
| originalCallback (std::move (inOriginalCallback)) | |||||
| { | { | ||||
| #if JUCE_SUPPORTS_AUv3 | #if JUCE_SUPPORTS_AUv3 | ||||
| block = CreateObjCBlock (this, &AUAsyncInitializationCallback::completion); | block = CreateObjCBlock (this, &AUAsyncInitializationCallback::completion); | ||||
| @@ -2708,15 +2707,14 @@ void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| std::unique_ptr<AudioUnitPluginInstance> instance (new AudioUnitPluginInstance (audioUnit)); | std::unique_ptr<AudioUnitPluginInstance> instance (new AudioUnitPluginInstance (audioUnit)); | ||||
| if (instance->initialise (sampleRate, framesPerBuffer)) | if (instance->initialise (sampleRate, framesPerBuffer)) | ||||
| originalCallback (passUserData, instance.release(), StringRef()); | |||||
| originalCallback (std::move (instance), {}); | |||||
| else | else | ||||
| originalCallback (passUserData, nullptr, | |||||
| NEEDS_TRANS ("Unable to initialise the AudioUnit plug-in")); | |||||
| originalCallback (nullptr, NEEDS_TRANS ("Unable to initialise the AudioUnit plug-in")); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| String errMsg = NEEDS_TRANS ("An OS error occurred during initialisation of the plug-in (XXX)"); | |||||
| originalCallback (passUserData, nullptr, errMsg.replace ("XXX", String (err))); | |||||
| auto errMsg = TRANS ("An OS error occurred during initialisation of the plug-in (XXX)"); | |||||
| originalCallback (nullptr, errMsg.replace ("XXX", String (err))); | |||||
| } | } | ||||
| delete this; | delete this; | ||||
| @@ -2724,7 +2722,6 @@ void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| double sampleRate; | double sampleRate; | ||||
| int framesPerBuffer; | int framesPerBuffer; | ||||
| void* passUserData; | |||||
| PluginCreationCallback originalCallback; | PluginCreationCallback originalCallback; | ||||
| #if JUCE_SUPPORTS_AUv3 | #if JUCE_SUPPORTS_AUv3 | ||||
| @@ -2732,7 +2729,7 @@ void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| #endif | #endif | ||||
| }; | }; | ||||
| auto callbackBlock = new AUAsyncInitializationCallback (rate, blockSize, userData, callback); | |||||
| auto callbackBlock = new AUAsyncInitializationCallback (rate, blockSize, std::move (callback)); | |||||
| #if JUCE_SUPPORTS_AUv3 | #if JUCE_SUPPORTS_AUv3 | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -2753,7 +2750,7 @@ void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| callback (userData, nullptr, NEEDS_TRANS ("Plug-in description is not an AudioUnit plug-in")); | |||||
| callback (nullptr, NEEDS_TRANS ("Plug-in description is not an AudioUnit plug-in")); | |||||
| } | } | ||||
| } | } | ||||
| @@ -586,7 +586,8 @@ void LADSPAPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& res | |||||
| desc.fileOrIdentifier = fileOrIdentifier; | desc.fileOrIdentifier = fileOrIdentifier; | ||||
| desc.uid = 0; | desc.uid = 0; | ||||
| std::unique_ptr<LADSPAPluginInstance> instance (dynamic_cast<LADSPAPluginInstance*> (createInstanceFromDescription (desc, 44100.0, 512))); | |||||
| auto createdInstance = createInstanceFromDescription (desc, 44100.0, 512); | |||||
| auto instance = dynamic_cast<LADSPAPluginInstance*> (createdInstance.get()); | |||||
| if (instance == nullptr || ! instance->isValid()) | if (instance == nullptr || ! instance->isValid()) | ||||
| return; | return; | ||||
| @@ -616,7 +617,7 @@ void LADSPAPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& res | |||||
| void LADSPAPluginFormat::createPluginInstance (const PluginDescription& desc, | void LADSPAPluginFormat::createPluginInstance (const PluginDescription& desc, | ||||
| double sampleRate, int blockSize, | double sampleRate, int blockSize, | ||||
| void* userData, PluginCreationCallback callback) | |||||
| PluginCreationCallback callback) | |||||
| { | { | ||||
| std::unique_ptr<LADSPAPluginInstance> result; | std::unique_ptr<LADSPAPluginInstance> result; | ||||
| @@ -647,9 +648,9 @@ void LADSPAPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| String errorMsg; | String errorMsg; | ||||
| if (result == nullptr) | if (result == nullptr) | ||||
| errorMsg = String (NEEDS_TRANS ("Unable to load XXX plug-in file")).replace ("XXX", "LADSPA"); | |||||
| errorMsg = TRANS ("Unable to load XXX plug-in file").replace ("XXX", "LADSPA"); | |||||
| callback (userData, result.release(), errorMsg); | |||||
| callback (std::move (result), errorMsg); | |||||
| } | } | ||||
| bool LADSPAPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | bool LADSPAPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | ||||
| @@ -55,7 +55,7 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| void createPluginInstance (const PluginDescription&, double initialSampleRate, | void createPluginInstance (const PluginDescription&, double initialSampleRate, | ||||
| int initialBufferSize, void* userData, PluginCreationCallback) override; | |||||
| int initialBufferSize, PluginCreationCallback) override; | |||||
| bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | ||||
| @@ -3078,8 +3078,8 @@ void VST3PluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& resul | |||||
| VST3ModuleHandle::getAllDescriptionsForFile (results, fileOrIdentifier); | VST3ModuleHandle::getAllDescriptionsForFile (results, fileOrIdentifier); | ||||
| } | } | ||||
| void VST3PluginFormat::createPluginInstance (const PluginDescription& description, double, int, | |||||
| void* userData, PluginCreationCallback callback) | |||||
| void VST3PluginFormat::createPluginInstance (const PluginDescription& description, | |||||
| double, int, PluginCreationCallback callback) | |||||
| { | { | ||||
| std::unique_ptr<VST3PluginInstance> result; | std::unique_ptr<VST3PluginInstance> result; | ||||
| @@ -3109,9 +3109,9 @@ void VST3PluginFormat::createPluginInstance (const PluginDescription& descriptio | |||||
| String errorMsg; | String errorMsg; | ||||
| if (result == nullptr) | if (result == nullptr) | ||||
| errorMsg = String (NEEDS_TRANS ("Unable to load XXX plug-in file")).replace ("XXX", "VST-3"); | |||||
| errorMsg = TRANS ("Unable to load XXX plug-in file").replace ("XXX", "VST-3"); | |||||
| callback (userData, result.release(), errorMsg); | |||||
| callback (std::move (result), errorMsg); | |||||
| } | } | ||||
| bool VST3PluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | bool VST3PluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | ||||
| @@ -63,7 +63,7 @@ public: | |||||
| private: | private: | ||||
| void createPluginInstance (const PluginDescription&, double initialSampleRate, | void createPluginInstance (const PluginDescription&, double initialSampleRate, | ||||
| int initialBufferSize, void* userData, PluginCreationCallback) override; | |||||
| int initialBufferSize, PluginCreationCallback) override; | |||||
| bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | ||||
| @@ -3498,11 +3498,11 @@ static pointer_sized_int VSTCALLBACK audioMaster (Vst2::AEffect* effect, int32 o | |||||
| VSTPluginFormat::VSTPluginFormat() {} | VSTPluginFormat::VSTPluginFormat() {} | ||||
| VSTPluginFormat::~VSTPluginFormat() {} | VSTPluginFormat::~VSTPluginFormat() {} | ||||
| static VSTPluginInstance* createAndUpdateDesc (VSTPluginFormat& format, PluginDescription& desc) | |||||
| static std::unique_ptr<VSTPluginInstance> createAndUpdateDesc (VSTPluginFormat& format, PluginDescription& desc) | |||||
| { | { | ||||
| if (auto* p = format.createInstanceFromDescription (desc, 44100.0, 512)) | |||||
| if (auto p = format.createInstanceFromDescription (desc, 44100.0, 512)) | |||||
| { | { | ||||
| if (auto* instance = dynamic_cast<VSTPluginInstance*> (p)) | |||||
| if (auto instance = dynamic_cast<VSTPluginInstance*> (p.release())) | |||||
| { | { | ||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| if (instance->vstModule->resFileId != 0) | if (instance->vstModule->resFileId != 0) | ||||
| @@ -3510,13 +3510,13 @@ static VSTPluginInstance* createAndUpdateDesc (VSTPluginFormat& format, PluginDe | |||||
| #endif | #endif | ||||
| instance->fillInPluginDescription (desc); | instance->fillInPluginDescription (desc); | ||||
| return instance; | |||||
| return std::unique_ptr<VSTPluginInstance> (instance); | |||||
| } | } | ||||
| jassertfalse; | jassertfalse; | ||||
| } | } | ||||
| return nullptr; | |||||
| return {}; | |||||
| } | } | ||||
| void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& results, | void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& results, | ||||
| @@ -3529,7 +3529,7 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& result | |||||
| desc.fileOrIdentifier = fileOrIdentifier; | desc.fileOrIdentifier = fileOrIdentifier; | ||||
| desc.uid = 0; | desc.uid = 0; | ||||
| std::unique_ptr<VSTPluginInstance> instance (createAndUpdateDesc (*this, desc)); | |||||
| auto instance = createAndUpdateDesc (*this, desc); | |||||
| if (instance == nullptr) | if (instance == nullptr) | ||||
| return; | return; | ||||
| @@ -3574,7 +3574,7 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& result | |||||
| void VSTPluginFormat::createPluginInstance (const PluginDescription& desc, | void VSTPluginFormat::createPluginInstance (const PluginDescription& desc, | ||||
| double sampleRate, int blockSize, | double sampleRate, int blockSize, | ||||
| void* userData, PluginCreationCallback callback) | |||||
| PluginCreationCallback callback) | |||||
| { | { | ||||
| std::unique_ptr<VSTPluginInstance> result; | std::unique_ptr<VSTPluginInstance> result; | ||||
| @@ -3601,9 +3601,9 @@ void VSTPluginFormat::createPluginInstance (const PluginDescription& desc, | |||||
| String errorMsg; | String errorMsg; | ||||
| if (result == nullptr) | if (result == nullptr) | ||||
| errorMsg = String (NEEDS_TRANS ("Unable to load XXX plug-in file")).replace ("XXX", "VST-2"); | |||||
| errorMsg = TRANS ("Unable to load XXX plug-in file").replace ("XXX", "VST-2"); | |||||
| callback (userData, result.release(), errorMsg); | |||||
| callback (std::move (result), errorMsg); | |||||
| } | } | ||||
| bool VSTPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | bool VSTPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept | ||||
| @@ -118,7 +118,7 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| void createPluginInstance (const PluginDescription&, double initialSampleRate, | void createPluginInstance (const PluginDescription&, double initialSampleRate, | ||||
| int initialBufferSize, void* userData, PluginCreationCallback) override; | |||||
| int initialBufferSize, PluginCreationCallback) override; | |||||
| bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; | ||||
| @@ -797,8 +797,8 @@ bool AudioProcessorGraph::Connection::operator< (const Connection& other) const | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| AudioProcessorGraph::Node::Node (NodeID n, AudioProcessor* p) noexcept | |||||
| : nodeID (n), processor (p) | |||||
| AudioProcessorGraph::Node::Node (NodeID n, std::unique_ptr<AudioProcessor> p) noexcept | |||||
| : nodeID (n), processor (std::move (p)) | |||||
| { | { | ||||
| jassert (processor != nullptr); | jassert (processor != nullptr); | ||||
| } | } | ||||
| @@ -914,9 +914,9 @@ AudioProcessorGraph::Node* AudioProcessorGraph::getNodeForId (NodeID nodeID) con | |||||
| return {}; | return {}; | ||||
| } | } | ||||
| AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (AudioProcessor* newProcessor, NodeID nodeID) | |||||
| AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (std::unique_ptr<AudioProcessor> newProcessor, NodeID nodeID) | |||||
| { | { | ||||
| if (newProcessor == nullptr || newProcessor == this) | |||||
| if (newProcessor == nullptr || newProcessor.get() == this) | |||||
| { | { | ||||
| jassertfalse; | jassertfalse; | ||||
| return {}; | return {}; | ||||
| @@ -927,7 +927,7 @@ AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (AudioProcessor* new | |||||
| for (auto* n : nodes) | for (auto* n : nodes) | ||||
| { | { | ||||
| if (n->getProcessor() == newProcessor || n->nodeID == nodeID) | |||||
| if (n->getProcessor() == newProcessor.get() || n->nodeID == nodeID) | |||||
| { | { | ||||
| jassertfalse; // Cannot add two copies of the same processor, or duplicate node IDs! | jassertfalse; // Cannot add two copies of the same processor, or duplicate node IDs! | ||||
| return {}; | return {}; | ||||
| @@ -939,7 +939,7 @@ AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (AudioProcessor* new | |||||
| newProcessor->setPlayHead (getPlayHead()); | newProcessor->setPlayHead (getPlayHead()); | ||||
| Node::Ptr n (new Node (nodeID, newProcessor)); | |||||
| Node::Ptr n (new Node (nodeID, std::move (newProcessor))); | |||||
| nodes.add (n.get()); | nodes.add (n.get()); | ||||
| n->setParentGraph (this); | n->setParentGraph (this); | ||||
| topologyChanged(); | topologyChanged(); | ||||
| @@ -145,7 +145,7 @@ public: | |||||
| Array<Connection> inputs, outputs; | Array<Connection> inputs, outputs; | ||||
| bool isPrepared = false, bypassed = false; | bool isPrepared = false, bypassed = false; | ||||
| Node (NodeID, AudioProcessor*) noexcept; | |||||
| Node (NodeID, std::unique_ptr<AudioProcessor>) noexcept; | |||||
| void setParentGraph (AudioProcessorGraph*) const; | void setParentGraph (AudioProcessorGraph*) const; | ||||
| void prepare (double newSampleRate, int newBlockSize, AudioProcessorGraph*, ProcessingPrecision); | void prepare (double newSampleRate, int newBlockSize, AudioProcessorGraph*, ProcessingPrecision); | ||||
| @@ -214,7 +214,7 @@ public: | |||||
| If this succeeds, it returns a pointer to the newly-created node. | If this succeeds, it returns a pointer to the newly-created node. | ||||
| */ | */ | ||||
| Node::Ptr addNode (AudioProcessor* newProcessor, NodeID nodeId = {}); | |||||
| Node::Ptr addNode (std::unique_ptr<AudioProcessor> newProcessor, NodeID nodeId = {}); | |||||
| /** Deletes a node within the graph which has the specified ID. | /** Deletes a node within the graph which has the specified ID. | ||||
| This will also delete any connections that are attached to this node. | This will also delete any connections that are attached to this node. | ||||
| @@ -95,7 +95,7 @@ public: | |||||
| withParameter() method, then the string will have these appended on the | withParameter() method, then the string will have these appended on the | ||||
| end and url-encoded. | end and url-encoded. | ||||
| */ | */ | ||||
| String getSubPath (bool includeGetParamters = false) const; | |||||
| String getSubPath (bool includeGetParameters = false) const; | |||||
| /** If any parameters are set, returns these URL encoded, including the "?" | /** If any parameters are set, returns these URL encoded, including the "?" | ||||
| * prefix. | * prefix. | ||||