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

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/opaqueaudioconverter?language=objc)
#[repr(C)]
#[derive(Debug)]
pub struct OpaqueAudioConverter {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

unsafe impl RefEncode for OpaqueAudioConverter {
    const ENCODING_REF: Encoding =
        Encoding::Pointer(&Encoding::Struct("OpaqueAudioConverter", &[]));
}

/// A reference to an AudioConverter object.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audioconverterref?language=objc)
pub type AudioConverterRef = *mut OpaqueAudioConverter;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audioconverterpropertyid?language=objc)
pub type AudioConverterPropertyID = u32;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertyminimuminputbuffersize?language=objc)
pub const kAudioConverterPropertyMinimumInputBufferSize: AudioConverterPropertyID = 0x6d696273;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertyminimumoutputbuffersize?language=objc)
pub const kAudioConverterPropertyMinimumOutputBufferSize: AudioConverterPropertyID = 0x6d6f6273;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertymaximuminputpacketsize?language=objc)
pub const kAudioConverterPropertyMaximumInputPacketSize: AudioConverterPropertyID = 0x78697073;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertymaximumoutputpacketsize?language=objc)
pub const kAudioConverterPropertyMaximumOutputPacketSize: AudioConverterPropertyID = 0x786f7073;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertycalculateinputbuffersize?language=objc)
pub const kAudioConverterPropertyCalculateInputBufferSize: AudioConverterPropertyID = 0x63696273;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertycalculateoutputbuffersize?language=objc)
pub const kAudioConverterPropertyCalculateOutputBufferSize: AudioConverterPropertyID = 0x636f6273;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertyinputcodecparameters?language=objc)
pub const kAudioConverterPropertyInputCodecParameters: AudioConverterPropertyID = 0x69636470;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertyoutputcodecparameters?language=objc)
pub const kAudioConverterPropertyOutputCodecParameters: AudioConverterPropertyID = 0x6f636470;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconvertercomplexity?language=objc)
pub const kAudioConverterSampleRateConverterComplexity: AudioConverterPropertyID = 0x73726361;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconverterquality?language=objc)
pub const kAudioConverterSampleRateConverterQuality: AudioConverterPropertyID = 0x73726371;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconverterinitialphase?language=objc)
pub const kAudioConverterSampleRateConverterInitialPhase: AudioConverterPropertyID = 0x73726370;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertercodecquality?language=objc)
pub const kAudioConverterCodecQuality: AudioConverterPropertyID = 0x63647175;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterprimemethod?language=objc)
pub const kAudioConverterPrimeMethod: AudioConverterPropertyID = 0x70726d6d;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterprimeinfo?language=objc)
pub const kAudioConverterPrimeInfo: AudioConverterPropertyID = 0x7072696d;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterchannelmap?language=objc)
pub const kAudioConverterChannelMap: AudioConverterPropertyID = 0x63686d70;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterdecompressionmagiccookie?language=objc)
pub const kAudioConverterDecompressionMagicCookie: AudioConverterPropertyID = 0x646d6763;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertercompressionmagiccookie?language=objc)
pub const kAudioConverterCompressionMagicCookie: AudioConverterPropertyID = 0x636d6763;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterencodebitrate?language=objc)
pub const kAudioConverterEncodeBitRate: AudioConverterPropertyID = 0x62726174;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterencodeadjustablesamplerate?language=objc)
pub const kAudioConverterEncodeAdjustableSampleRate: AudioConverterPropertyID = 0x616a7372;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterinputchannellayout?language=objc)
pub const kAudioConverterInputChannelLayout: AudioConverterPropertyID = 0x69636c20;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverteroutputchannellayout?language=objc)
pub const kAudioConverterOutputChannelLayout: AudioConverterPropertyID = 0x6f636c20;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterapplicableencodebitrates?language=objc)
pub const kAudioConverterApplicableEncodeBitRates: AudioConverterPropertyID = 0x61656272;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverteravailableencodebitrates?language=objc)
pub const kAudioConverterAvailableEncodeBitRates: AudioConverterPropertyID = 0x76656272;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterapplicableencodesamplerates?language=objc)
pub const kAudioConverterApplicableEncodeSampleRates: AudioConverterPropertyID = 0x61657372;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverteravailableencodesamplerates?language=objc)
pub const kAudioConverterAvailableEncodeSampleRates: AudioConverterPropertyID = 0x76657372;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverteravailableencodechannellayouttags?language=objc)
pub const kAudioConverterAvailableEncodeChannelLayoutTags: AudioConverterPropertyID = 0x6165636c;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertercurrentoutputstreamdescription?language=objc)
pub const kAudioConverterCurrentOutputStreamDescription: AudioConverterPropertyID = 0x61636f64;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertercurrentinputstreamdescription?language=objc)
pub const kAudioConverterCurrentInputStreamDescription: AudioConverterPropertyID = 0x61636964;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertysettings?language=objc)
pub const kAudioConverterPropertySettings: AudioConverterPropertyID = 0x61637073;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertybitdepthhint?language=objc)
pub const kAudioConverterPropertyBitDepthHint: AudioConverterPropertyID = 0x61636264;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertyformatlist?language=objc)
pub const kAudioConverterPropertyFormatList: AudioConverterPropertyID = 0x666c7374;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertyperformdownmix?language=objc)
pub const kAudioConverterPropertyPerformDownmix: AudioConverterPropertyID = 0x646d6978;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertychannelmixmap?language=objc)
pub const kAudioConverterPropertyChannelMixMap: AudioConverterPropertyID = 0x6d6d6170;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertydithering?language=objc)
pub const kAudioConverterPropertyDithering: AudioConverterPropertyID = 0x64697468;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertyditherbitdepth?language=objc)
pub const kAudioConverterPropertyDitherBitDepth: AudioConverterPropertyID = 0x64626974;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kditheralgorithm_tpdf?language=objc)
pub const kDitherAlgorithm_TPDF: u32 = 1;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kditheralgorithm_noiseshaping?language=objc)
pub const kDitherAlgorithm_NoiseShaping: u32 = 2;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterquality_max?language=objc)
pub const kAudioConverterQuality_Max: u32 = 0x7F;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterquality_high?language=objc)
pub const kAudioConverterQuality_High: u32 = 0x60;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterquality_medium?language=objc)
pub const kAudioConverterQuality_Medium: u32 = 0x40;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterquality_low?language=objc)
pub const kAudioConverterQuality_Low: u32 = 0x20;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterquality_min?language=objc)
pub const kAudioConverterQuality_Min: u32 = 0;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconvertercomplexity_linear?language=objc)
pub const kAudioConverterSampleRateConverterComplexity_Linear: u32 = 0x6c696e65;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconvertercomplexity_normal?language=objc)
pub const kAudioConverterSampleRateConverterComplexity_Normal: u32 = 0x6e6f726d;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconvertercomplexity_mastering?language=objc)
pub const kAudioConverterSampleRateConverterComplexity_Mastering: u32 = 0x62617473;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconvertercomplexity_minimumphase?language=objc)
pub const kAudioConverterSampleRateConverterComplexity_MinimumPhase: u32 = 0x6d696e70;

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kconverterprimemethod_pre?language=objc)
pub const kConverterPrimeMethod_Pre: u32 = 0;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kconverterprimemethod_normal?language=objc)
pub const kConverterPrimeMethod_Normal: u32 = 1;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kconverterprimemethod_none?language=objc)
pub const kConverterPrimeMethod_None: u32 = 2;

