mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
AUv3 Client: Remove unnecessary base class
This commit is contained in:
parent
064fb6fa53
commit
a1e8aa4278
1 changed files with 240 additions and 340 deletions
|
|
@ -103,260 +103,10 @@ private:
|
|||
AudioProcessorHolder& operator= (AudioProcessorHolder&) = delete;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JuceAudioUnitv3Base
|
||||
{
|
||||
public:
|
||||
JuceAudioUnitv3Base (const AudioComponentDescription& descr,
|
||||
AudioComponentInstantiationOptions options,
|
||||
NSError** error)
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wobjc-method-access")
|
||||
: au ([getClass().createInstance() initWithComponentDescription: descr
|
||||
options: options
|
||||
error: error
|
||||
juceClass: this])
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
{}
|
||||
|
||||
JuceAudioUnitv3Base (AUAudioUnit* audioUnit) : au (audioUnit)
|
||||
{
|
||||
jassert (MessageManager::getInstance()->isThisTheMessageThread());
|
||||
initialiseJuce_GUI();
|
||||
}
|
||||
|
||||
virtual ~JuceAudioUnitv3Base() = default;
|
||||
|
||||
//==============================================================================
|
||||
AUAudioUnit* getAudioUnit() noexcept { return au; }
|
||||
|
||||
//==============================================================================
|
||||
virtual void reset() = 0;
|
||||
|
||||
//==============================================================================
|
||||
virtual AUAudioUnitPreset* getCurrentPreset() = 0;
|
||||
virtual void setCurrentPreset (AUAudioUnitPreset*) = 0;
|
||||
virtual NSArray<AUAudioUnitPreset*>* getFactoryPresets() = 0;
|
||||
|
||||
virtual NSDictionary<NSString*, id>* getFullState()
|
||||
{
|
||||
return ObjCMsgSendSuper<AUAudioUnit, NSDictionary<NSString*, id>*> (getAudioUnit(), @selector (fullState));
|
||||
}
|
||||
|
||||
virtual void setFullState (NSDictionary<NSString*, id>* state)
|
||||
{
|
||||
ObjCMsgSendSuper<AUAudioUnit, void> (getAudioUnit(), @selector (setFullState:), state);
|
||||
}
|
||||
|
||||
virtual AUParameterTree* getParameterTree() = 0;
|
||||
virtual NSArray<NSNumber*>* parametersForOverviewWithCount (int) = 0;
|
||||
|
||||
//==============================================================================
|
||||
virtual NSTimeInterval getLatency() = 0;
|
||||
virtual NSTimeInterval getTailTime() = 0;
|
||||
|
||||
//==============================================================================
|
||||
virtual AUAudioUnitBusArray* getInputBusses() = 0;
|
||||
virtual AUAudioUnitBusArray* getOutputBusses() = 0;
|
||||
virtual NSArray<NSNumber*>* getChannelCapabilities() = 0;
|
||||
virtual bool shouldChangeToFormat (AVAudioFormat*, AUAudioUnitBus*) = 0;
|
||||
|
||||
//==============================================================================
|
||||
virtual int getVirtualMIDICableCount() = 0;
|
||||
virtual bool getSupportsMPE() = 0;
|
||||
virtual NSArray<NSString*>* getMIDIOutputNames() = 0;
|
||||
|
||||
//==============================================================================
|
||||
virtual AUInternalRenderBlock getInternalRenderBlock() = 0;
|
||||
virtual bool getCanProcessInPlace() { return false; }
|
||||
virtual bool getRenderingOffline() = 0;
|
||||
virtual void setRenderingOffline (bool offline) = 0;
|
||||
|
||||
virtual bool getShouldBypassEffect()
|
||||
{
|
||||
return (ObjCMsgSendSuper<AUAudioUnit, BOOL> (getAudioUnit(), @selector (shouldBypassEffect)) == YES);
|
||||
}
|
||||
|
||||
virtual void setShouldBypassEffect (bool shouldBypass)
|
||||
{
|
||||
ObjCMsgSendSuper<AUAudioUnit, void> (getAudioUnit(), @selector (setShouldBypassEffect:), shouldBypass ? YES : NO);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
virtual NSString* getContextName() const = 0;
|
||||
virtual void setContextName (NSString*) = 0;
|
||||
|
||||
virtual bool allocateRenderResourcesAndReturnError (NSError **outError)
|
||||
{
|
||||
return (ObjCMsgSendSuper<AUAudioUnit, BOOL, NSError**> (getAudioUnit(), @selector (allocateRenderResourcesAndReturnError:), outError) == YES);
|
||||
}
|
||||
|
||||
virtual void deallocateRenderResources()
|
||||
{
|
||||
ObjCMsgSendSuper<AUAudioUnit, void> (getAudioUnit(), @selector (deallocateRenderResources));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
virtual NSIndexSet* getSupportedViewConfigurations (NSArray<AUAudioUnitViewConfiguration*>*) = 0;
|
||||
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
virtual void selectViewConfiguration (AUAudioUnitViewConfiguration*) = 0;
|
||||
|
||||
private:
|
||||
struct Class : public ObjCClass<AUAudioUnit>
|
||||
{
|
||||
Class() : ObjCClass<AUAudioUnit> ("AUAudioUnit_")
|
||||
{
|
||||
addIvar<JuceAudioUnitv3Base*> ("cppObject");
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
addMethod (@selector (initWithComponentDescription:options:error:juceClass:), [] (id _self,
|
||||
SEL,
|
||||
AudioComponentDescription descr,
|
||||
AudioComponentInstantiationOptions options,
|
||||
NSError** error,
|
||||
JuceAudioUnitv3Base* juceAU)
|
||||
{
|
||||
AUAudioUnit* self = _self;
|
||||
|
||||
self = ObjCMsgSendSuper<AUAudioUnit, AUAudioUnit*, AudioComponentDescription,
|
||||
AudioComponentInstantiationOptions, NSError**> (self, @selector(initWithComponentDescription:options:error:), descr, options, error);
|
||||
|
||||
|
||||
setThis (self, juceAU);
|
||||
return self;
|
||||
});
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
addMethod (@selector (initWithComponentDescription:options:error:), [] (id _self,
|
||||
SEL,
|
||||
AudioComponentDescription descr,
|
||||
AudioComponentInstantiationOptions options,
|
||||
NSError** error)
|
||||
{
|
||||
AUAudioUnit* self = _self;
|
||||
|
||||
self = ObjCMsgSendSuper<AUAudioUnit, AUAudioUnit*, AudioComponentDescription,
|
||||
AudioComponentInstantiationOptions, NSError**> (self, @selector (initWithComponentDescription:options:error:), descr, options, error);
|
||||
|
||||
JuceAudioUnitv3Base* juceAU = JuceAudioUnitv3Base::create (self, descr, options, error);
|
||||
|
||||
setThis (self, juceAU);
|
||||
return self;
|
||||
});
|
||||
|
||||
addMethod (@selector (dealloc), [] (id self, SEL)
|
||||
{
|
||||
if (! MessageManager::getInstance()->isThisTheMessageThread())
|
||||
{
|
||||
WaitableEvent deletionEvent;
|
||||
|
||||
struct AUDeleter : public CallbackMessage
|
||||
{
|
||||
AUDeleter (id selfToDelete, WaitableEvent& event)
|
||||
: parentSelf (selfToDelete), parentDeletionEvent (event)
|
||||
{
|
||||
}
|
||||
|
||||
void messageCallback() override
|
||||
{
|
||||
delete _this (parentSelf);
|
||||
parentDeletionEvent.signal();
|
||||
}
|
||||
|
||||
id parentSelf;
|
||||
WaitableEvent& parentDeletionEvent;
|
||||
};
|
||||
|
||||
(new AUDeleter (self, deletionEvent))->post();
|
||||
deletionEvent.wait (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete _this (self);
|
||||
}
|
||||
});
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (reset), [] (id self, SEL) { return _this (self)->reset(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (currentPreset), [] (id self, SEL) { return _this (self)->getCurrentPreset(); });
|
||||
addMethod (@selector (setCurrentPreset:), [] (id self, SEL, AUAudioUnitPreset* preset) { return _this (self)->setCurrentPreset (preset); });
|
||||
addMethod (@selector (factoryPresets), [] (id self, SEL) { return _this (self)->getFactoryPresets(); });
|
||||
addMethod (@selector (fullState), [] (id self, SEL) { return _this (self)->getFullState(); });
|
||||
addMethod (@selector (setFullState:), [] (id self, SEL, NSDictionary<NSString *, id>* state) { return _this (self)->setFullState (state); });
|
||||
addMethod (@selector (parameterTree), [] (id self, SEL) { return _this (self)->getParameterTree(); });
|
||||
addMethod (@selector (parametersForOverviewWithCount:), [] (id self, SEL, NSInteger count) { return _this (self)->parametersForOverviewWithCount (static_cast<int> (count)); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (latency), [] (id self, SEL) { return _this (self)->getLatency(); });
|
||||
addMethod (@selector (tailTime), [] (id self, SEL) { return _this (self)->getTailTime(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (inputBusses), [] (id self, SEL) { return _this (self)->getInputBusses(); });
|
||||
addMethod (@selector (outputBusses), [] (id self, SEL) { return _this (self)->getOutputBusses(); });
|
||||
addMethod (@selector (channelCapabilities), [] (id self, SEL) { return _this (self)->getChannelCapabilities(); });
|
||||
addMethod (@selector (shouldChangeToFormat:forBus:), [] (id self, SEL, AVAudioFormat* format, AUAudioUnitBus* bus) { return _this (self)->shouldChangeToFormat (format, bus) ? YES : NO; });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (virtualMIDICableCount), [] (id self, SEL) { return _this (self)->getVirtualMIDICableCount(); });
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
addMethod (@selector (supportsMPE), [] (id self, SEL) { return _this (self)->getSupportsMPE() ? YES : NO; });
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
addMethod (@selector (MIDIOutputNames), [] (id self, SEL) { return _this (self)->getMIDIOutputNames(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (internalRenderBlock), [] (id self, SEL) { return _this (self)->getInternalRenderBlock(); });
|
||||
addMethod (@selector (canProcessInPlace), [] (id self, SEL) { return _this (self)->getCanProcessInPlace() ? YES : NO; });
|
||||
addMethod (@selector (isRenderingOffline), [] (id self, SEL) { return _this (self)->getRenderingOffline() ? YES : NO; });
|
||||
addMethod (@selector (setRenderingOffline:), [] (id self, SEL, BOOL renderingOffline) { return _this (self)->setRenderingOffline (renderingOffline); });
|
||||
addMethod (@selector (shouldBypassEffect), [] (id self, SEL) { return _this (self)->getShouldBypassEffect() ? YES : NO; });
|
||||
addMethod (@selector (setShouldBypassEffect:), [] (id self, SEL, BOOL shouldBypass) { return _this (self)->setShouldBypassEffect (shouldBypass); });
|
||||
addMethod (@selector (allocateRenderResourcesAndReturnError:), [] (id self, SEL, NSError** error) { return _this (self)->allocateRenderResourcesAndReturnError (error) ? YES : NO; });
|
||||
addMethod (@selector (deallocateRenderResources), [] (id self, SEL) { return _this (self)->deallocateRenderResources(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (contextName), [] (id self, SEL) { return _this (self)->getContextName(); });
|
||||
addMethod (@selector (setContextName:), [](id self, SEL, NSString* str) { return _this (self)->setContextName (str); });
|
||||
|
||||
//==============================================================================
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
{
|
||||
addMethod (@selector (supportedViewConfigurations:), [] (id self, SEL, NSArray<AUAudioUnitViewConfiguration*>* configs) { return _this (self)->getSupportedViewConfigurations (configs); });
|
||||
addMethod (@selector (selectViewConfiguration:), [] (id self, SEL, AUAudioUnitViewConfiguration* config) { return _this (self)->selectViewConfiguration (config); });
|
||||
}
|
||||
|
||||
registerClass();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static JuceAudioUnitv3Base* _this (id self) { return getIvar<JuceAudioUnitv3Base*> (self, "cppObject"); }
|
||||
static void setThis (id self, JuceAudioUnitv3Base* cpp) { object_setInstanceVariable (self, "cppObject", cpp); }
|
||||
};
|
||||
|
||||
static JuceAudioUnitv3Base* create (AUAudioUnit*, AudioComponentDescription, AudioComponentInstantiationOptions, NSError**);
|
||||
|
||||
//==============================================================================
|
||||
static Class& getClass()
|
||||
{
|
||||
static Class result;
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
AUAudioUnit* au;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
//=========================== The actual AudioUnit =============================
|
||||
//==============================================================================
|
||||
class JuceAudioUnitv3 : public JuceAudioUnitv3Base,
|
||||
public AudioProcessorListener,
|
||||
class JuceAudioUnitv3 : public AudioProcessorListener,
|
||||
public AudioPlayHead,
|
||||
private AudioProcessorParameter::Listener
|
||||
{
|
||||
|
|
@ -365,16 +115,24 @@ public:
|
|||
const AudioComponentDescription& descr,
|
||||
AudioComponentInstantiationOptions options,
|
||||
NSError** error)
|
||||
: JuceAudioUnitv3Base (descr, options, error),
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wobjc-method-access")
|
||||
: au ([getClass().createInstance() initWithComponentDescription: descr
|
||||
options: options
|
||||
error: error
|
||||
juceClass: this]),
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
processorHolder (processor)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
JuceAudioUnitv3 (AUAudioUnit* audioUnit, AudioComponentDescription, AudioComponentInstantiationOptions, NSError**)
|
||||
: JuceAudioUnitv3Base (audioUnit),
|
||||
: au (audioUnit),
|
||||
processorHolder (new AudioProcessorHolder (createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3)))
|
||||
{
|
||||
jassert (MessageManager::getInstance()->isThisTheMessageThread());
|
||||
initialiseJuce_GUI();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +159,7 @@ public:
|
|||
inParameterChangedCallback = false;
|
||||
|
||||
AudioProcessor& processor = getAudioProcessor();
|
||||
const AUAudioFrameCount maxFrames = [getAudioUnit() maximumFramesToRender];
|
||||
const AUAudioFrameCount maxFrames = [au maximumFramesToRender];
|
||||
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
short configs[][2] = {JucePlugin_PreferredChannelConfigurations};
|
||||
|
|
@ -459,7 +217,7 @@ public:
|
|||
AudioProcessor& getAudioProcessor() const noexcept { return **processorHolder; }
|
||||
|
||||
//==============================================================================
|
||||
void reset() override
|
||||
void reset()
|
||||
{
|
||||
midiMessages.clear();
|
||||
lastTimeStamp.mSampleTime = std::numeric_limits<Float64>::max();
|
||||
|
|
@ -467,27 +225,27 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
AUAudioUnitPreset* getCurrentPreset() override
|
||||
AUAudioUnitPreset* getCurrentPreset()
|
||||
{
|
||||
return factoryPresets.getAtIndex (getAudioProcessor().getCurrentProgram());
|
||||
}
|
||||
|
||||
void setCurrentPreset (AUAudioUnitPreset* preset) override
|
||||
void setCurrentPreset (AUAudioUnitPreset* preset)
|
||||
{
|
||||
getAudioProcessor().setCurrentProgram (static_cast<int> ([preset number]));
|
||||
}
|
||||
|
||||
NSArray<AUAudioUnitPreset*>* getFactoryPresets() override
|
||||
NSArray<AUAudioUnitPreset*>* getFactoryPresets()
|
||||
{
|
||||
return factoryPresets.get();
|
||||
}
|
||||
|
||||
NSDictionary<NSString*, id>* getFullState() override
|
||||
NSDictionary<NSString*, id>* getFullState()
|
||||
{
|
||||
NSMutableDictionary<NSString*, id>* retval = [[NSMutableDictionary<NSString*, id> alloc] init];
|
||||
|
||||
{
|
||||
NSDictionary<NSString*, id>* superRetval = JuceAudioUnitv3Base::getFullState();
|
||||
auto* superRetval = ObjCMsgSendSuper<AUAudioUnit, NSDictionary<NSString*, id>*> (au, @selector (fullState));
|
||||
|
||||
if (superRetval != nullptr)
|
||||
[retval addEntriesFromDictionary:superRetval];
|
||||
|
|
@ -518,7 +276,7 @@ public:
|
|||
return [retval autorelease];
|
||||
}
|
||||
|
||||
void setFullState (NSDictionary<NSString*, id>* state) override
|
||||
void setFullState (NSDictionary<NSString*, id>* state)
|
||||
{
|
||||
if (state == nullptr)
|
||||
return;
|
||||
|
|
@ -530,7 +288,7 @@ public:
|
|||
[modifiedState removeObjectForKey: nsPresetKey];
|
||||
[nsPresetKey release];
|
||||
|
||||
JuceAudioUnitv3Base::setFullState (modifiedState);
|
||||
ObjCMsgSendSuper<AUAudioUnit, void> (au, @selector (setFullState:), state);
|
||||
|
||||
NSString* nsKey = [[NSString alloc] initWithUTF8String: JUCE_STATE_DICTIONARY_KEY];
|
||||
NSObject* obj = [modifiedState objectForKey: nsKey];
|
||||
|
|
@ -558,12 +316,12 @@ public:
|
|||
[modifiedState release];
|
||||
}
|
||||
|
||||
AUParameterTree* getParameterTree() override
|
||||
AUParameterTree* getParameterTree()
|
||||
{
|
||||
return paramTree.get();
|
||||
}
|
||||
|
||||
NSArray<NSNumber*>* parametersForOverviewWithCount (int count) override
|
||||
NSArray<NSNumber*>* parametersForOverviewWithCount (int count)
|
||||
{
|
||||
const int n = static_cast<int> ([overviewParams.get() count]);
|
||||
|
||||
|
|
@ -577,23 +335,23 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
NSTimeInterval getLatency() override
|
||||
NSTimeInterval getLatency()
|
||||
{
|
||||
auto& p = getAudioProcessor();
|
||||
return p.getLatencySamples() / p.getSampleRate();
|
||||
}
|
||||
|
||||
NSTimeInterval getTailTime() override
|
||||
NSTimeInterval getTailTime()
|
||||
{
|
||||
return getAudioProcessor().getTailLengthSeconds();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
AUAudioUnitBusArray* getInputBusses() override { return inputBusses.get(); }
|
||||
AUAudioUnitBusArray* getOutputBusses() override { return outputBusses.get(); }
|
||||
NSArray<NSNumber*>* getChannelCapabilities() override { return channelCapabilities.get(); }
|
||||
AUAudioUnitBusArray* getInputBusses() { return inputBusses.get(); }
|
||||
AUAudioUnitBusArray* getOutputBusses() { return outputBusses.get(); }
|
||||
NSArray<NSNumber*>* getChannelCapabilities() { return channelCapabilities.get(); }
|
||||
|
||||
bool shouldChangeToFormat (AVAudioFormat* format, AUAudioUnitBus* auBus) override
|
||||
bool shouldChangeToFormat (AVAudioFormat* format, AUAudioUnitBus* auBus)
|
||||
{
|
||||
const bool isInput = ([auBus busType] == AUAudioUnitBusTypeInput);
|
||||
const int busIdx = static_cast<int> ([auBus index]);
|
||||
|
|
@ -638,7 +396,7 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
int getVirtualMIDICableCount() override
|
||||
int getVirtualMIDICableCount()
|
||||
{
|
||||
#if JucePlugin_WantsMidiInput
|
||||
return 1;
|
||||
|
|
@ -647,12 +405,12 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
bool getSupportsMPE() override
|
||||
bool getSupportsMPE()
|
||||
{
|
||||
return getAudioProcessor().supportsMPE();
|
||||
}
|
||||
|
||||
NSArray<NSString*>* getMIDIOutputNames() override
|
||||
NSArray<NSString*>* getMIDIOutputNames()
|
||||
{
|
||||
#if JucePlugin_ProducesMidiOutput
|
||||
return @[@"MIDI Out"];
|
||||
|
|
@ -662,9 +420,9 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
AUInternalRenderBlock getInternalRenderBlock() override { return internalRenderBlock; }
|
||||
bool getRenderingOffline() override { return getAudioProcessor().isNonRealtime(); }
|
||||
void setRenderingOffline (bool offline) override
|
||||
AUInternalRenderBlock getInternalRenderBlock() { return internalRenderBlock; }
|
||||
bool getRenderingOffline() { return getAudioProcessor().isNonRealtime(); }
|
||||
void setRenderingOffline (bool offline)
|
||||
{
|
||||
auto& processor = getAudioProcessor();
|
||||
auto isCurrentlyNonRealtime = processor.isNonRealtime();
|
||||
|
|
@ -678,25 +436,25 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool getShouldBypassEffect() override
|
||||
bool getShouldBypassEffect()
|
||||
{
|
||||
if (bypassParam != nullptr)
|
||||
return (bypassParam->getValue() != 0.0f);
|
||||
|
||||
return JuceAudioUnitv3Base::getShouldBypassEffect();
|
||||
return (ObjCMsgSendSuper<AUAudioUnit, BOOL> (au, @selector (shouldBypassEffect)) == YES);
|
||||
}
|
||||
|
||||
void setShouldBypassEffect (bool shouldBypass) override
|
||||
void setShouldBypassEffect (bool shouldBypass)
|
||||
{
|
||||
if (bypassParam != nullptr)
|
||||
bypassParam->setValue (shouldBypass ? 1.0f : 0.0f);
|
||||
|
||||
JuceAudioUnitv3Base::setShouldBypassEffect (shouldBypass);
|
||||
ObjCMsgSendSuper<AUAudioUnit, void> (au, @selector (setShouldBypassEffect:), shouldBypass ? YES : NO);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
NSString* getContextName() const override { return juceStringToNS (contextName); }
|
||||
void setContextName (NSString* str) override
|
||||
NSString* getContextName() const { return juceStringToNS (contextName); }
|
||||
void setContextName (NSString* str)
|
||||
{
|
||||
if (str != nullptr)
|
||||
{
|
||||
|
|
@ -708,12 +466,12 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
bool allocateRenderResourcesAndReturnError (NSError **outError) override
|
||||
bool allocateRenderResourcesAndReturnError (NSError **outError)
|
||||
{
|
||||
AudioProcessor& processor = getAudioProcessor();
|
||||
const AUAudioFrameCount maxFrames = [getAudioUnit() maximumFramesToRender];
|
||||
const AUAudioFrameCount maxFrames = [au maximumFramesToRender];
|
||||
|
||||
if (! JuceAudioUnitv3Base::allocateRenderResourcesAndReturnError (outError))
|
||||
if (ObjCMsgSendSuper<AUAudioUnit, BOOL, NSError**> (au, @selector (allocateRenderResourcesAndReturnError:), outError) == NO)
|
||||
return false;
|
||||
|
||||
if (outError != nullptr)
|
||||
|
|
@ -726,7 +484,7 @@ public:
|
|||
const int n = AudioUnitHelpers::getBusCountForWrapper (processor, isInput);
|
||||
Array<AudioChannelSet>& channelSets = (isInput ? layouts.inputBuses : layouts.outputBuses);
|
||||
|
||||
AUAudioUnitBusArray* auBuses = (isInput ? [getAudioUnit() inputBusses] : [getAudioUnit() outputBusses]);
|
||||
AUAudioUnitBusArray* auBuses = (isInput ? [au inputBusses] : [au outputBusses]);
|
||||
jassert ([auBuses count] == static_cast<NSUInteger> (n));
|
||||
|
||||
for (int busIdx = 0; busIdx < n; ++busIdx)
|
||||
|
|
@ -797,8 +555,8 @@ public:
|
|||
midiMessages.ensureSize (2048);
|
||||
midiMessages.clear();
|
||||
|
||||
hostMusicalContextCallback = [getAudioUnit() musicalContextBlock];
|
||||
hostTransportStateCallback = [getAudioUnit() transportStateBlock];
|
||||
hostMusicalContextCallback = [au musicalContextBlock];
|
||||
hostTransportStateCallback = [au transportStateBlock];
|
||||
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
midiOutputEventBlock = [au MIDIOutputEventBlock];
|
||||
|
|
@ -808,7 +566,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void deallocateRenderResources() override
|
||||
void deallocateRenderResources()
|
||||
{
|
||||
midiOutputEventBlock = nullptr;
|
||||
|
||||
|
|
@ -823,49 +581,10 @@ public:
|
|||
|
||||
mapper.release();
|
||||
|
||||
JuceAudioUnitv3Base::deallocateRenderResources();
|
||||
ObjCMsgSendSuper<AUAudioUnit, void> (au, @selector (deallocateRenderResources));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
NSIndexSet* getSupportedViewConfigurations (NSArray<AUAudioUnitViewConfiguration*>* configs) override
|
||||
{
|
||||
auto supportedViewIndecies = [[NSMutableIndexSet alloc] init];
|
||||
auto n = [configs count];
|
||||
|
||||
if (auto* editor = getAudioProcessor().createEditorIfNeeded())
|
||||
{
|
||||
// If you hit this assertion then your plug-in's editor is reporting that it doesn't support
|
||||
// any host MIDI controller configurations!
|
||||
jassert (editor->supportsHostMIDIControllerPresence (true) || editor->supportsHostMIDIControllerPresence (false));
|
||||
|
||||
for (auto i = 0u; i < n; ++i)
|
||||
{
|
||||
if (auto viewConfiguration = [configs objectAtIndex: i])
|
||||
{
|
||||
if (editor->supportsHostMIDIControllerPresence ([viewConfiguration hostHasController] == YES))
|
||||
{
|
||||
auto* constrainer = editor->getConstrainer();
|
||||
auto height = (int) [viewConfiguration height];
|
||||
auto width = (int) [viewConfiguration width];
|
||||
|
||||
if (height <= constrainer->getMaximumHeight() && height >= constrainer->getMinimumHeight()
|
||||
&& width <= constrainer->getMaximumWidth() && width >= constrainer->getMinimumWidth())
|
||||
[supportedViewIndecies addIndex: i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [supportedViewIndecies autorelease];
|
||||
}
|
||||
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
void selectViewConfiguration (AUAudioUnitViewConfiguration* config) override
|
||||
{
|
||||
processorHolder->viewConfiguration.reset (new AudioProcessorHolder::ViewConfig { [config width], [config height], [config hostHasController] == YES });
|
||||
}
|
||||
|
||||
struct ScopedKeyChange
|
||||
{
|
||||
ScopedKeyChange (AUAudioUnit* a, NSString* k)
|
||||
|
|
@ -1029,7 +748,195 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
AUAudioUnit* getAudioUnit() const { return au; }
|
||||
|
||||
private:
|
||||
struct Class : public ObjCClass<AUAudioUnit>
|
||||
{
|
||||
Class() : ObjCClass<AUAudioUnit> ("AUAudioUnit_")
|
||||
{
|
||||
addIvar<JuceAudioUnitv3*> ("cppObject");
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
addMethod (@selector (initWithComponentDescription:options:error:juceClass:), [] (id _self,
|
||||
SEL,
|
||||
AudioComponentDescription descr,
|
||||
AudioComponentInstantiationOptions options,
|
||||
NSError** error,
|
||||
JuceAudioUnitv3* juceAU)
|
||||
{
|
||||
AUAudioUnit* self = _self;
|
||||
|
||||
self = ObjCMsgSendSuper<AUAudioUnit, AUAudioUnit*, AudioComponentDescription,
|
||||
AudioComponentInstantiationOptions, NSError**> (self, @selector(initWithComponentDescription:options:error:), descr, options, error);
|
||||
|
||||
setThis (self, juceAU);
|
||||
return self;
|
||||
});
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
addMethod (@selector (initWithComponentDescription:options:error:), [] (id _self,
|
||||
SEL,
|
||||
AudioComponentDescription descr,
|
||||
AudioComponentInstantiationOptions options,
|
||||
NSError** error)
|
||||
{
|
||||
AUAudioUnit* self = _self;
|
||||
|
||||
self = ObjCMsgSendSuper<AUAudioUnit, AUAudioUnit*, AudioComponentDescription,
|
||||
AudioComponentInstantiationOptions, NSError**> (self, @selector (initWithComponentDescription:options:error:), descr, options, error);
|
||||
|
||||
auto* juceAU = JuceAudioUnitv3::create (self, descr, options, error);
|
||||
|
||||
setThis (self, juceAU);
|
||||
return self;
|
||||
});
|
||||
|
||||
addMethod (@selector (dealloc), [] (id self, SEL)
|
||||
{
|
||||
if (! MessageManager::getInstance()->isThisTheMessageThread())
|
||||
{
|
||||
WaitableEvent deletionEvent;
|
||||
|
||||
struct AUDeleter : public CallbackMessage
|
||||
{
|
||||
AUDeleter (id selfToDelete, WaitableEvent& event)
|
||||
: parentSelf (selfToDelete), parentDeletionEvent (event)
|
||||
{
|
||||
}
|
||||
|
||||
void messageCallback() override
|
||||
{
|
||||
delete _this (parentSelf);
|
||||
parentDeletionEvent.signal();
|
||||
}
|
||||
|
||||
id parentSelf;
|
||||
WaitableEvent& parentDeletionEvent;
|
||||
};
|
||||
|
||||
(new AUDeleter (self, deletionEvent))->post();
|
||||
deletionEvent.wait (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete _this (self);
|
||||
}
|
||||
});
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (reset), [] (id self, SEL) { return _this (self)->reset(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (currentPreset), [] (id self, SEL) { return _this (self)->getCurrentPreset(); });
|
||||
addMethod (@selector (setCurrentPreset:), [] (id self, SEL, AUAudioUnitPreset* preset) { return _this (self)->setCurrentPreset (preset); });
|
||||
addMethod (@selector (factoryPresets), [] (id self, SEL) { return _this (self)->getFactoryPresets(); });
|
||||
addMethod (@selector (fullState), [] (id self, SEL) { return _this (self)->getFullState(); });
|
||||
addMethod (@selector (setFullState:), [] (id self, SEL, NSDictionary<NSString *, id>* state) { return _this (self)->setFullState (state); });
|
||||
addMethod (@selector (parameterTree), [] (id self, SEL) { return _this (self)->getParameterTree(); });
|
||||
addMethod (@selector (parametersForOverviewWithCount:), [] (id self, SEL, NSInteger count) { return _this (self)->parametersForOverviewWithCount (static_cast<int> (count)); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (latency), [] (id self, SEL) { return _this (self)->getLatency(); });
|
||||
addMethod (@selector (tailTime), [] (id self, SEL) { return _this (self)->getTailTime(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (inputBusses), [] (id self, SEL) { return _this (self)->getInputBusses(); });
|
||||
addMethod (@selector (outputBusses), [] (id self, SEL) { return _this (self)->getOutputBusses(); });
|
||||
addMethod (@selector (channelCapabilities), [] (id self, SEL) { return _this (self)->getChannelCapabilities(); });
|
||||
addMethod (@selector (shouldChangeToFormat:forBus:), [] (id self, SEL, AVAudioFormat* format, AUAudioUnitBus* bus) { return _this (self)->shouldChangeToFormat (format, bus) ? YES : NO; });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (virtualMIDICableCount), [] (id self, SEL) { return _this (self)->getVirtualMIDICableCount(); });
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
addMethod (@selector (supportsMPE), [] (id self, SEL) { return _this (self)->getSupportsMPE() ? YES : NO; });
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
addMethod (@selector (MIDIOutputNames), [] (id self, SEL) { return _this (self)->getMIDIOutputNames(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (internalRenderBlock), [] (id self, SEL) { return _this (self)->getInternalRenderBlock(); });
|
||||
addMethod (@selector (canProcessInPlace), [] (id, SEL) { return NO; });
|
||||
addMethod (@selector (isRenderingOffline), [] (id self, SEL) { return _this (self)->getRenderingOffline() ? YES : NO; });
|
||||
addMethod (@selector (setRenderingOffline:), [] (id self, SEL, BOOL renderingOffline) { return _this (self)->setRenderingOffline (renderingOffline); });
|
||||
addMethod (@selector (shouldBypassEffect), [] (id self, SEL) { return _this (self)->getShouldBypassEffect() ? YES : NO; });
|
||||
addMethod (@selector (setShouldBypassEffect:), [] (id self, SEL, BOOL shouldBypass) { return _this (self)->setShouldBypassEffect (shouldBypass); });
|
||||
addMethod (@selector (allocateRenderResourcesAndReturnError:), [] (id self, SEL, NSError** error) { return _this (self)->allocateRenderResourcesAndReturnError (error) ? YES : NO; });
|
||||
addMethod (@selector (deallocateRenderResources), [] (id self, SEL) { return _this (self)->deallocateRenderResources(); });
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (contextName), [] (id self, SEL) { return _this (self)->getContextName(); });
|
||||
addMethod (@selector (setContextName:), [](id self, SEL, NSString* str) { return _this (self)->setContextName (str); });
|
||||
|
||||
//==============================================================================
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
{
|
||||
addMethod (@selector (supportedViewConfigurations:), [] (id self, SEL, NSArray<AUAudioUnitViewConfiguration*>* configs)
|
||||
{
|
||||
auto supportedViewIndices = [[NSMutableIndexSet alloc] init];
|
||||
auto n = [configs count];
|
||||
|
||||
if (auto* editor = _this (self)->getAudioProcessor().createEditorIfNeeded())
|
||||
{
|
||||
// If you hit this assertion then your plug-in's editor is reporting that it doesn't support
|
||||
// any host MIDI controller configurations!
|
||||
jassert (editor->supportsHostMIDIControllerPresence (true) || editor->supportsHostMIDIControllerPresence (false));
|
||||
|
||||
for (auto i = 0u; i < n; ++i)
|
||||
{
|
||||
if (auto viewConfiguration = [configs objectAtIndex: i])
|
||||
{
|
||||
if (editor->supportsHostMIDIControllerPresence ([viewConfiguration hostHasController] == YES))
|
||||
{
|
||||
auto* constrainer = editor->getConstrainer();
|
||||
auto height = (int) [viewConfiguration height];
|
||||
auto width = (int) [viewConfiguration width];
|
||||
|
||||
const auto maxLimits = std::numeric_limits<int>::max() / 2;
|
||||
const Rectangle<int> requestedBounds { width, height };
|
||||
auto modifiedBounds = requestedBounds;
|
||||
constrainer->checkBounds (modifiedBounds, editor->getBounds().withZeroOrigin(), { maxLimits, maxLimits }, false, false, false, false);
|
||||
|
||||
if (modifiedBounds == requestedBounds)
|
||||
[supportedViewIndices addIndex: i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [supportedViewIndices autorelease];
|
||||
});
|
||||
|
||||
addMethod (@selector (selectViewConfiguration:), [] (id self, SEL, AUAudioUnitViewConfiguration* config)
|
||||
{
|
||||
_this (self)->processorHolder->viewConfiguration.reset (new AudioProcessorHolder::ViewConfig { [config width], [config height], [config hostHasController] == YES });
|
||||
});
|
||||
}
|
||||
|
||||
registerClass();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static JuceAudioUnitv3* _this (id self) { return getIvar<JuceAudioUnitv3*> (self, "cppObject"); }
|
||||
static void setThis (id self, JuceAudioUnitv3* cpp) { object_setInstanceVariable (self, "cppObject", cpp); }
|
||||
};
|
||||
|
||||
static JuceAudioUnitv3* create (AUAudioUnit* audioUnit, AudioComponentDescription descr, AudioComponentInstantiationOptions options, NSError** error)
|
||||
{
|
||||
PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_AudioUnitv3;
|
||||
return new JuceAudioUnitv3 (audioUnit, descr, options, error);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static Class& getClass()
|
||||
{
|
||||
static Class result;
|
||||
return result;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct BusBuffer
|
||||
{
|
||||
|
|
@ -1415,7 +1322,7 @@ private:
|
|||
busBuffers.clear();
|
||||
|
||||
const int n = AudioUnitHelpers::getBusCountForWrapper (getAudioProcessor(), isInput);
|
||||
const AUAudioFrameCount maxFrames = [getAudioUnit() maximumFramesToRender];
|
||||
const AUAudioFrameCount maxFrames = [au maximumFramesToRender];
|
||||
|
||||
for (int busIdx = 0; busIdx < n; ++busIdx)
|
||||
busBuffers.add (new BusBuffer ([(isInput ? inputBusses.get() : outputBusses.get()) objectAtIndexedSubscript: static_cast<unsigned int> (busIdx)],
|
||||
|
|
@ -1685,7 +1592,7 @@ private:
|
|||
// this is only ever called for the bypass parameter
|
||||
void parameterValueChanged (int, float newValue) override
|
||||
{
|
||||
JuceAudioUnitv3Base::setShouldBypassEffect (newValue != 0.0f);
|
||||
JuceAudioUnitv3::setShouldBypassEffect (newValue != 0.0f);
|
||||
}
|
||||
|
||||
void parameterGestureChanged (int, bool) override {}
|
||||
|
|
@ -1723,8 +1630,9 @@ private:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
static const double kDefaultSampleRate;
|
||||
static constexpr double kDefaultSampleRate = 44100.0;
|
||||
|
||||
AUAudioUnit* au;
|
||||
AudioProcessorHolder::Ptr processorHolder;
|
||||
|
||||
int totalInChannels, totalOutChannels;
|
||||
|
|
@ -1782,14 +1690,6 @@ private:
|
|||
AudioProcessorParameter* bypassParam = nullptr;
|
||||
};
|
||||
|
||||
const double JuceAudioUnitv3::kDefaultSampleRate = 44100.0;
|
||||
|
||||
JuceAudioUnitv3Base* JuceAudioUnitv3Base::create (AUAudioUnit* audioUnit, AudioComponentDescription descr, AudioComponentInstantiationOptions options, NSError** error)
|
||||
{
|
||||
PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_AudioUnitv3;
|
||||
return new JuceAudioUnitv3 (audioUnit, descr, options, error);
|
||||
}
|
||||
|
||||
#if JUCE_IOS
|
||||
namespace juce
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue