//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
#[cfg(feature = "objc2-core-audio-types")]
use objc2_core_audio_types::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;

use crate::*;

/// An audio unit is of type AudioComponentInstance as defined in
/// AudioComponent.h
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounit?language=objc)
#[cfg(feature = "AudioComponent")]
pub type AudioUnit = AudioComponentInstance;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_output?language=objc)
pub const kAudioUnitType_Output: u32 = 0x61756f75;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_musicdevice?language=objc)
pub const kAudioUnitType_MusicDevice: u32 = 0x61756d75;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_musiceffect?language=objc)
pub const kAudioUnitType_MusicEffect: u32 = 0x61756d66;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_formatconverter?language=objc)
pub const kAudioUnitType_FormatConverter: u32 = 0x61756663;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_effect?language=objc)
pub const kAudioUnitType_Effect: u32 = 0x61756678;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_mixer?language=objc)
pub const kAudioUnitType_Mixer: u32 = 0x61756d78;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_panner?language=objc)
pub const kAudioUnitType_Panner: u32 = 0x6175706e;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_generator?language=objc)
pub const kAudioUnitType_Generator: u32 = 0x6175676e;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_offlineeffect?language=objc)
pub const kAudioUnitType_OfflineEffect: u32 = 0x61756f6c;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_midiprocessor?language=objc)
pub const kAudioUnitType_MIDIProcessor: u32 = 0x61756d69;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_speechsynthesizer?language=objc)
pub const kAudioUnitType_SpeechSynthesizer: u32 = 0x61757370;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_remoteeffect?language=objc)
pub const kAudioUnitType_RemoteEffect: u32 = 0x61757278;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_remotegenerator?language=objc)
pub const kAudioUnitType_RemoteGenerator: u32 = 0x61757267;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_remoteinstrument?language=objc)
pub const kAudioUnitType_RemoteInstrument: u32 = 0x61757269;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounittype_remotemusiceffect?language=objc)
pub const kAudioUnitType_RemoteMusicEffect: u32 = 0x6175726d;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitmanufacturer_apple?language=objc)
pub const kAudioUnitManufacturer_Apple: u32 = 0x6170706c;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_genericoutput?language=objc)
pub const kAudioUnitSubType_GenericOutput: u32 = 0x67656e72;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_voiceprocessingio?language=objc)
pub const kAudioUnitSubType_VoiceProcessingIO: u32 = 0x7670696f;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_haloutput?language=objc)
pub const kAudioUnitSubType_HALOutput: u32 = 0x6168616c;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_defaultoutput?language=objc)
pub const kAudioUnitSubType_DefaultOutput: u32 = 0x64656620;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_systemoutput?language=objc)
pub const kAudioUnitSubType_SystemOutput: u32 = 0x73797320;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_dlssynth?language=objc)
pub const kAudioUnitSubType_DLSSynth: u32 = 0x646c7320;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_sampler?language=objc)
pub const kAudioUnitSubType_Sampler: u32 = 0x73616d70;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_midisynth?language=objc)
pub const kAudioUnitSubType_MIDISynth: u32 = 0x6d73796e;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_auconverter?language=objc)
pub const kAudioUnitSubType_AUConverter: u32 = 0x636f6e76;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_varispeed?language=objc)
pub const kAudioUnitSubType_Varispeed: u32 = 0x76617269;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_deferredrenderer?language=objc)
pub const kAudioUnitSubType_DeferredRenderer: u32 = 0x64656672;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_splitter?language=objc)
pub const kAudioUnitSubType_Splitter: u32 = 0x73706c74;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_multisplitter?language=objc)
pub const kAudioUnitSubType_MultiSplitter: u32 = 0x6d73706c;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_merger?language=objc)
pub const kAudioUnitSubType_Merger: u32 = 0x6d657267;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_newtimepitch?language=objc)
pub const kAudioUnitSubType_NewTimePitch: u32 = 0x6e757470;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_auipodtimeother?language=objc)
pub const kAudioUnitSubType_AUiPodTimeOther: u32 = 0x6970746f;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_roundtripaac?language=objc)
pub const kAudioUnitSubType_RoundTripAAC: u32 = 0x72616163;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_auaudiomix?language=objc)
pub const kAudioUnitSubType_AUAudioMix: u32 = 0x616d6978;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_timepitch?language=objc)
pub const kAudioUnitSubType_TimePitch: u32 = 0x746d7074;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_peaklimiter?language=objc)
pub const kAudioUnitSubType_PeakLimiter: u32 = 0x6c6d7472;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_dynamicsprocessor?language=objc)
pub const kAudioUnitSubType_DynamicsProcessor: u32 = 0x64636d70;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_lowpassfilter?language=objc)
pub const kAudioUnitSubType_LowPassFilter: u32 = 0x6c706173;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_highpassfilter?language=objc)
pub const kAudioUnitSubType_HighPassFilter: u32 = 0x68706173;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_bandpassfilter?language=objc)
pub const kAudioUnitSubType_BandPassFilter: u32 = 0x62706173;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_highshelffilter?language=objc)
pub const kAudioUnitSubType_HighShelfFilter: u32 = 0x68736866;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_lowshelffilter?language=objc)
pub const kAudioUnitSubType_LowShelfFilter: u32 = 0x6c736866;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_parametriceq?language=objc)
pub const kAudioUnitSubType_ParametricEQ: u32 = 0x706d6571;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_distortion?language=objc)
pub const kAudioUnitSubType_Distortion: u32 = 0x64697374;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_delay?language=objc)
pub const kAudioUnitSubType_Delay: u32 = 0x64656c79;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_sampledelay?language=objc)
pub const kAudioUnitSubType_SampleDelay: u32 = 0x73646c79;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_nbandeq?language=objc)
pub const kAudioUnitSubType_NBandEQ: u32 = 0x6e626571;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_reverb2?language=objc)
pub const kAudioUnitSubType_Reverb2: u32 = 0x72766232;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_ausoundisolation?language=objc)
pub const kAudioUnitSubType_AUSoundIsolation: u32 = 0x766f6973;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_graphiceq?language=objc)
pub const kAudioUnitSubType_GraphicEQ: u32 = 0x67726571;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_multibandcompressor?language=objc)
pub const kAudioUnitSubType_MultiBandCompressor: u32 = 0x6d636d70;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_matrixreverb?language=objc)
pub const kAudioUnitSubType_MatrixReverb: u32 = 0x6d726576;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_pitch?language=objc)
pub const kAudioUnitSubType_Pitch: u32 = 0x746d7074;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_aufilter?language=objc)
pub const kAudioUnitSubType_AUFilter: u32 = 0x66696c74;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_netsend?language=objc)
pub const kAudioUnitSubType_NetSend: u32 = 0x6e736e64;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_rogerbeep?language=objc)
pub const kAudioUnitSubType_RogerBeep: u32 = 0x726f6772;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_multichannelmixer?language=objc)
pub const kAudioUnitSubType_MultiChannelMixer: u32 = 0x6d636d78;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_matrixmixer?language=objc)
pub const kAudioUnitSubType_MatrixMixer: u32 = 0x6d786d78;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_spatialmixer?language=objc)
pub const kAudioUnitSubType_SpatialMixer: u32 = 0x3364656d;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_stereomixer?language=objc)
pub const kAudioUnitSubType_StereoMixer: u32 = 0x736d7872;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_3dmixer?language=objc)
#[deprecated = "no longer supported"]
pub const kAudioUnitSubType_3DMixer: u32 = 0x33646d78;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_sphericalheadpanner?language=objc)
pub const kAudioUnitSubType_SphericalHeadPanner: u32 = 0x73706872;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_vectorpanner?language=objc)
pub const kAudioUnitSubType_VectorPanner: u32 = 0x76626173;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_soundfieldpanner?language=objc)
pub const kAudioUnitSubType_SoundFieldPanner: u32 = 0x616d6269;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_hrtfpanner?language=objc)
pub const kAudioUnitSubType_HRTFPanner: u32 = 0x68727466;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_netreceive?language=objc)
pub const kAudioUnitSubType_NetReceive: u32 = 0x6e726376;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_scheduledsoundplayer?language=objc)
pub const kAudioUnitSubType_ScheduledSoundPlayer: u32 = 0x7373706c;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsubtype_audiofileplayer?language=objc)
pub const kAudioUnitSubType_AudioFilePlayer: u32 = 0x6166706c;

