20 #include <CoreServices/CoreServices.h> 21 #include <AudioUnit/AUComponent.h> 22 #include <AudioUnit/AudioUnitProperties.h> 23 #include <AudioToolbox/AudioUnitUtilities.h> 24 #include <AvailabilityMacros.h> 31 struct AudioComponentPlugInInstance
33 AudioComponentPlugInInstance() =
default;
34 AudioComponentPlugInInstance(
const AudioComponentPlugInInstance&) =
delete;
35 AudioComponentPlugInInstance& operator=(
const AudioComponentPlugInInstance&) =
delete;
37 AudioComponentPlugInInterface mPlugInInterface;
38 void* (*mConstruct)(
void* pMemory, AudioComponentInstance ci);
39 void (*mDestruct)(
void* pMemory);
41 UInt32 mInstanceStorage;
44 static const AudioUnitPropertyID kIPlugObjectPropertyID = UINT32_MAX-100;
49 WDL_String mCocoaViewFactoryClassName;
60 IPlugAU(
const InstanceInfo& info,
const Config& config);
64 void BeginInformHostOfParamChange(
int idx)
override;
65 void InformHostOfParamChange(
int idx,
double normalizedValue)
override;
66 void EndInformHostOfParamChange(
int idx)
override;
67 void InformHostOfPresetChange()
override;
68 void InformHostOfParameterDetailsChange()
override;
71 virtual void GetTrackName(WDL_String& str)
override { str = mTrackName; };
74 bool SendMidiMsg(
const IMidiMsg& msg)
override;
75 bool SendMidiMsgs(WDL_TypedBuf<IMidiMsg>& msgs)
override;
76 bool SendSysEx(
const ISysEx& msg)
override;
77 void SetLatency(
int samples)
override;
80 void OutputSysexFromEditor();
82 void ResizeScratchBuffers();
83 static const char* AUInputTypeStr(
int type);
84 #ifndef AU_NO_COMPONENT_ENTRY 85 static OSStatus IPlugAUEntry(ComponentParameters* pParams,
void* pPlug);
102 int mPlugChannelStartIdx;
108 AudioBuffer mBuffers[AU_MAX_IO_CHANNELS];
111 struct InputBusConnection
114 AudioUnit mUpstreamUnit;
116 AudioUnitRenderProc mUpstreamRenderProc;
117 AURenderCallbackStruct mUpstreamRenderCallback;
118 EAUInputType mInputType;
121 struct PropertyListener
123 AudioUnitPropertyID mPropID;
124 AudioUnitPropertyListenerProc mListenerProc;
128 int NHostChannelsConnected(WDL_PtrList<BusChannels>* pBuses,
int excludeIdx = -1);
129 void ClearConnections();
130 BusChannels* GetBus(AudioUnitScope scope, AudioUnitElement busIdx);
131 bool CheckLegalIO(AudioUnitScope scope,
int busIdx,
int nChannels);
133 void AssessInputConnections();
135 UInt32 GetTagForNumChannels(
int numChannels);
136 UInt32 GetChannelLayoutTags(AudioUnitScope scope, AudioUnitElement element, AudioChannelLayoutTag* pTags);
138 #pragma mark - Component Manager Methods 139 OSStatus GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, UInt32* pDataSize, Boolean* pWriteable);
140 OSStatus GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, UInt32* pDataSize, Boolean* pWriteable,
void* pData);
141 OSStatus SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, UInt32* pDataSize,
const void* pData);
143 OSStatus GetProc(AudioUnitElement element, UInt32* pDataSize,
void* pData);
144 virtual OSStatus GetState(CFPropertyListRef* ppPropList);
145 virtual OSStatus SetState(CFPropertyListRef pPropList);
146 void InformListeners(AudioUnitPropertyID propID, AudioUnitScope scope);
147 void SendAUEvent(AudioUnitEventType type, AudioComponentInstance ci,
int idx);
149 static OSStatus GetParamProc(
void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, AudioUnitParameterValue* pValue);
150 static OSStatus SetParamProc(
void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, AudioUnitParameterValue value, UInt32 offsetFrames);
151 static OSStatus RenderProc(
void* pPlug, AudioUnitRenderActionFlags* pFlags,
const AudioTimeStamp* pTimestamp, UInt32 outputBusIdx, UInt32 nFrames, AudioBufferList* pBufferList);
153 #pragma mark - Dispatch Methods 154 static OSStatus AUMethodInitialize(
void* pSelf);
155 static OSStatus AUMethodUninitialize(
void* pSelf);
156 static OSStatus AUMethodGetPropertyInfo(
void* pSelf, AudioUnitPropertyID prop, AudioUnitScope scope, AudioUnitElement elem, UInt32* pOutDataSize, Boolean* pOutWritable);
157 static OSStatus AUMethodGetProperty(
void* pSelf, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement,
void* pOutData, UInt32* pIODataSize);
158 static OSStatus AUMethodSetProperty(
void* pSelf, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement,
const void* pInData, UInt32* pInDataSize);
159 static OSStatus AUMethodAddPropertyListener(
void* pSelf, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc,
void* pUserData);
160 static OSStatus AUMethodRemovePropertyListener(
void* pSelf, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc);
161 static OSStatus AUMethodRemovePropertyListenerWithUserData(
void* pSelf, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc,
void* pUserData);
162 static OSStatus AUMethodAddRenderNotify(
void* pSelf, AURenderCallback proc,
void* pUserData);
163 static OSStatus AUMethodRemoveRenderNotify(
void* pSelf, AURenderCallback proc,
void* pUserData);
164 static OSStatus AUMethodGetParameter(
void* pSelf, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue *value);
165 static OSStatus AUMethodSetParameter(
void* pSelf, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue value, UInt32 bufferOffset);
166 static OSStatus AUMethodScheduleParameters(
void* pSelf,
const AudioUnitParameterEvent *pEvent, UInt32 nEvents);
167 static OSStatus AUMethodRender(
void* pSelf, AudioUnitRenderActionFlags* pIOActionFlags,
const AudioTimeStamp* pInTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList* pIOData);
168 static OSStatus AUMethodReset(
void* pSelf, AudioUnitScope scope, AudioUnitElement elem);
169 static OSStatus AUMethodMIDIEvent(
void* pSelf, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame);
170 static OSStatus AUMethodSysEx(
void* pSelf,
const UInt8* pInData, UInt32 inLength);
172 #pragma mark - Implementation Methods 173 static OSStatus DoInitialize(
IPlugAU* pPlug);
174 static OSStatus DoUninitialize(
IPlugAU* pPlug);
175 static OSStatus DoGetPropertyInfo(
IPlugAU* pPlug, AudioUnitPropertyID prop, AudioUnitScope scope, AudioUnitElement elem, UInt32 *pOutDataSize, Boolean* pOutWritable);
176 static OSStatus DoGetProperty(
IPlugAU* pPlug, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement,
void *pOutData, UInt32* pIODataSize);
177 static OSStatus DoSetProperty(
IPlugAU* pPlug, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement,
const void* pInData, UInt32* pInDataSize);
178 static OSStatus DoAddPropertyListener(
IPlugAU* pPlug, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc,
void* pUserData);
179 static OSStatus DoRemovePropertyListener(
IPlugAU* pPlug, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc);
180 static OSStatus DoRemovePropertyListenerWithUserData(
IPlugAU* pPlug, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc,
void* pUserData);
181 static OSStatus DoAddRenderNotify(
IPlugAU* pPlug, AURenderCallback proc,
void* pUserData);
182 static OSStatus DoRemoveRenderNotify(
IPlugAU* pPlug, AURenderCallback proc,
void* pUserData);
183 static OSStatus DoGetParameter(
IPlugAU* pPlug, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue* pValue);
184 static OSStatus DoSetParameter(
IPlugAU* pPlug, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue value, UInt32 bufferOffset);
185 static OSStatus DoScheduleParameters(
IPlugAU* pPlug,
const AudioUnitParameterEvent *pEvent, UInt32 nEvents);
186 static OSStatus DoRender(
IPlugAU* pPlug, AudioUnitRenderActionFlags* pIOActionFlags,
const AudioTimeStamp* pInTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList* pIOData);
187 static OSStatus DoReset(
IPlugAU* pPlug);
188 static OSStatus DoMIDIEvent(
IPlugAU* pPlug, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame);
189 static OSStatus DoSysEx(
IPlugAU* pPlug,
const UInt8 *inData, UInt32 inLength);
193 #pragma mark - Utilities 195 static void PutNumberInDict(CFMutableDictionaryRef pDict,
const char* key,
void* pNumber, CFNumberType type);
196 static void PutStrInDict(CFMutableDictionaryRef pDict,
const char* key,
const char* value);
197 static void PutDataInDict(CFMutableDictionaryRef pDict,
const char* key,
IByteChunk* pChunk);
198 static bool GetNumberFromDict(CFDictionaryRef pDict,
const char* key,
void* pNumber, CFNumberType type);
199 static bool GetStrFromDict(CFDictionaryRef pDict,
const char* key,
char* value);
200 static bool GetDataFromDict(CFDictionaryRef pDict,
const char* key,
IByteChunk* pChunk);
206 bool mActive =
false;
207 double mLastRenderSampleTime = -1.0;
208 WDL_String mCocoaViewFactoryClassName;
209 AudioComponentInstance mCI =
nullptr;
210 HostCallbackInfo mHostCallbacks;
211 WDL_PtrList<BusChannels> mInBuses, mOutBuses;
212 WDL_PtrList<InputBusConnection> mInBusConnections;
213 WDL_PtrList<PropertyListener> mPropertyListeners;
214 WDL_TypedBuf<AudioSampleType> mInScratchBuf;
215 WDL_TypedBuf<AudioSampleType> mOutScratchBuf;
216 WDL_PtrList<AURenderCallbackStruct> mRenderNotify;
217 AUMIDIOutputCallbackStruct mMidiCallback;
218 AudioTimeStamp mLastRenderTimeStamp;
219 WDL_String mTrackName;
220 template <
class Plug,
bool DoesMIDIIn>
224 IPlugAU* MakePlug(
void* memory);
228 template <
class Plug,
bool MIDIIn>
232 static void* Construct(
void* pMemory, AudioComponentInstance compInstance)
234 return MakePlug(pMemory);
237 static void Destruct(
void* pMemory)
239 ((Plug*) pMemory)->~Plug();
242 static AudioComponentMethod Lookup(SInt16 selector)
244 using Method = AudioComponentMethod;
248 case kAudioUnitInitializeSelect:
return (Method)IPlugAU::AUMethodInitialize;
249 case kAudioUnitUninitializeSelect:
return (Method)IPlugAU::AUMethodUninitialize;
250 case kAudioUnitGetPropertyInfoSelect:
return (Method)IPlugAU::AUMethodGetPropertyInfo;
251 case kAudioUnitGetPropertySelect:
return (Method)IPlugAU::AUMethodGetProperty;
252 case kAudioUnitSetPropertySelect:
return (Method)IPlugAU::AUMethodSetProperty;
254 case kAudioUnitAddPropertyListenerSelect:
return (Method)IPlugAU::AUMethodAddPropertyListener;
255 case kAudioUnitRemovePropertyListenerSelect:
return (Method)IPlugAU::AUMethodRemovePropertyListener;
256 case kAudioUnitRemovePropertyListenerWithUserDataSelect:
257 return (Method)IPlugAU::AUMethodRemovePropertyListenerWithUserData;
259 case kAudioUnitAddRenderNotifySelect:
return (Method)IPlugAU::AUMethodAddRenderNotify;
260 case kAudioUnitRemoveRenderNotifySelect:
return (Method)IPlugAU::AUMethodRemoveRenderNotify;
261 case kAudioUnitGetParameterSelect:
return (Method)IPlugAU::AUMethodGetParameter;
262 case kAudioUnitSetParameterSelect:
return (Method)IPlugAU::AUMethodSetParameter;
263 case kAudioUnitScheduleParametersSelect:
return (Method)IPlugAU::AUMethodScheduleParameters;
264 case kAudioUnitRenderSelect:
return (Method)IPlugAU::AUMethodRender;
265 case kAudioUnitResetSelect:
return (Method)IPlugAU::AUMethodReset;
267 case kMusicDeviceMIDIEventSelect:
return MIDIIn ? (Method)IPlugAU::AUMethodMIDIEvent : NULL;
268 case kMusicDeviceSysExSelect:
return MIDIIn ? (Method)IPlugAU::AUMethodSysEx : NULL;
276 static OSStatus Open(
void* pSelf, AudioUnit compInstance)
278 AudioComponentPlugInInstance* acpi = (AudioComponentPlugInInstance *) pSelf;
281 (*acpi->mConstruct)(&acpi->mInstanceStorage, compInstance);
284 plug->mCI = compInstance;
290 static OSStatus Close(
void* pSelf)
292 AudioComponentPlugInInstance* acpi = (AudioComponentPlugInInstance *) pSelf;
294 (*acpi->mDestruct)(&acpi->mInstanceStorage);
299 static AudioComponentPlugInInterface* Factory(
const AudioComponentDescription* pInDesc)
301 void *ptr = malloc(offsetof(AudioComponentPlugInInstance, mInstanceStorage) +
sizeof(Plug));
302 AudioComponentPlugInInstance* acpi =
reinterpret_cast<AudioComponentPlugInInstance*
>(ptr);
303 acpi->mPlugInInterface.Open = Open;
304 acpi->mPlugInInterface.Close = Close;
305 acpi->mPlugInInterface.Lookup = Lookup;
306 acpi->mPlugInInterface.reserved = NULL;
307 acpi->mConstruct = Construct;
308 acpi->mDestruct = Destruct;
309 acpi->mPad[0] = NULL;
310 acpi->mPad[1] = NULL;
311 return (AudioComponentPlugInInterface*)acpi;
The base class for IPlug Audio Processing.
The base class of an IPlug plug-in, which interacts with the different plug-in APIs.
Encapsulates a MIDI message and provides helper functions.
void PruneUninitializedPresets()
[AUV2 only] Removes any presets that weren't initialized
Manages a block of memory, for plug-in settings store/recall.
AudioUnit v2 Factory Class Template.
The base class for IPlug Audio Processing.
The base class of an IPlug plug-in, which interacts with the different plug-in APIs.
virtual void GetTrackName(WDL_String &str) override
Get the name of the track that the plug-in is inserted on.
AudioUnit v2 API base class for an IPlug plug-in.
A struct for dealing with SysEx messages.