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