/// These flags can be set in a callback from an audio unit during an audio unit
/// render operation from either the RenderNotify Proc or the render input
/// callback.
///
///
/// Called on a render notification Proc - which is called either before or after
/// the render operation of the audio unit. If this flag is set, the proc is being
/// called before the render operation is performed.
///
///
/// Called on a render notification Proc - which is called either before or after
/// the render operation of the audio unit. If this flag is set, the proc is being
/// called after the render operation is completed.
///
///
/// The originator of a buffer, in a render input callback, or in an audio unit's
/// render operation, may use this flag to indicate that the buffer contains
/// only silence.
///
/// The receiver of the buffer can then use the flag as a hint as to whether the
/// buffer needs to be processed or not.
///
/// Note that because the flag is only a hint, when setting the silence flag,
/// the originator of a buffer must also ensure that it contains silence (zeroes).
///
///
/// This is used with offline audio units (of type 'auol'). It is used when an
/// offline unit is being preflighted, which is performed prior to the actual
/// offline rendering actions are performed. It is used for those cases where the
/// offline process needs it (for example, with an offline unit that normalises an
/// audio file, it needs to see all of the audio data first before it can perform
/// its normalization)
///
///
/// Once an offline unit has been successfully preflighted, it is then put into
/// its render mode. So this flag is set to indicate to the audio unit that it is
/// now in that state and that it should perform its processing on the input data.
///
///
/// This flag is set when an offline unit has completed either its preflight or
/// performed render operations
///
///
/// If this flag is set on the post-render call an error was returned by the
/// AUs render operation. In this case, the error can be retrieved through the
/// lastRenderError property and the audio data in ioData handed to the post-render
/// notification will be invalid.
///
/// If this flag is set, then checks that are done on the arguments provided to render
/// are not performed. This can be useful to use to save computation time in
/// situations where you are sure you are providing the correct arguments
/// and structures to the various render calls
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitrenderactionflags?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AudioUnitRenderActionFlags(pub u32);
bitflags::bitflags! {
    impl AudioUnitRenderActionFlags: u32 {
        #[doc(alias = "kAudioUnitRenderAction_PreRender")]
        const UnitRenderAction_PreRender = 1<<2;
        #[doc(alias = "kAudioUnitRenderAction_PostRender")]
        const UnitRenderAction_PostRender = 1<<3;
        #[doc(alias = "kAudioUnitRenderAction_OutputIsSilence")]
        const UnitRenderAction_OutputIsSilence = 1<<4;
        #[doc(alias = "kAudioOfflineUnitRenderAction_Preflight")]
        const OfflineUnitRenderAction_Preflight = 1<<5;
        #[doc(alias = "kAudioOfflineUnitRenderAction_Render")]
        const OfflineUnitRenderAction_Render = 1<<6;
        #[doc(alias = "kAudioOfflineUnitRenderAction_Complete")]
        const OfflineUnitRenderAction_Complete = 1<<7;
        #[doc(alias = "kAudioUnitRenderAction_PostRenderError")]
        const UnitRenderAction_PostRenderError = 1<<8;
        #[doc(alias = "kAudioUnitRenderAction_DoNotCheckRenderArgs")]
        const UnitRenderAction_DoNotCheckRenderArgs = 1<<9;
    }
}

unsafe impl Encode for AudioUnitRenderActionFlags {
    const ENCODING: Encoding = u32::ENCODING;
}

