1 /**
2 Dynamic bindings to the AudioUnit and AudioToolbox frameworks.
3
4 Copyright: Guillaume Piolat 2015.
5 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
6 */
7 module derelict.carbon.audiounit;
8
9 // AudioUnit and AudioToolbox frameworks loader
10 // Not strictly in Carbon, this is technical debt
11
12 import core.stdc.config;
13
14 import dplug.core.sharedlib;
15 import dplug.core.nogc;
16 import derelict.carbon.corefoundation;
17 import derelict.carbon.coreaudio;
18 import derelict.carbon.coreservices;
19
20 version(OSX)
21 enum libNames = "/System/Library/Frameworks/AudioUnit.framework/AudioUnit";
22 else
23 enum libNames = "";
24
25
26 class DerelictAudioUnitLoader : SharedLibLoader
27 {
28 public
29 {
30 this() nothrow @nogc
31 {
32 super(libNames);
33 }
34
35 override void loadSymbols() nothrow @nogc
36 {
37 bindFunc(cast(void**)&AudioUnitGetProperty, "AudioUnitGetProperty");
38 bindFunc(cast(void**)&AudioUnitRender, "AudioUnitRender");
39 }
40 }
41 }
42
43
44 private __gshared DerelictAudioUnitLoader DerelictAudioUnit;
45
46 private __gshared loaderCounterAU = 0;
47
48 // Call this each time a novel owner uses these functions
49 // TODO: hold a mutex, because this isn't thread-safe
50 void acquireAudioUnitFunctions() nothrow @nogc
51 {
52 if (DerelictAudioUnit is null) // You only live once
53 {
54 DerelictAudioUnit = mallocNew!DerelictAudioUnitLoader();
55 DerelictAudioUnit.load();
56 }
57 }
58
59 // Call this each time a novel owner releases a Cocoa functions
60 // TODO: hold a mutex, because this isn't thread-safe
61 void releaseAudioUnitFunctions() nothrow @nogc
62 {
63 /*if (--loaderCounterAU == 0)
64 {
65 DerelictAudioUnit.unload();
66 DerelictAudioUnit.destroyFree();
67 }*/
68 }
69
70
71 unittest
72 {
73 version(OSX)
74 {
75 acquireAudioUnitFunctions();
76 releaseAudioUnitFunctions();
77 }
78 }
79
80
81 enum : int
82 {
83 kAudioUnitRange = 0x0000,
84 kAudioUnitInitializeSelect = 0x0001,
85 kAudioUnitUninitializeSelect = 0x0002,
86 kAudioUnitGetPropertyInfoSelect = 0x0003,
87 kAudioUnitGetPropertySelect = 0x0004,
88 kAudioUnitSetPropertySelect = 0x0005,
89 kAudioUnitAddPropertyListenerSelect = 0x000A,
90 kAudioUnitRemovePropertyListenerSelect = 0x000B,
91 kAudioUnitRemovePropertyListenerWithUserDataSelect = 0x0012,
92 kAudioUnitAddRenderNotifySelect = 0x000F,
93 kAudioUnitRemoveRenderNotifySelect = 0x0010,
94 kAudioUnitGetParameterSelect = 0x0006,
95 kAudioUnitSetParameterSelect = 0x0007,
96 kAudioUnitScheduleParametersSelect = 0x0011,
97 kAudioUnitRenderSelect = 0x000E,
98 kAudioUnitResetSelect = 0x0009,
99 kAudioUnitComplexRenderSelect = 0x0013,
100 kAudioUnitProcessSelect = 0x0014,
101 kAudioUnitProcessMultipleSelect = 0x0015
102 }
103
104 // AUComponent.h
105
106 alias AudioComponentInstance = void*;
107 alias AudioUnit = AudioComponentInstance;
108
109 alias AudioUnitPropertyID = uint;
110 alias AudioUnitScope = uint;
111 alias AudioUnitElement = uint;
112 alias AudioUnitParameterID = uint;
113 alias AudioUnitParameterValue = float;
114
115 extern(C) nothrow @nogc
116 {
117 alias AURenderCallback = OSStatus function(void * inRefCon,
118 AudioUnitRenderActionFlags * ioActionFlags,
119 const(AudioTimeStamp)* inTimeStamp,
120 UInt32 inBusNumber,
121 UInt32 inNumberFrames,
122 AudioBufferList * ioData);
123
124 alias AudioUnitPropertyListenerProc = void function(void * inRefCon,
125 AudioUnit inUnit,
126 AudioUnitPropertyID inID,
127 AudioUnitScope inScope,
128 AudioUnitElement inElement);
129 }
130
131 alias AudioUnitRenderActionFlags = uint;
132 enum : AudioUnitRenderActionFlags
133 {
134 kAudioUnitRenderAction_PreRender = (1 << 2),
135 kAudioUnitRenderAction_PostRender = (1 << 3),
136 kAudioUnitRenderAction_OutputIsSilence = (1 << 4),
137 kAudioOfflineUnitRenderAction_Preflight = (1 << 5),
138 kAudioOfflineUnitRenderAction_Render = (1 << 6),
139 kAudioOfflineUnitRenderAction_Complete = (1 << 7),
140 kAudioUnitRenderAction_PostRenderError = (1 << 8),
141 kAudioUnitRenderAction_DoNotCheckRenderArgs = (1 << 9)
142 }
143
144 enum : OSStatus
145 {
146 kAudioUnitErr_InvalidProperty = -10879,
147 kAudioUnitErr_InvalidParameter = -10878,
148 kAudioUnitErr_InvalidElement = -10877,
149 kAudioUnitErr_NoConnection = -10876,
150 kAudioUnitErr_FailedInitialization = -10875,
151 kAudioUnitErr_TooManyFramesToProcess = -10874,
152 kAudioUnitErr_InvalidFile = -10871,
153 kAudioUnitErr_UnknownFileType = -10870,
154 kAudioUnitErr_FileNotSpecified = -10869,
155 kAudioUnitErr_FormatNotSupported = -10868,
156 kAudioUnitErr_Uninitialized = -10867,
157 kAudioUnitErr_InvalidScope = -10866,
158 kAudioUnitErr_PropertyNotWritable = -10865,
159 kAudioUnitErr_CannotDoInCurrentContext = -10863,
160 kAudioUnitErr_InvalidPropertyValue = -10851,
161 kAudioUnitErr_PropertyNotInUse = -10850,
162 kAudioUnitErr_Initialized = -10849,
163 kAudioUnitErr_InvalidOfflineRender = -10848,
164 kAudioUnitErr_Unauthorized = -10847,
165 kAudioComponentErr_InstanceInvalidated = -66749,
166 }
167
168 alias AUParameterEventType = uint;
169
170 enum : AUParameterEventType
171 {
172 kParameterEvent_Immediate = 1,
173 kParameterEvent_Ramped = 2
174 }
175
176 struct AudioUnitParameterEvent
177 {
178 AudioUnitScope scope_;
179 AudioUnitElement element;
180 AudioUnitParameterID parameter;
181
182 AUParameterEventType eventType;
183
184 static union EventValues
185 {
186 static struct Ramp
187 {
188 SInt32 startBufferOffset;
189 UInt32 durationInFrames;
190 AudioUnitParameterValue startValue;
191 AudioUnitParameterValue endValue;
192 } ;
193 Ramp ramp;
194
195 static struct Immediate
196 {
197 UInt32 bufferOffset;
198 AudioUnitParameterValue value;
199 }
200 Immediate immediate;
201
202 }
203 EventValues eventValues;
204 }
205
206 struct AudioUnitParameter
207 {
208 AudioUnit mAudioUnit;
209 AudioUnitParameterID mParameterID;
210 AudioUnitScope mScope;
211 AudioUnitElement mElement;
212 }
213
214 struct AudioUnitProperty
215 {
216 AudioUnit mAudioUnit;
217 AudioUnitPropertyID mPropertyID;
218 AudioUnitScope mScope;
219 AudioUnitElement mElement;
220 }
221
222 extern(C) nothrow @nogc
223 {
224 alias AudioUnitGetParameterProc = OSStatus function(
225 void * inComponentStorage,
226 AudioUnitParameterID inID,
227 AudioUnitScope inScope,
228 AudioUnitElement inElement,
229 AudioUnitParameterValue * outValue);
230
231 alias AudioUnitSetParameterProc = OSStatus function(
232 void * inComponentStorage,
233 AudioUnitParameterID inID,
234 AudioUnitScope inScope,
235 AudioUnitElement inElement,
236 AudioUnitParameterValue inValue,
237 UInt32 inBufferOffsetInFrames);
238
239 alias AudioUnitRenderProc = OSStatus function(
240 void * inComponentStorage,
241 AudioUnitRenderActionFlags * ioActionFlags,
242 const(AudioTimeStamp)* inTimeStamp,
243 UInt32 inOutputBusNumber,
244 UInt32 inNumberFrames,
245 AudioBufferList * ioData);
246 }
247
248 __gshared
249 {
250 AudioUnitRenderProc AudioUnitRender;
251 }
252
253 extern(C) nothrow @nogc
254 {
255 alias AudioUnitGetPropertyProc = OSStatus function(
256 AudioUnit inUnit,
257 AudioUnitPropertyID inID,
258 AudioUnitScope inScope,
259 AudioUnitElement inElement,
260 void * outData,
261 UInt32 * ioDataSize);
262 }
263
264 __gshared
265 {
266 AudioUnitGetPropertyProc AudioUnitGetProperty;
267 }
268
269 // AudioUnitCarbonView.h
270
271 enum
272 {
273 kAudioUnitCarbonViewRange = 0x0300,
274 kAudioUnitCarbonViewCreateSelect = 0x0301,
275 kAudioUnitCarbonViewSetEventListenerSelect = 0x0302
276 }
277
278 enum
279 {
280 kAudioUnitCarbonViewComponentType = CCONST('a', 'u', 'v', 'w'),
281 kAUCarbonViewSubType_Generic = CCONST('g', 'n', 'r', 'c')
282 }
283
284 // AudioUnitProperties.h
285
286 enum : AudioUnitScope
287 {
288 kAudioUnitScope_Global = 0,
289 kAudioUnitScope_Input = 1,
290 kAudioUnitScope_Output = 2,
291 kAudioUnitScope_Group = 3,
292 kAudioUnitScope_Part = 4,
293 kAudioUnitScope_Note = 5,
294 kAudioUnitScope_Layer = 6,
295 kAudioUnitScope_LayerItem = 7
296 }
297
298 enum : AudioUnitPropertyID
299 {
300 kAudioUnitProperty_ClassInfo = 0,
301 kAudioUnitProperty_MakeConnection = 1,
302 kAudioUnitProperty_SampleRate = 2,
303 kAudioUnitProperty_ParameterList = 3,
304 kAudioUnitProperty_ParameterInfo = 4,
305 kAudioUnitProperty_FastDispatch = 5,
306 kAudioUnitProperty_CPULoad = 6,
307 kAudioUnitProperty_StreamFormat = 8,
308 kAudioUnitProperty_ElementCount = 11,
309 kAudioUnitProperty_Latency = 12,
310 kAudioUnitProperty_SupportedNumChannels = 13,
311 kAudioUnitProperty_MaximumFramesPerSlice = 14,
312 kAudioUnitProperty_ParameterValueStrings = 16,
313 kAudioUnitProperty_AudioChannelLayout = 19,
314 kAudioUnitProperty_TailTime = 20,
315 kAudioUnitProperty_BypassEffect = 21,
316 kAudioUnitProperty_LastRenderError = 22,
317 kAudioUnitProperty_SetRenderCallback = 23,
318 kAudioUnitProperty_FactoryPresets = 24,
319 kAudioUnitProperty_RenderQuality = 26,
320 kAudioUnitProperty_HostCallbacks = 27,
321 kAudioUnitProperty_InPlaceProcessing = 29,
322 kAudioUnitProperty_ElementName = 30,
323 kAudioUnitProperty_SupportedChannelLayoutTags = 32,
324 kAudioUnitProperty_PresentPreset = 36,
325 kAudioUnitProperty_DependentParameters = 45,
326 kAudioUnitProperty_InputSamplesInOutput = 49,
327 kAudioUnitProperty_ShouldAllocateBuffer = 51,
328 kAudioUnitProperty_FrequencyResponse = 52,
329 kAudioUnitProperty_ParameterHistoryInfo = 53,
330 kAudioUnitProperty_NickName = 54,
331 kAudioUnitProperty_OfflineRender = 37,
332 kAudioUnitProperty_ParameterIDName = 34,
333 kAudioUnitProperty_ParameterStringFromValue = 33,
334 kAudioUnitProperty_ParameterClumpName = 35,
335 kAudioUnitProperty_ParameterValueFromString = 38,
336 kAudioUnitProperty_ContextName = 25,
337 kAudioUnitProperty_PresentationLatency = 40,
338 kAudioUnitProperty_ClassInfoFromDocument = 50,
339 kAudioUnitProperty_RequestViewController = 56,
340 kAudioUnitProperty_ParametersForOverview = 57,
341 kAudioUnitProperty_SetExternalBuffer = 15,
342 kAudioUnitProperty_GetUIComponentList = 18,
343 kAudioUnitProperty_CocoaUI = 31,
344 kAudioUnitProperty_IconLocation = 39,
345 kAudioUnitProperty_AUHostIdentifier = 46,
346 kAudioUnitProperty_MIDIOutputCallbackInfo = 47,
347 kAudioUnitProperty_MIDIOutputCallback = 48,
348 }
349
350 enum : AudioUnitPropertyID
351 {
352 kMusicDeviceProperty_InstrumentCount = 1000,
353 kMusicDeviceProperty_BankName = 1007,
354 kMusicDeviceProperty_SoundBankURL = 1100
355 }
356
357 static immutable string
358 kAUPresetVersionKey = "version",
359 kAUPresetTypeKey = "type",
360 kAUPresetSubtypeKey = "subtype",
361 kAUPresetManufacturerKey = "manufacturer",
362 kAUPresetDataKey = "data",
363 kAUPresetNameKey = "name",
364 kAUPresetRenderQualityKey = "render-quality",
365 kAUPresetCPULoadKey = "cpu-load",
366 kAUPresetElementNameKey = "element-name",
367 kAUPresetExternalFileRefs = "file-references",
368 kAUPresetVSTDataKey = "vstdata",
369 kAUPresetVSTPresetKey = "vstpreset",
370 kAUPresetMASDataKey = "masdata",
371 kAUPresetPartKey = "part";
372
373 version(BigEndian)
374 struct AUNumVersion
375 {
376 UInt8 majorRev;
377 UInt8 minorAndBugRev;
378 UInt8 stage;
379 UInt8 nonRelRev;
380 }
381
382 version(LittleEndian)
383 struct AUNumVersion
384 {
385 UInt8 nonRelRev;
386 UInt8 stage;
387 UInt8 minorAndBugRev;
388 UInt8 majorRev;
389 }
390
391 struct AUHostIdentifier
392 {
393 CFStringRef hostName;
394 AUNumVersion hostVersion;
395 }
396
397 struct AudioUnitConnection
398 {
399 AudioUnit sourceAudioUnit;
400 UInt32 sourceOutputNumber;
401 UInt32 destInputNumber;
402 }
403
404 struct AUChannelInfo
405 {
406 SInt16 inChannels;
407 SInt16 outChannels;
408 }
409
410 struct AURenderCallbackStruct
411 {
412 AURenderCallback inputProc;
413 void* inputProcRefCon;
414 }
415
416
417
418 struct AUPreset
419 {
420 SInt32 presetNumber;
421 CFStringRef presetName;
422 }
423
424 enum : AudioUnitPropertyID
425 {
426 kAudioUnitProperty_SRCAlgorithm = 9, // see kAudioUnitProperty_SampleRateConverterComplexity
427 kAudioUnitProperty_MIDIControlMapping = 17, // see ParameterMIDIMapping Properties
428 kAudioUnitProperty_CurrentPreset = 28, // see PresentPreset
429
430 kAudioUnitProperty_ParameterValueName = kAudioUnitProperty_ParameterStringFromValue,
431 kAudioUnitProperty_BusCount = kAudioUnitProperty_ElementCount,
432 }
433
434
435 extern(C) nothrow @nogc
436 {
437 alias HostCallback_GetBeatAndTempo = OSStatus function(void * inHostUserData,
438 Float64 * outCurrentBeat,
439 Float64 * outCurrentTempo);
440
441 alias HostCallback_GetMusicalTimeLocation = OSStatus function(void * inHostUserData,
442 UInt32 * outDeltaSampleOffsetToNextBeat,
443 Float32 * outTimeSig_Numerator,
444 UInt32 * outTimeSig_Denominator,
445 Float64 * outCurrentMeasureDownBeat);
446 alias HostCallback_GetTransportState = OSStatus function(void * inHostUserData,
447 Boolean * outIsPlaying,
448 Boolean * outTransportStateChanged,
449 Float64 * outCurrentSampleInTimeLine,
450 Boolean * outIsCycling,
451 Float64 * outCycleStartBeat,
452 Float64 * outCycleEndBeat);
453 alias HostCallback_GetTransportState2 = OSStatus function(void * inHostUserData,
454 Boolean * outIsPlaying,
455 Boolean * outIsRecording,
456 Boolean * outTransportStateChanged,
457 Float64 * outCurrentSampleInTimeLine,
458 Boolean * outIsCycling,
459 Float64 * outCycleStartBeat,
460 Float64 * outCycleEndBeat);
461 }
462
463 struct HostCallbackInfo
464 {
465 void * hostUserData;
466 HostCallback_GetBeatAndTempo beatAndTempoProc;
467 HostCallback_GetMusicalTimeLocation musicalTimeLocationProc;
468 HostCallback_GetTransportState transportStateProc;
469 HostCallback_GetTransportState2 transportStateProc2;
470 }
471
472 struct AudioUnitCocoaViewInfo
473 {
474 CFURLRef mCocoaAUViewBundleLocation;
475 CFStringRef[1] mCocoaAUViewClass;
476 }
477
478 extern(C) nothrow @nogc
479 {
480 alias AUMIDIOutputCallback = OSStatus function(void* userData,
481 const(AudioTimeStamp)* timeStamp,
482 UInt32 midiOutNum,
483 const(MIDIPacketList)* pktlist);
484 }
485
486 struct AUMIDIOutputCallbackStruct
487 {
488 AUMIDIOutputCallback midiOutputCallback;
489 void* userData;
490 }
491
492 struct AudioUnitParameterInfo
493 {
494 char[52] name;
495 CFStringRef unitName;
496 UInt32 clumpID;
497 CFStringRef cfNameString;
498 AudioUnitParameterUnit unit;
499 AudioUnitParameterValue minValue;
500 AudioUnitParameterValue maxValue;
501 AudioUnitParameterValue defaultValue;
502 AudioUnitParameterOptions flags;
503 }
504
505 alias AudioUnitParameterUnit = UInt32;
506 enum : AudioUnitParameterUnit
507 {
508 kAudioUnitParameterUnit_Generic = 0,
509 kAudioUnitParameterUnit_Indexed = 1,
510 kAudioUnitParameterUnit_Boolean = 2,
511 kAudioUnitParameterUnit_Percent = 3,
512 kAudioUnitParameterUnit_Seconds = 4,
513 kAudioUnitParameterUnit_SampleFrames = 5,
514 kAudioUnitParameterUnit_Phase = 6,
515 kAudioUnitParameterUnit_Rate = 7,
516 kAudioUnitParameterUnit_Hertz = 8,
517 kAudioUnitParameterUnit_Cents = 9,
518 kAudioUnitParameterUnit_RelativeSemiTones = 10,
519 kAudioUnitParameterUnit_MIDINoteNumber = 11,
520 kAudioUnitParameterUnit_MIDIController = 12,
521 kAudioUnitParameterUnit_Decibels = 13,
522 kAudioUnitParameterUnit_LinearGain = 14,
523 kAudioUnitParameterUnit_Degrees = 15,
524 kAudioUnitParameterUnit_EqualPowerCrossfade = 16,
525 kAudioUnitParameterUnit_MixerFaderCurve1 = 17,
526 kAudioUnitParameterUnit_Pan = 18,
527 kAudioUnitParameterUnit_Meters = 19,
528 kAudioUnitParameterUnit_AbsoluteCents = 20,
529 kAudioUnitParameterUnit_Octaves = 21,
530 kAudioUnitParameterUnit_BPM = 22,
531 kAudioUnitParameterUnit_Beats = 23,
532 kAudioUnitParameterUnit_Milliseconds = 24,
533 kAudioUnitParameterUnit_Ratio = 25,
534 kAudioUnitParameterUnit_CustomUnit = 26
535 }
536
537 alias AudioUnitParameterOptions = UInt32;
538 enum : AudioUnitParameterOptions
539 {
540 kAudioUnitParameterFlag_CFNameRelease = (1UL << 4),
541
542 kAudioUnitParameterFlag_OmitFromPresets = (1UL << 13),
543 kAudioUnitParameterFlag_PlotHistory = (1UL << 14),
544 kAudioUnitParameterFlag_MeterReadOnly = (1UL << 15),
545
546 // bit positions 18,17,16 are set aside for display scales. bit 19 is reserved.
547 kAudioUnitParameterFlag_DisplayMask = (7UL << 16) | (1UL << 22),
548 kAudioUnitParameterFlag_DisplaySquareRoot = (1UL << 16),
549 kAudioUnitParameterFlag_DisplaySquared = (2UL << 16),
550 kAudioUnitParameterFlag_DisplayCubed = (3UL << 16),
551 kAudioUnitParameterFlag_DisplayCubeRoot = (4UL << 16),
552 kAudioUnitParameterFlag_DisplayExponential = (5UL << 16),
553
554 kAudioUnitParameterFlag_HasClump = (1UL << 20),
555 kAudioUnitParameterFlag_ValuesHaveStrings = (1UL << 21),
556
557 kAudioUnitParameterFlag_DisplayLogarithmic = (1UL << 22),
558
559 kAudioUnitParameterFlag_IsHighResolution = (1UL << 23),
560 // parameter is non-automatable
561 kAudioUnitParameterFlag_NonRealTime = (1UL << 24),
562 kAudioUnitParameterFlag_CanRamp = (1UL << 25),
563 kAudioUnitParameterFlag_ExpertMode = (1UL << 26),
564 kAudioUnitParameterFlag_HasCFNameString = (1UL << 27),
565 kAudioUnitParameterFlag_IsGlobalMeta = (1UL << 28),
566 kAudioUnitParameterFlag_IsElementMeta = (1UL << 29),
567 kAudioUnitParameterFlag_IsReadable = (1UL << 30),
568 kAudioUnitParameterFlag_IsWritable = (1UL << 31)
569 }
570
571 struct AudioUnitParameterNameInfo
572 {
573 AudioUnitParameterID inID;
574 SInt32 inDesiredLength;
575 CFStringRef outName;
576 }
577 alias AudioUnitParameterIDName = AudioUnitParameterNameInfo;
578
579 struct AudioUnitParameterStringFromValue
580 {
581 AudioUnitParameterID inParamID;
582 const(AudioUnitParameterValue)* inValue;
583 CFStringRef outString;
584 }
585
586 struct AudioUnitParameterValueFromString
587 {
588 AudioUnitParameterID inParamID;
589 CFStringRef inString;
590 AudioUnitParameterValue outValue;
591 }
592
593
594
595 // AudioToolbox framework
596
597 version(OSX)
598 enum libNamesToolbox = "/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox";
599 else
600 enum libNamesToolbox = "";
601
602
603 class DerelictAudioToolboxLoader : SharedLibLoader
604 {
605 public
606 {
607 nothrow @nogc:
608 this()
609 {
610 super(libNamesToolbox);
611 }
612
613 override void loadSymbols()
614 {
615 bindFunc(cast(void**)&AUEventListenerNotify, "AUEventListenerNotify");
616 }
617 }
618 }
619
620
621 private __gshared DerelictAudioToolboxLoader DerelictAudioToolbox;
622
623 private __gshared loaderCounterATB = 0;
624
625 // Call this each time a novel owner uses these functions
626 // TODO: hold a mutex, because this isn't thread-safe
627 void acquireAudioToolboxFunctions() nothrow @nogc
628 {
629 if (DerelictAudioToolbox is null) // You only live once
630 {
631 DerelictAudioToolbox = mallocNew!DerelictAudioToolboxLoader();
632 DerelictAudioToolbox.load();
633 }
634 }
635
636 // Call this each time a novel owner releases a Cocoa functions
637 // TODO: hold a mutex, because this isn't thread-safe
638 void releaseAudioToolboxFunctions() nothrow @nogc
639 {
640 /*if (--loaderCounterATB == 0)
641 {
642 DerelictAudioToolbox.unload();
643 DerelictAudioToolbox.destroyFree();
644 }*/
645 }
646
647 unittest
648 {
649 version(OSX)
650 {
651 acquireAudioToolboxFunctions();
652 releaseAudioToolboxFunctions();
653 }
654 }
655
656
657 alias AudioUnitEventType = UInt32;
658 enum : AudioUnitEventType
659 {
660 kAudioUnitEvent_ParameterValueChange = 0,
661 kAudioUnitEvent_BeginParameterChangeGesture = 1,
662 kAudioUnitEvent_EndParameterChangeGesture = 2,
663 kAudioUnitEvent_PropertyChange = 3
664 }
665
666 alias AUEventListenerRef = void*;
667
668 struct AudioUnitEvent
669 {
670 AudioUnitEventType mEventType;
671 union Argument
672 {
673 AudioUnitParameter mParameter; // for parameter value change, begin and end gesture
674 AudioUnitProperty mProperty; // for kAudioUnitEvent_PropertyChange
675 }
676 Argument mArgument;
677 }
678
679 extern(C) nothrow @nogc
680 {
681 alias da_AUEventListenerNotify = OSStatus function(AUEventListenerRef inSendingListener, void* inSendingObject, const(AudioUnitEvent)* inEvent);
682 }
683
684 __gshared
685 {
686 da_AUEventListenerNotify AUEventListenerNotify;
687 }
688
689 enum
690 {
691 kMusicDeviceRange = 0x0100,
692 kMusicDeviceMIDIEventSelect = 0x0101,
693 kMusicDeviceSysExSelect = 0x0102,
694 kMusicDevicePrepareInstrumentSelect = 0x0103,
695 kMusicDeviceReleaseInstrumentSelect = 0x0104,
696 kMusicDeviceStartNoteSelect = 0x0105,
697 kMusicDeviceStopNoteSelect = 0x0106,
698 }
699
700 alias MusicDeviceInstrumentID = uint;
701 alias MusicDeviceGroupID = uint;
702 alias NoteInstanceID = uint;
703
704 struct MusicDeviceNoteParams
705 {
706 UInt32 argCount;
707 Float32 mPitch;
708 Float32 mVelocity;
709 //NoteParamsControlValue[1] mControls; /* arbitrary length */
710 }
711
712 //
713 // AUDIO COMPONENT API
714 //
715 // AudioComponent.h
716
717
718 alias AudioComponentFlags = UInt32;
719 enum : AudioComponentFlags
720 {
721 kAudioComponentFlag_Unsearchable = 1, // available: OSX 10.7
722 kAudioComponentFlag_SandboxSafe = 2 // available: OSX 10.8
723 }
724
725 struct AudioComponentDescription
726 {
727 OSType componentType;
728 OSType componentSubType;
729 OSType componentManufacturer;
730 UInt32 componentFlags;
731 UInt32 componentFlagsMask;
732 }
733
734 alias AudioComponent = void*;
735
736 extern(C) nothrow
737 {
738 alias AudioComponentMethod = OSStatus function(void *self,...);
739 }
740
741 struct AudioComponentPlugInInterface
742 {
743 extern(C) nothrow OSStatus function(void *self, AudioComponentInstance mInstance) Open;
744 extern(C) nothrow OSStatus function(void *self) Close;
745 extern(C) nothrow AudioComponentMethod function(SInt16 selector) Lookup;
746 void* reserved;
747 }
748
749 extern(C) nothrow
750 {
751 alias AudioComponentFactoryFunction = AudioComponentPlugInInterface* function(const(AudioComponentDescription)* inDesc);
752 }
753
754
755 // <CoreMIDI/MIDIServices.h>
756
757 alias MIDITimeStamp = ulong;
758
759 struct MIDIPacket
760 {
761 MIDITimeStamp timeStamp;
762 UInt16 length;
763 byte[256] data;
764 }
765 static assert(MIDIPacket.sizeof == 8 + 2 + 6 + 256); // verified with c++ Godbolt
766
767 const(MIDIPacket)* MIDIPacketNext(const(MIDIPacket)* pkt)
768 {
769 version(ARM)
770 {
771 ptrdiff_t mask = ~3;
772 size_t p = cast(size_t)(pkt.data.ptr + pkt.length);
773 p = (p + 3) & mask;
774 return cast(const(MIDIPacket)*)p;
775 }
776 else version(AArch64)
777 {
778 ptrdiff_t mask = ~3;
779 size_t p = cast(size_t)(pkt.data.ptr + pkt.length);
780 p = (p + 3) & mask;
781 return cast(const(MIDIPacket)*)p;
782 }
783 else
784 {
785 return cast(const(MIDIPacket)*)(pkt.data.ptr + pkt.length);
786 }
787 }
788
789 struct MIDIPacketList
790 {
791 UInt32 numPackets;
792 MIDIPacket[1] packet;
793 }
794 static assert(MIDIPacketList.sizeof == 4 + 4 + MIDIPacket.sizeof); // verified with C++ Godbolt