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