Audio Component Framework Tutorial

This tutorial describes how to use the Audio Component Framework (ACF).

Purpose

The purpose of this tutorial is to show you how to create an audio processing group containing a context, an audio stream and three audio processing units.

Required Background

The following entities, specific to the Advanced Audio Adaptation Framework (A3F), are used to create an audio processing group:

  • Context - one or more audio streams.

  • Audio stream - a source, a codec and a sink.

  • Source - a source of multimedia data.

  • Codec - an encoder or decoder of multimedia data.

  • Gain control - a controller of gain balance.

  • Sink - a consumer of multimedia data.

Introduction

To define audio functionality, the client must group the required audio processing units into an audio processing group. The starting point for the group is the context. Once a context has been created, an audio stream can be added to it. Once the audio stream has been added, the necessary audio processing units can be added.

Using ACF

The framework described in this document allows you to manage and manipulate an audio processing group.

Basic Procedure

The high level steps to create a context are shown here:

  1. Create an ACF Factory

  2. Create and Configure the Context

  3. Create and Configure the Audio Stream

  4. Add the Audio Source

  5. Add the Audio Codec

  6. Add the Audio Sink

  7. Commit the Changes

  8. Initialize the Audio Stream

Creating an ACF Factory

The steps to create an ACF Factory are shown here:

Creating and Configure the Context

The steps to create and configure the context are shown here:

  1. Call CAudioContextFactory::CreateAudioContext() to create the new context.

             
              
             
             IMPORT_C TInt CreateAudioContext(MAudioContext*& aContext);
            
  2. Set the client information for the new context by calling MAudioContext::SetClientSettings() . Client settings contain information about the client application utilising the audio functionality.

             
              
             
             virtual TInt SetClientSettings(const TClientContextSettings& aSettings)=0;
            

    Note: This must be called before any call to MAudioContext::Commit() .

  3. Register a context observer using MAudioContext::RegisterAudioContextObserver() .

             
              
             
             virtual TInt RegisterAudioContextObserver(MAudioContextObserver& aObserver) = 0;
            

Creating and Configuring an Audio Stream

The steps to create and configure an audio stream are shown here:

  1. Call MAudioContext::CreateAudioStream() to add a new audio stream to the existing context.

             
              
             
             virtual TInt CreateAudioStream(MAudioStream*& aStream)=0;
            
  2. Set the type of audio being processed in the audio stream by calling MAudioStream::SetAudioType() .

             
              
             
             virtual TInt SetAudioType(const TAudioTypeSettings& aAudioTypeSettings)=0;
            
  3. Register an audio stream observer by calling MAudioStream::RegisterAudioStreamObserver() .

             
              
             
             virtual TInt RegisterAudioStreamObserver(MAudioStreamObserver& aObserver)=0;
            
  4. Set the audio configuration using MAudioStream::SetConfiguration() .

             
              
             
             virtual TInt SetConfiguration(const TAudioConfiguration&  aConfig)=0;
            

Adding a Source

The audio stream cannot operate until a source, a codec and a sink have been added. To add a source:

  1. Create a new audio processing unit by calling MAudioContext::CreateAudioProcessingUnit() .

             
              
             
             virtual TInt CreateAudioProcessingUnit(TUid aTypeId, MAudioProcessingUnit*& aProcessingUnit)=0;
            
  2. Call MAudioStream::AddSource() to add a source for the audio stream.

             
              
             
             virtual TInt AddSource(MAudioProcessingUnit* aSource)=0;
            

    Note: This call is asynchronous, if KErrNone is returned, there will be a subsequent callback on MAudioStreamObserver::AddProcessingUnitComplete() .

Adding a Codec

To add a codec:

  1. Create another new audio processing unit by calling MAudioContext::CreateAudioProcessingUnit() .

             
              
             
             virtual TInt CreateAudioProcessingUnit(TUid aTypeId, MAudioProcessingUnit*& aProcessingUnit)=0;
            
  2. Call MAudioStream::AddAudioCodec() to add the codec.

             
              
             
             virtual TInt AddAudioCodec(MAudioProcessingUnit* aCodec)=0;
            

    Note: This call is asynchronous, if KErrNone is returned, there will be a subsequent callback on MAudioStreamObserver::AddProcessingUnitComplete() .

Adding a Sink

To add a sink:

  1. Create another audio processing unit by calling MAudioContext::CreateAudioProcessingUnit() .

             
              
             
             virtual TInt CreateAudioProcessingUnit(TUid aTypeId, MAudioProcessingUnit*& aProcessingUnit)=0;
            
  2. Call MAudioStream::AddSink() to add the sink for the audio stream.

             
              
             
             virtual TInt AddSink(MAudioProcessingUnit* aSink)=0;
            

    Note: This call is asynchronous, if KErrNone is returned, there will be a subsequent callback on MAudioStreamObserver::AddProcessingUnitComplete() .

Committing the Changes

To apply the changes made to the audio processing group, the client must call a Commit() . The Commit() call is the mechanism for implementing requested changes and all changes are considered to be pending until successfully committed.

On success, the client is informed by the appropriate ContextEvent() callback. KUidA3FContextUpdateComplete signals that all changes have been completed and Commit() can now be called again, if required.

Note: The A3F Commit() cycle is transactional, that is, if a Commit() fails, then all changes are rolled back.

The steps to commit the context are shown here:

Initializing the Audio Stream

During construction, the audio stream is in the EUninitialized state. In order to relate the audio stream to a physical adaptation, it must be transitioned to the EInitialized state.

The steps to initialize the audio stream are shown here:

  1. To request a transition to EInitialized , call MAudioStream::Initialize() .

             
              
             
             virtual TInt Initialize()=0;
            
  2. Call MAudioContext::Commit() to apply the state change.

             
              
             
             virtual TInt Commit()=0;
            

Note: This is one example of a state change to an audio stream. There are other state changes, for example, the transition from the EPrimed to EActive state which starts the audio processing. For more information, see Stream States in the Advanced Audio Adaptation Framework Technology Guide .