1 /* 2 File: AUPlugInDispatch.cpp 3 Abstract: AUPlugInDispatch.h 4 Version: 1.1 5 6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 Inc. ("Apple") in consideration of your agreement to the following 8 terms, and your use, installation, modification or redistribution of 9 this Apple software constitutes acceptance of these terms. If you do 10 not agree with these terms, please do not use, install, modify or 11 redistribute this Apple software. 12 13 In consideration of your agreement to abide by the following terms, and 14 subject to these terms, Apple grants you a personal, non-exclusive 15 license, under Apple's copyrights in this original Apple software (the 16 "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 Software, with or without modifications, in source and/or binary forms; 18 provided that if you redistribute the Apple Software in its entirety and 19 without modifications, you must retain this notice and the following 20 text and disclaimers in all such redistributions of the Apple Software. 21 Neither the name, trademarks, service marks or logos of Apple Inc. may 22 be used to endorse or promote products derived from the Apple Software 23 without specific prior written permission from Apple. Except as 24 expressly stated in this notice, no other rights or licenses, express or 25 implied, are granted by Apple herein, including but not limited to any 26 patent rights that may be infringed by your derivative works or by other 27 works in which the Apple Software may be incorporated. 28 29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 POSSIBILITY OF SUCH DAMAGE. 43 44 Copyright (C) 2014 Apple Inc. All Rights Reserved. 45 46 */ 47 /** 48 * Dispatcher for the Audio Component API. 49 * Copyright: Copyright Auburn Sounds 2016. 50 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 51 * Authors: Guillaume Piolat 52 */ 53 module dplug.au.audiocomponentdispatch; 54 55 version(AU): 56 57 import core.stdc.stdio; 58 import core.stdc.stdlib: malloc, free; 59 import derelict.carbon; 60 61 import dplug.core.runtime; 62 import dplug.core.nogc; 63 import dplug.au.client; 64 65 nothrow: 66 @nogc: 67 68 //debug = logDispatcher; 69 // Factory function entry point for Audio Component 70 void* audioUnitComponentFactory(alias ClientClass)(void* inDesc) 71 { 72 ScopedForeignCallback!(false, true) scopedCallback; 73 scopedCallback.enter(); 74 acquireAUFunctions(); 75 76 const(AudioComponentDescription)* desc = cast(const(AudioComponentDescription)*)inDesc; 77 AudioComponentPlugInInterface* pinter = cast(AudioComponentPlugInInterface*) malloc(PlugInInstance.sizeof); 78 79 pinter.Open = &audioComponentOpen!ClientClass; 80 pinter.Close = &audioComponentClose; 81 pinter.Lookup = &audioComponentLookup; 82 pinter.reserved = null; 83 return pinter; 84 } 85 86 private: 87 88 struct PlugInInstance 89 { 90 AudioComponentPlugInInterface iface; 91 AUClient instance; 92 } 93 94 extern(C) 95 { 96 OSStatus audioComponentOpen(ClientClass)(void *pSelf, AudioUnit compInstance) 97 { 98 PlugInInstance* acpi = cast(PlugInInstance *) pSelf; 99 assert(acpi); 100 ClientClass client = mallocNew!ClientClass(); 101 AUClient auClient = mallocNew!AUClient(client, null, compInstance); 102 acpi.instance = auClient; 103 return noErr; 104 } 105 106 OSStatus audioComponentClose(void* pSelf) 107 { 108 PlugInInstance* acpi = cast(PlugInInstance *) pSelf; 109 assert(acpi); 110 destroyFree(acpi.instance); 111 acpi.instance = null; 112 return noErr; 113 } 114 115 AudioComponentMethod audioComponentLookup(SInt16 selector) 116 { 117 switch(selector) 118 { 119 case kAudioUnitInitializeSelect: // 1 120 return cast(AudioComponentMethod)&AUMethodInitialize; 121 case kAudioUnitUninitializeSelect: // 2 122 return cast(AudioComponentMethod)&AUMethodUninitialize; 123 case kAudioUnitGetPropertyInfoSelect: // 3 124 return cast(AudioComponentMethod)&AUMethodGetPropertyInfo; 125 case kAudioUnitGetPropertySelect: // 4 126 return cast(AudioComponentMethod)&AUMethodGetProperty; 127 case kAudioUnitSetPropertySelect: // 5 128 return cast(AudioComponentMethod)&AUMethodSetProperty; 129 case kAudioUnitAddPropertyListenerSelect: // 10 130 return cast(AudioComponentMethod)&AUMethodAddPropertyListener; 131 case kAudioUnitRemovePropertyListenerSelect: // 11 132 return cast(AudioComponentMethod)&AUMethodRemovePropertyListener; 133 case kAudioUnitRemovePropertyListenerWithUserDataSelect: // 18 134 return cast(AudioComponentMethod)&AUMethodRemovePropertyListenerWithUserData; 135 case kAudioUnitAddRenderNotifySelect: // 15 136 return cast(AudioComponentMethod)&AUMethodAddRenderNotify; 137 case kAudioUnitRemoveRenderNotifySelect: // 138 return cast(AudioComponentMethod)&AUMethodRemoveRenderNotify; 139 case kAudioUnitGetParameterSelect: 140 return cast(AudioComponentMethod)&AUMethodGetParameter; 141 case kAudioUnitSetParameterSelect: 142 return cast(AudioComponentMethod)&AUMethodSetParameter; 143 case kAudioUnitScheduleParametersSelect: 144 return cast(AudioComponentMethod)&AUMethodScheduleParameters; 145 case kAudioUnitRenderSelect: 146 return cast(AudioComponentMethod)&AUMethodRender; 147 case kAudioUnitResetSelect: 148 return cast(AudioComponentMethod)&AUMethodReset; 149 case kAudioUnitComplexRenderSelect: // 19 150 return null; // unsupported 151 case kAudioUnitProcessSelect: // 20 152 return null; 153 case kAudioUnitProcessMultipleSelect: // 21 154 return null; 155 156 case kMusicDeviceMIDIEventSelect: // 0x0101 157 return cast(AudioComponentMethod)&AUMethodMIDIEvent; 158 case kMusicDeviceSysExSelect: // 0x0102 159 return cast(AudioComponentMethod)&AUMethodSysEx; 160 case kMusicDevicePrepareInstrumentSelect: // 0x0103 161 return cast(AudioComponentMethod)&AUMethodPrepareInstrument; 162 case kMusicDeviceReleaseInstrumentSelect: // 0x0104 163 return cast(AudioComponentMethod)&AUMethodReleaseInstrument; 164 case kMusicDeviceStartNoteSelect: // 0x0105 165 return cast(AudioComponentMethod)&AUMethodStartNote; 166 case kMusicDeviceStopNoteSelect: // 0x0106 167 return cast(AudioComponentMethod)&AUMethodStopNote; 168 169 default: 170 debug(logDispatcher) printf("WARNING: unsupported audioComponentLookup selector %d\n", selector); 171 return null; 172 } 173 } 174 175 AUClient getPlug(void *pSelf) 176 { 177 return (cast(PlugInInstance*) pSelf).instance; 178 } 179 180 // <Dispatch methods> 181 182 OSStatus AUMethodInitialize(void* pSelf) 183 { 184 debug(logDispatcher) printf("AUMethodInitialize\n"); 185 return getPlug(pSelf).DoInitialize(); 186 } 187 188 OSStatus AUMethodUninitialize(void* pSelf) 189 { 190 debug(logDispatcher) printf("AUMethodUninitialize\n"); 191 return getPlug(pSelf).DoUninitialize(); 192 } 193 194 OSStatus AUMethodGetPropertyInfo(void* pSelf, 195 AudioUnitPropertyID prop, 196 AudioUnitScope scope_, 197 AudioUnitElement elem, 198 UInt32* pOutDataSize, 199 Boolean* pOutWritable) 200 { 201 debug(logDispatcher) printf("AUMethodGetPropertyInfo\n"); 202 return getPlug(pSelf).DoGetPropertyInfo(prop, scope_, elem, pOutDataSize, pOutWritable); 203 } 204 205 OSStatus AUMethodGetProperty(void* pSelf, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void* pOutData, UInt32* pIODataSize) 206 { 207 debug(logDispatcher) printf("AUMethodGetProperty\n"); 208 return getPlug(pSelf).DoGetProperty(inID, inScope, inElement, pOutData, pIODataSize); 209 } 210 211 OSStatus AUMethodSetProperty(void* pSelf, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void* pInData, UInt32* pInDataSize) 212 { 213 debug(logDispatcher) printf("AUMethodSetProperty\n"); 214 return getPlug(pSelf).DoSetProperty(inID, inScope, inElement, pInData, pInDataSize); 215 } 216 217 OSStatus AUMethodAddPropertyListener(void* pSelf, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void* pUserData) 218 { 219 debug(logDispatcher) printf("AUMethodAddPropertyListener\n"); 220 return getPlug(pSelf).DoAddPropertyListener(prop, proc, pUserData); 221 } 222 223 OSStatus AUMethodRemovePropertyListener(void* pSelf, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc) 224 { 225 debug(logDispatcher) printf("AUMethodRemovePropertyListener\n"); 226 return getPlug(pSelf).DoRemovePropertyListener(prop, proc); 227 } 228 229 OSStatus AUMethodRemovePropertyListenerWithUserData(void* pSelf, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void* pUserData) 230 { 231 debug(logDispatcher) printf("AUMethodRemovePropertyListenerWithUserData\n"); 232 return getPlug(pSelf).DoRemovePropertyListenerWithUserData(prop, proc, pUserData); 233 } 234 235 OSStatus AUMethodAddRenderNotify(void* pSelf, AURenderCallback proc, void* pUserData) 236 { 237 debug(logDispatcher) printf("AUMethodAddRenderNotify\n"); 238 return getPlug(pSelf).DoAddRenderNotify(proc, pUserData); 239 } 240 241 OSStatus AUMethodRemoveRenderNotify(void* pSelf, AURenderCallback proc, void* pUserData) 242 { 243 debug(logDispatcher) printf("AUMethodRemoveRenderNotify\n"); 244 return getPlug(pSelf).DoRemoveRenderNotify(proc, pUserData); 245 } 246 247 // Note: used even without Audio Component API 248 OSStatus AUMethodGetParameter(void* pSelf, 249 AudioUnitParameterID param, 250 AudioUnitScope scope_, 251 AudioUnitElement elem, 252 AudioUnitParameterValue *value) 253 { 254 debug(logDispatcher) printf("AUMethodGetParameter\n"); 255 return getPlug(pSelf).DoGetParameter(param, scope_, elem, value); 256 } 257 258 // Note: used even without Audio Component API 259 OSStatus AUMethodSetParameter(void* pSelf, AudioUnitParameterID param, AudioUnitScope scope_, AudioUnitElement elem, AudioUnitParameterValue value, UInt32 bufferOffset) 260 { 261 debug(logDispatcher) printf("AUMethodSetParameter\n"); 262 return getPlug(pSelf).DoSetParameter(param, scope_, elem, value, bufferOffset); 263 } 264 265 OSStatus AUMethodScheduleParameters(void* pSelf, const AudioUnitParameterEvent *pEvent, UInt32 nEvents) 266 { 267 debug(logDispatcher) printf("AUMethodScheduleParameters\n"); 268 return getPlug(pSelf).DoScheduleParameters(pEvent, nEvents); 269 } 270 271 OSStatus AUMethodRender(void* pSelf, AudioUnitRenderActionFlags* pIOActionFlags, const AudioTimeStamp* pInTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList* pIOData) 272 { 273 debug(logDispatcher) printf("AUMethodRender\n"); 274 return getPlug(pSelf).DoRender(pIOActionFlags, pInTimeStamp, inOutputBusNumber, inNumberFrames, pIOData); 275 } 276 277 OSStatus AUMethodReset(void* pSelf, AudioUnitScope scope_, AudioUnitElement elem) 278 { 279 debug(logDispatcher) printf("AUMethodReset\n"); 280 return getPlug(pSelf).DoReset(scope_, elem); 281 } 282 283 OSStatus AUMethodMIDIEvent(void* pSelf, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame) 284 { 285 debug(logDispatcher) printf("AUMethodMIDIEvent\n"); 286 return getPlug(pSelf).DoMIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame); 287 } 288 289 OSStatus AUMethodSysEx(void* pSelf, const UInt8* pInData, UInt32 inLength) 290 { 291 debug(logDispatcher) printf("AUMethodSysEx\n"); 292 return getPlug(pSelf).DoSysEx(pInData, inLength); 293 } 294 295 OSStatus AUMethodPrepareInstrument(void* pSelf, MusicDeviceInstrumentID inInstrument) 296 { 297 debug(logDispatcher) printf("AUMethodPrepareInstrument\n"); 298 return getPlug(pSelf).DoPrepareInstrument(inInstrument); 299 } 300 301 OSStatus AUMethodReleaseInstrument(void* pSelf, MusicDeviceInstrumentID inInstrument) 302 { 303 debug(logDispatcher) printf("AUMethodReleaseInstrument\n"); 304 return getPlug(pSelf).DoReleaseInstrument(inInstrument); 305 } 306 307 OSStatus AUMethodStartNote(void *pSelf, MusicDeviceInstrumentID inInstrument, 308 MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, 309 UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams) 310 { 311 debug(logDispatcher) printf("AUMethodStartNote\n"); 312 return getPlug(pSelf).DoStartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, inParams); 313 } 314 315 OSStatus AUMethodStopNote(void *pSelf, MusicDeviceGroupID inGroupID, NoteInstanceID inNoteInstanceID, UInt32 inOffsetSampleFrame) 316 { 317 debug(logDispatcher) printf("AUMethodStopNote\n"); 318 return getPlug(pSelf).DoStopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame); 319 } 320 // </Dispatch methods> 321 322 } 323 324