/// Specifies priming information.
///
/// When using AudioConverterFillComplexBuffer() (either a single call or a series of calls), some
/// conversions, particularly involving sample-rate conversion, ideally require a certain
/// number of input frames previous to the normal start input frame and beyond the end of
/// the last expected input frame in order to yield high-quality results.
///
/// These are expressed in the leadingFrames and trailingFrames members of the structure.
///
/// The very first call to AudioConverterFillComplexBuffer(), or first call after
/// AudioConverterReset(), will request additional input frames beyond those normally
/// expected in the input proc callback to fulfill this first AudioConverterFillComplexBuffer()
/// request. The number of additional frames requested, depending on the prime method, will
/// be approximately:
///
/// Prime method                  | Additional frames
/// ------------------------------|----------------------
/// kConverterPrimeMethod_Pre     | leadingFrames + trailingFrames
/// kConverterPrimeMethod_Normal  | trailingFrames
/// kConverterPrimeMethod_None    | 0
///
/// Thus, in effect, the first input proc callback(s) may provide not only the leading
/// frames, but also may "read ahead" by an additional number of trailing frames depending
/// on the prime method.
///
/// kConverterPrimeMethod_None is useful in a real-time application processing live input,
/// in which case trailingFrames (relative to input sample rate) of through latency will be
/// seen at the beginning of the output of the AudioConverter.  In other real-time
/// applications such as DAW systems, it may be possible to provide these initial extra
/// audio frames since they are stored on disk or in memory somewhere and
/// kConverterPrimeMethod_Pre may be preferable.  The default method is
/// kConverterPrimeMethod_Normal, which requires no pre-seeking of the input stream and
/// generates no latency at the output.
///
///
/// Specifies the number of leading (previous) input frames, relative to the normal/desired
/// start input frame, required by the converter to perform a high quality conversion. If
/// using kConverterPrimeMethod_Pre, the client should "pre-seek" the input stream provided
/// through the input proc by leadingFrames. If no frames are available previous to the
/// desired input start frame (because, for example, the desired start frame is at the very
/// beginning of available audio), then provide "leadingFrames" worth of initial zero frames
/// in the input proc.  Do not "pre-seek" in the default case of
/// kConverterPrimeMethod_Normal or when using kConverterPrimeMethod_None.
///
///
/// Specifies the number of trailing input frames (past the normal/expected end input frame)
/// required by the converter to perform a high quality conversion.  The client should be
/// prepared to provide this number of additional input frames except when using
/// kConverterPrimeMethod_None. If no more frames of input are available in the input stream
/// (because, for example, the desired end frame is at the end of an audio file), then zero
/// (silent) trailing frames will be synthesized for the client.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audioconverterprimeinfo?language=objc)
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AudioConverterPrimeInfo {
    pub leadingFrames: u32,
    pub trailingFrames: u32,
}