unsafe impl RefEncode for AudioUnitRenderActionFlags {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidproperty?language=objc)
pub const kAudioUnitErr_InvalidProperty: OSStatus = -10879;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidparameter?language=objc)
pub const kAudioUnitErr_InvalidParameter: OSStatus = -10878;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidelement?language=objc)
pub const kAudioUnitErr_InvalidElement: OSStatus = -10877;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_noconnection?language=objc)
pub const kAudioUnitErr_NoConnection: OSStatus = -10876;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_failedinitialization?language=objc)
pub const kAudioUnitErr_FailedInitialization: OSStatus = -10875;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_toomanyframestoprocess?language=objc)
pub const kAudioUnitErr_TooManyFramesToProcess: OSStatus = -10874;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidfile?language=objc)
pub const kAudioUnitErr_InvalidFile: OSStatus = -10871;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_unknownfiletype?language=objc)
pub const kAudioUnitErr_UnknownFileType: OSStatus = -10870;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_filenotspecified?language=objc)
pub const kAudioUnitErr_FileNotSpecified: OSStatus = -10869;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_formatnotsupported?language=objc)
pub const kAudioUnitErr_FormatNotSupported: OSStatus = -10868;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_uninitialized?language=objc)
pub const kAudioUnitErr_Uninitialized: OSStatus = -10867;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidscope?language=objc)
pub const kAudioUnitErr_InvalidScope: OSStatus = -10866;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_propertynotwritable?language=objc)
pub const kAudioUnitErr_PropertyNotWritable: OSStatus = -10865;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_cannotdoincurrentcontext?language=objc)
pub const kAudioUnitErr_CannotDoInCurrentContext: OSStatus = -10863;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidpropertyvalue?language=objc)
pub const kAudioUnitErr_InvalidPropertyValue: OSStatus = -10851;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_propertynotinuse?language=objc)
pub const kAudioUnitErr_PropertyNotInUse: OSStatus = -10850;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_initialized?language=objc)
pub const kAudioUnitErr_Initialized: OSStatus = -10849;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidofflinerender?language=objc)
pub const kAudioUnitErr_InvalidOfflineRender: OSStatus = -10848;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_unauthorized?language=objc)
pub const kAudioUnitErr_Unauthorized: OSStatus = -10847;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_midioutputbufferfull?language=objc)
pub const kAudioUnitErr_MIDIOutputBufferFull: OSStatus = -66753;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_instancetimedout?language=objc)
pub const kAudioComponentErr_InstanceTimedOut: OSStatus = -66754;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_instanceinvalidated?language=objc)
pub const kAudioComponentErr_InstanceInvalidated: OSStatus = -66749;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_rendertimeout?language=objc)
pub const kAudioUnitErr_RenderTimeout: OSStatus = -66745;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_extensionnotfound?language=objc)
pub const kAudioUnitErr_ExtensionNotFound: OSStatus = -66744;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidparametervalue?language=objc)
pub const kAudioUnitErr_InvalidParameterValue: OSStatus = -66743;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_invalidfilepath?language=objc)
pub const kAudioUnitErr_InvalidFilePath: OSStatus = -66742;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_missingkey?language=objc)
pub const kAudioUnitErr_MissingKey: OSStatus = -66741;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_componentmanagernotsupported?language=objc)
pub const kAudioUnitErr_ComponentManagerNotSupported: OSStatus = -66740;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_multiplevoiceprocessors?language=objc)
pub const kAudioUnitErr_MultipleVoiceProcessors: OSStatus = -66635;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_duplicatedescription?language=objc)
pub const kAudioComponentErr_DuplicateDescription: OSStatus = -66752;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_unsupportedtype?language=objc)
pub const kAudioComponentErr_UnsupportedType: OSStatus = -66751;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_toomanyinstances?language=objc)
pub const kAudioComponentErr_TooManyInstances: OSStatus = -66750;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_notpermitted?language=objc)
pub const kAudioComponentErr_NotPermitted: OSStatus = -66748;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_initializationtimedout?language=objc)
pub const kAudioComponentErr_InitializationTimedOut: OSStatus = -66747;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponenterr_invalidformat?language=objc)
pub const kAudioComponentErr_InvalidFormat: OSStatus = -66746;

/// Type used for audio unit properties.
/// Properties are used to describe the state of an audio unit (for instance,
/// the input or output audio format)
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitpropertyid?language=objc)
pub type AudioUnitPropertyID = u32;

/// Type used for audio unit scopes. Apple reserves the 0
/// <
/// 1024 range for
/// audio unit scope identifiers.
/// Scopes are used to delineate a major attribute of an audio unit
/// (for instance, global, input, output)
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitscope?language=objc)
pub type AudioUnitScope = u32;

/// Type used for audio unit elements.
/// Scopes can have one or more member, and a member of a scope is
/// addressed / described by its element
/// For instance, input bus 1 is input scope, element 1
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitelement?language=objc)
pub type AudioUnitElement = u32;

/// Type used for audio unit parameters.
/// Parameters are typically used to control and set render state
/// (for instance, filter cut-off frequency)
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitparameterid?language=objc)
pub type AudioUnitParameterID = u32;

/// Type used for audio unit parameter values.
/// The value of a given parameter is specified using this type
/// (typically a Float32)
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitparametervalue?language=objc)
pub type AudioUnitParameterValue = f32;

/// The type of a parameter event (see AudioUnitScheduleParameter)
///
///
/// The parameter event describes an immediate change to the parameter value to
/// the new value
///
/// The parameter event describes a change to the parameter value that should
/// be applied over the specified period of time
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auparametereventtype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AUParameterEventType(pub u32);
impl AUParameterEventType {
    #[doc(alias = "kParameterEvent_Immediate")]
    pub const ParameterEvent_Immediate: Self = Self(1);
    #[doc(alias = "kParameterEvent_Ramped")]
    pub const ParameterEvent_Ramped: Self = Self(2);
}

unsafe impl Encode for AUParameterEventType {
    const ENCODING: Encoding = u32::ENCODING;
}

unsafe impl RefEncode for AUParameterEventType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// An audio unit parameter is defined by the triplet of audio unit scope, element
/// and parameterID. This struct is used with the functions in AudioUnitUtilities.h
/// to deal with audio unit parameters, but is included in this header file for
/// completeness.
///
///
/// The audio unit instance to which the specified parameter applies.
///
/// The parameterID for the parameter
///
/// The scope for the parameter
///
/// The element for the parameter
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitparameter?language=objc)
#[cfg(feature = "AudioComponent")]
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AudioUnitParameter {
    pub mAudioUnit: AudioUnit,
    pub mParameterID: AudioUnitParameterID,
    pub mScope: AudioUnitScope,
    pub mElement: AudioUnitElement,
}

#[cfg(feature = "AudioComponent")]
unsafe impl Encode for AudioUnitParameter {
    const ENCODING: Encoding = Encoding::Struct(
        "AudioUnitParameter",
        &[
            <AudioUnit>::ENCODING,
            <AudioUnitParameterID>::ENCODING,
            <AudioUnitScope>::ENCODING,
            <AudioUnitElement>::ENCODING,
        ],
    );
}

#[cfg(feature = "AudioComponent")]
unsafe impl RefEncode for AudioUnitParameter {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// An audio unit property is defined by the triplet of audio unit scope, element
/// and propertyID. This struct is used with the functions in AudioUnitUtilities.h
/// to deal with audio unit properties, but is included in this header file for
/// completeness.
///
///
/// The audio unit instance which the specified property applies too
///
/// The propertyID for the property
///
/// The scope for the property
///
/// The element for the property
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitproperty?language=objc)
#[cfg(feature = "AudioComponent")]
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AudioUnitProperty {
    pub mAudioUnit: AudioUnit,
    pub mPropertyID: AudioUnitPropertyID,
    pub mScope: AudioUnitScope,
    pub mElement: AudioUnitElement,
}

#[cfg(feature = "AudioComponent")]
unsafe impl Encode for AudioUnitProperty {
    const ENCODING: Encoding = Encoding::Struct(
        "AudioUnitProperty",
        &[
            <AudioUnit>::ENCODING,
            <AudioUnitPropertyID>::ENCODING,
            <AudioUnitScope>::ENCODING,
            <AudioUnitElement>::ENCODING,
        ],
    );
}

#[cfg(feature = "AudioComponent")]
unsafe impl RefEncode for AudioUnitProperty {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// This is the prototype for a function callback Proc that is used both with the
/// AudioUnit render notification API and the render input callback. See
/// kAudioUnitProperty_SetRenderCallback property or AudioUnitAddRenderNotify.
/// This callback is part of the process of a call to AudioUnitRender. As a
/// notification it is called either before or after the audio unit's render
/// operations. As a render input callback, it is called to provide input data for
/// the particular input bus the callback is attached too.
///
///
/// Parameter `inRefCon`: The client data that is provided either with the AURenderCallbackStruct or as
/// specified with the Add API call
///
/// Parameter `ioActionFlags`: Flags used to describe more about the context of this call (pre or post in the
/// notify case for instance)
///
/// Parameter `inTimeStamp`: The times stamp associated with this call of audio unit render
///
/// Parameter `inBusNumber`: The bus number associated with this call of audio unit render
///
/// Parameter `inNumberFrames`: The number of sample frames that will be represented in the audio data in the
/// provided ioData parameter
///
/// Parameter `ioData`: The AudioBufferList that will be used to contain the rendered or provided
/// audio data. These buffers will be aligned to 16 byte boundaries (which is
/// normally what malloc will return). Can be null in the notification that
/// input is available.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/aurendercallback?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AURenderCallback = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        NonNull<AudioUnitRenderActionFlags>,
        NonNull<AudioTimeStamp>,
        u32,
        u32,
        *mut AudioBufferList,
    ) -> OSStatus,
>;

/// This is the prototype for a function callback Proc that is registered with an
/// audio unit to notify the caller of any changes to a value of an audio unit
/// property. See AudioUnitAddPropertyListener
///
///
/// Parameter `inRefCon`: The client data that is provided with the add property listener registration
///
/// Parameter `inUnit`: The audio unit upon which the specified property value has changed
///
/// Parameter `inID`: The property whose value has changed
///
/// Parameter `inScope`: The scope of the property whose value has changed
///
/// Parameter `inElement`: The element ID on the scope of the property whose value has changed
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitpropertylistenerproc?language=objc)
#[cfg(feature = "AudioComponent")]
pub type AudioUnitPropertyListenerProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnit,
        AudioUnitPropertyID,
        AudioUnitScope,
        AudioUnitElement,
    ),
>;

/// This is the prototype for a function callback Proc that is registered with an
/// audio unit to notify the caller of for the user of a varispeed or AUTimePitch
/// audio unit where it is not clear what input sample is represented in the
/// rendered output samples.
///
///
/// Parameter `inRefCon`: The client data that is provided with the add property listener registration
///
/// Parameter `inOutputTimeStamp`: The time stamp that corresponds to the first sample of audio data produced in
/// AudioUnitRender (its output data)
///
/// Parameter `inInputSample`: The sample number of the input that is represented in the first sample of that
/// output time stamp
///
/// Parameter `inNumberInputSamples`: The number of input samples that are represented in an output buffer
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auinputsamplesinoutputcallback?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AUInputSamplesInOutputCallback =
    Option<unsafe extern "C-unwind" fn(NonNull<c_void>, NonNull<AudioTimeStamp>, f64, f64)>;

extern "C" {
    /// Notification generated when the set of available AudioComponents changes.
    ///
    /// Register for this notification name with `[NSNotificationCenter defaultCenter]` or
    /// `CFNotificationCenterGetLocalCenter()`, using an object of NULL.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponentregistrationschangednotification?language=objc)
    #[cfg(feature = "objc2-core-foundation")]
    pub static kAudioComponentRegistrationsChangedNotification: &'static CFString;
}

extern "C" {
    /// Notification generated when the connection to an audio unit extension process
    /// is invalidated.
    ///
    /// Register for this notification name with `[NSNotificationCenter defaultCenter]` or
    /// `CFNotificationCenterGetLocalCenter()`. The "object" refers to an AUAudioUnit instance
    /// to be observed, or can be nil to observe all instances.
    ///
    /// This notification can happen for several reasons, for instance the connection being
    /// invalidated or the process abnormally ending. There can be multiple notifications for
    /// the same event (i.e. a terminated process will also invalidate the connection).
    ///
    /// The notification's userInfo dictionary may contain the following keys, depending on
    /// the reason for the invalidation and the platform in which it's running:
    ///
    /// "
    /// audioUnit", a NSValue whose pointerValue is the AudioUnit or
    /// AudioComponentInstance which is wrapping the AUAudioUnit communicating with
    /// the extension process. (This may be null if there is no such component instance.).
    /// For example:
    ///
    /// ```text
    /// [[NSNotificationCenter defaultCenter]
    /// addObserverForName:(NSString *)kAudioComponentInstanceInvalidationNotification
    /// object:nil queue:nil usingBlock:^(NSNotification *note) {
    /// AUAudioUnit *auAudioUnit = (AUAudioUnit *)note.object;
    /// NSValue *val = note.userInfo[
    /// "
    /// audioUnit"];
    /// AudioUnit audioUnit = (AudioUnit)val.pointerValue;
    /// NSLog(
    /// "
    /// Received kAudioComponentInstanceInvalidationNotification: auAudioUnit %
    /// @
    /// , audioUnit %p",
    /// auAudioUnit, audioUnit);
    /// }];
    /// ```
    ///
    /// "
    /// Service PID", a NSNumber with the process ID for the service.
    /// "
    /// Host PID", a NSNumber with the process ID for the host.
    /// "
    /// Executable Path", a NSString with the path for the executable that may be responsible
    /// for the abnormal exit.
    /// "
    /// Descriptions" a NSArray of NSValues representing byte encoded
    /// AudioComponentDescriptions that may be responsible for the abnormal exit.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiocomponentinstanceinvalidationnotification?language=objc)
    #[cfg(feature = "objc2-core-foundation")]
    pub static kAudioComponentInstanceInvalidationNotification: &'static CFString;
}

