Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



How to use audio output stream utility

The Audio streaming API is the interface providing the functionalities for playing, stopping, and recording the audio stream to and from the audio buffers. The audio output stream interface class, CMdaAudioOutputStream, enables client applications to:

The user need to maintain the data packets in a queue before starting to send it to the server. There is no need for the entire sound clip to arrive to be able to pass on to the low level audio controller. They can be forwarded as they arrive. If the server tends to receive data more than it can read or process, then a separate queue is maintained in the client side whose elements are references to the buffers passed to it. Once the server is free to receive more data the client sends the data in the queue and receives a notification from the server by means of a callback. As a result of this, the client deletes the data fragments from the queue.

Upon receiving the data packets the audio controller maintains them in the received buffers. A read function is instantiated to read the data into the destination descriptors.


Using an audio output stream

Typically, using an audio output stream involves the following steps as shown in the sequence diagram below:

  1. Constructing an audio output stream

  2. Opening an audio output stream

  3. Getting and setting the stream properties

  4. Playing an audio output stream

  5. Stopping an audio output stream


Constructing an audio output stream

The client application creates an audio output stream object using the static function CMdaAudioOutputStream::NewL(). Optionally, it also sets the audio priorities to be able to access the audio hardware in relation to the other clients trying to access the same device.

static IMPORT_C CMdaAudioOutputStream *NewL(MMdaAudioOutputStreamCallback &aCallBack, 
TInt aPriority, TMdaPriorityPreference aPref=EMdaPriorityPreferenceTimeAndQuality);


Opening an audio output stream

To open the output stream, use the Open() member function. For example:

virtual void Open(TMdaPackage* aSettings);

Once the stream is open MMdaAudioOutputStreamCallback::MaoscOpenComplete() is invoked to indicate that the stream is ready to use.

void CIOStreamAudio::MaoscOpenComplete(TInt aError)
    {
    ASSERT(iState==EStateOpeningOutput);
    TInt error = aError;
    if (error==KErrNone)
        {
        iState = EStateWriting;   
        iOutputStream->SetVolume(iOutputStream->MaxVolume()/2);
        TRAP(error, iOutputStream->WriteL(iMainBuffer));
        }
    if (error!=KErrNone)
        {
        Complete(aError);   
        }
    }


Getting and setting the stream properties

The CMdaAudioOutputStream member functions get and set the properties of the audio output stream.

To set the sampling rate and number of audio channels use SetAudioPropertiesL(). For example:

virtual void SetAudioPropertiesL(TInt aSampleRate, TInt aChannels);

You cannot set these values while playing the stream. Also, you must specify them as enums; for example, TMdaAudioDataSettings::ESampleRate8000Hz rather than 8000 (Hz).

The Volume() and GetbalanceL() member functions let you determine current volume and balance settings. For example:

The SetVolume() and SetBalanceL() member functions let you set the volume and balance respectively. You can use them while the stream is open, with the new settings taking immediate effect.


Playing an audio output stream

To play an audio stream from the current position use the WriteL() member function. For example:

virtual void WriteL(const TDesC8& aData);

This function is asynchronous.

When aData is received, the client is notified by a call to MdaAudioOutputStreamCallback::MaoscBufferCopied().

void CIOStreamAudio::MaoscBufferCopied(TInt aError, const TDesC8& IFDEBUG(aBuffer))
    {
    ASSERT(iState==EStateWriting);
    if (aError!=KErrNone)
        {
        // ignore any KErrAbort returns - this would happen during a Stop() call
        // if we were playing 
        if (aError!=KErrAbort)
            {
            Complete(aError);   
            }
        }
    else
        {
        ASSERT(aBuffer.Length()==iMainBuffer.Length());
        // output almost complete - have been asked for more data
        iState = EStateWritingPostBuffer;
        }
    }

The WriteL() can be called again before this notification is triggered because the buffers are held in a client-side queue until they have been sent.

When the audio stream has completed playing, the callback function MMdaAudioOutputStreamCallback::MaoscPlayComplete() is invoked.

void CIOStreamAudio::MaoscPlayComplete(TInt aError)
    {
    ASSERT(iState==EStateWriting || iState==EStateWritingPostBuffer);
    TInt error = aError;
    if (aError==KErrUnderflow && iState==EStateWritingPostBuffer)
        {
        error = KErrNone; // normal termination is underflow following buffer request 
        }
    Complete(error);
    }

This closes the stream and sets the callback aError to KErrUnderFlow.


Stopping an audio output stream

To stop audio playback (stop data being sent to the stream) use the Stop() member function.

For example:

virtual void Stop();

This invokes MMdaAudioOutputStreamCallback::MaoscPlayComplete() to notify successful closure of the stream.