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