iOS Reference Library Apple Developer
Search

Creating Audio Processing Graphs

An audio processing graph is an interconnected set of audio units that you manage as a group. This facility can simplify your code, even if the graph consists of only two units. What you learn in this brief chapter depends on concepts and techniques presented in “Accessing Audio Units.”

Obtaining an Audio Processing Graph

To obtain an audio processing graph, you declare it, create it, and open it, as shown in Listing 3-1.

Listing 3-1  Creating and opening an audio processing graph

AUGraph graph;
 
NewAUGraph (&graph);
AUGraphOpen (graph);

Once open, the graph is ready to configure.

Adding a Node to an Audio Processing Graph

An audio unit node is an opaque type that represents an audio unit in an audio processing graph. Using nodes as wrappers simplifies the accessing and interconnecting of audio units, as described here.

Recall from the last chapter that to access an audio unit directly, you specify its unique description and then obtain a reference to it. In contrast, when using an audio processing graph, you make one function call that obtains the reference, associates it with a node, and adds the node to the audio processing graph. Listing 3-2 shows the steps.

Listing 3-2  Adding an audio unit node to an audio processing graph

// prepare the audio unit description    // 1
 
AUNode mixerNode;
 
AUGraphAddNode (
    graph,                               // 2
    &mixer_au_description,               // 3
    &mixerNode                           // 4
);

Here’s how this code works:

  1. First, create a description that identifies the audio unit for the node (see “Creating a Description That Uniquely Identifies an Audio Unit”).

  2. The audio processing graph to add the node to.

  3. The description of the audio unit to obtain and instantiate.

  4. On function return, the audio unit node—which contains the instantiated audio unit and is now part of the audio processing graph.

Configuring an Audio Unit Node

Before using an audio unit node, you must configure it to ensure that its audio stream format and other characteristics are compatible with your application. To configure a node, you configure its contained audio unit instance. The process is like that shown in “Configuring an Audio Unit” save for two differences:

Listing 3-3 shows how to get an audio unit instance from its node.

Listing 3-3  Retrieving an audio unit instance from its containing node

AudioUnit multichannel_mixer_instance;
 
AUGraphNodeInfo (
    graph,                                // 1
    mixerNode,                            // 2
    NULL,                                 // 3
    &multichannel_mixer_instance          // 4
);

Here’s how this code works:

  1. The audio processing graph that has the node.

  2. The node whose audio unit you want.

  3. If used, on function return contains the filled-in description structure for the node’s audio unit. The description is not needed here because what you want is the audio unit instance itself, so you pass NULL.

  4. On function return, the node’s audio unit instance.

Next, configure the audio unit instance. Except for registering the render callback function, follow the steps shown in “Configuring an Audio Unit.” To register the render callback, use code like that shown in Listing 3-4.

Listing 3-4  Registering a render callback function with an audio unit node

AURenderCallbackStruct callbackStructure;
AudioUnitElement bus = 0;
 
callbackStructure.inputProc       = renderCallback;
callbackStructure.inputProcRefCon = &state;
 
AUGraphSetNodeInputCallback (
    graph,                                             // 1
    audio_unit_node,                                   // 2
    bus,                                               // 3
    &callbackStructure                                 // 4
);

Here’s how this code works:

  1. The graph that contains the node.

  2. The audio unit node.

  3. The bus that you are registering the callback function on.

  4. The callback data structure.

Connecting Audio Unit Nodes

The final step before initializing an audio processing graph is to connect its nodes together. For each such connection, you call the AUGraphConnectNodeInput function as shown in Listing 3-5.

Listing 3-5  Connecting two audio unit nodes

AudioUnitElement bus = 0;        // 1
 
AUGraphConnectNodeInput (        // 2
    graph,                       // 3
    mixerNode,                   // 4
    bus,                         // 5
    IONode,                      // 6
    bus                          // 7
);

Here’s how this code works:

  1. Defines a number to indicate the audio unit bus to use for the connection. Here, the connection is between bus 0 of both nodes, and so just one bus variable is used for both sides of the connection.

  2. Connects the output of one node to the input of another node. Here, you connect the output of a mixer unit node to the input of an I/O node.

  3. The graph that contains the nodes.

  4. The source node, which contains the audio unit instance that the audio comes from.

  5. The number of the bus of the source node.

  6. The destination node, which contains the audio unit instance that the audio goes to.

  7. The number of the bus of the destination node.

Initializing an Audio Processing Graph

After you have fully configured your audio processing graph, you initialize it by making the function call shown in Listing 3-6.

Listing 3-6  Initializing an audio processing graph

AUGraphInitialize (graph);

At this point, the graph is fully connected with your host application and is ready for use.

As with any resource, when you’re done using an audio processing graph, you deallocate it. Use the DisposeAUGraph function as shown in Listing 3-7.

Listing 3-7  Deallocating an audio processing graph and its resources

DisposeAUGraph (graph);

This also deallocates all of the nodes in the graph along with any resources they are using.




Last updated: 2010-01-20

Did this document help you? Yes It's good, but... Not helpful...