objc2-avf-audio 0.3.2

Bindings to the AVFAudio framework
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
//! 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::*;
use objc2_foundation::*;

use crate::*;

/// values for the primeMethod property. See further discussion under AVAudioConverterPrimeInfo.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioconverterprimemethod?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AVAudioConverterPrimeMethod(pub NSInteger);
impl AVAudioConverterPrimeMethod {
    /// Primes with leading + trailing input frames.
    #[doc(alias = "AVAudioConverterPrimeMethod_Pre")]
    pub const Pre: Self = Self(0);
    /// Only primes with trailing (zero latency). Leading frames are assumed to be silence.
    #[doc(alias = "AVAudioConverterPrimeMethod_Normal")]
    pub const Normal: Self = Self(1);
    /// Acts in "latency" mode. Both leading and trailing frames assumed to be silence.
    #[doc(alias = "AVAudioConverterPrimeMethod_None")]
    pub const None: Self = Self(2);
}

unsafe impl Encode for AVAudioConverterPrimeMethod {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

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

/// This struct is the value of the primeInfo property and specifies priming information.
///
/// When using convertToBuffer:error:withInputFromBlock: (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 convertToBuffer:error:withInputFromBlock:, or first call after
/// reset, 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
/// ------------------------------------|----------------------
/// AVAudioConverterPrimeMethod_Pre     | leadingFrames + trailingFrames
/// AVAudioConverterPrimeMethod_Normal  | trailingFrames
/// AVAudioConverterPrimeMethod_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.
///
/// AVAudioConverterPrimeMethod_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
/// AVAudioConverterPrimeMethod_Pre may be preferable.  The default method is
/// AVAudioConverterPrimeMethod_Normal, which requires no pre-seeking of the input stream and
/// generates no latency at the output.
///
/// Field: leadingFrames
/// 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 AVAudioConverterPrimeMethod_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
/// AVAudioConverterPrimeMethod_Normal or when using AVAudioConverterPrimeMethod_None.
///
/// Field: trailingFrames
/// 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
/// AVAudioConverterPrimeMethod_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/avfaudio/avaudioconverterprimeinfo?language=objc)
#[cfg(feature = "AVAudioTypes")]
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AVAudioConverterPrimeInfo {
    pub leadingFrames: AVAudioFrameCount,
    pub trailingFrames: AVAudioFrameCount,
}

#[cfg(feature = "AVAudioTypes")]
unsafe impl Encode for AVAudioConverterPrimeInfo {
    const ENCODING: Encoding = Encoding::Struct(
        "AVAudioConverterPrimeInfo",
        &[<AVAudioFrameCount>::ENCODING, <AVAudioFrameCount>::ENCODING],
    );
}

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

/// You must return one of these codes from your AVAudioConverterInputBlock.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioconverterinputstatus?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AVAudioConverterInputStatus(pub NSInteger);
impl AVAudioConverterInputStatus {
    /// This is the normal case where you supply data to the converter.
    #[doc(alias = "AVAudioConverterInputStatus_HaveData")]
    pub const HaveData: Self = Self(0);
    /// If you are out of data for now, set *ioNumberOfPackets = 0 and return
    /// AVAudioConverterInputStatus_NoDataNow; it is possible that some of the supplied input data
    /// may not be converted to output immediately, but instead may be converted to output only
    /// if/when more input is provided or the end-of-stream is indicated with the
    /// AVAudioConverterInputStatus_EndOfStream status code.
    #[doc(alias = "AVAudioConverterInputStatus_NoDataNow")]
    pub const NoDataNow: Self = Self(1);
    /// If you are at the end of stream, set *ioNumberOfPackets = 0 and return
    /// AVAudioConverterInputStatus_EndOfStream.
    #[doc(alias = "AVAudioConverterInputStatus_EndOfStream")]
    pub const EndOfStream: Self = Self(2);
}

unsafe impl Encode for AVAudioConverterInputStatus {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

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

/// These values are returned from convertToBuffer:error:withInputFromBlock:
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioconverteroutputstatus?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AVAudioConverterOutputStatus(pub NSInteger);
impl AVAudioConverterOutputStatus {
    /// All of the requested data was returned.
    #[doc(alias = "AVAudioConverterOutputStatus_HaveData")]
    pub const HaveData: Self = Self(0);
    /// Not enough input was available to satisfy the request at the current time. The output buffer
    /// contains as much as could be converted.
    #[doc(alias = "AVAudioConverterOutputStatus_InputRanDry")]
    pub const InputRanDry: Self = Self(1);
    /// The end of stream has been reached. No data was returned.
    #[doc(alias = "AVAudioConverterOutputStatus_EndOfStream")]
    pub const EndOfStream: Self = Self(2);
    /// An error occurred.
    #[doc(alias = "AVAudioConverterOutputStatus_Error")]
    pub const Error: Self = Self(3);
}

unsafe impl Encode for AVAudioConverterOutputStatus {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

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

/// A block which will be called by convertToBuffer:error:withInputFromBlock: to get input data as needed.
///
///
/// Parameter `inNumberOfPackets`: This will be the number of packets required to complete the request. You may supply more or
/// less that this amount. If less, then the input block will get called again.
///
///
/// Parameter `outStatus`: The block must set the appropriate AVAudioConverterInputStatus enum value.
///
/// If you have supplied data, set outStatus to AVAudioConverterInputStatus_HaveData and return
/// an AVAudioBuffer.
///
/// If you are out of data for now, set outStatus to AVAudioConverterInputStatus_NoDataNow and
/// return nil, and the conversion routine will return as much output as could be converted with
/// the input already supplied.
///
/// If you are at the end of stream, set outStatus to AVAudioConverterInputStatus_EndOfStream,
/// and return nil.
///
///
/// Returns: An AVAudioBuffer containing data to be converted, or nil if at end of stream or no data is
/// available. The data in the returned buffer must not be cleared or re-filled until the input
/// block is called again or the conversion has finished.
///
/// convertToBuffer:error:withInputFromBlock: will return as much output as could be converted
/// with the input already supplied.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioconverterinputblock?language=objc)
#[cfg(all(
    feature = "AVAudioBuffer",
    feature = "AVAudioTypes",
    feature = "block2"
))]
pub type AVAudioConverterInputBlock = *mut block2::DynBlock<
    dyn Fn(AVAudioPacketCount, NonNull<AVAudioConverterInputStatus>) -> *mut AVAudioBuffer,
>;

extern_class!(
    /// Converts streams of audio between various formats.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioconverter?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVAudioConverter;
);

unsafe impl Send for AVAudioConverter {}

unsafe impl Sync for AVAudioConverter {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVAudioConverter {}
);

impl AVAudioConverter {
    extern_methods!(
        #[cfg(feature = "AVAudioFormat")]
        /// Initialize from input and output formats.
        ///
        /// Parameter `fromFormat`: The input format.
        ///
        /// Parameter `toFormat`: The output format.
        ///
        /// Returns nil if the format conversion is not possible.
        #[unsafe(method(initFromFormat:toFormat:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initFromFormat_toFormat(
            this: Allocated<Self>,
            from_format: &AVAudioFormat,
            to_format: &AVAudioFormat,
        ) -> Option<Retained<Self>>;

        /// Resets the converter so that a new stream may be converted.
        #[unsafe(method(reset))]
        #[unsafe(method_family = none)]
        pub unsafe fn reset(&self);

        #[cfg(feature = "AVAudioFormat")]
        /// The format of the input audio stream. (NB. AVAudioFormat includes the channel layout)
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(inputFormat))]
        #[unsafe(method_family = none)]
        pub unsafe fn inputFormat(&self) -> Retained<AVAudioFormat>;

        #[cfg(feature = "AVAudioFormat")]
        /// The format of the output audio stream. (NB. AVAudioFormat includes the channel layout)
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(outputFormat))]
        #[unsafe(method_family = none)]
        pub unsafe fn outputFormat(&self) -> Retained<AVAudioFormat>;

        /// An array of integers indicating from which input to derive each output.
        ///
        /// The array has size equal to the number of output channels. Each element's value is the input
        /// channel number, starting with zero, that is to be copied to that output. A negative value
        /// means that the output channel will have no source and will be silent. Setting a channel map
        /// overrides channel mapping due to any channel layouts in the input and output formats that
        /// may have been supplied.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(channelMap))]
        #[unsafe(method_family = none)]
        pub unsafe fn channelMap(&self) -> Retained<NSArray<NSNumber>>;

        /// Setter for [`channelMap`][Self::channelMap].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setChannelMap:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setChannelMap(&self, channel_map: &NSArray<NSNumber>);

        /// Decoders require some data in the form of a magicCookie in order to decode properly.
        /// Encoders will produce a magicCookie.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(magicCookie))]
        #[unsafe(method_family = none)]
        pub unsafe fn magicCookie(&self) -> Option<Retained<NSData>>;

        /// Setter for [`magicCookie`][Self::magicCookie].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setMagicCookie:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMagicCookie(&self, magic_cookie: Option<&NSData>);

        /// If YES and channel remapping is necessary, then channels will be mixed as
        /// appropriate instead of remapped. Default value is NO.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(downmix))]
        #[unsafe(method_family = none)]
        pub unsafe fn downmix(&self) -> bool;

        /// Setter for [`downmix`][Self::downmix].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setDownmix:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDownmix(&self, downmix: bool);

        /// Setting YES will turn on dither, if dither makes sense in given the current formats
        /// and settings. Default value is NO.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(dither))]
        #[unsafe(method_family = none)]
        pub unsafe fn dither(&self) -> bool;

        /// Setter for [`dither`][Self::dither].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setDither:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDither(&self, dither: bool);

        /// An AVAudioQuality value as defined in AVAudioSettings.h.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(sampleRateConverterQuality))]
        #[unsafe(method_family = none)]
        pub unsafe fn sampleRateConverterQuality(&self) -> NSInteger;

        /// Setter for [`sampleRateConverterQuality`][Self::sampleRateConverterQuality].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setSampleRateConverterQuality:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSampleRateConverterQuality(
            &self,
            sample_rate_converter_quality: NSInteger,
        );

        /// An AVSampleRateConverterAlgorithmKey value as defined in AVAudioSettings.h.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(sampleRateConverterAlgorithm))]
        #[unsafe(method_family = none)]
        pub unsafe fn sampleRateConverterAlgorithm(&self) -> Option<Retained<NSString>>;

        /// Setter for [`sampleRateConverterAlgorithm`][Self::sampleRateConverterAlgorithm].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setSampleRateConverterAlgorithm:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSampleRateConverterAlgorithm(
            &self,
            sample_rate_converter_algorithm: Option<&NSString>,
        );

        /// Indicates the priming method to be used by the sample rate converter or decoder.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(primeMethod))]
        #[unsafe(method_family = none)]
        pub unsafe fn primeMethod(&self) -> AVAudioConverterPrimeMethod;

        /// Setter for [`primeMethod`][Self::primeMethod].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setPrimeMethod:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPrimeMethod(&self, prime_method: AVAudioConverterPrimeMethod);

        #[cfg(feature = "AVAudioTypes")]
        /// Indicates the the number of priming frames.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(primeInfo))]
        #[unsafe(method_family = none)]
        pub unsafe fn primeInfo(&self) -> AVAudioConverterPrimeInfo;

        #[cfg(feature = "AVAudioTypes")]
        /// Setter for [`primeInfo`][Self::primeInfo].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setPrimeInfo:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPrimeInfo(&self, prime_info: AVAudioConverterPrimeInfo);

        /// Number of packets between consecutive sync packets.
        ///
        /// A sync packet is an independently-decodable packet that completely refreshes the decoder without
        /// needing to decode other packets.  When compressing to a format which supports it (such as APAC),
        /// the audio sync packet frequency indicates the distance in packets between two sync packets, with
        /// non-sync packets between.  This is useful to set when saving compressed packets to a file and
        /// efficient random access is desired.  Note: Separating sync packets by at least one second of
        /// encoded audio (e.g. 75 packets) is recommended.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(audioSyncPacketFrequency))]
        #[unsafe(method_family = none)]
        pub unsafe fn audioSyncPacketFrequency(&self) -> NSInteger;

        /// Setter for [`audioSyncPacketFrequency`][Self::audioSyncPacketFrequency].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setAudioSyncPacketFrequency:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setAudioSyncPacketFrequency(&self, audio_sync_packet_frequency: NSInteger);

        #[cfg(feature = "AVAudioSettings")]
        /// Index to select a pre-defined content source type that describes the content type and
        /// how it was generated.  Note: This is only supported when compressing audio to formats
        /// which support it.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(contentSource))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentSource(&self) -> AVAudioContentSource;

        #[cfg(feature = "AVAudioSettings")]
        /// Setter for [`contentSource`][Self::contentSource].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setContentSource:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setContentSource(&self, content_source: AVAudioContentSource);

        #[cfg(feature = "AVAudioSettings")]
        /// Encoder Dynamic Range Control (DRC) configuration.
        ///
        /// When supported by the encoder, this property controls which configuration is applied when a
        /// bitstream is generated.  Note: This is only supported when compressing audio to formats
        /// which support it.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(dynamicRangeControlConfiguration))]
        #[unsafe(method_family = none)]
        pub unsafe fn dynamicRangeControlConfiguration(
            &self,
        ) -> AVAudioDynamicRangeControlConfiguration;

        #[cfg(feature = "AVAudioSettings")]
        /// Setter for [`dynamicRangeControlConfiguration`][Self::dynamicRangeControlConfiguration].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setDynamicRangeControlConfiguration:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDynamicRangeControlConfiguration(
            &self,
            dynamic_range_control_configuration: AVAudioDynamicRangeControlConfiguration,
        );

        #[cfg(feature = "AVAudioBuffer")]
        /// Perform a simple conversion. That is, a conversion which does not involve codecs or sample rate conversion.
        ///
        /// Parameter `inputBuffer`: The input buffer.
        ///
        /// Parameter `outputBuffer`: The output buffer.
        ///
        /// Parameter `outError`: An error if the conversion fails.
        ///
        /// Returns: YES is returned on success, NO when an error has occurred.
        ///
        /// The output buffer's frameCapacity should be at least at large as the inputBuffer's frameLength.
        /// If the conversion involves a codec or sample rate conversion, you instead must use
        /// convertToBuffer:error:withInputFromBlock:.
        #[unsafe(method(convertToBuffer:fromBuffer:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn convertToBuffer_fromBuffer_error(
            &self,
            output_buffer: &AVAudioPCMBuffer,
            input_buffer: &AVAudioPCMBuffer,
        ) -> Result<(), Retained<NSError>>;

        #[cfg(all(
            feature = "AVAudioBuffer",
            feature = "AVAudioTypes",
            feature = "block2"
        ))]
        /// Perform any supported conversion.
        ///
        /// Parameter `inputBlock`: A block which will be called to get input data as needed. See description for AVAudioConverterInputBlock.
        ///
        /// Parameter `outputBuffer`: The output buffer.
        ///
        /// Parameter `outError`: An error if the conversion fails.
        ///
        /// Returns: An AVAudioConverterOutputStatus is returned.
        ///
        /// It attempts to fill the buffer to its capacity. On return, the buffer's length indicates the number of
        /// sample frames successfully converted.
        ///
        /// # Safety
        ///
        /// `input_block` must be a valid pointer.
        #[unsafe(method(convertToBuffer:error:withInputFromBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn convertToBuffer_error_withInputFromBlock(
            &self,
            output_buffer: &AVAudioBuffer,
            out_error: Option<&mut Option<Retained<NSError>>>,
            input_block: AVAudioConverterInputBlock,
        ) -> AVAudioConverterOutputStatus;
    );
}

