Nugget
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
psyqo::SPU Class Reference

#include <psyqo/spu.hh>

Classes

struct  ChannelPlaybackConfig
 

Public Member Functions

void initAsync ()
 Enables asynchronous DMA transfers for this SPU object.
 
void dmaWrite (uint32_t spuAddress, const void *ramAddress, size_t dataSize, eastl::function< void()> &&callback, DMA::DmaCallback dmaCallback=DMA::FROM_MAIN_LOOP)
 Asynchronously uploads data to the SPU's sound RAM.
 

Static Public Member Functions

static void initialize ()
 Resets the SPU to a known, silent state.
 
static void silenceChannels (uint32_t channelMask)
 Silences the given channels.
 
static void dmaWrite (uint32_t spuAddress, const void *ramAddress, size_t dataSize, size_t blockSize=0)
 Synchronously uploads data to the SPU's sound RAM.
 
static void playADPCM (uint8_t channelId, uint32_t spuRamAddress, const ChannelPlaybackConfig &config, bool hardCut)
 Starts playing an ADPCM sample on the given channel.
 
static uint32_t getNextFreeChannel ()
 

Static Public Attributes

static constexpr uint32_t SOUND_RAM_SIZE = 512 * 1024
 The size of the SPU's sound RAM, in bytes.
 
static constexpr size_t ADPCM_BLOCK_SIZE = 16
 The size of a single ADPCM block, in bytes.
 
static constexpr size_t MAX_DMA_BLOCK_SIZE = 16 * sizeof(uint32_t)
 The largest DMA block size the SPU will accept, in bytes.
 
static constexpr uint32_t NO_FREE_CHANNEL = 0xffffffff
 
static constexpr uint32_t BASE_SAMPLE_RATE = 44100
 
static constexpr uint16_t BASE_ALLOC_ADDR = 0x1010
 

Member Function Documentation

◆ dmaWrite() [1/2]

void psyqo::SPU::dmaWrite ( uint32_t  spuAddress,
const void ramAddress,
size_t  dataSize,
eastl::function< void()> &&  callback,
DMA::DmaCallback  dmaCallback = DMA::FROM_MAIN_LOOP 
)

Asynchronously uploads data to the SPU's sound RAM.

Returns as soon as the transfer has started, and requires initAsync to have been called. Only one transfer may be in flight at a time, but callback is free to start the next one.

Parameters
spuAddressThe destination address in sound RAM. Must be 8 byte aligned, and the transfer has to fit within SOUND_RAM_SIZE.
ramAddressThe source address in main RAM. Must be 4 byte aligned, and has to stay alive until the callback fires.
dataSizeThe number of bytes to transfer. Must be a non-zero multiple of ADPCM_BLOCK_SIZE.
callbackThe function to call once the transfer has completed.
dmaCallbackWhether to call it from the interrupt handler, or from the main loop.

◆ dmaWrite() [2/2]

void psyqo::SPU::dmaWrite ( uint32_t  spuAddress,
const void ramAddress,
size_t  dataSize,
size_t  blockSize = 0 
)
static

Synchronously uploads data to the SPU's sound RAM.

Blocks until the transfer completes. All sizes are in bytes.

Parameters
spuAddressThe destination address in sound RAM. Must be 8 byte aligned, and the transfer has to fit within SOUND_RAM_SIZE.
ramAddressThe source address in main RAM. Must be 4 byte aligned.
dataSizeThe number of bytes to transfer. Must be a non-zero multiple of ADPCM_BLOCK_SIZE.
blockSizeThe DMA block size in bytes, or 0 to pick the largest one dividing dataSize. Must be a multiple of 4 and no larger than MAX_DMA_BLOCK_SIZE.

◆ getNextFreeChannel()

uint32_t psyqo::SPU::getNextFreeChannel ( )
static

◆ initAsync()

void psyqo::SPU::initAsync ( )

Enables asynchronous DMA transfers for this SPU object.

Registers the SPU's DMA completion handler and arms the corresponding interrupt, which is what lets the callback taking overload of dmaWrite ever complete. Call it once, during application start.

◆ initialize()

void psyqo::SPU::initialize ( )
static

Resets the SPU to a known, silent state.

The kernel calls this during application startup, so there is normally no reason to call it again.

◆ playADPCM()

void psyqo::SPU::playADPCM ( uint8_t  channelId,
uint32_t  spuRamAddress,
const ChannelPlaybackConfig config,
bool  hardCut 
)
static

Starts playing an ADPCM sample on the given channel.

Parameters
channelIdThe channel to play on, 0 to 23.
spuRamAddressThe address of the sample in sound RAM. Must be 8 byte aligned and within SOUND_RAM_SIZE.
configThe volume, sample rate and ADSR settings to use.
hardCutWhether to key the channel off before keying it back on.

◆ silenceChannels()

void psyqo::SPU::silenceChannels ( uint32_t  channelMask)
static

Silences the given channels.

Parameters
channelMaskA bitmask of the channels to silence.

Member Data Documentation

◆ ADPCM_BLOCK_SIZE

constexpr size_t psyqo::SPU::ADPCM_BLOCK_SIZE = 16
staticconstexpr

The size of a single ADPCM block, in bytes.

An ADPCM block is a two byte header followed by 28 samples stored as 4 bit nibbles. The SPU only ever addresses sound RAM in whole blocks, so every transfer into it is a multiple of this.

◆ BASE_ALLOC_ADDR

constexpr uint16_t psyqo::SPU::BASE_ALLOC_ADDR = 0x1010
staticconstexpr

◆ BASE_SAMPLE_RATE

constexpr uint32_t psyqo::SPU::BASE_SAMPLE_RATE = 44100
staticconstexpr

◆ MAX_DMA_BLOCK_SIZE

constexpr size_t psyqo::SPU::MAX_DMA_BLOCK_SIZE = 16 * sizeof(uint32_t)
staticconstexpr

The largest DMA block size the SPU will accept, in bytes.

The block size field of BCR counts words, and the SPU's fifo tops out at 16 of them.

◆ NO_FREE_CHANNEL

constexpr uint32_t psyqo::SPU::NO_FREE_CHANNEL = 0xffffffff
staticconstexpr

◆ SOUND_RAM_SIZE

constexpr uint32_t psyqo::SPU::SOUND_RAM_SIZE = 512 * 1024
staticconstexpr

The size of the SPU's sound RAM, in bytes.

Voice start and repeat addresses are stored as address / 8 in a 16 bit register, which covers exactly this range and not one byte more.


The documentation for this class was generated from the following files: