Streaming Overview

For most voices, the entire buffer of samples in an audio file can be kept in memory for playback. However, keeping the entire audio file in memory for a single voice may be impractical in some cases. For instance, ten minutes of uncompressed music in 32KHz PCM16 format is over 50 MB in size. The standard way of handling such large audio files is streaming. By using streaming, any size audio file may be played with a relatively small buffer in RAM.

Concept

When playing an audio file, two sets of samples must be kept in RAM:

When streaming, pieces of an audio file are loaded only as they are needed, and then are discarded when they are no longer needed. The basic steps involved in streaming are as follows:

By streaming audio this way, an arbitrarily large audio file may be played without requiring more than two stream buffer blocks be loaded in to RAM at any given time. However, this benefit comes with a cost: the audio file must be accessed each time that a new block of samples must be loaded.

Implementation

Streaming on Cafe requires specialized use of the parameters set with AXSetVoiceOffsets and AXSetVoiceSamplesAddr. The key to streaming is effective use of a voice's looping offset.

If a given voice has looping enabled and the playback reaches its endOffset, then playback continues at the loopOffset. The loopOffset does not need to be a point within the same buffer that the voice was previously playing. Because of this, the loopOffset of a voice can be used to jump to an arbitrary location in memory.

The essential steps are as follows.

  1. Load at least two stream buffer blocks into memory.
  2. Acquire a voice, and then set up the playback parameters.
  3. Initialize the address parameters for the voice as follows:
    1. sample address: Starting address of the first stream buffer block.
    2. loopFlag: AXPBADDR_LOOP_ON.
    3. currentOffset: Starting offset of the first stream buffer block.
    4. endOffset: Ending offset of the first stream buffer block.
    5. loopOffset: Starting offset of the second stream buffer block.
  4. Start voice playback.
  5. Each audio frame, call AXGetVoiceLoopCount to get the number of times the voice has looped. If the voice's loop count increased, then it has started to play the next stream buffer block. When this occurs, take the following steps:
    1. Update the voice's endOffset to be the ending offset of the newly playing stream buffer block.
    2. Load the next pending samples for the stream buffer block into the location of the stream buffer block that just finished playing.
    3. Update the loopOffset for the voice to the starting offset of the loaded stream buffer block.
NOTE:
  • All stream buffer blocks for one voice must exist within the same 512 MB page of memory. For information about this limitation, see AXCheckVoiceOffsets.
  • When streaming ADPCM format voices, it is important to set the voice type to be AX_PB_TYPE_STREAM using AXSetVoiceType. For more information, see the Voice Type section in AX Overview.
  • When processing the last buffer of the stream or if the voice is dropped, voice type needs to be set to AX_PB_TYPE_NORMAL. It is not necessary to perform this for PCM formats.

Streaming Library

As a convenience, the SDK provides a library, streamlib, that implements the management of voice offsets as described above. To use it, applications need to supply stream buffer blocks periodically and call an update function once per audio frame.

Source for the library can be found among the SDK demos in the following directory:

$CAFE_ROOT/system/src/demo/ax/streamlib

Instructions for using streamlib can be found in the AXStream.h file located in the above folder.

Demos

The SDK includes a few demo applications as examples of how to perform streaming on Cafe. These demos are located in the following folder:

$CAFE_ROOT/system/src/demo/ax

Revision History

2013/05/08 Automated cleanup pass.
2013/02/18 Initial version.


CONFIDENTIAL