objc2_avf_audio/generated/AVAudioEngine.rs
1//! This file has been automatically generated by `objc2`'s `header-translator`.
2//! DO NOT EDIT
3use core::ffi::*;
4use core::ptr::NonNull;
5use objc2::__framework_prelude::*;
6#[cfg(feature = "objc2-audio-toolbox")]
7#[cfg(not(target_os = "watchos"))]
8use objc2_audio_toolbox::*;
9#[cfg(feature = "objc2-core-audio-types")]
10use objc2_core_audio_types::*;
11use objc2_foundation::*;
12
13use crate::*;
14
15/// Error codes that could be returned from AVAudioEngine manual rendering mode methods,
16/// e.g. `enableManualRenderingMode:format:maximumFrameCount:error:` and
17/// `renderOffline:toBuffer:error:`.
18/// Note that this is not a comprehensive list, and the underlying audio units could
19/// return other error codes (e.g. see kAudioUnitErr_* in AudioToolbox/AUComponent.h) from these
20/// methods as applicable.
21///
22/// AVAudioEngineManualRenderingErrorInvalidMode
23/// The operation cannot be performed because the engine is either not in manual
24/// rendering mode or the right variant of it.
25///
26/// AVAudioEngineManualRenderingErrorInitialized
27/// The operation cannot be performed because the engine is initialized (i.e. not stopped).
28///
29/// AVAudioEngineManualRenderingErrorNotRunning
30/// The operation cannot be performed because the engine is not running (i.e. not started).
31///
32/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioenginemanualrenderingerror?language=objc)
33// NS_ENUM
34#[repr(transparent)]
35#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
36pub struct AVAudioEngineManualRenderingError(pub OSStatus);
37impl AVAudioEngineManualRenderingError {
38 #[doc(alias = "AVAudioEngineManualRenderingErrorInvalidMode")]
39 pub const InvalidMode: Self = Self(-80800);
40 #[doc(alias = "AVAudioEngineManualRenderingErrorInitialized")]
41 pub const Initialized: Self = Self(-80801);
42 #[doc(alias = "AVAudioEngineManualRenderingErrorNotRunning")]
43 pub const NotRunning: Self = Self(-80802);
44}
45
46unsafe impl Encode for AVAudioEngineManualRenderingError {
47 const ENCODING: Encoding = OSStatus::ENCODING;
48}
49
50unsafe impl RefEncode for AVAudioEngineManualRenderingError {
51 const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
52}
53
54/// Status codes returned from the render call to the engine operating in manual rendering mode.
55///
56/// AVAudioEngineManualRenderingStatusError
57/// An error occurred when rendering and no data was returned. See the returned error code
58/// for the description of the error.
59///
60/// AVAudioEngineManualRenderingStatusSuccess
61/// All of the requested data was returned successfully.
62///
63/// AVAudioEngineManualRenderingStatusInsufficientDataFromInputNode
64/// Applicable only to the input node, when it provides input data for rendering
65/// (see `AVAudioInputNode(setManualRenderingInputPCMFormat:inputBlock:)`).
66/// Indicates that not enough input data was returned by the input node to satisfy the
67/// render request at the current time. The output buffer may contain data rendered by other
68/// active sources in the engine's processing graph.
69///
70/// AVAudioEngineManualRenderingStatusCannotDoInCurrentContext
71/// The operation could not be performed now, but the client could retry later if needed.
72/// This is usually to guard a realtime render operation (e.g. rendering through
73/// `manualRenderingBlock`) when a reconfiguration of the engine's internal state
74/// is in progress.
75///
76/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioenginemanualrenderingstatus?language=objc)
77// NS_ENUM
78#[repr(transparent)]
79#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
80pub struct AVAudioEngineManualRenderingStatus(pub NSInteger);
81impl AVAudioEngineManualRenderingStatus {
82 #[doc(alias = "AVAudioEngineManualRenderingStatusError")]
83 pub const Error: Self = Self(-1);
84 #[doc(alias = "AVAudioEngineManualRenderingStatusSuccess")]
85 pub const Success: Self = Self(0);
86 #[doc(alias = "AVAudioEngineManualRenderingStatusInsufficientDataFromInputNode")]
87 pub const InsufficientDataFromInputNode: Self = Self(1);
88 #[doc(alias = "AVAudioEngineManualRenderingStatusCannotDoInCurrentContext")]
89 pub const CannotDoInCurrentContext: Self = Self(2);
90}
91
92unsafe impl Encode for AVAudioEngineManualRenderingStatus {
93 const ENCODING: Encoding = NSInteger::ENCODING;
94}
95
96unsafe impl RefEncode for AVAudioEngineManualRenderingStatus {
97 const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
98}
99
100/// By default, the engine is connected to an audio device and automatically renders in realtime.
101/// It can also be configured to operate in manual rendering mode, i.e. not connected to an
102/// audio device and rendering in response to requests from the client.
103///
104/// AVAudioEngineManualRenderingModeOffline
105/// The engine operates in an offline mode without any realtime constraints.
106///
107/// AVAudioEngineManualRenderingModeRealtime
108/// The engine operates under realtime constraints, i.e. it will not make any blocking call
109/// (e.g. calling libdispatch, blocking on a mutex, allocating memory etc.) while rendering.
110/// Note that only the block based render mechanism can be used in this mode
111/// (see `AVAudioEngine(manualRenderingBlock)`.
112///
113/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioenginemanualrenderingmode?language=objc)
114// NS_ENUM
115#[repr(transparent)]
116#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
117pub struct AVAudioEngineManualRenderingMode(pub NSInteger);
118impl AVAudioEngineManualRenderingMode {
119 #[doc(alias = "AVAudioEngineManualRenderingModeOffline")]
120 pub const Offline: Self = Self(0);
121 #[doc(alias = "AVAudioEngineManualRenderingModeRealtime")]
122 pub const Realtime: Self = Self(1);
123}
124
125unsafe impl Encode for AVAudioEngineManualRenderingMode {
126 const ENCODING: Encoding = NSInteger::ENCODING;
127}
128
129unsafe impl RefEncode for AVAudioEngineManualRenderingMode {
130 const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
131}
132
133/// Block to render the engine when operating in manual rendering mode
134///
135/// Parameter `numberOfFrames`: The number of PCM sample frames to be rendered
136///
137/// Parameter `outBuffer`: The PCM buffer to which the engine must render the audio.
138/// The buffer pointers (outBuffer->mBuffers[x].mData) may be null on entry, in which case
139/// the block will render into a memory it owns and modify the mData pointers to point to that
140/// memory. The block is responsible for preserving the validity of that memory until it is next
141/// called to render, or `AVAudioEngine(stop)` is called.
142///
143/// Parameter `outError`: On exit, if an error occurs during rendering, a description of the error (see
144/// `AVAudioEngineManualRenderingError` for the possible errors)
145///
146/// Returns: One of the status codes from `AVAudioEngineManualRenderingStatus`. Irrespective of the
147/// returned status code, on exit, the output buffer's mDataByteSize
148/// (outBuffer->mBuffers[x].mDataByteSize) will indicate the number of PCM data bytes rendered by
149/// the engine.
150///
151/// Use this if you want to render the engine from a realtime context when it is operating in
152/// the manual rendering mode. See `AVAudioEngine(manualRenderingBlock)` for details.
153///
154/// Note that when using AVAudioEngine manual rendering with
155/// `AVAudioEngineManualRenderingModeRealtime`, calling into the engine or related classes
156/// from a non-realtime thread (e.g. for setting or getting node properties), can cause
157/// `AVAudioEngineManualRenderingBlock` on the IO thread to return
158/// `AVAudioEngineManualRenderingStatusCannotDoInCurrentContext`.
159///
160/// This is because interacting with some of these properties requires synchronization between
161/// the realtime and calling threads.
162///
163/// In such a case, the client could implement their own synchronization between their realtime
164/// and non-realtime threads and retry calling `AVAudioEngineManualRenderingBlock`.
165///
166/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioenginemanualrenderingblock?language=objc)
167#[cfg(all(
168 feature = "AVAudioTypes",
169 feature = "block2",
170 feature = "objc2-core-audio-types"
171))]
172pub type AVAudioEngineManualRenderingBlock = *mut block2::DynBlock<
173 dyn Fn(
174 AVAudioFrameCount,
175 NonNull<AudioBufferList>,
176 *mut OSStatus,
177 ) -> AVAudioEngineManualRenderingStatus,
178>;
179
180extern_class!(
181 /// An AVAudioEngine contains a group of connected AVAudioNodes ("nodes"), each of which performs
182 /// an audio signal generation, processing, or input/output task.
183 ///
184 /// Nodes are created separately and attached to the engine.
185 ///
186 /// The engine supports dynamic connection, disconnection and removal of nodes while running,
187 /// with only minor limitations:
188 /// - all dynamic reconnections must occur upstream of a mixer
189 /// - while removals of effects will normally result in the automatic connection of the adjacent
190 /// nodes, removal of a node which has differing input vs. output channel counts, or which
191 /// is a mixer, is likely to result in a broken graph.
192 ///
193 /// By default, the engine is connected to an audio device and automatically renders in realtime.
194 /// It can also be configured to operate in manual rendering mode, i.e. not connected to an
195 /// audio device and rendering in response to requests from the client, normally at or
196 /// faster than realtime rate.
197 ///
198 /// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioengine?language=objc)
199 #[unsafe(super(NSObject))]
200 #[derive(Debug, PartialEq, Eq, Hash)]
201 pub struct AVAudioEngine;
202);
203
204extern_conformance!(
205 unsafe impl NSObjectProtocol for AVAudioEngine {}
206);
207
208impl AVAudioEngine {
209 extern_methods!(
210 /// Initialize a new engine.
211 ///
212 /// On creation, the engine is by default connected to an audio device and automatically renders
213 /// in realtime. It can be configured to operate in manual rendering mode through
214 /// `enableManualRenderingMode:format:maximumFrameCount:error:`.
215 #[unsafe(method(init))]
216 #[unsafe(method_family = init)]
217 pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
218
219 #[cfg(feature = "AVAudioNode")]
220 /// Take ownership of a new node.
221 ///
222 /// Parameter `node`: The node to be attached to the engine.
223 ///
224 /// To support the instantiation of arbitrary AVAudioNode subclasses, instances are created
225 /// externally to the engine, but are not usable until they are attached to the engine via
226 /// this method. Thus the idiom, without ARC, is:
227 ///
228 /// ```text
229 /// // when building engine:
230 /// AVAudioNode *_player; // member of controller class (for example)
231 /// ...
232 /// _player = [[AVAudioPlayerNode alloc] init];
233 /// [engine attachNode: _player];
234 /// ...
235 /// // when destroying engine (without ARC)
236 /// [_player release];
237 /// ```
238 #[unsafe(method(attachNode:))]
239 #[unsafe(method_family = none)]
240 pub unsafe fn attachNode(&self, node: &AVAudioNode);
241
242 #[cfg(feature = "AVAudioNode")]
243 /// Detach a node previously attached to the engine.
244 ///
245 /// If necessary, the engine will safely disconnect the node before detaching it.
246 #[unsafe(method(detachNode:))]
247 #[unsafe(method_family = none)]
248 pub unsafe fn detachNode(&self, node: &AVAudioNode);
249
250 #[cfg(all(
251 feature = "AVAudioFormat",
252 feature = "AVAudioNode",
253 feature = "AVAudioTypes"
254 ))]
255 /// Establish a connection between two nodes.
256 ///
257 /// Parameter `node1`: The source node
258 ///
259 /// Parameter `node2`: The destination node
260 ///
261 /// Parameter `bus1`: The output bus on the source node
262 ///
263 /// Parameter `bus2`: The input bus on the destination node
264 ///
265 /// Parameter `format`: If non-nil, the format of the source node's output bus is set to this
266 /// format. In all cases, the format of the destination node's input bus is set to
267 /// match that of the source node's output bus.
268 ///
269 /// Nodes have input and output buses (AVAudioNodeBus). Use this method to establish
270 /// one-to-one connections betweeen nodes. Connections made using this method are always
271 /// one-to-one, never one-to-many or many-to-one.
272 ///
273 /// Note that any pre-existing connection(s) involving the source's output bus or the
274 /// destination's input bus will be broken.
275 #[unsafe(method(connect:to:fromBus:toBus:format:))]
276 #[unsafe(method_family = none)]
277 pub unsafe fn connect_to_fromBus_toBus_format(
278 &self,
279 node1: &AVAudioNode,
280 node2: &AVAudioNode,
281 bus1: AVAudioNodeBus,
282 bus2: AVAudioNodeBus,
283 format: Option<&AVAudioFormat>,
284 );
285
286 #[cfg(all(feature = "AVAudioFormat", feature = "AVAudioNode"))]
287 /// Establish a connection between two nodes
288 ///
289 /// This calls connect:to:fromBus:toBus:format: using bus 0 on the source node,
290 /// and bus 0 on the destination node, except in the case of a destination which is a mixer,
291 /// in which case the destination is the mixer's nextAvailableInputBus.
292 #[unsafe(method(connect:to:format:))]
293 #[unsafe(method_family = none)]
294 pub unsafe fn connect_to_format(
295 &self,
296 node1: &AVAudioNode,
297 node2: &AVAudioNode,
298 format: Option<&AVAudioFormat>,
299 );
300
301 #[cfg(all(
302 feature = "AVAudioConnectionPoint",
303 feature = "AVAudioFormat",
304 feature = "AVAudioNode",
305 feature = "AVAudioTypes"
306 ))]
307 /// Establish connections between a source node and multiple destination nodes.
308 ///
309 /// Parameter `sourceNode`: The source node
310 ///
311 /// Parameter `destNodes`: An array of AVAudioConnectionPoint objects specifying destination
312 /// nodes and busses
313 ///
314 /// Parameter `sourceBus`: The output bus on source node
315 ///
316 /// Parameter `format`: If non-nil, the format of the source node's output bus is set to this
317 /// format. In all cases, the format of the destination nodes' input bus is set to
318 /// match that of the source node's output bus
319 ///
320 /// Use this method to establish connections from a source node to multiple destination nodes.
321 /// Connections made using this method are either one-to-one (when a single destination
322 /// connection is specified) or one-to-many (when multiple connections are specified), but
323 /// never many-to-one.
324 ///
325 /// To incrementally add a new connection to a source node, use this method with an array
326 /// of AVAudioConnectionPoint objects comprising of pre-existing connections (obtained from
327 /// `outputConnectionPointsForNode:outputBus:`) and the new connection.
328 ///
329 /// Note that any pre-existing connection involving the destination's input bus will be
330 /// broken. And, any pre-existing connection on source node which is not a part of the
331 /// specified destination connection array will also be broken.
332 ///
333 /// Also note that when the output of a node is split into multiple paths, all the paths
334 /// must render at the same rate until they reach a common mixer.
335 /// In other words, starting from the split node until the common mixer node where all split
336 /// paths terminate, you cannot have:
337 /// - any AVAudioUnitTimeEffect
338 /// - any sample rate conversion
339 #[unsafe(method(connect:toConnectionPoints:fromBus:format:))]
340 #[unsafe(method_family = none)]
341 pub unsafe fn connect_toConnectionPoints_fromBus_format(
342 &self,
343 source_node: &AVAudioNode,
344 dest_nodes: &NSArray<AVAudioConnectionPoint>,
345 source_bus: AVAudioNodeBus,
346 format: Option<&AVAudioFormat>,
347 );
348
349 #[cfg(all(feature = "AVAudioNode", feature = "AVAudioTypes"))]
350 /// Remove a connection between two nodes.
351 ///
352 /// Parameter `node`: The node whose input is to be disconnected
353 ///
354 /// Parameter `bus`: The destination's input bus to disconnect
355 #[unsafe(method(disconnectNodeInput:bus:))]
356 #[unsafe(method_family = none)]
357 pub unsafe fn disconnectNodeInput_bus(&self, node: &AVAudioNode, bus: AVAudioNodeBus);
358
359 #[cfg(feature = "AVAudioNode")]
360 /// Remove a connection between two nodes.
361 ///
362 /// Parameter `node`: The node whose inputs are to be disconnected
363 ///
364 /// Connections are broken on each of the node's input busses.
365 #[unsafe(method(disconnectNodeInput:))]
366 #[unsafe(method_family = none)]
367 pub unsafe fn disconnectNodeInput(&self, node: &AVAudioNode);
368
369 #[cfg(all(feature = "AVAudioNode", feature = "AVAudioTypes"))]
370 /// Remove a connection between two nodes.
371 ///
372 /// Parameter `node`: The node whose output is to be disconnected
373 ///
374 /// Parameter `bus`: The source's output bus to disconnect
375 #[unsafe(method(disconnectNodeOutput:bus:))]
376 #[unsafe(method_family = none)]
377 pub unsafe fn disconnectNodeOutput_bus(&self, node: &AVAudioNode, bus: AVAudioNodeBus);
378
379 #[cfg(feature = "AVAudioNode")]
380 /// Remove a connection between two nodes.
381 ///
382 /// Parameter `node`: The node whose outputs are to be disconnected
383 ///
384 /// Connections are broken on each of the node's output busses.
385 #[unsafe(method(disconnectNodeOutput:))]
386 #[unsafe(method_family = none)]
387 pub unsafe fn disconnectNodeOutput(&self, node: &AVAudioNode);
388
389 /// Prepare the engine for starting.
390 ///
391 /// This method preallocates many of the resources the engine requires in order to start.
392 /// Use it to responsively start audio input or output.
393 ///
394 /// On AVAudioSession supported platforms, this method may cause the audio session to be implicitly activated. Activating the audio session (implicitly or explicitly) may cause other audio sessions to be interrupted or ducked depending on the session's configuration. It is recommended to configure and activate the app's audio session before preparing the engine.
395 /// See https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Introduction/Introduction.html for details.
396 #[unsafe(method(prepare))]
397 #[unsafe(method_family = none)]
398 pub unsafe fn prepare(&self);
399
400 /// Start the engine.
401 ///
402 /// Returns: YES for success
403 ///
404 /// Calls prepare if it has not already been called since stop.
405 ///
406 /// When the engine is rendering to/from an audio device, starts the audio hardware via the
407 /// AVAudioInputNode and/or AVAudioOutputNode instances in the engine. Audio begins to flow
408 /// through the engine.
409 /// Reasons for potential failure to start in this mode include:
410 /// 1. There is problem in the structure of the graph. Input can't be routed to output or to a
411 /// recording tap through converter type nodes.
412 /// 2. An AVAudioSession error.
413 /// 3. The driver failed to start the hardware.
414 ///
415 /// In manual rendering mode, prepares the engine to render when requested by the client.
416 ///
417 /// On AVAudioSession supported platforms, this method may cause the audio session to be implicitly activated. It is recommended to configure and activate the app's audio session before starting the engine. For more information, see the `prepare` method above.
418 #[unsafe(method(startAndReturnError:_))]
419 #[unsafe(method_family = none)]
420 pub unsafe fn startAndReturnError(&self) -> Result<(), Retained<NSError>>;
421
422 /// Pause the engine.
423 ///
424 /// When the engine is rendering to/from an audio device, stops the audio hardware and the flow
425 /// of audio through the engine. When operating in this mode, it is recommended that the engine
426 /// be paused or stopped (as applicable) when not in use, to minimize power consumption.
427 ///
428 /// Pausing the engine does not deallocate the resources allocated by prepare. Resume the
429 /// engine by invoking start again.
430 #[unsafe(method(pause))]
431 #[unsafe(method_family = none)]
432 pub unsafe fn pause(&self);
433
434 /// reset
435 /// Reset all of the nodes in the engine.
436 ///
437 /// This will reset all of the nodes in the engine. This is useful, for example, for silencing
438 /// reverb and delay tails.
439 ///
440 /// In manual rendering mode, the render timeline is reset to a sample time of zero.
441 #[unsafe(method(reset))]
442 #[unsafe(method_family = none)]
443 pub unsafe fn reset(&self);
444
445 /// When the engine is rendering to/from an audio device, stops the audio hardware and the
446 /// engine. When operating in this mode, it is recommended that the engine be paused or stopped
447 /// (as applicable) when not in use, to minimize power consumption.
448 ///
449 /// Stopping the engine releases the resources allocated by prepare.
450 #[unsafe(method(stop))]
451 #[unsafe(method_family = none)]
452 pub unsafe fn stop(&self);
453
454 #[cfg(all(
455 feature = "AVAudioConnectionPoint",
456 feature = "AVAudioNode",
457 feature = "AVAudioTypes"
458 ))]
459 /// Get connection information on a node's input bus.
460 ///
461 /// Parameter `node`: The node whose input connection is being queried.
462 ///
463 /// Parameter `bus`: The node's input bus on which the connection is being queried.
464 ///
465 /// Returns: An AVAudioConnectionPoint object with connection information on the node's
466 /// specified input bus.
467 ///
468 /// Connections are always one-to-one or one-to-many, never many-to-one.
469 ///
470 /// Returns nil if there is no connection on the node's specified input bus.
471 #[unsafe(method(inputConnectionPointForNode:inputBus:))]
472 #[unsafe(method_family = none)]
473 pub unsafe fn inputConnectionPointForNode_inputBus(
474 &self,
475 node: &AVAudioNode,
476 bus: AVAudioNodeBus,
477 ) -> Option<Retained<AVAudioConnectionPoint>>;
478
479 #[cfg(all(
480 feature = "AVAudioConnectionPoint",
481 feature = "AVAudioNode",
482 feature = "AVAudioTypes"
483 ))]
484 /// Get connection information on a node's output bus.
485 ///
486 /// Parameter `node`: The node whose output connections are being queried.
487 ///
488 /// Parameter `bus`: The node's output bus on which connections are being queried.
489 ///
490 /// Returns: An array of AVAudioConnectionPoint objects with connection information on the node's
491 /// specified output bus.
492 ///
493 /// Connections are always one-to-one or one-to-many, never many-to-one.
494 ///
495 /// Returns an empty array if there are no connections on the node's specified output bus.
496 #[unsafe(method(outputConnectionPointsForNode:outputBus:))]
497 #[unsafe(method_family = none)]
498 pub unsafe fn outputConnectionPointsForNode_outputBus(
499 &self,
500 node: &AVAudioNode,
501 bus: AVAudioNodeBus,
502 ) -> Retained<NSArray<AVAudioConnectionPoint>>;
503
504 #[cfg(feature = "objc2-audio-toolbox")]
505 #[cfg(not(target_os = "watchos"))]
506 /// The MusicSequence previously attached to the engine (if any).
507 #[unsafe(method(musicSequence))]
508 #[unsafe(method_family = none)]
509 pub unsafe fn musicSequence(&self) -> MusicSequence;
510
511 #[cfg(feature = "objc2-audio-toolbox")]
512 #[cfg(not(target_os = "watchos"))]
513 /// Setter for [`musicSequence`][Self::musicSequence].
514 ///
515 /// # Safety
516 ///
517 /// `music_sequence` must be a valid pointer or null.
518 #[unsafe(method(setMusicSequence:))]
519 #[unsafe(method_family = none)]
520 pub unsafe fn setMusicSequence(&self, music_sequence: MusicSequence);
521
522 #[cfg(all(feature = "AVAudioIONode", feature = "AVAudioNode"))]
523 /// The engine's singleton output node.
524 ///
525 /// Audio output is performed via an output node. The engine creates a singleton on demand when
526 /// this property is first accessed. Connect another node to the input of the output node, or
527 /// obtain a mixer that is connected there by default, using the "mainMixerNode" property.
528 ///
529 /// When the engine is rendering to/from an audio device, the AVAudioSesssion category and/or
530 /// availability of hardware determine whether an app can perform output. Check the output
531 /// format of output node (i.e. hardware format) for non-zero sample rate and channel count to
532 /// see if output is enabled.
533 /// Trying to perform output through the output node when it is not enabled or available will
534 /// cause the engine to throw an error (when possible) or an exception.
535 ///
536 /// In manual rendering mode, the output format of the output node will determine the
537 /// render format of the engine. It can be changed through
538 /// `enableManualRenderingMode:format:maximumFrameCount:error:`.
539 #[unsafe(method(outputNode))]
540 #[unsafe(method_family = none)]
541 pub unsafe fn outputNode(&self) -> Retained<AVAudioOutputNode>;
542
543 #[cfg(all(feature = "AVAudioIONode", feature = "AVAudioNode"))]
544 /// The engine's singleton input node.
545 ///
546 /// Audio input is performed via an input node. The engine creates a singleton on demand when
547 /// this property is first accessed. To receive input, connect another node from the output of
548 /// the input node, or create a recording tap on it.
549 ///
550 /// When the engine is rendering to/from an audio device, the AVAudioSesssion category and/or
551 /// availability of hardware determine whether an app can perform input. Check for the input node's
552 /// input format (i.e. hardware format) for non-zero sample rate and channel count to see if input is enabled.
553 /// Trying to perform input through the input node when it is not enabled or available will
554 /// cause the engine to throw an error (when possible) or an exception.
555 ///
556 /// Note that if the engine has at any point previously had its inputNode enabled and permission to
557 /// record was granted, then any time the engine is running, the mic-in-use indicator will appear.
558 ///
559 /// For applications which may need to dynamically switch between output-only and input-output
560 /// modes, it may be advantageous to use two engine instances.
561 ///
562 /// In manual rendering mode, the input node can be used to synchronously supply data to
563 /// the engine while it is rendering (see
564 /// `AVAudioInputNode(setManualRenderingInputPCMFormat:inputBlock:)`.
565 #[unsafe(method(inputNode))]
566 #[unsafe(method_family = none)]
567 pub unsafe fn inputNode(&self) -> Retained<AVAudioInputNode>;
568
569 #[cfg(all(feature = "AVAudioMixerNode", feature = "AVAudioNode"))]
570 /// The engine's optional singleton main mixer node.
571 ///
572 /// The engine will construct a singleton main mixer and connect it to the outputNode on demand,
573 /// when this property is first accessed. You can then connect additional nodes to the mixer.
574 ///
575 /// If the client has never explicitly set the connection format between the mainMixerNode and
576 /// the outputNode, the engine will always set/update the format to track the format of the outputNode
577 /// on (re)start, even after an AVAudioEngineConfigurationChangeNotification.
578 /// Otherwise, it's the client's responsibility to set/update this connection format after an
579 /// AVAudioEngineConfigurationChangeNotification.
580 ///
581 /// By default, the mixer's output format (sample rate and channel count) will track the format
582 /// of the output node. You may however make the connection explicitly with a different format.
583 #[unsafe(method(mainMixerNode))]
584 #[unsafe(method_family = none)]
585 pub unsafe fn mainMixerNode(&self) -> Retained<AVAudioMixerNode>;
586
587 /// The engine's running state.
588 #[unsafe(method(isRunning))]
589 #[unsafe(method_family = none)]
590 pub unsafe fn isRunning(&self) -> bool;
591
592 /// When auto shutdown is enabled, the engine can start and stop the audio hardware dynamically,
593 /// to conserve power. This is the enforced behavior on watchOS and can be optionally enabled on
594 /// other platforms.
595 ///
596 /// To conserve power, it is advised that the client pause/stop the engine when not in use.
597 /// But when auto shutdown is enabled, the engine will stop the audio hardware if it was running
598 /// idle for a certain duration, and restart it later when required.
599 /// Note that, because this operation is dynamic, it may affect the start times of the source
600 /// nodes (e.g. `AVAudioPlayerNode`), if the engine has to resume from its shutdown state.
601 ///
602 /// On watchOS, auto shutdown is always enabled. On other platforms, it is disabled by
603 /// default, but the client can enable it if needed.
604 ///
605 /// This property is applicable only when the engine is rendering to/from an audio device. If
606 /// the value is changed when the engine is in manual rendering mode, it will take effect
607 /// whenever the engine is switched to render to/from the audio device.
608 #[unsafe(method(isAutoShutdownEnabled))]
609 #[unsafe(method_family = none)]
610 pub unsafe fn isAutoShutdownEnabled(&self) -> bool;
611
612 /// Setter for [`isAutoShutdownEnabled`][Self::isAutoShutdownEnabled].
613 #[unsafe(method(setAutoShutdownEnabled:))]
614 #[unsafe(method_family = none)]
615 pub unsafe fn setAutoShutdownEnabled(&self, auto_shutdown_enabled: bool);
616
617 #[cfg(feature = "AVAudioNode")]
618 /// Set of all nodes attached to the engine.
619 #[unsafe(method(attachedNodes))]
620 #[unsafe(method_family = none)]
621 pub unsafe fn attachedNodes(&self) -> Retained<NSSet<AVAudioNode>>;
622
623 #[cfg(all(feature = "AVAudioFormat", feature = "AVAudioTypes"))]
624 /// Set the engine to operate in a manual rendering mode with the specified render format and
625 /// maximum frame count.
626 ///
627 /// Parameter `mode`: The manual rendering mode to use.
628 ///
629 /// Parameter `pcmFormat`: The format of the output PCM audio data from the engine.
630 ///
631 /// Parameter `maximumFrameCount`: The maximum number of PCM sample frames the engine will be asked to produce in any single
632 /// render call.
633 ///
634 /// Parameter `outError`: On exit, if the engine cannot switch to the manual rendering mode, a description of the
635 /// error (see `AVAudioEngineManualRenderingError` for the possible errors).
636 ///
637 /// Returns: YES for success.
638 ///
639 /// Use this method to configure the engine to render in response to requests from the client.
640 ///
641 /// The engine must be in a stopped state before calling this method.
642 /// The render format must be a PCM format and match the format of the buffer to which
643 /// the engine is asked to render (see `renderOffline:toBuffer:error:`).
644 ///
645 /// It is advised to enable manual rendering mode soon after the engine is created, and
646 /// before accessing any of mainMixerNode, inputNode or outputNode of the engine.
647 /// Otherwise, accessing or interacting with the engine before enabling manual rendering
648 /// mode could have the unintended side-effect of configuring the hardware for device-rendering
649 /// mode.
650 ///
651 /// The input data in manual rendering mode can be supplied through the source nodes, e.g.
652 /// `AVAudioPlayerNode`, `AVAudioInputNode` etc.
653 ///
654 /// When switching to manual rendering mode, the engine:
655 /// 1. Switches the input and output nodes to manual rendering mode. Their input and output
656 /// formats may change.
657 /// 2. Removes any taps previously installed on the input and output nodes.
658 /// 3. Maintains all the engine connections as is.
659 ///
660 /// Reasons for potential failure when switching to manual rendering mode include:
661 /// - Engine is not in a stopped state.
662 #[unsafe(method(enableManualRenderingMode:format:maximumFrameCount:error:_))]
663 #[unsafe(method_family = none)]
664 pub unsafe fn enableManualRenderingMode_format_maximumFrameCount_error(
665 &self,
666 mode: AVAudioEngineManualRenderingMode,
667 pcm_format: &AVAudioFormat,
668 maximum_frame_count: AVAudioFrameCount,
669 ) -> Result<(), Retained<NSError>>;
670
671 /// Set the engine to render to/from an audio device.
672 ///
673 /// When disabling the manual rendering mode, the engine:
674 /// 1. Stops and resets itself (see `stop` and `reset`).
675 /// 2. Switches the output/input nodes to render to/from an audio device. Their input and
676 /// output formats may change.
677 /// 3. Removes any taps previously installed on the input and output nodes.
678 /// 4. Maintains all the engine connections as is.
679 ///
680 /// Calling this method when the engine is already rendering to/from an audio device has no
681 /// effect.
682 #[unsafe(method(disableManualRenderingMode))]
683 #[unsafe(method_family = none)]
684 pub unsafe fn disableManualRenderingMode(&self);
685
686 #[cfg(all(
687 feature = "AVAudioTypes",
688 feature = "block2",
689 feature = "objc2-core-audio-types"
690 ))]
691 /// Block to render the engine operating in manual rendering mode
692 ///
693 /// This block based render call must be used to render the engine when operating in
694 /// `AVAudioEngineManualRenderingModeRealtime`. In this mode, the engine operates under
695 /// realtime constraints and will not make any blocking call (e.g. calling libdispatch, blocking
696 /// on a mutex, allocating memory etc.) while rendering.
697 ///
698 /// Before invoking the rendering functionality, client must fetch this block and cache the
699 /// result. The block can then be called from a realtime context, without any possibility of
700 /// blocking.
701 ///
702 /// When rendering in `AVAudioEngineManualRenderingModeOffline`, either this block based render
703 /// call or `renderOffline:toBuffer:error:` ObjC method can be used.
704 /// All the rules outlined in `renderOffline:toBuffer:error:` are applicable here as well.
705 ///
706 /// # Safety
707 ///
708 /// - The returned block's argument 2 must be a valid pointer.
709 /// - The returned block's argument 3 must be a valid pointer or null.
710 #[unsafe(method(manualRenderingBlock))]
711 #[unsafe(method_family = none)]
712 pub unsafe fn manualRenderingBlock(&self) -> AVAudioEngineManualRenderingBlock;
713
714 /// Whether or not the engine is operating in manual rendering mode, i.e. not connected
715 /// to an audio device and rendering in response to the requests from the client
716 #[unsafe(method(isInManualRenderingMode))]
717 #[unsafe(method_family = none)]
718 pub unsafe fn isInManualRenderingMode(&self) -> bool;
719
720 /// The manual rendering mode configured on the engine
721 ///
722 /// This property is meaningful only when the engine is operating in manual rendering mode,
723 /// i.e. when `isInManualRenderingMode` returns true.
724 #[unsafe(method(manualRenderingMode))]
725 #[unsafe(method_family = none)]
726 pub unsafe fn manualRenderingMode(&self) -> AVAudioEngineManualRenderingMode;
727
728 #[cfg(feature = "AVAudioFormat")]
729 /// The render format of the engine in manual rendering mode.
730 ///
731 /// Querying this property when the engine is not in manual rendering mode will return an
732 /// invalid format, with zero sample rate and channel count.
733 #[unsafe(method(manualRenderingFormat))]
734 #[unsafe(method_family = none)]
735 pub unsafe fn manualRenderingFormat(&self) -> Retained<AVAudioFormat>;
736
737 #[cfg(feature = "AVAudioTypes")]
738 /// The maximum number of PCM sample frames the engine can produce in any single render call in
739 /// the manual rendering mode.
740 ///
741 /// Querying this property when the engine is not in manual rendering mode will return zero.
742 #[unsafe(method(manualRenderingMaximumFrameCount))]
743 #[unsafe(method_family = none)]
744 pub unsafe fn manualRenderingMaximumFrameCount(&self) -> AVAudioFrameCount;
745
746 #[cfg(feature = "AVAudioTypes")]
747 /// Indicates where the engine is on its render timeline in manual rendering mode.
748 ///
749 /// The timeline in manual rendering mode starts at a sample time of zero, and is in terms
750 /// of the render format's sample rate. Resetting the engine (see `reset`) will reset the
751 /// timeline back to zero.
752 #[unsafe(method(manualRenderingSampleTime))]
753 #[unsafe(method_family = none)]
754 pub unsafe fn manualRenderingSampleTime(&self) -> AVAudioFramePosition;
755
756 #[cfg(all(
757 feature = "AVAudioFormat",
758 feature = "AVAudioNode",
759 feature = "objc2-audio-toolbox"
760 ))]
761 #[cfg(not(target_os = "watchos"))]
762 /// Establish a MIDI only connection between two nodes.
763 ///
764 /// Parameter `sourceNode`: The source node.
765 ///
766 /// Parameter `destinationNode`: The destination node.
767 ///
768 /// Parameter `format`: If non-nil, the format of the source node's output bus is set to this format.
769 /// In all cases, the format of the source nodes' output bus has to match with the
770 /// destination nodes' output bus format.
771 /// Although the output bus of the source is not in use, the format needs to be set
772 /// in order to be able to use the sample rate for MIDI event timing calculations.
773 ///
774 /// Parameter `tapBlock`: If non-nil, this block is called from the source node's `AUMIDIOutputEventBlock`
775 /// on the realtime thread. The host can tap the MIDI data of the source node through
776 /// this block. May be nil.
777 ///
778 /// Use this method to establish a MIDI only connection between a source node and a
779 /// destination node that has MIDI input capability.
780 ///
781 /// The source node can only be a AVAudioUnit node of type `kAudioUnitType_MIDIProcessor`.
782 /// The destination node types can be `kAudioUnitType_MusicDevice`,
783 /// `kAudioUnitType_MusicEffect` or `kAudioUnitType_MIDIProcessor`.
784 ///
785 /// Note that any pre-existing MIDI connection involving the destination will be broken.
786 ///
787 /// Any client installed block on the source node's audio unit `AUMIDIOutputEventBlock`
788 /// will be overwritten when making the MIDI connection.
789 ///
790 /// # Safety
791 ///
792 /// `tap_block` must be a valid pointer or null.
793 #[deprecated]
794 #[unsafe(method(connectMIDI:to:format:block:))]
795 #[unsafe(method_family = none)]
796 pub unsafe fn connectMIDI_to_format_block(
797 &self,
798 source_node: &AVAudioNode,
799 destination_node: &AVAudioNode,
800 format: Option<&AVAudioFormat>,
801 tap_block: AUMIDIOutputEventBlock,
802 );
803
804 #[cfg(all(
805 feature = "AVAudioFormat",
806 feature = "AVAudioNode",
807 feature = "objc2-audio-toolbox"
808 ))]
809 #[cfg(not(target_os = "watchos"))]
810 /// Establish a MIDI only connection between a source node and multiple destination nodes.
811 ///
812 /// Parameter `sourceNode`: The source node.
813 ///
814 /// Parameter `destinationNodes`: An array of AVAudioNodes specifying destination nodes.
815 ///
816 /// Parameter `format`: If non-nil, the format of the source node's output bus is set to this format.
817 /// In all cases, the format of the source nodes' output bus has to match with the
818 /// destination nodes' output bus format.
819 /// Although the output bus of the source is not in use, the format needs to be set
820 /// in order to be able to use the sample rate for MIDI event timing calculations.
821 ///
822 /// Parameter `tapBlock`: If non-nil, this block is called from the source node's `AUMIDIOutputEventBlock`
823 /// on the realtime thread. The host can tap the MIDI data of the source node through
824 /// this block. May be nil.
825 ///
826 /// Use this method to establish a MIDI only connection between a source node and
827 /// multiple destination nodes.
828 ///
829 /// The source node can only be a AVAudioUnit node of type `kAudioUnitType_MIDIProcessor`.
830 /// The destination node types can be `kAudioUnitType_MusicDevice`,
831 /// `kAudioUnitType_MusicEffect` or `kAudioUnitType_MIDIProcessor`.
832 ///
833 /// MIDI connections made using this method are either one-to-one (when a single
834 /// destination connection is specified) or one-to-many (when multiple connections are
835 /// specified), but never many-to-one.
836 ///
837 /// Note that any pre-existing connection involving the destination will be broken.
838 ///
839 /// Any client installed block on the source node's audio unit `AUMIDIOutputEventBlock`
840 /// will be overwritten when making the MIDI connection.
841 ///
842 /// # Safety
843 ///
844 /// `tap_block` must be a valid pointer or null.
845 #[deprecated]
846 #[unsafe(method(connectMIDI:toNodes:format:block:))]
847 #[unsafe(method_family = none)]
848 pub unsafe fn connectMIDI_toNodes_format_block(
849 &self,
850 source_node: &AVAudioNode,
851 destination_nodes: &NSArray<AVAudioNode>,
852 format: Option<&AVAudioFormat>,
853 tap_block: AUMIDIOutputEventBlock,
854 );
855
856 #[cfg(feature = "AVAudioNode")]
857 /// Remove a MIDI connection between two nodes.
858 ///
859 /// Parameter `sourceNode`: The node whose MIDI output is to be disconnected.
860 ///
861 /// Parameter `destinationNode`: The node whose MIDI input is to be disconnected.
862 ///
863 /// If a tap block is installed on the source node, it will be removed when the last
864 /// connection from the source node is removed.
865 #[unsafe(method(disconnectMIDI:from:))]
866 #[unsafe(method_family = none)]
867 pub unsafe fn disconnectMIDI_from(
868 &self,
869 source_node: &AVAudioNode,
870 destination_node: &AVAudioNode,
871 );
872
873 #[cfg(feature = "AVAudioNode")]
874 /// Remove a MIDI connection between one source node and multiple destination nodes.
875 ///
876 /// Parameter `sourceNode`: The node whose MIDI output is to be disconnected.
877 ///
878 /// Parameter `destinationNodes`: An array of AVAudioNodes specifying nodes whose MIDI input is to be disconnected.
879 ///
880 /// If a tap block is installed on the source node, it will be removed when the last
881 /// connection from the source node is removed.
882 #[unsafe(method(disconnectMIDI:fromNodes:))]
883 #[unsafe(method_family = none)]
884 pub unsafe fn disconnectMIDI_fromNodes(
885 &self,
886 source_node: &AVAudioNode,
887 destination_nodes: &NSArray<AVAudioNode>,
888 );
889
890 #[cfg(feature = "AVAudioNode")]
891 /// Disconnects all input MIDI connections of this node.
892 ///
893 /// Parameter `node`: The node whose MIDI input is to be disconnected.
894 #[unsafe(method(disconnectMIDIInput:))]
895 #[unsafe(method_family = none)]
896 pub unsafe fn disconnectMIDIInput(&self, node: &AVAudioNode);
897
898 #[cfg(feature = "AVAudioNode")]
899 /// Disconnects all output MIDI connections of this node.
900 ///
901 /// Parameter `node`: The node whose MIDI outputs are to be disconnected.
902 #[unsafe(method(disconnectMIDIOutput:))]
903 #[unsafe(method_family = none)]
904 pub unsafe fn disconnectMIDIOutput(&self, node: &AVAudioNode);
905 );
906}
907
908/// Methods declared on superclass `NSObject`.
909impl AVAudioEngine {
910 extern_methods!(
911 #[unsafe(method(new))]
912 #[unsafe(method_family = new)]
913 pub unsafe fn new() -> Retained<Self>;
914 );
915}
916
917extern "C" {
918 /// A notification generated on engine configuration changes when rendering to/from an audio
919 /// device.
920 ///
921 /// Register for this notification on your engine instances, as follows:
922 ///
923 /// ```text
924 /// [[NSNotificationCenter defaultCenter] addObserver: myObject
925 /// selector:
926 /// sel!(handleInterruption:)
927 /// name: AVAudioEngineConfigurationChangeNotification
928 /// object: engine];
929 /// ```
930 ///
931 /// When the engine's I/O unit observes a change to the audio input or output hardware's
932 /// channel count or sample rate, the engine stops itself (see `AVAudioEngine(stop)`), and
933 /// issues this notification.
934 /// The nodes remain attached and connected with previously set formats. However, the app
935 /// must reestablish connections if the connection formats need to change (e.g. in an
936 /// input node chain, connections must follow the hardware sample rate, while in an output only
937 /// chain, the output node supports rate conversion).
938 ///
939 /// Note that the engine must not be deallocated from within the client's notification handler
940 /// because the callback happens on an internal dispatch queue and can deadlock while trying to
941 /// synchronously teardown the engine.
942 ///
943 /// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avaudioengineconfigurationchangenotification?language=objc)
944 pub static AVAudioEngineConfigurationChangeNotification: &'static NSString;
945}