extern "C-unwind" {
    /// initialize an audio unit
    ///
    /// Upon success, the audio unit has been successfully initialized. This means
    /// that the formats for input and output are valid and can be supported and it
    /// has based its allocations on the max number of frames that it is able to
    /// render at any given time. Once initialized, it is in a state where it can be
    /// asked to render.
    ///
    /// In common practice, major state of an audio unit (such as its I/O formats,
    /// memory allocations) cannot be changed while an audio unit is initialized.
    ///
    ///
    /// Parameter `inUnit`: The audio unit to initialize
    ///
    /// Returns: noErr, or an error representing the reasons why the audio unit was not able
    /// to be initialized successfully
    ///
    /// # Safety
    ///
    /// `in_unit` must be a valid pointer.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitInitialize(in_unit: AudioUnit) -> OSStatus;
}

extern "C-unwind" {
    /// uninitialize an audio unit
    ///
    /// Once an audio unit has been initialized, to change its state in response to
    /// some kind of environmental change, the audio unit should be uninitialized.
    /// This will have the effect of the audio unit de-allocating its resources.
    /// The caller can then reconfigure the audio unit to match the new environment
    /// (for instance, the sample rate to process audio is different than it was) and
    /// then re-initialize the audio unit when those changes have been applied.
    ///
    ///
    /// Parameter `inUnit`: The audio unit to uninitialize
    ///
    /// Returns: noErr, or an error representing the reasons why the audio unit was not able
    /// to be initialized successfully. Typically this call won't return an error
    /// unless the audio unit in question is no longer valid.
    ///
    /// # Safety
    ///
    /// `in_unit` must be a valid pointer.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitUninitialize(in_unit: AudioUnit) -> OSStatus;
}

