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