axvpb.pb.addr

C Specification

// loopFlag
#define AXPBADDR_LOOP_OFF   0       // one shot
#define AXPBADDR_LOOP_ON    1       // looped
    
// format
#define AX_PB_FORMAT_PCM16  0x000A  // signed 16 bit PCM (mono)
#define AX_PB_FORMAT_PCM8   0x0019  // signed 8 bit PCM (mono)
#define AX_PB_FORMAT_ADPCM  0x0000  // ADPCM encoded (mono)
    
typedef struct _AXPBADDR
{ 

u16 loopFlag;                   // one shot or looped sample (see above)
u16 format;                     // sample format used (see above)
u16 loopAddressHi;              // Loop start
u16 loopAddressLo;
u16 endAddressHi;               // Loop/sample end, including last sample played
u16 endAddressLo;
u16 currentAddressHi;           // Current playback position
u16 currentAddressLo;

} AXPBADDR;

Description

The AXPBADDR structure specifies the memory-addressing context.

The loopFlag parameter specifies whether the given sample is looped or played only once ("one-shot").

The format parameter specifies the type of sample the DSP should load from memory. This in turn dictates the addressing mode of the DSP's streaming cache. If the sample is encoded as "raw" 16-bit PCM, the cache will address memory in 16-bit words. For 8-bit PCM, the cache will address memory as bytes. For ADPCM samples, the cache will address memory as 4-bit nibbles. Note: All memory addresses used in the ADDR member are absolute memory addresses. They are accessed using an offset from the bottom of memory (address 0x0000000).

The loopAddressHi and loopAddressLo values specify the beginning address of the loop for the given sample.
Note: The interpretation of the address will depend on the format of the sample (as specified in format). The endAddressHi and endAddressLo values specify the end address of the loop for the given sample. The currentAddressHi and currentAddressLo values specify the current playback position of the sample.

Once these addresses have been programmed into the streaming cache, the DSP will begin reading samples from memory. If the current sample address exceeds the loop-end address, the streaming cache will reset itself to the loop-start position and assert an interrupt.

The associated interrupt service routine will determine how the loop should be handled. If the loopFlag is AXPBADDR_LOOP_ON, the DSP will simply continue to read samples from the loop-start location. If loopFlag is AXPBADDR_LOOP_OFF, the DSP will set the voice state to AX_PB_STATE_STOP and continue reading samples (from the specified loop-start address) for the remainder of the frame.

The Zero Buffer

Applications must prepare a "zero buffer" in memory to accomodate samples that finish playing mid-frame. The zero buffer is a contiguous block of at least 256 bytes in memory. Each byte must be set to zero. The buffer must be 32-byte aligned in memory and must be a multiple of 32 bytes in length. The buffer is required for all DSP audio applications.

The buffer is part of a sample-address optimization scheme, used by the DSP to reduce processing overhead when mixing voices. Essentially, the DSP checks every millisecond if a voice has reached the end of a sound effect, rather than on every individual sample. Upon reaching the end of a sound effect, the sample-address engine will casually extract samples from the zero buffer until the DSP can turn the voice off.

The millisecond accuracy for voice termination is not considered an issue, because voice acquisition can only occur on (three-millisecond) frame boundaries. This optimization saves several million DSP cycles per second.

The DSP-ADPCM data format

DSP ADPCM frames are 8 bytes long. The first byte is the frame header and contains the predictor and scale values needed to decode the samples within the given frame. The following seven bytes contain a payload of 14 samples. A sound effect encoded in DSP-ADPCM format must be stored on an 8-byte boundary in memory because the DSP's hardware ADPCM decoder assumes that data on an 8-byte boundary contains a frame header.
Note: The sound effect does not have to end on an 8-byte boundary.

When programming the address parameter block for an ADPCM-encoded sample, the memory addresses (loopAddress, endAddress, currentAddress) must never point to the frame header. A simple formula for calculating the appropriate nibble address for a given sample offset (starting from zero) is given below:

nibble_address = ((sample/14)*16) + (sample % 14) + 2);

Synchronization

If the loopFlag parameter has changed, assert the AX_SYNC_USER_LOOP bit in the axvpb.sync member.

If loopAddress* has changed, assert the AX_SYNC_USER_LOOPADDR bit in the axvpb.sync member.

If currentAddress* has changed, assert the AX_SYNC_USER_CURRADDR bit in the axvpb.sync member.

If endAddress* has changed, assert the AX_SYNC_USER_ENDADDR bit in the axvpb.sync member.

To force synchronization of the entire structure, assert the AX_SYNC_USER_ADDR bit.

See Also

axvpb.sync
AXSetVoiceAddr

Revision History

03/01/2006 Initial version.