extern "C-unwind" {
    /// retrieves information about a specified property
    ///
    /// The API can be used to retrieve both the size of the property, and whether it
    /// is writable or not. In order to get a general answer on the capability of an
    /// audio unit, this function should be called before the audio unit
    /// is initialized (as some properties are writable when the audio unit is
    /// initialized, and others not)
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inID`: the property identifier
    ///
    /// Parameter `inScope`: the scope of the property
    ///
    /// Parameter `inElement`: the element of the scope
    ///
    /// Parameter `outDataSize`: if not null, then will retrieve the maximum size for the property. if null,
    /// then it is ignored
    ///
    /// Parameter `outWritable`: if not null, then will retrieve whether the property can be written or not.
    /// if null, then it is ignored
    ///
    ///
    /// Returns: noErr, or various audio unit errors related to properties
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `out_data_size` must be a valid pointer or null.
    /// - `out_writable` must be a valid pointer or null.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitGetPropertyInfo(
        in_unit: AudioUnit,
        in_id: AudioUnitPropertyID,
        in_scope: AudioUnitScope,
        in_element: AudioUnitElement,
        out_data_size: *mut u32,
        out_writable: *mut Boolean,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// retrieves the value of a specified property
    ///
    /// The API can is used to retrieve the value of the property. Property values for
    /// audio units are always passed by reference
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inID`: the property identifier
    ///
    /// Parameter `inScope`: the scope of the property
    ///
    /// Parameter `inElement`: the element of the scope
    ///
    /// Parameter `outData`: used to retrieve the value of the property. It should point to memory at least
    /// as large as the value described by ioDataSize
    ///
    /// Parameter `ioDataSize`: on input contains the size of the data pointed to by outData, on output, the
    /// size of the data that was returned.
    ///
    ///
    /// Returns: noErr, or various audio unit errors related to properties
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `out_data` must be a valid pointer.
    /// - `io_data_size` must be a valid pointer.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitGetProperty(
        in_unit: AudioUnit,
        in_id: AudioUnitPropertyID,
        in_scope: AudioUnitScope,
        in_element: AudioUnitElement,
        out_data: NonNull<c_void>,
        io_data_size: NonNull<u32>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// sets the value of a specified property
    ///
    /// The API can is used to set the value of the property. Property values for
    /// audio units are always passed by reference
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inID`: the property identifier
    ///
    /// Parameter `inScope`: the scope of the property
    ///
    /// Parameter `inElement`: the element of the scope
    ///
    /// Parameter `inData`: if not null, then is the new value for the property that will be set. If null,
    /// then inDataSize should be zero, and the call is then used to remove a
    /// previously set value for a property. This removal is only valid for
    /// some properties, as most properties will always have a default value if not
    /// set.
    ///
    /// Parameter `inDataSize`: the size of the data being provided in inData
    ///
    ///
    /// Returns: noErr, or various audio unit errors related to properties
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `in_data` must be a valid pointer or null.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitSetProperty(
        in_unit: AudioUnit,
        in_id: AudioUnitPropertyID,
        in_scope: AudioUnitScope,
        in_element: AudioUnitElement,
        in_data: *const c_void,
        in_data_size: u32,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// registration call to receive notifications for when a property changes
    ///
    /// When an audio unit property value changes, a notification callback can be
    /// called by the audio unit to  inform interested parties that this event has
    /// occurred. The notification is defined by the tuple of inProc and
    /// inProcUserData as paired to the specified property ID, so the previously
    /// defined AudioUnitRemovePropertyListener is deprecated because it didn't allow
    /// for the provision of the inProcUserData to remove a given listener (so,
    /// you should use AudioUnitRemovePropertyListenerWithUserData).
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inID`: the property identifier
    ///
    /// Parameter `inProc`: the procedure to call when the property changes (on any scope or element)
    ///
    /// Parameter `inProcUserData`: the user data to provide with the callback
    ///
    ///
    /// Returns: noErr, or various audio unit errors related to properties
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `in_proc` must be implemented correctly.
    /// - `in_proc_user_data` must be a valid pointer or null.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitAddPropertyListener(
        in_unit: AudioUnit,
        in_id: AudioUnitPropertyID,
        in_proc: AudioUnitPropertyListenerProc,
        in_proc_user_data: *mut c_void,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// remove a previously registered property listener
    ///
    /// Removes a previously registered property listener as specified by the inProc
    /// and inProcUser data as paired to the property identifier
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inID`: the property identifier
    ///
    /// Parameter `inProc`: the procedure previously registered
    ///
    /// Parameter `inProcUserData`: the user data paired with the provided inProc
    ///
    ///
    /// Returns: noErr, or various audio unit errors related to properties
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `in_proc` must be implemented correctly.
    /// - `in_proc_user_data` must be a valid pointer or null.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitRemovePropertyListenerWithUserData(
        in_unit: AudioUnit,
        in_id: AudioUnitPropertyID,
        in_proc: AudioUnitPropertyListenerProc,
        in_proc_user_data: *mut c_void,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// a notification callback to call when an audio unit is asked to render
    ///
    /// allows an application to register a callback with an audio unit for whenever
    /// the audio unit is asked to render. The callback is called both before the
    /// audio unit performs its render operations (the render flag's pre-render bit
    /// is set) and after the audio unit has completed its render operations (the
    /// render flag's post-render bit is set). On post-render, the audio buffer list
    /// (ioData) will contain valid audio data that was rendered by the audio unit.
    ///
    /// The inProc and inProcUserData are treated as a tuple entity, so when wanting
    /// to remove one, both the inProc and its inProcUserData must be specified
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inProc`: an AURenderCallback proc
    ///
    /// Parameter `inProcUserData`: the user data that will be provided with the proc when it is called
    ///
    ///
    /// Returns: noErr, or an audio unit error code
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `in_proc` must be implemented correctly.
    /// - `in_proc_user_data` must be a valid pointer or null.
    #[cfg(all(feature = "AudioComponent", feature = "objc2-core-audio-types"))]
    pub fn AudioUnitAddRenderNotify(
        in_unit: AudioUnit,
        in_proc: AURenderCallback,
        in_proc_user_data: *mut c_void,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// remove a previously registered render notification proc
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inProc`: an AURenderCallback proc
    ///
    /// Parameter `inProcUserData`: the user data that was provided with the proc when it was previously
    /// registered
    ///
    ///
    /// Returns: noErr, or an audio unit error code
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `in_proc` must be implemented correctly.
    /// - `in_proc_user_data` must be a valid pointer or null.
    #[cfg(all(feature = "AudioComponent", feature = "objc2-core-audio-types"))]
    pub fn AudioUnitRemoveRenderNotify(
        in_unit: AudioUnit,
        in_proc: AURenderCallback,
        in_proc_user_data: *mut c_void,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Get the value of a parameter
    ///
    /// Get the value of a parameter as specified by its ID, scope and element.
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inID`: the parameter ID
    ///
    /// Parameter `inScope`: the scope for the parameter
    ///
    /// Parameter `inElement`: the element on the scope for the parameter
    ///
    /// Parameter `outValue`: Must be non-null, and upon success will contain the current value for the
    /// specified parameter
    ///
    ///
    /// Returns: noErr, or an audio unit error code (such as InvalidParameter)
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `out_value` must be a valid pointer.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitGetParameter(
        in_unit: AudioUnit,
        in_id: AudioUnitParameterID,
        in_scope: AudioUnitScope,
        in_element: AudioUnitElement,
        out_value: NonNull<AudioUnitParameterValue>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Set the value of a parameter
    ///
    /// Set the value of a parameter as specified by its ID, scope and element.
    /// Parameter IDs are consistent across all of the elements in a scope - so for a
    /// mixer, the "input volume" parameter can be applied on any input, and the
    /// particular input is specified by the elementID.
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inID`: the parameter ID
    ///
    /// Parameter `inScope`: the scope for the parameter
    ///
    /// Parameter `inElement`: the element on the scope for the parameter
    ///
    /// Parameter `inValue`: the new value for the parameter.
    ///
    /// Parameter `inBufferOffsetInFrames`: generally should be set to zero - see AudioUnitScheduleParameters
    ///
    ///
    /// Returns: noErr, or an audio unit error code (such as InvalidParameter)
    ///
    /// # Safety
    ///
    /// `in_unit` must be a valid pointer.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitSetParameter(
        in_unit: AudioUnit,
        in_id: AudioUnitParameterID,
        in_scope: AudioUnitScope,
        in_element: AudioUnitElement,
        in_value: AudioUnitParameterValue,
        in_buffer_offset_in_frames: u32,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// the render operation where ioData will contain the results of the audio unit's
    /// render operations
    ///
    /// an audio unit will render the amount of audio data described by
    /// inNumberOfFrames and the results of that render will be contained within
    /// ioData. The caller should provide audio time stamps where at least the sample
    /// time is valid and it is incrementing sequentially from its previous call
    /// (so, the next time stamp will be the current time stamp + inNumberFrames)
    /// If the sample time is not incrementing sequentially, the audio unit will infer
    /// that there is some discontinuity with the timeline it is rendering for
    ///
    /// The caller must provide a valid ioData AudioBufferList that matches the
    /// expected topology for the current audio format for the given bus. The buffer
    /// list can be of two variants:
    /// (1) If the mData pointers are non-null then the audio unit will render its
    /// output into those buffers. These buffers should be aligned to 16 byte
    /// boundaries (which is normally what malloc will return).
    /// (2) If the mData pointers are null, then the audio unit can provide pointers
    /// to its own buffers. In this case the audio unit is required to keep those
    /// buffers valid for the duration of the calling thread's I/O cycle
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `ioActionFlags`: any appropriate action flags for the render operation
    ///
    /// Parameter `inTimeStamp`: the time stamp that applies to this particular render operation. when
    /// rendering for multiple output buses the time stamp will generally be the same
    /// for each output bus, so the audio unit is able to determine without doubt that
    /// this the same render operation
    ///
    /// Parameter `inOutputBusNumber`: the output bus to render for
    ///
    /// Parameter `inNumberFrames`: the number of sample frames to render
    ///
    /// Parameter `ioData`: the audio buffer list that the audio unit is to render into.
    ///
    ///
    /// Returns: noErr, or an audio unit render error
    ///
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `io_action_flags` must be a valid pointer or null.
    /// - `in_time_stamp` must be a valid pointer.
    /// - `io_data` must be a valid pointer.
    #[cfg(all(feature = "AudioComponent", feature = "objc2-core-audio-types"))]
    pub fn AudioUnitRender(
        in_unit: AudioUnit,
        io_action_flags: *mut AudioUnitRenderActionFlags,
        in_time_stamp: NonNull<AudioTimeStamp>,
        in_output_bus_number: u32,
        in_number_frames: u32,
        io_data: NonNull<AudioBufferList>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `io_action_flags` must be a valid pointer or null.
    /// - `in_time_stamp` must be a valid pointer.
    /// - `io_data` must be a valid pointer.
    #[cfg(all(feature = "AudioComponent", feature = "objc2-core-audio-types"))]
    pub fn AudioUnitProcess(
        in_unit: AudioUnit,
        io_action_flags: *mut AudioUnitRenderActionFlags,
        in_time_stamp: NonNull<AudioTimeStamp>,
        in_number_frames: u32,
        io_data: NonNull<AudioBufferList>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// # Safety
    ///
    /// - `in_unit` must be a valid pointer.
    /// - `io_action_flags` must be a valid pointer or null.
    /// - `in_time_stamp` must be a valid pointer.
    /// - `in_input_buffer_lists` must be a valid pointer.
    /// - `io_output_buffer_lists` must be a valid pointer.
    #[cfg(all(feature = "AudioComponent", feature = "objc2-core-audio-types"))]
    pub fn AudioUnitProcessMultiple(
        in_unit: AudioUnit,
        io_action_flags: *mut AudioUnitRenderActionFlags,
        in_time_stamp: NonNull<AudioTimeStamp>,
        in_number_frames: u32,
        in_number_input_buffer_lists: u32,
        in_input_buffer_lists: NonNull<NonNull<AudioBufferList>>,
        in_number_output_buffer_lists: u32,
        io_output_buffer_lists: NonNull<NonNull<AudioBufferList>>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// reset an audio unit's render state
    ///
    /// This call will clear any render state of an audio unit. For instance, with a
    /// delay or reverb type of audio unit reset will clear any of the delay lines
    /// maintained within the audio unit. Typically, this call is made when an
    /// audio unit was previously rendering, and was taken out of the render chain
    /// (say, the track it is in was muted) and is being added back in (unmuted).
    /// The host should reset the audio unit before adding it back so that it doesn't
    /// produce audio from its delay lines that is no longer valid.
    ///
    /// The call should only clear memory, it should NOT allocate or free memory
    /// resources (this is done in the Initialize calls).
    ///
    ///
    /// Parameter `inUnit`: the audio unit
    ///
    /// Parameter `inScope`: the scope - typically this is set to GlobalScope
    ///
    /// Parameter `inElement`: the element - typically this is set to 0
    ///
    ///
    /// Returns: noErr, or an audio unit error
    ///
    /// # Safety
    ///
    /// `in_unit` must be a valid pointer.
    #[cfg(feature = "AudioComponent")]
    pub fn AudioUnitReset(
        in_unit: AudioUnit,
        in_scope: AudioUnitScope,
        in_element: AudioUnitElement,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Register an audio output unit as available to be used as an audio unit by
    /// other applications.
    ///
    ///
    /// Parameter `inOutputUnit`: The audio output unit to be published.
    ///
    /// Parameter `inDesc`: The AudioComponentDescription under which to register the application.
    ///
    /// Parameter `inName`: The application or component name.
    ///
    /// Returns: An OSStatus result code.
    ///
    ///
    /// This allows a publishing application to register its audio (input/)output unit as being able
    /// to be redirected and repurposed as an audio unit effect, generator, music device or music
    /// effect by another host application.
    ///
    /// # Safety
    ///
    /// - `in_desc` must be a valid pointer.
    /// - `in_output_unit` must be a valid pointer.
    #[cfg(all(feature = "AudioComponent", feature = "objc2-core-foundation"))]
    #[deprecated = "Inter-App Audio API is deprecated in favor of Audio Units"]
    pub fn AudioOutputUnitPublish(
        in_desc: NonNull<AudioComponentDescription>,
        in_name: &CFString,
        in_version: u32,
        in_output_unit: AudioUnit,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Fetches the time at which the application publishing the component was last active.
    ///
    /// Inter-app audio hosts can use this to sort the list of available nodes by how recently
    /// the user interacted with them.
    ///
    ///
    /// Parameter `comp`: The AudioComponent being queried.
    ///
    /// Returns: The CFAbsoluteTime at which the node was last active (0 if never).
    ///
    /// # Safety
    ///
    /// `comp` must be a valid pointer.
    #[cfg(all(feature = "AudioComponent", feature = "objc2-core-foundation"))]
    #[deprecated = "Inter-App Audio API is deprecated in favor of Audio Units"]
    pub fn AudioComponentGetLastActiveTime(comp: AudioComponent) -> CFAbsoluteTime;
}

extern "C-unwind" {
    /// Allows the implementor of an audio unit extension to dynamically modify the
    /// list of component registrations for the extension.
    ///
    /// Parameter `extensionIdentifier`: The bundle ID of the audio unit extension.
    ///
    /// Parameter `audioComponentInfo`: An array of dictionaries, one for each component, in the same format as
    /// described in AudioComponent.h for the Info.plist key "AudioComponents".
    ///
    /// Returns: An OSStatus result code.
    ///
    /// Note that the bundle ID of the process calling this API must prefix (or match)
    /// the provided extension identifier.
    ///
    /// # Safety
    ///
    /// `audio_component_info` generic must be of the correct type.
    #[cfg(feature = "objc2-core-foundation")]
    pub fn AudioUnitExtensionSetComponentList(
        extension_identifier: &CFString,
        audio_component_info: Option<&CFArray>,
    ) -> OSStatus;
}

/// Returns the component registrations for a given audio unit extension.
///
/// Parameter `extensionIdentifier`: The bundle ID of the audio unit extension.
///
/// Returns: An array of dictionaries, one for each component, in the same format as
/// described in AudioComponent.h for the Info.plist key "AudioComponents".
/// The caller should release this value when done with it.
#[cfg(feature = "objc2-core-foundation")]
#[inline]
pub unsafe extern "C-unwind" fn AudioUnitExtensionCopyComponentList(
    extension_identifier: &CFString,
) -> Option<CFRetained<CFArray>> {
    extern "C-unwind" {
        fn AudioUnitExtensionCopyComponentList(
            extension_identifier: &CFString,
        ) -> Option<NonNull<CFArray>>;
    }
    let ret = unsafe { AudioUnitExtensionCopyComponentList(extension_identifier) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitrange?language=objc)
pub const kAudioUnitRange: c_uint = 0x0000;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitinitializeselect?language=objc)
pub const kAudioUnitInitializeSelect: c_uint = 0x0001;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounituninitializeselect?language=objc)
pub const kAudioUnitUninitializeSelect: c_uint = 0x0002;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitgetpropertyinfoselect?language=objc)
pub const kAudioUnitGetPropertyInfoSelect: c_uint = 0x0003;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitgetpropertyselect?language=objc)
pub const kAudioUnitGetPropertySelect: c_uint = 0x0004;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsetpropertyselect?language=objc)
pub const kAudioUnitSetPropertySelect: c_uint = 0x0005;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitaddpropertylistenerselect?language=objc)
pub const kAudioUnitAddPropertyListenerSelect: c_uint = 0x000A;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitremovepropertylistenerselect?language=objc)
pub const kAudioUnitRemovePropertyListenerSelect: c_uint = 0x000B;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitremovepropertylistenerwithuserdataselect?language=objc)
pub const kAudioUnitRemovePropertyListenerWithUserDataSelect: c_uint = 0x0012;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitaddrendernotifyselect?language=objc)
pub const kAudioUnitAddRenderNotifySelect: c_uint = 0x000F;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitremoverendernotifyselect?language=objc)
pub const kAudioUnitRemoveRenderNotifySelect: c_uint = 0x0010;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitgetparameterselect?language=objc)
pub const kAudioUnitGetParameterSelect: c_uint = 0x0006;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitsetparameterselect?language=objc)
pub const kAudioUnitSetParameterSelect: c_uint = 0x0007;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitscheduleparametersselect?language=objc)
pub const kAudioUnitScheduleParametersSelect: c_uint = 0x0011;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitrenderselect?language=objc)
pub const kAudioUnitRenderSelect: c_uint = 0x000E;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitresetselect?language=objc)
pub const kAudioUnitResetSelect: c_uint = 0x0009;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitcomplexrenderselect?language=objc)
pub const kAudioUnitComplexRenderSelect: c_uint = 0x0013;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitprocessselect?language=objc)
pub const kAudioUnitProcessSelect: c_uint = 0x0014;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiounitprocessmultipleselect?language=objc)
pub const kAudioUnitProcessMultipleSelect: c_uint = 0x0015;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitinitializeproc?language=objc)
pub type AudioUnitInitializeProc = Option<unsafe extern "C-unwind" fn(NonNull<c_void>) -> OSStatus>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounituninitializeproc?language=objc)
pub type AudioUnitUninitializeProc =
    Option<unsafe extern "C-unwind" fn(NonNull<c_void>) -> OSStatus>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitgetpropertyinfoproc?language=objc)
pub type AudioUnitGetPropertyInfoProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitPropertyID,
        AudioUnitScope,
        AudioUnitElement,
        *mut u32,
        *mut Boolean,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitgetpropertyproc?language=objc)
pub type AudioUnitGetPropertyProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitPropertyID,
        AudioUnitScope,
        AudioUnitElement,
        NonNull<c_void>,
        NonNull<u32>,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitsetpropertyproc?language=objc)
pub type AudioUnitSetPropertyProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitPropertyID,
        AudioUnitScope,
        AudioUnitElement,
        NonNull<c_void>,
        u32,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitaddpropertylistenerproc?language=objc)
#[cfg(feature = "AudioComponent")]
pub type AudioUnitAddPropertyListenerProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitPropertyID,
        AudioUnitPropertyListenerProc,
        NonNull<c_void>,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitremovepropertylistenerproc?language=objc)
#[cfg(feature = "AudioComponent")]
pub type AudioUnitRemovePropertyListenerProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitPropertyID,
        AudioUnitPropertyListenerProc,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitremovepropertylistenerwithuserdataproc?language=objc)
#[cfg(feature = "AudioComponent")]
pub type AudioUnitRemovePropertyListenerWithUserDataProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitPropertyID,
        AudioUnitPropertyListenerProc,
        *mut c_void,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitaddrendernotifyproc?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioUnitAddRenderNotifyProc =
    Option<unsafe extern "C-unwind" fn(NonNull<c_void>, AURenderCallback, *mut c_void) -> OSStatus>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitremoverendernotifyproc?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioUnitRemoveRenderNotifyProc =
    Option<unsafe extern "C-unwind" fn(NonNull<c_void>, AURenderCallback, *mut c_void) -> OSStatus>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitresetproc?language=objc)
pub type AudioUnitResetProc = Option<
    unsafe extern "C-unwind" fn(NonNull<c_void>, AudioUnitScope, AudioUnitElement) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitcomplexrenderproc?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioUnitComplexRenderProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        *mut AudioUnitRenderActionFlags,
        NonNull<AudioTimeStamp>,
        u32,
        u32,
        NonNull<u32>,
        NonNull<AudioStreamPacketDescription>,
        NonNull<AudioBufferList>,
        NonNull<c_void>,
        NonNull<u32>,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitprocessproc?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioUnitProcessProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        *mut AudioUnitRenderActionFlags,
        NonNull<AudioTimeStamp>,
        u32,
        NonNull<AudioBufferList>,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitprocessmultipleproc?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioUnitProcessMultipleProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        *mut AudioUnitRenderActionFlags,
        NonNull<AudioTimeStamp>,
        u32,
        u32,
        NonNull<NonNull<AudioBufferList>>,
        u32,
        NonNull<NonNull<AudioBufferList>>,
    ) -> OSStatus,
>;

/// This proc can be exported through the FastDispatch property or is used as the prototype for
/// an audio component dispatch for this selector.
///
/// The arguments are the same as are provided to the corresponding API call
///
///
/// Parameter `inComponentStorage`: For a component manager component, this is the component instance storage
/// pointer
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitgetparameterproc?language=objc)
pub type AudioUnitGetParameterProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitParameterID,
        AudioUnitScope,
        AudioUnitElement,
        NonNull<AudioUnitParameterValue>,
    ) -> OSStatus,
>;

/// This proc can be exported through the FastDispatch property or is used as the prototype for
/// an audio component dispatch for this selector.
///
/// The arguments are the same as are provided to the corresponding API call
///
///
/// Parameter `inComponentStorage`: For a component manager component, this is the component instance storage
/// pointer
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitsetparameterproc?language=objc)
pub type AudioUnitSetParameterProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        AudioUnitParameterID,
        AudioUnitScope,
        AudioUnitElement,
        AudioUnitParameterValue,
        u32,
    ) -> OSStatus,
>;

/// This proc can be exported through the FastDispatch property or is used as the prototype for
/// an audio component dispatch for this selector.
///
/// The arguments are the same as are provided to the corresponding API call
///
///
/// Parameter `inComponentStorage`: For a component manager component, this is the component instance storage
/// pointer
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audiounitrenderproc?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioUnitRenderProc = Option<
    unsafe extern "C-unwind" fn(
        NonNull<c_void>,
        *mut AudioUnitRenderActionFlags,
        NonNull<AudioTimeStamp>,
        u32,
        u32,
        NonNull<AudioBufferList>,
    ) -> OSStatus,
>;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_illegalinstrument?language=objc)
#[deprecated]
pub const kAudioUnitErr_IllegalInstrument: OSStatus = -10873;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudiouniterr_instrumenttypenotfound?language=objc)
#[deprecated]
pub const kAudioUnitErr_InstrumentTypeNotFound: OSStatus = -10872;