unsafe impl Encode for AudioConverterPrimeInfo {
    const ENCODING: Encoding = Encoding::Struct(
        "AudioConverterPrimeInfo",
        &[<u32>::ENCODING, <u32>::ENCODING],
    );
}

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

/// This is an option for AudioConverterNewWithOptions which removes unnecessary
/// buffering, both for input and internally to the converter, saving memory
/// at the cost of reduced format support and usage restrictions:
///
/// - Input and output formats must be constant bit-rate, non-zero bytes per packet
/// (e.g. linear PCM, a-law, etc.) with the same sample rate and frames per packet.
/// - AudioConverterFillBuffer cannot be used.
/// - AudioConverterFillComplexBuffer cannot be used.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audioconverteroptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AudioConverterOptions(pub u32);
bitflags::bitflags! {
    impl AudioConverterOptions: u32 {
        #[doc(alias = "kAudioConverterOption_Unbuffered")]
        const Unbuffered = 1<<16;
    }
}

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

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

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_formatnotsupported?language=objc)
pub const kAudioConverterErr_FormatNotSupported: OSStatus = 0x666d743f;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_operationnotsupported?language=objc)
pub const kAudioConverterErr_OperationNotSupported: OSStatus = 0x6F703F3F;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_propertynotsupported?language=objc)
pub const kAudioConverterErr_PropertyNotSupported: OSStatus = 0x70726f70;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_invalidinputsize?language=objc)
pub const kAudioConverterErr_InvalidInputSize: OSStatus = 0x696e737a;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_invalidoutputsize?language=objc)
pub const kAudioConverterErr_InvalidOutputSize: OSStatus = 0x6f74737a;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_unspecifiederror?language=objc)
pub const kAudioConverterErr_UnspecifiedError: OSStatus = 0x77686174;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_badpropertysizeerror?language=objc)
pub const kAudioConverterErr_BadPropertySizeError: OSStatus = 0x2173697a;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_requirespacketdescriptionserror?language=objc)
pub const kAudioConverterErr_RequiresPacketDescriptionsError: OSStatus = 0x21706b64;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_inputsamplerateoutofrange?language=objc)
pub const kAudioConverterErr_InputSampleRateOutOfRange: OSStatus = 0x21697372;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertererr_outputsamplerateoutofrange?language=objc)
pub const kAudioConverterErr_OutputSampleRateOutOfRange: OSStatus = 0x216f7372;

extern "C-unwind" {
    /// Optimizes the subsequent creation of audio converters by the current process.
    ///
    /// This function performs its work asynchronously.  The optional completion block,
    /// if provided, is executed once preparation is complete.
    /// Although a best effort is made to ensure future audio converters will be created quickly,
    /// there are no guarantees.
    ///
    ///
    /// Parameter `inFlags`: Reserved for future use.  Pass 0.
    ///
    /// Parameter `ioReserved`: Reserved for future use.  Pass NULL.
    ///
    /// Parameter `inCompletionBlock`: Optional block to execute once preparation is complete.  May be NULL.
    /// The block is given the OSStatus result of the preparation.
    ///
    /// # Safety
    ///
    /// `io_reserved` must be a valid pointer or null.
    #[cfg(feature = "block2")]
    pub fn AudioConverterPrepare(
        in_flags: u32,
        io_reserved: *mut c_void,
        in_completion_block: Option<&block2::DynBlock<dyn Fn(OSStatus)>>,
    );
}