/// Methods declared on superclass `NSObject`.
impl AVAudioConverter {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

/// Encoding.
impl AVAudioConverter {
    extern_methods!(
        /// bitRate in bits per second. Only applies when encoding.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(bitRate))]
        #[unsafe(method_family = none)]
        pub unsafe fn bitRate(&self) -> NSInteger;

        /// Setter for [`bitRate`][Self::bitRate].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setBitRate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setBitRate(&self, bit_rate: NSInteger);

        /// When encoding, an AVEncoderBitRateStrategyKey value constant as defined in AVAudioSettings.h. Returns nil if not encoding.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(bitRateStrategy))]
        #[unsafe(method_family = none)]
        pub unsafe fn bitRateStrategy(&self) -> Option<Retained<NSString>>;

        /// Setter for [`bitRateStrategy`][Self::bitRateStrategy].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setBitRateStrategy:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setBitRateStrategy(&self, bit_rate_strategy: Option<&NSString>);

        /// The maximum size of an output packet, in bytes.
        ///
        /// When encoding it is useful to know how large a packet can be in order to allocate a buffer to receive the output.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(maximumOutputPacketSize))]
        #[unsafe(method_family = none)]
        pub unsafe fn maximumOutputPacketSize(&self) -> NSInteger;

        /// When encoding, an NSArray of NSNumber of all bit rates provided by the codec. Returns nil if not encoding.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(availableEncodeBitRates))]
        #[unsafe(method_family = none)]
        pub unsafe fn availableEncodeBitRates(&self) -> Option<Retained<NSArray<NSNumber>>>;

        /// When encoding, an NSArray of NSNumber of bit rates that can be applied based on the current formats and settings. Returns nil if not encoding.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(applicableEncodeBitRates))]
        #[unsafe(method_family = none)]
        pub unsafe fn applicableEncodeBitRates(&self) -> Option<Retained<NSArray<NSNumber>>>;

        /// When encoding, an NSArray of NSNumber of all output sample rates provided by the codec. Returns nil if not encoding.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(availableEncodeSampleRates))]
        #[unsafe(method_family = none)]
        pub unsafe fn availableEncodeSampleRates(&self) -> Option<Retained<NSArray<NSNumber>>>;

        /// When encoding, an NSArray of NSNumber of output sample rates that can be applied based on the current formats and settings. Returns nil if not encoding.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(applicableEncodeSampleRates))]
        #[unsafe(method_family = none)]
        pub unsafe fn applicableEncodeSampleRates(&self) -> Option<Retained<NSArray<NSNumber>>>;

        /// When encoding, an NSArray of NSNumber of all output channel layout tags provided by the codec. Returns nil if not encoding.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(availableEncodeChannelLayoutTags))]
        #[unsafe(method_family = none)]
        pub unsafe fn availableEncodeChannelLayoutTags(
            &self,
        ) -> Option<Retained<NSArray<NSNumber>>>;
    );
}