From 32178f4a1f089fa9d1407855c0982efbe670cad5 Mon Sep 17 00:00:00 2001 From: jules Date: Fri, 8 Apr 2016 16:07:25 +0100 Subject: [PATCH] Tidied up some AUv3 code --- .../AU/juce_AUv3_Wrapper.mm | 333 +++++++++--------- .../juce_AudioUnitPluginFormat.mm | 8 +- .../juce_audio_processors.cpp | 34 +- 3 files changed, 193 insertions(+), 182 deletions(-) diff --git a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm index e208176f92..afea2897f9 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm @@ -50,9 +50,9 @@ #endif #if JUCE_IOS -#define IOS_MAC_VIEW UIView + #define JUCE_IOS_MAC_VIEW UIView #else -#define IOS_MAC_VIEW NSView + #define JUCE_IOS_MAC_VIEW NSView #endif #define JUCE_AUDIOUNIT_OBJC_NAME(x) JUCE_JOIN_MACRO (x, AUv3) @@ -63,32 +63,32 @@ JUCE_DEFINE_WRAPPER_TYPE (wrapperType_AudioUnitv3); // TODO: ask Timur: use SFINAE to automatically generate this for all NSObjects -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; -template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy > { static void destroy (NSObject* o) { [o release]; } }; +template <> struct ContainerDeletePolicy { static void destroy (NSObject* o) { [o release]; } }; //============================================================================== struct AudioProcessorHolder : public ReferenceCountedObject { AudioProcessorHolder() {} - AudioProcessorHolder (AudioProcessor* p) : juceFilter (p) {} - AudioProcessor& operator*() noexcept { return *juceFilter; } - AudioProcessor* operator->() noexcept { return juceFilter; } - AudioProcessor* get() noexcept { return juceFilter; } + AudioProcessorHolder (AudioProcessor* p) : processor (p) {} + AudioProcessor& operator*() noexcept { return *processor; } + AudioProcessor* operator->() noexcept { return processor; } + AudioProcessor* get() noexcept { return processor; } typedef ReferenceCountedObjectPtr Ptr; private: - ScopedPointer juceFilter; + ScopedPointer processor; AudioProcessorHolder& operator= (AudioProcessor*) JUCE_DELETED_FUNCTION; AudioProcessorHolder (AudioProcessorHolder&) JUCE_DELETED_FUNCTION; @@ -99,7 +99,8 @@ private: class JuceAudioUnitv3Base { public: - JuceAudioUnitv3Base (const AudioComponentDescription& descr, AudioComponentInstantiationOptions options, + JuceAudioUnitv3Base (const AudioComponentDescription& descr, + AudioComponentInstantiationOptions options, NSError** error) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-method-access" @@ -117,6 +118,8 @@ public: initialiseJuce_GUI(); } + virtual ~JuceAudioUnitv3Base() {} + //============================================================================== AUAudioUnit* getAudioUnit() noexcept { return au; } virtual int getVirtualMIDICableCount() { return 0; } @@ -175,12 +178,8 @@ public: ObjCMsgSendSuper (&s, @selector (deallocateRenderResources)); } - //============================================================================== -protected: - virtual ~JuceAudioUnitv3Base() {} - private: - struct Class : public ObjCClass + struct Class : public ObjCClass { Class() : ObjCClass ("AUAudioUnit_") { @@ -271,17 +270,17 @@ private: static NSArray* getFactoryPresets (id self, SEL) { return _this (self)->getFactoryPresets(); } static AUAudioUnitPreset* getCurrentPreset (id self, SEL) { return _this (self)->getCurrentPreset(); } static void setCurrentPreset (id self, SEL, AUAudioUnitPreset* preset) { return _this (self)->setCurrentPreset (preset); } - static NSDictionary* getFullState (id self, SEL) { return _this (self)->getFullState(); } + static NSDictionary* getFullState (id self, SEL) { return _this (self)->getFullState(); } static void setFullState (id self, SEL, NSDictionary* state) { return _this (self)->setFullState (state); } static NSTimeInterval getLatency (id self, SEL) { return _this (self)->getLatency(); } static NSTimeInterval getTailTime (id self, SEL) { return _this (self)->getTailTime(); } static BOOL getCanProcessInPlace (id self, SEL) { return _this (self)->getCanProcessInPlace(); } static BOOL getRenderingOffline (id self, SEL) { return _this (self)->getRenderingOffline(); } static void setRenderingOffline (id self, SEL, BOOL renderingOffline) { _this (self)->setRenderingOffline (renderingOffline); } - static NSArray* getChannelCapabilities (id self, SEL) { return _this (self)->getChannelCapabilities(); } + static NSArray* getChannelCapabilities (id self, SEL) { return _this (self)->getChannelCapabilities(); } }; - static JuceAudioUnitv3Base* create (AUAudioUnit* audioUnit, AudioComponentDescription descr, AudioComponentInstantiationOptions options, NSError** error); + static JuceAudioUnitv3Base* create (AUAudioUnit*, AudioComponentDescription, AudioComponentInstantiationOptions, NSError**); //============================================================================== static Class audioUnitObjCClass; @@ -296,15 +295,18 @@ JuceAudioUnitv3Base::Class JuceAudioUnitv3Base::audioUnitObjCClass; //============================================================================== //=========================== The actual AudioUnit ============================= //============================================================================== -class JuceAudioUnitv3 : public JuceAudioUnitv3Base, public AudioProcessorListener, public AudioPlayHead +class JuceAudioUnitv3 : public JuceAudioUnitv3Base, + public AudioProcessorListener, + public AudioPlayHead { public: - JuceAudioUnitv3 (const AudioProcessorHolder::Ptr& jFilter, + JuceAudioUnitv3 (const AudioProcessorHolder::Ptr& processor, const AudioComponentDescription& descr, AudioComponentInstantiationOptions options, NSError** error) : JuceAudioUnitv3Base (descr, options, error), - juceFilter (jFilter), busUtils (**juceFilter, true, 8), + processorHolder (processor), + busUtils (**processorHolder, true, 8), mapper (busUtils) { init(); @@ -312,19 +314,34 @@ public: JuceAudioUnitv3 (AUAudioUnit* audioUnit, AudioComponentDescription, AudioComponentInstantiationOptions, NSError**) : JuceAudioUnitv3Base (audioUnit), - juceFilter (new AudioProcessorHolder (createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3))), - busUtils (**juceFilter, true, 8), + processorHolder (new AudioProcessorHolder (createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3))), + busUtils (**processorHolder, true, 8), mapper (busUtils) { init(); } + ~JuceAudioUnitv3() + { + auto& processor = getAudioProcessor(); + processor.removeListener (this); + + if (AudioProcessorEditor* editor = processor.getActiveEditor()) + processor.editorBeingDeleted (editor); + + if (editorObserverToken != nullptr) + { + [paramTree removeParameterObserver: editorObserverToken]; + editorObserverToken = nullptr; + } + } + //============================================================================== void init() { busUtils.init(); - (*juceFilter)->setPlayHead (this); + getAudioProcessor().setPlayHead (this); totalInChannels = busUtils.findTotalNumChannels (true); totalOutChannels = busUtils.findTotalNumChannels (false); @@ -347,10 +364,11 @@ public: internalRenderBlock = CreateObjCBlock (this, &JuceAudioUnitv3::renderCallback); const AUAudioFrameCount maxFrames = [getAudioUnit() maximumFramesToRender]; - (*juceFilter)->setRateAndBufferSizeDetails (kDefaultSampleRate, static_cast (maxFrames)); - (*juceFilter)->prepareToPlay (kDefaultSampleRate, static_cast (maxFrames)); - (*juceFilter)->addListener (this); + auto& processor = getAudioProcessor(); + processor.setRateAndBufferSizeDetails (kDefaultSampleRate, static_cast (maxFrames)); + processor.prepareToPlay (kDefaultSampleRate, static_cast (maxFrames)); + processor.addListener (this); addParameters(); addPresets(); @@ -360,20 +378,21 @@ public: } //============================================================================== + AudioProcessor& getAudioProcessor() const noexcept { return **processorHolder; } AUAudioUnitBusArray* getInputBusses() override { return inputBusses; } AUAudioUnitBusArray* getOutputBusses() override { return outputBusses; } AUParameterTree* getParameterTree() override { return paramTree; } AUInternalRenderBlock getInternalRenderBlock() override { return internalRenderBlock; } NSArray* getFactoryPresets() override { return factoryPresets; } - bool getRenderingOffline() override { return (*juceFilter)->isNonRealtime(); } - void setRenderingOffline (bool offline) override { (*juceFilter)->setNonRealtime (offline); } - NSArray* getChannelCapabilities() override { return channelCapabilities; } + bool getRenderingOffline() override { return getAudioProcessor().isNonRealtime(); } + void setRenderingOffline (bool offline) override { getAudioProcessor().setNonRealtime (offline); } + NSArray* getChannelCapabilities() override { return channelCapabilities; } //============================================================================== AUAudioUnitPreset* getCurrentPreset() override { const int n = static_cast ([factoryPresets count]); - const int idx = static_cast ((*juceFilter)->getCurrentProgram()); + const int idx = static_cast (getAudioProcessor().getCurrentProgram()); if (idx < n) return [factoryPresets objectAtIndex:static_cast (idx)]; @@ -385,8 +404,9 @@ public: { const int n = static_cast ([factoryPresets count]); const int idx = static_cast ([preset number]); + if (isPositiveAndBelow (idx, n)) - (*juceFilter)->setCurrentProgram (idx); + getAudioProcessor().setCurrentProgram (idx); } //============================================================================== @@ -402,7 +422,8 @@ public: } juce::MemoryBlock state; - (*juceFilter)->getCurrentProgramStateInformation (state); + getAudioProcessor().getCurrentProgramStateInformation (state); + if (state.getSize() > 0) { NSData* ourState = [[NSData alloc] initWithBytes: state.getData() @@ -447,7 +468,7 @@ public: const juce::uint8* const rawBytes = reinterpret_cast< const juce::uint8* const> ([data bytes]); if (numBytes > 0) - (*juceFilter)->setCurrentProgramStateInformation (rawBytes, numBytes); + getAudioProcessor().setCurrentProgramStateInformation (rawBytes, numBytes); } } @@ -498,8 +519,9 @@ public: double sampleRate = (jmax (busUtils.getBusCount (true), busUtils.getBusCount (false)) > 0 ? [[[([inputBusses count] > 0 ? inputBusses : outputBusses) objectAtIndexedSubscript: 0] format] sampleRate] : 44100.0); - (*juceFilter)->setRateAndBufferSizeDetails (sampleRate, static_cast (maxFrames)); - (*juceFilter)->prepareToPlay (sampleRate, static_cast (maxFrames)); + auto& processor = getAudioProcessor(); + processor.setRateAndBufferSizeDetails (sampleRate, static_cast (maxFrames)); + processor.prepareToPlay (sampleRate, static_cast (maxFrames)); zeromem (&lastAudioHead, sizeof (lastAudioHead)); hostMusicalContextCallback = [getAudioUnit() musicalContextBlock]; @@ -515,7 +537,7 @@ public: hostMusicalContextCallback = nullptr; hostTransportStateCallback = nullptr; - (*juceFilter)->releaseResources(); + getAudioProcessor().releaseResources(); audioBuffer.release(); inBusBuffers. clear(); @@ -549,7 +571,7 @@ public: if (newLayout.size() != newNumChannels) return false; - bool success = (*juceFilter)->setPreferredBusArrangement (isInput, busIdx, newLayout); + bool success = getAudioProcessor().setPreferredBusArrangement (isInput, busIdx, newLayout); totalInChannels = busUtils.findTotalNumChannels (true); totalOutChannels = busUtils.findTotalNumChannels (false); @@ -571,8 +593,7 @@ public: if (AUParameter* param = [paramTree parameterWithAddress: static_cast (idx)]) { if (editorObserverToken != nullptr) - [param setValue: newValue - originator: editorObserverToken]; + [param setValue: newValue originator: editorObserverToken]; else [param setValue: newValue]; } @@ -581,11 +602,11 @@ public: //============================================================================== NSTimeInterval getLatency() override { - double samples = static_cast ((*juceFilter)->getLatencySamples()); - return samples / (*juceFilter)->getSampleRate(); + auto& p = getAudioProcessor(); + return p.getLatencySamples() / p.getSampleRate(); } - NSTimeInterval getTailTime() override { return (*juceFilter)->getTailLengthSeconds(); } + NSTimeInterval getTailTime() override { return getAudioProcessor().getTailLengthSeconds(); } //============================================================================== bool getCurrentPosition (CurrentPositionInfo& info) override @@ -595,7 +616,7 @@ public: info = lastAudioHead; info.timeInSamples = (int64) (lastTimeStamp.mSampleTime + 0.5); - info.timeInSeconds = info.timeInSamples / (*juceFilter)->getSampleRate(); + info.timeInSeconds = info.timeInSamples / getAudioProcessor().getSampleRate(); switch (lastTimeStamp.mSMPTETime.mType) { @@ -637,16 +658,18 @@ public: if (hostTransportStateCallback != nullptr) { AUHostTransportStateBlock transportStateCallback = hostTransportStateCallback; + if (transportStateCallback (&flags, &outCurrentSampleInTimeLine, &outCycleStartBeat, &outCycleEndBeat)) { transportStateCallSucceeded = true; - info.isPlaying = ((flags & AUHostTransportStateMoving) != 0); - info.timeInSamples = (int64) (outCurrentSampleInTimeLine + 0.5); - info.timeInSeconds = info.timeInSamples / (*juceFilter)->getSampleRate(); - info.isLooping = ((flags & AUHostTransportStateCycling) != 0); - info.isRecording = ((flags & AUHostTransportStateRecording) != 0); - info.ppqLoopStart = outCycleStartBeat; - info.ppqLoopEnd = outCycleEndBeat; + + info.timeInSamples = (int64) (outCurrentSampleInTimeLine + 0.5); + info.timeInSeconds = info.timeInSamples / getAudioProcessor().getSampleRate(); + info.isPlaying = ((flags & AUHostTransportStateMoving) != 0); + info.isLooping = ((flags & AUHostTransportStateCycling) != 0); + info.isRecording = ((flags & AUHostTransportStateRecording) != 0); + info.ppqLoopStart = outCycleStartBeat; + info.ppqLoopEnd = outCycleEndBeat; } } @@ -656,29 +679,10 @@ public: return true; } -protected: - - //============================================================================== - virtual ~JuceAudioUnitv3() - { - (*juceFilter)->removeListener (this); - - if (AudioProcessorEditor* editor = (*juceFilter)->getActiveEditor()) - (*juceFilter)->editorBeingDeleted (editor); - - if (editorObserverToken != nullptr) - { - [paramTree removeParameterObserver: editorObserverToken]; - editorObserverToken = nullptr; - } - } - private: - //============================================================================== - class BusBuffer + struct BusBuffer { - public: BusBuffer (AUAudioUnitBus* bus, int maxFramesPerBuffer) : auBus (bus), bufferList (nullptr), maxFrames (maxFramesPerBuffer), @@ -719,7 +723,7 @@ private: void prepare (UInt32 nFrames, const AudioBufferList* other = nullptr) noexcept { const int numBuffers = isInterleaved ? 1 : numberOfChannels; - const bool isCompatible = compatible (other); + const bool isCompatible = isCompatibleWith (other); bufferList->mNumberBuffers = static_cast (numBuffers); @@ -727,13 +731,14 @@ private: { const UInt32 bufferChannels = static_cast (isInterleaved ? numberOfChannels : 1); bufferList->mBuffers[i].mNumberChannels = bufferChannels; - bufferList->mBuffers[i].mData = (isCompatible ? other->mBuffers[i].mData : scratchBuffer.getWritePointer (i)); + bufferList->mBuffers[i].mData = (isCompatible ? other->mBuffers[i].mData + : scratchBuffer.getWritePointer (i)); bufferList->mBuffers[i].mDataByteSize = nFrames * bufferChannels * sizeof (float); } } //============================================================================== - bool compatible (const AudioBufferList* other) const noexcept + bool isCompatibleWith (const AudioBufferList* other) const noexcept { if (other == nullptr) return false; @@ -741,16 +746,17 @@ private: if (other->mNumberBuffers > 0) { const bool otherInterleaved = AudioUnitHelpers::isAudioBufferInterleaved (*other); - const int otherChannels = static_cast (otherInterleaved ? other->mBuffers[0].mNumberChannels : other->mNumberBuffers); + const int otherChannels = static_cast (otherInterleaved ? other->mBuffers[0].mNumberChannels + : other->mNumberBuffers); - return (otherInterleaved == isInterleaved && numberOfChannels == otherChannels); + return otherInterleaved == isInterleaved + && numberOfChannels == otherChannels; } - return (numberOfChannels == 0); + return numberOfChannels == 0; } private: - //============================================================================== AUAudioUnitBus* auBus; HeapBlock bufferListStorage; AudioBufferList* bufferList; @@ -793,11 +799,13 @@ private: overviewParams = [[NSMutableArray alloc] init]; - const int n = (*juceFilter)->getNumParameters(); + auto& processor = getAudioProcessor(); + const int n = processor.getNumParameters(); + for (int idx = 0; idx < n; ++idx) { - const String identifier = String (idx); - const String name = (*juceFilter)->getParameterName (idx); + const String identifier (idx); + const String name = processor.getParameterName (idx); AudioUnitParameterOptions flags = (UInt32) (kAudioUnitParameterFlag_IsWritable | kAudioUnitParameterFlag_IsReadable @@ -809,10 +817,10 @@ private: #endif // set whether the param is automatable (unnamed parameters aren't allowed to be automated) - if (name.isEmpty() || ! (*juceFilter)->isParameterAutomatable (idx)) + if (name.isEmpty() || ! processor.isParameterAutomatable (idx)) flags |= kAudioUnitParameterFlag_NonRealTime; - if ((*juceFilter)->isMetaParameter (idx)) + if (processor.isMetaParameter (idx)) flags |= kAudioUnitParameterFlag_IsGlobalMeta; AUParameterAddress address = static_cast (idx); @@ -840,7 +848,7 @@ private: [paramTree setImplementorValueObserver: paramObserver]; [paramTree setImplementorValueProvider: paramProvider]; - if ((*juceFilter)->hasEditor()) + if (processor.hasEditor()) { editorParamObserver = CreateObjCBlock (this, &JuceAudioUnitv3::valueChangedForObserver); editorObserverToken = [paramTree tokenByAddingParameterObserver: editorParamObserver]; @@ -851,11 +859,11 @@ private: { factoryPresets = [[NSMutableArray alloc] init]; - const int n = (*juceFilter)->getNumPrograms(); + const int n = getAudioProcessor().getNumPrograms(); for (int idx = 0; idx < n; ++idx) { - String name = (*juceFilter)->getProgramName (idx); + String name = getAudioProcessor().getProgramName (idx); ScopedPointer preset = [[AUAudioUnitPreset alloc] init]; [preset setName: juceStringToNS (name)]; @@ -875,7 +883,8 @@ private: const AUAudioFrameCount maxFrames = [getAudioUnit() maximumFramesToRender]; for (int busIdx = 0; busIdx < n; ++busIdx) - busBuffers.add (new BusBuffer ([(isInput ? inputBusses : outputBusses) objectAtIndexedSubscript: static_cast (busIdx)], static_cast (maxFrames))); + busBuffers.add (new BusBuffer ([(isInput ? inputBusses : outputBusses) objectAtIndexedSubscript: static_cast (busIdx)], + static_cast (maxFrames))); } void processEvents (const AURenderEvent *__nullable realtimeEventListHead, int numParams, AUEventSampleTime startTime) @@ -884,23 +893,26 @@ private: { switch (event->head.eventType) { - case AURenderEventMIDI: + case AURenderEventMIDI: { const AUMIDIEvent& midiEvent = event->MIDI; midiMessages.addEvent (midiEvent.data, midiEvent.length, static_cast (midiEvent.eventSampleTime - startTime)); } break; - case AURenderEventParameter: - case AURenderEventParameterRamp: + + case AURenderEventParameter: + case AURenderEventParameterRamp: { const AUParameterEvent& paramEvent = event->parameter; const int idx = static_cast (paramEvent.parameterAddress); + if (isPositiveAndBelow (idx, numParams)) - (*juceFilter)->setParameter (idx, paramEvent.value); + getAudioProcessor().setParameter (idx, paramEvent.value); } break; - default: - break; + + default: + break; } } } @@ -909,10 +921,10 @@ private: NSInteger outputBusNumber, AudioBufferList* outputData, const AURenderEvent *__nullable realtimeEventListHead, AURenderPullInputBlock __nullable pullInputBlock) { - jassert (static_cast (frameCount) <= (*juceFilter)->getBlockSize()); + jassert (static_cast (frameCount) <= getAudioProcessor().getBlockSize()); // process params - const int numParams = (*juceFilter)->getNumParameters(); + const int numParams = getAudioProcessor().getNumParameters(); processEvents (realtimeEventListHead, numParams, static_cast (timestamp->mSampleTime)); if (lastTimeStamp.mSampleTime != timestamp->mSampleTime) @@ -960,6 +972,7 @@ private: // set buffer pointer to minimize copying { int chIdx = 0; + for (int busIdx = 0; busIdx < numOutputBuses; ++busIdx) { BusBuffer& busBuffer = *outBusBuffers[busIdx]; @@ -976,6 +989,7 @@ private: // use input pointers on remaining channels int channelCount = 0; + for (int busIdx = 0; chIdx < totalInChannels;) { busIdx = busUtils.getBusIdxForChannelIdx (true, chIdx, channelCount, busIdx); @@ -1009,52 +1023,50 @@ private: } // copy back - { - audioBuffer.pop (*outBusBuffers[(int) outputBusNumber]->get(), mapper.get (false, (int) outputBusNumber)); - } + audioBuffer.pop (*outBusBuffers[(int) outputBusNumber]->get(), + mapper.get (false, (int) outputBusNumber)); return noErr; } void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiBuffer) noexcept { - const ScopedLock sl ((*juceFilter)->getCallbackLock()); + auto& processor = getAudioProcessor(); + const ScopedLock sl (processor.getCallbackLock()); - if ((*juceFilter)->isSuspended()) - { + if (processor.isSuspended()) buffer.clear(); - } else if ([au shouldBypassEffect]) - { - (*juceFilter)->processBlockBypassed (buffer, midiBuffer); - } + processor.processBlockBypassed (buffer, midiBuffer); else - { - (*juceFilter)->processBlock (buffer, midiBuffer); - } + processor.processBlock (buffer, midiBuffer); } //============================================================================== - void valueChangedFromHost (AUParameter *param, AUValue value) + void valueChangedFromHost (AUParameter* param, AUValue value) { if (param != nullptr) { const int idx = static_cast ([param address]); - if (isPositiveAndBelow (idx, (*juceFilter)->getNumParameters())) - (*juceFilter)->setParameter (idx, value); + auto& processor = getAudioProcessor(); + + if (isPositiveAndBelow (idx, processor.getNumParameters())) + processor.setParameter (idx, value); } } - AUValue getValue(AUParameter *param) + AUValue getValue (AUParameter* param) { if (param != nullptr) { const int idx = static_cast ([param address]); - if (isPositiveAndBelow (idx, (*juceFilter)->getNumParameters())) - return (*juceFilter)->getParameter (idx); + auto& processor = getAudioProcessor(); + + if (isPositiveAndBelow (idx, processor.getNumParameters())) + return processor.getParameter (idx); } - return 0.f; + return 0; } void valueChangedForObserver(AUParameterAddress, AUValue) @@ -1065,7 +1077,7 @@ private: //============================================================================== static const double kDefaultSampleRate; - AudioProcessorHolder::Ptr juceFilter; + AudioProcessorHolder::Ptr processorHolder; PluginBusUtilities busUtils; int totalInChannels, totalOutChannels; @@ -1115,8 +1127,8 @@ class JuceAUViewController { public: - JuceAUViewController (AUViewController * p) - : myself (p), juceFilter (nullptr), preferredSize (1.f, 1.f) + JuceAUViewController (AUViewController* p) + : myself (p), processorHolder (nullptr), preferredSize (1.0f, 1.0f) { jassert (MessageManager::getInstance()->isThisTheMessageThread()); @@ -1129,26 +1141,23 @@ public: jassert (MessageManager::getInstance()->isThisTheMessageThread()); } - //============================================================================== - AUViewController * getController() noexcept { return myself; } - - //============================================================================== void loadView() { jassert (MessageManager::getInstance()->isThisTheMessageThread()); - AudioProcessor* filter = createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3); - if (filter != nullptr) + if (AudioProcessor* p = createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3)) { - juceFilter = new AudioProcessorHolder (filter); - if ((*juceFilter)->hasEditor()) + processorHolder = new AudioProcessorHolder (p); + auto& processor = getAudioProcessor(); + + if (processor.hasEditor()) { - if (AudioProcessorEditor* editor = (*juceFilter)->createEditorIfNeeded()) + if (AudioProcessorEditor* editor = processor.createEditorIfNeeded()) { preferredSize = editor->getBounds(); - IOS_MAC_VIEW* view = [[[IOS_MAC_VIEW alloc] initWithFrame: (convertToCGRect (editor->getBounds()))] autorelease]; + JUCE_IOS_MAC_VIEW* view = [[[JUCE_IOS_MAC_VIEW alloc] initWithFrame: convertToCGRect (editor->getBounds())] autorelease]; [myself setView: view]; editor->setVisible (true); @@ -1160,13 +1169,13 @@ public: void viewDidLayoutSubviews() { - if (juceFilter != nullptr && [myself view] != nullptr) + if (processorHolder != nullptr && [myself view] != nullptr) { - if (AudioProcessorEditor* editor = (*juceFilter)->getActiveEditor()) + if (AudioProcessorEditor* editor = getAudioProcessor().getActiveEditor()) { editor->setBounds (convertToRectInt ([[myself view] bounds])); - if (IOS_MAC_VIEW* peerView = [[[myself view] subviews] objectAtIndex: 0]) + if (JUCE_IOS_MAC_VIEW* peerView = [[[myself view] subviews] objectAtIndex: 0]) { #if JUCE_IOS [peerView setNeedsDisplay]; @@ -1178,15 +1187,16 @@ public: } } - CGSize getPreferredContentSize() + CGSize getPreferredContentSize() const { - return CGSizeMake (static_cast (preferredSize.getWidth()), static_cast (preferredSize.getHeight())); + return CGSizeMake (static_cast (preferredSize.getWidth()), + static_cast (preferredSize.getHeight())); } //============================================================================== AUAudioUnit* createAudioUnit (const AudioComponentDescription& descr, NSError** error) { - AUAudioUnit* retval = nullptr; + AUAudioUnit* retval = nil; if (! MessageManager::getInstance()->isThisTheMessageThread()) { @@ -1194,7 +1204,7 @@ public: // AUv3 headers say that we may block this thread and that the message thread is guaranteed // to be unblocked - struct AUCreator : public CallbackMessage + struct AUCreator : public CallbackMessage { JuceAUViewController& owner; AudioComponentDescription pDescr; @@ -1207,9 +1217,6 @@ public: : owner (parent), pDescr (paramDescr), pError (paramError), outAU (outputAU), e (event) {} - ~AUCreator() - {} - void messageCallback() override { outAU = owner.createAudioUnitOnMessageThread (pDescr, pError); @@ -1227,38 +1234,42 @@ public: } private: + //============================================================================== + AUViewController* myself; + AudioProcessorHolder::Ptr processorHolder; + Rectangle preferredSize; //============================================================================== AUAudioUnit* createAudioUnitOnMessageThread (const AudioComponentDescription& descr, NSError** error) { jassert (MessageManager::getInstance()->isThisTheMessageThread()); - // this will call [view load] and ensure that the juce filter has been instantiated - [myself view]; - if (juceFilter == nullptr) + [myself view]; // this will call [view load] and ensure that the AudioProcessor has been instantiated + + if (processorHolder == nullptr) return nullptr; - return (new JuceAudioUnitv3 (juceFilter, descr, 0, error))->getAudioUnit(); + return (new JuceAudioUnitv3 (processorHolder, descr, 0, error))->getAudioUnit(); } - //============================================================================== - AUViewController * myself; - AudioProcessorHolder::Ptr juceFilter; - Rectangle preferredSize; + AudioProcessor& getAudioProcessor() const noexcept { return **processorHolder; } }; //============================================================================== // necessary glue code -@interface JUCE_VIEWCONTROLLER_OBJC_NAME (JucePlugin_AUExportPrefix) : AUViewController +@interface JUCE_VIEWCONTROLLER_OBJC_NAME (JucePlugin_AUExportPrefix) : AUViewController @end -@implementation JUCE_VIEWCONTROLLER_OBJC_NAME (JucePlugin_AUExportPrefix) { + +@implementation JUCE_VIEWCONTROLLER_OBJC_NAME (JucePlugin_AUExportPrefix) +{ ScopedPointer cpp; } -- (instancetype)initWithNibName:(nullable NSString *)nib bundle:(nullable NSBundle *)bndl { self = [super initWithNibName:nib bundle:bndl]; cpp = new JuceAUViewController (self); return self;} -- (void) loadView { cpp->loadView(); } + +- (instancetype) initWithNibName: (nullable NSString*) nib bundle: (nullable NSBundle*) bndl { self = [super initWithNibName: nib bundle: bndl]; cpp = new JuceAUViewController (self); return self;} +- (void) loadView { cpp->loadView(); } - (AUAudioUnit *)createAudioUnitWithComponentDescription:(AudioComponentDescription)desc error:(NSError **)error { return cpp->createAudioUnit (desc, error); } - (CGSize) preferredContentSize { return cpp->getPreferredContentSize(); } -- (void)viewDidLayoutSubviews { return cpp->viewDidLayoutSubviews(); } +- (void)viewDidLayoutSubviews { return cpp->viewDidLayoutSubviews(); } @end #pragma clang diagnostic pop diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index c45e90a2dc..b473b53909 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -1467,7 +1467,7 @@ public: } #if JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES - void embedViewController (IOS_MAC_VIEW* pluginView, const CGSize& size) + void embedViewController (JUCE_IOS_MAC_VIEW* pluginView, const CGSize& size) { wrapper.setView (pluginView); waitingForViewCallback = false; @@ -1516,7 +1516,7 @@ private: if (! plugin.initialiseAudioUnit()) return false; - IOS_MAC_VIEW* pluginView = nil; + JUCE_IOS_MAC_VIEW* pluginView = nil; UInt32 dataSize = 0; Boolean isWritable = false; @@ -1616,10 +1616,10 @@ private: struct AsyncViewControllerCallback : public CallbackMessage { AudioUnitPluginWindowCocoa* owner; - IOS_MAC_VIEW* controllerView; + JUCE_IOS_MAC_VIEW* controllerView; CGSize size; - AsyncViewControllerCallback (AudioUnitPluginWindowCocoa* plugInWindow, IOS_MAC_VIEW* inView, + AsyncViewControllerCallback (AudioUnitPluginWindowCocoa* plugInWindow, JUCE_IOS_MAC_VIEW* inView, const CGSize& preferredSize) : owner (plugInWindow), controllerView ([inView retain]), size (preferredSize) {} diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 390689f453..d76fb2ef64 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -56,16 +56,20 @@ #define JUCE_PLUGINHOST_VST3 0 #endif -#if JUCE_IOS -#define IOS_MAC_VIEW UIView -#elif JUCE_MAC -#define IOS_MAC_VIEW NSView -#endif - //============================================================================== namespace juce { +#if JUCE_IOS + #define JUCE_IOS_MAC_VIEW UIView + typedef UIViewComponent ViewComponentBaseClass; +#elif JUCE_MAC + #define JUCE_IOS_MAC_VIEW NSView + typedef NSViewComponent ViewComponentBaseClass; +#else + #error +#endif + static inline bool arrayContainsPlugin (const OwnedArray& list, const PluginDescription& desc) { @@ -77,14 +81,10 @@ static inline bool arrayContainsPlugin (const OwnedArray& lis } #if JUCE_MAC || JUCE_IOS + //============================================================================== -struct AutoResizingNSViewComponent : -#if JUCE_MAC - public NSViewComponent, -#else - public UIViewComponent, -#endif - private AsyncUpdater +struct AutoResizingNSViewComponent : public ViewComponentBaseClass, + private AsyncUpdater { AutoResizingNSViewComponent() : recursive (false) {} @@ -113,16 +113,16 @@ struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewCompone { AutoResizingNSViewComponentWithParent() { - IOS_MAC_VIEW* v = [[IOS_MAC_VIEW alloc] init]; + JUCE_IOS_MAC_VIEW* v = [[JUCE_IOS_MAC_VIEW alloc] init]; setView (v); [v release]; startTimer (30); } - IOS_MAC_VIEW* getChildView() const + JUCE_IOS_MAC_VIEW* getChildView() const { - if (IOS_MAC_VIEW* parent = (IOS_MAC_VIEW*) getView()) + if (JUCE_IOS_MAC_VIEW* parent = (JUCE_IOS_MAC_VIEW*) getView()) if ([[parent subviews] count] > 0) return [[parent subviews] objectAtIndex: 0]; @@ -131,7 +131,7 @@ struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewCompone void timerCallback() override { - if (IOS_MAC_VIEW* child = getChildView()) + if (JUCE_IOS_MAC_VIEW* child = getChildView()) { stopTimer(); setView (child);