extern "C-unwind" {
    /// Create a new AudioConverter.
    ///
    ///
    /// Parameter `inSourceFormat`: The format of the source audio to be converted.
    ///
    /// Parameter `inDestinationFormat`: The destination format to which the audio is to be converted.
    ///
    /// Parameter `outAudioConverter`: On successful return, points to a new AudioConverter instance.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// For a pair of linear PCM formats, the following conversions
    /// are supported:
    ///
    /// <ul>
    /// <li>
    /// addition and removal of channels, when the stream descriptions'
    /// mChannelsPerFrame does not match. Channels may also be reordered and removed
    /// using the kAudioConverterChannelMap property.
    /// </li>
    /// <li>
    /// sample rate conversion
    /// </li>
    /// <li>
    /// interleaving/deinterleaving, when the stream descriptions' (mFormatFlags
    /// &
    /// kAudioFormatFlagIsNonInterleaved) does not match.
    /// </li>
    /// <li>
    /// conversion between any pair of the following formats:
    /// </li>
    /// <ul>
    /// <li>
    /// 8 bit integer, signed or unsigned
    /// </li>
    /// <li>
    /// 16, 24, or 32-bit integer, big- or little-endian. Other integral
    /// bit depths, if high-aligned and non-packed, are also supported
    /// </li>
    /// <li>
    /// 32 and 64-bit float, big- or little-endian.
    /// </li>
    /// </ul>
    /// </ul>
    ///
    /// Also, encoding and decoding between linear PCM and compressed formats is
    /// supported. Functions in AudioToolbox/AudioFormat.h return information about the
    /// supported formats. When using a codec, you can use any supported PCM format (as
    /// above); the converter will perform any necessary additional conversion between
    /// your PCM format and the one created or consumed by the codec.
    ///
    /// Note that AudioConverter may change the formats to correct any
    /// inconsistent or erroneous values.  The actual formats expected and used
    /// by the newly created AudioConverter can be obtained by getting the
    /// properties `kAudioConverterCurrentInputStreamDescription` and
    /// `kAudioConverterCurrentOutputStreamDescription` from it.
    ///
    /// # Safety
    ///
    /// - `in_source_format` must be a valid pointer.
    /// - `in_destination_format` must be a valid pointer.
    /// - `out_audio_converter` must be a valid pointer.
    #[cfg(feature = "objc2-core-audio-types")]
    pub fn AudioConverterNew(
        in_source_format: NonNull<AudioStreamBasicDescription>,
        in_destination_format: NonNull<AudioStreamBasicDescription>,
        out_audio_converter: NonNull<AudioConverterRef>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Create a new AudioConverter using specific codecs.
    ///
    ///
    /// Parameter `inSourceFormat`: The format of the source audio to be converted.
    ///
    /// Parameter `inDestinationFormat`: The destination format to which the audio is to be converted.
    ///
    /// Parameter `inNumberClassDescriptions`: The number of class descriptions.
    ///
    /// Parameter `inClassDescriptions`: AudioClassDescriptions specifiying the codec to instantiate.
    ///
    /// Parameter `outAudioConverter`: On successful return, points to a new AudioConverter instance.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// This function is identical to AudioConverterNew(), except that the client may
    /// explicitly choose which codec to instantiate if there is more than one choice.
    ///
    /// # Safety
    ///
    /// - `in_source_format` must be a valid pointer.
    /// - `in_destination_format` must be a valid pointer.
    /// - `in_class_descriptions` must be a valid pointer.
    /// - `out_audio_converter` must be a valid pointer.
    #[cfg(feature = "objc2-core-audio-types")]
    pub fn AudioConverterNewSpecific(
        in_source_format: NonNull<AudioStreamBasicDescription>,
        in_destination_format: NonNull<AudioStreamBasicDescription>,
        in_number_class_descriptions: u32,
        in_class_descriptions: NonNull<AudioClassDescription>,
        out_audio_converter: NonNull<AudioConverterRef>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Create a new AudioConverter with one or more options enabled.
    ///
    ///
    /// Parameter `inSourceFormat`: The format of the source audio to be converted.
    ///
    /// Parameter `inDestinationFormat`: The destination format to which the audio is to be converted.
    ///
    /// Parameter `inOptions`: Flags selecting one or more optional configurations for the AudioConverter.
    ///
    /// Parameter `outAudioConverter`: On successful return, points to a new AudioConverter instance.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// This is an alternative to AudioConverterNew which supports enabling
    /// one or more optional configurations for the new AudioConverter.
    ///
    /// # Safety
    ///
    /// - `in_source_format` must be a valid pointer.
    /// - `in_destination_format` must be a valid pointer.
    /// - `out_audio_converter` must be a valid pointer.
    #[cfg(feature = "objc2-core-audio-types")]
    pub fn AudioConverterNewWithOptions(
        in_source_format: NonNull<AudioStreamBasicDescription>,
        in_destination_format: NonNull<AudioStreamBasicDescription>,
        in_options: AudioConverterOptions,
        out_audio_converter: NonNull<AudioConverterRef>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Destroy an AudioConverter.
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to dispose.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// # Safety
    ///
    /// `in_audio_converter` must be a valid pointer.
    pub fn AudioConverterDispose(in_audio_converter: AudioConverterRef) -> OSStatus;
}

extern "C-unwind" {
    /// Reset an AudioConverter
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to reset.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// Should be called whenever there is a discontinuity in the source audio stream
    /// being provided to the converter. This will flush any internal buffers in the
    /// converter.
    ///
    /// # Safety
    ///
    /// `in_audio_converter` must be a valid pointer.
    pub fn AudioConverterReset(in_audio_converter: AudioConverterRef) -> OSStatus;
}

extern "C-unwind" {
    /// Returns information about an AudioConverter property.
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to query.
    ///
    /// Parameter `inPropertyID`: The property to query.
    ///
    /// Parameter `outSize`: If non-null, on exit, the maximum size of the property value in bytes.
    ///
    /// Parameter `outWritable`: If non-null, on exit, indicates whether the property value is writable.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `out_size` must be a valid pointer or null.
    /// - `out_writable` must be a valid pointer or null.
    pub fn AudioConverterGetPropertyInfo(
        in_audio_converter: AudioConverterRef,
        in_property_id: AudioConverterPropertyID,
        out_size: *mut u32,
        out_writable: *mut Boolean,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Returns an AudioConverter property value.
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to query.
    ///
    /// Parameter `inPropertyID`: The property to fetch.
    ///
    /// Parameter `ioPropertyDataSize`: On entry, the size of the memory pointed to by outPropertyData. On
    /// successful exit, the size of the property value.
    ///
    /// Parameter `outPropertyData`: On exit, the property value.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `io_property_data_size` must be a valid pointer.
    /// - `out_property_data` must be a valid pointer.
    pub fn AudioConverterGetProperty(
        in_audio_converter: AudioConverterRef,
        in_property_id: AudioConverterPropertyID,
        io_property_data_size: NonNull<u32>,
        out_property_data: NonNull<c_void>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Sets an AudioConverter property value.
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to modify.
    ///
    /// Parameter `inPropertyID`: The property to set.
    ///
    /// Parameter `inPropertyDataSize`: The size in bytes of the property value.
    ///
    /// Parameter `inPropertyData`: Points to the new property value.
    ///
    /// Returns: An OSStatus result code.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `in_property_data` must be a valid pointer.
    pub fn AudioConverterSetProperty(
        in_audio_converter: AudioConverterRef,
        in_property_id: AudioConverterPropertyID,
        in_property_data_size: u32,
        in_property_data: NonNull<c_void>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Converts data from an input buffer to an output buffer.
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to use.
    ///
    /// Parameter `inInputDataSize`: The size of the buffer inInputData.
    ///
    /// Parameter `inInputData`: The input audio data buffer.
    ///
    /// Parameter `ioOutputDataSize`: On entry, the size of the buffer outOutputData. On exit, the number of bytes
    /// written to outOutputData.
    ///
    /// Parameter `outOutputData`: The output data buffer.
    ///
    /// Returns: Produces a buffer of output data from an AudioConverter, using the supplied
    /// input buffer.
    ///
    /// WARNING: this function will fail for any conversion where there is a
    /// variable relationship between the input and output data buffer sizes. This
    /// includes sample rate conversions and most compressed formats. In these cases,
    /// use AudioConverterFillComplexBuffer. Generally this function is only appropriate for
    /// PCM-to-PCM conversions where there is no sample rate conversion.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `in_input_data` must be a valid pointer.
    /// - `io_output_data_size` must be a valid pointer.
    /// - `out_output_data` must be a valid pointer.
    pub fn AudioConverterConvertBuffer(
        in_audio_converter: AudioConverterRef,
        in_input_data_size: u32,
        in_input_data: NonNull<c_void>,
        io_output_data_size: NonNull<u32>,
        out_output_data: NonNull<c_void>,
    ) -> OSStatus;
}

/// Callback function for supplying input data to AudioConverterFillComplexBuffer.
///
///
/// Parameter `inAudioConverter`: The AudioConverter requesting input.
///
/// Parameter `ioNumberDataPackets`: On entry, the minimum number of packets of input audio data the converter
/// would like in order to fulfill its current FillBuffer request. On exit, the
/// number of packets of audio data actually being provided for input, or 0 if
/// there is no more input.
///
/// Parameter `ioData`: This points to an audio buffer list to be filled in by the callback to refer to the
/// buffer(s) provided by the callback.
/// On exit, the members of ioData should be set to point to the audio data
/// being provided for input.
///
/// Parameter `outDataPacketDescription`: If non-null, on exit, the callback is expected to fill this in with
/// an AudioStreamPacketDescription for each packet of input data being provided.
///
/// Parameter `inUserData`: The inInputDataProcUserData parameter passed to AudioConverterFillComplexBuffer().
///
/// Returns: An OSStatus result code.
///
/// This callback function supplies input to AudioConverterFillComplexBuffer.
///
/// The AudioConverter requests a minimum number of packets (*ioNumberDataPackets).
/// The callback may return one or more packets. If this is less than the minimum,
/// the callback will simply be called again in the near future. Note that ioNumberDataPackets counts
/// packets in terms of the converter's input format (not its output format).
/// Also note that the callback must provide a whole number of packets.
///
/// The callback may be asked to provide multiple input packets in a single call, even for compressed
/// formats.  The callback must update the number of packets pointed to by ioNumberDataPackets
/// to indicate the number of packets actually being provided, and if the packets require packet
/// descriptions, these must be filled into the array pointed to by outDataPacketDescription, one
/// packet description per packet.
///
/// The callback is given an audio buffer list pointed to by ioData.  This buffer list may refer to
/// existing buffers owned and allocated by the audio converter, in which case the callback may
/// use them and copy input audio data into them.  However, the buffer list may also be empty
/// (mDataByteSize == 0 and/or mData == NULL), in which case the callback must provide its own
/// buffers.  The callback manipulates the members of ioData to point to one or more buffers
/// of audio data (multiple buffers are used with non-interleaved PCM data). The
/// callback is responsible for not freeing or altering this buffer until it is called again.
///
/// For input data that varies from one packet to another in either size (bytes per packet)
/// or duration (frames per packet), such as when decoding compressed audio, the callback
/// should expect outDataPacketDescription to be non-null and point to array of packet descriptions,
/// which the callback must fill in, one for every packet provided by the callback.  Each packet must
/// have a valid packet description, regardless of whether or not these descriptions are different
/// from each other.  Packet descriptions are required even if there is only one packet.
///
/// If the callback returns an error, it must return zero packets of data.
/// AudioConverterFillComplexBuffer will stop producing output and return whatever
/// output has already been produced to its caller, along with the error code. This
/// mechanism can be used when an input proc has temporarily run out of data, but
/// has not yet reached end of stream.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audioconvertercomplexinputdataproc?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioConverterComplexInputDataProc = Option<
    unsafe extern "C-unwind" fn(
        AudioConverterRef,
        NonNull<u32>,
        NonNull<AudioBufferList>,
        *mut *mut AudioStreamPacketDescription,
        *mut c_void,
    ) -> OSStatus,
>;

/// Realtime-safe variant of AudioConverterComplexInputDataProc.
///
/// See the discussions of AudioConverterComplexInputDataProc and AudioConverterFillComplexBuffer.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audioconvertercomplexinputdataprocrealtimesafe?language=objc)
#[cfg(feature = "objc2-core-audio-types")]
pub type AudioConverterComplexInputDataProcRealtimeSafe = Option<
    unsafe extern "C-unwind" fn(
        AudioConverterRef,
        NonNull<u32>,
        NonNull<AudioBufferList>,
        *mut *mut AudioStreamPacketDescription,
        *mut c_void,
    ) -> OSStatus,
>;

extern "C-unwind" {
    /// Converts data supplied by an input callback function, supporting non-interleaved
    /// and packetized formats.
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to use.
    ///
    /// Parameter `inInputDataProc`: A callback function which supplies the input data.
    ///
    /// Parameter `inInputDataProcUserData`: A value for the use of the callback function.
    ///
    /// Parameter `ioOutputDataPacketSize`: On entry, the capacity of outOutputData expressed in packets in the
    /// converter's output format. On exit, the number of packets of converted
    /// data that were written to outOutputData.
    ///
    /// Parameter `outOutputData`: The converted output data is written to this buffer. On entry, the buffers'
    /// mDataByteSize fields (which must all be the same) reflect buffer capacity.
    /// On exit, mDataByteSize is set to the number of bytes written.
    ///
    /// Parameter `outPacketDescription`: If non-null, and the converter's output uses packet descriptions, then
    /// packet descriptions are written to this array. It must point to a memory
    /// block capable of holding *ioOutputDataPacketSize packet descriptions.
    /// (See AudioFormat.h for ways to determine whether an audio format
    /// uses packet descriptions).
    ///
    /// Returns: An OSStatus result code.
    ///
    /// Produces a buffer list of output data from an AudioConverter. The supplied input
    /// callback function is called whenever necessary.
    ///
    /// If the output format uses packet descriptions, such as most compressed formats where packets
    /// vary in size or duration, the caller is expected to provide a buffer for holding packet descriptions,
    /// pointed to by outPacketDescription.  The array must have the capacity to hold a packet description
    /// for each output packet that may be written.  A packet description array is expected even if only
    /// a single output packet is to be written.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `in_input_data_proc` must be implemented correctly.
    /// - `in_input_data_proc_user_data` must be a valid pointer or null.
    /// - `io_output_data_packet_size` must be a valid pointer.
    /// - `out_output_data` must be a valid pointer.
    /// - `out_packet_description` must be a valid pointer or null.
    #[cfg(feature = "objc2-core-audio-types")]
    pub fn AudioConverterFillComplexBuffer(
        in_audio_converter: AudioConverterRef,
        in_input_data_proc: AudioConverterComplexInputDataProc,
        in_input_data_proc_user_data: *mut c_void,
        io_output_data_packet_size: NonNull<u32>,
        out_output_data: NonNull<AudioBufferList>,
        out_packet_description: *mut AudioStreamPacketDescription,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Identical to AudioConverterFillComplexBuffer, with the addition of a realtime-safety
    /// guarantee.
    ///
    /// Conversions involving only PCM formats -- interleaving, deinterleaving, channel count changes,
    /// sample rate conversions -- are realtime-safe. Such conversions may use this API in order to
    /// obtain compiler checks involving the `CA_REALTIME_API` attributes.
    ///
    /// At runtime, this function returns `kAudioConverterErr_OperationNotSupported` if the conversion
    /// requires non-realtime-safe functionality.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `in_input_data_proc` must be implemented correctly.
    /// - `in_input_data_proc_user_data` must be a valid pointer or null.
    /// - `io_output_data_packet_size` must be a valid pointer.
    /// - `out_output_data` must be a valid pointer.
    /// - `out_packet_description` must be a valid pointer or null.
    #[cfg(feature = "objc2-core-audio-types")]
    pub fn AudioConverterFillComplexBufferRealtimeSafe(
        in_audio_converter: AudioConverterRef,
        in_input_data_proc: AudioConverterComplexInputDataProcRealtimeSafe,
        in_input_data_proc_user_data: *mut c_void,
        io_output_data_packet_size: NonNull<u32>,
        out_output_data: NonNull<AudioBufferList>,
        out_packet_description: *mut AudioStreamPacketDescription,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Converts audio data supplied by a callback function, supporting non-interleaved and
    /// packetized formats, and also supporting packet dependency descriptions.
    ///
    /// For output formats that use packet dependency descriptions, this must be used instead of
    /// AudioConverterFillComplexBuffer, which will return an error for such formats.
    ///
    /// Parameter `inAudioConverter`: The audio converter to use for format conversion.
    ///
    /// Parameter `inInputDataProc`: A callback function that supplies audio data to convert.
    /// This callback is invoked repeatedly as the converter is ready for
    /// new input data.
    ///
    /// Parameter `inInputDataProcUserData`: Custom data for use by your application when receiving a
    /// callback invocation.
    ///
    /// Parameter `ioOutputDataPacketSize`: On input, the size of the output buffer (in the `outOutputData`
    /// parameter), expressed in number packets in the audio converter’s
    /// output format.  On output, the number of packets of converted data
    /// that were written to the output buffer.
    ///
    /// Parameter `outOutputData`: The converted output data is written to this buffer. On entry, the
    /// buffers' `mDataByteSize` fields (which must all be the same) reflect
    /// buffer capacity.  On exit, `mDataByteSize` is set to the number of
    /// bytes written.
    ///
    /// Parameter `outPacketDescriptions`: If not `NULL`, and if the audio converter's output format uses packet
    /// descriptions, this must point to a block of memory capable of holding
    /// the number of packet descriptions specified in the `ioOutputDataPacketSize`
    /// parameter.  (See _Audio Format Services Reference_ for functions that
    /// let you determine whether an audio format uses packet descriptions).
    /// If not `NULL` on output and if the audio converter's output format
    /// uses packet descriptions, then this parameter contains an array of
    /// packet descriptions.
    ///
    /// Parameter `outPacketDependencies`: Should point to a memory block capable of holding the number of
    /// packet dependency description structures specified in the
    /// `ioOutputDataPacketSize` parameter.  Must not be `NULL`.  This array
    /// will be filled out only by encoders that produce a format which has a
    /// non-zero value for `kAudioFormatProperty_FormatEmploysDependentPackets`.
    ///
    /// Returns: A result code.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `in_input_data_proc` must be implemented correctly.
    /// - `in_input_data_proc_user_data` must be a valid pointer or null.
    /// - `io_output_data_packet_size` must be a valid pointer.
    /// - `out_output_data` must be a valid pointer.
    /// - `out_packet_descriptions` must be a valid pointer or null.
    /// - `out_packet_dependencies` must be a valid pointer.
    #[cfg(feature = "objc2-core-audio-types")]
    pub fn AudioConverterFillComplexBufferWithPacketDependencies(
        in_audio_converter: AudioConverterRef,
        in_input_data_proc: AudioConverterComplexInputDataProc,
        in_input_data_proc_user_data: *mut c_void,
        io_output_data_packet_size: NonNull<u32>,
        out_output_data: NonNull<AudioBufferList>,
        out_packet_descriptions: *mut AudioStreamPacketDescription,
        out_packet_dependencies: NonNull<AudioStreamPacketDependencyDescription>,
    ) -> OSStatus;
}

extern "C-unwind" {
    /// Converts PCM data from an input buffer list to an output buffer list.
    ///
    ///
    /// Parameter `inAudioConverter`: The AudioConverter to use.
    ///
    /// Parameter `inNumberPCMFrames`: The number of PCM frames to convert.
    ///
    /// Parameter `inInputData`: The source audio buffer list.
    ///
    /// Parameter `outOutputData`: The converted output data is written to this buffer list.
    ///
    /// Returns: An OSStatus result code.
    ///
    ///
    /// Warning: This function will fail for any conversion where there is a
    /// variable relationship between the input and output data buffer sizes. This
    /// includes sample rate conversions and most compressed formats. In these cases,
    /// use AudioConverterFillComplexBuffer. Generally this function is only appropriate for
    /// PCM-to-PCM conversions where there is no sample rate conversion.
    ///
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `in_input_data` must be a valid pointer.
    /// - `out_output_data` must be a valid pointer.
    #[cfg(feature = "objc2-core-audio-types")]
    pub fn AudioConverterConvertComplexBuffer(
        in_audio_converter: AudioConverterRef,
        in_number_pcm_frames: u32,
        in_input_data: NonNull<AudioBufferList>,
        out_output_data: NonNull<AudioBufferList>,
    ) -> OSStatus;
}

/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconverterpropertymaximuminputbuffersize?language=objc)
pub const kAudioConverterPropertyMaximumInputBufferSize: AudioConverterPropertyID = 0x78696273;
/// [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/kaudioconvertersamplerateconverteralgorithm?language=objc)
pub const kAudioConverterSampleRateConverterAlgorithm: AudioConverterPropertyID = 0x73726369;

/// Callback function for supplying input data to AudioConverterFillBuffer.
///
///
/// Parameter `inAudioConverter`: The AudioConverter requesting input.
///
/// Parameter `ioDataSize`: On entry, the minimum number of bytes of audio data the converter
/// would like in order to fulfill its current FillBuffer request.
/// On exit, the number of bytes of audio data actually being provided
/// for input, or 0 if there is no more input.
///
/// Parameter `outData`: On exit, *outData should point to the audio data being provided
/// for input.
///
/// Parameter `inUserData`: The inInputDataProcUserData parameter passed to AudioConverterFillBuffer().
///
/// Returns: An OSStatus result code.
///
/// This callback function supplies input to AudioConverterFillBuffer.
///
/// The AudioConverter requests a minimum amount of data (*ioDataSize). The callback
/// may return any amount of data. If it is less than than the minimum, the callback
/// will simply be called again in the near future.
///
/// The callback supplies a pointer to a buffer of audio data. The callback is
/// responsible for not freeing or altering this buffer until it is called again.
///
/// If the callback returns an error, it must return zero bytes of data.
/// AudioConverterFillBuffer will stop producing output and return whatever output
/// has already been produced to its caller, along with the error code. This
/// mechanism can be used when an input proc has temporarily run out of data, but
/// has not yet reached end of stream.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/audioconverterinputdataproc?language=objc)
pub type AudioConverterInputDataProc = Option<
    unsafe extern "C-unwind" fn(
        AudioConverterRef,
        NonNull<u32>,
        NonNull<NonNull<c_void>>,
        *mut c_void,
    ) -> OSStatus,
>;

extern "C-unwind" {
    /// # Safety
    ///
    /// - `in_audio_converter` must be a valid pointer.
    /// - `in_input_data_proc` must be implemented correctly.
    /// - `in_input_data_proc_user_data` must be a valid pointer or null.
    /// - `io_output_data_size` must be a valid pointer.
    /// - `out_output_data` must be a valid pointer.
    #[deprecated = "no longer supported"]
    pub fn AudioConverterFillBuffer(
        in_audio_converter: AudioConverterRef,
        in_input_data_proc: AudioConverterInputDataProc,
        in_input_data_proc_user_data: *mut c_void,
        io_output_data_size: NonNull<u32>,
        out_output_data: NonNull<c_void>,
    ) -> OSStatus;
}
