The GBA audio system has 6 channels. 4 of the channels provide synthensized audio (like square waves, and noise...); they are mostly for compatibility with GameBoy Color games. The other 2 channels are called "Direct Sound" channels, they accept raw data and convert it into speaker output. We will use the direct sound channels to output our final audio data.
Here is a list of the hardware registers used by the sound system:
| 4000060h | SOUND1CNT_L | Channel 1 (Square Wave 1) Sweep Register |
| 4000062h | SOUND1CNT_H | Channel 1 (Square Wave 1) Duty/Length/Envelope |
| 4000064h | SOUND1CNT_X | Channel 1 (Square Wave 1) Frequency/Control |
| 4000068h | SOUND2CNT_L | Channel 2 (Square Wave 2) Duty/Length/Envelope |
| 400006Ch | SOUND2CNT_H | Channel 2 (Square Wave 2) Frequency/Control |
| 4000070h | SOUND3CNT_L | Channel 3 (4-bit Wave Output) Stop/Wave RAM Select |
| 4000072h | SOUND3CNT_H | Channel 3 (4-bit Wave Output) Length/Volume |
| 4000074h | SOUND3CNT_X | Channel 3 (4-bit Wave Output) Frequency/Control |
| 4000078h | SOUND4CNT_L | Channel 4 (Noise) Length/Envelope |
| 400007Ch | SOUND4CNT_H | Channel 4 (Noise) Frequency/Control |
| 4000080h | SOUNDCNT_L | Channel Left/Right Volume/Enable |
| 4000082h | SOUNDCNT_H | Direct Sound Control/Mixing |
| 4000084h | SOUNDCNT_X | Master Sound Enable |
| 40000A0h | FIFO_A | Direct Sound A FIFO Access |
| 40000A4h | FIFO_B | Direct Sound B FIFO Access |
The last four registers are the ones we are interested in. Here is the format of SOUNDCNT_H
| Bit | Description |
| 0-1 | Sound Channel 1-4 volume |
| 2 | Direct Sound A Volume (0=50%, 1=100%) |
| 3 | Direct Sound B Volume (0=50%, 1=100%) |
| 4-7 | Not used. |
| 8 | Direct Sound A - Enable Right Output |
| 9 | Direct Sound A - Enable Left Output |
| 10 | Direct Sound A - Timer Selection (0 = Timer0, 1 = Timer1) |
| 11 | Direct Sound A - Reset FIFO (1 = reset FIFO status) |
| 12 | Direct Sound B - Enable Right Output |
| 13 | Direct Sound B - Enable Left Output |
| 14 | Direct Sound B - Timer Selection (0 = Timer0, 1 = Timer1) |
| 15 | Direct Sound B - Reset FIFO (1 = reset FIFO status) |
Various bits... The first two bits control the volume of the old GBC channels; we're not interested in those. The next two bits control the volume of our direct sound channels. We want 100% volume, so we'll write "1,1" in those bits. We have 4 more bits to control each direct sound channel, the first two bits enable left/right speaker output (although the difference can only be heard with headphones since the GBA only has one built-in speaker). The third bit selects a hardware timer that will be used for the sampling rate. GBA has 4 hardware timers total, and the first two can be used for timing the sound. We will use timer 0 for our sampling-rate. The last bit is a reset flag; if you write '1' to it, then the FIFO will be cleared and reset. We will reset the FIFO at startup.
The next register (SOUNDCNT_X) is simple, it only has 1 bit that concerns us, the Master Enable bit.
| Bit | Description |
| 0-3 | Sound Channel 1-4 Status |
| 4-6 | Not used |
| 7 | Master Sound Enable |
| 8-15 | Not used |
We have to set '1' in that bit before we will hear any sound.
Next we have the FIFO access registers. Internally, each direct sound channel has a FIFO that is 8 words wide (32 bytes). Data written to FIFO_A/FIFO_B gets pushed into the buffer and remains until it is feed into the sound circuit.
Feeding the data manually with the CPU will generate some huge overhead, there's another hardware feature that can help us out here: Direct Memory Access(DMA). The GBA has 4 DMA channels (DMA0,DMA1,DMA2,DMA3), 2 of them (DMA1,DMA2) have a special function that can be used to feed audio data to the FIFOs.
What we will do is set the destination address of the DMA to the sound FIFO registers, and set the source to our mixing buffer. Here's the control register bits for DMA1 and DMA2.
| Bit | Description |
| 0-4 | Not used |
| 5-6 | Destination Address Control (0=Increment,1=Decrement,2=Fixed,3=Increment/Reload) |
| 7-8 | Source Address Control (0=Increment,1=Decrement,2=Fixed,3=Prohibited) |
| 9 | DMA Repeat (0=Single transfer,1=Repeat until stopped) |
| 10 | DMA Transfer Type (0=16bit, 1=32bit) |
| 11 | Not Used |
| 12-13 | Start Timing (0=Immediately,1=VBlank,2=HBlank,3=Sound Request) |
| 14 | Request interrupt after transfer |
| 15 | DMA Enable |
For transferring sound data, we must set the source/destination control to increment, the repeat flag to on, the transfer type to 32-bit, and the start timing to 3 (Sound Request). I'm not really sure why the destination address control is supposed to be increment, but all the documents say to do this (and it works fine). We must also set the source address of the DMA channel to our wave buffer, and the destination address to the FIFO register.
When DMA1/DMA2 Start Timing is set to 3, then a transfer of 4 words (16 bytes) will occur when the sound FIFO contains 4 or less words.
There's one thing that's scary here, the DMA has NO way of restarting automatically when it has finished passing through our ring-buffer. What we must do is count the number of samples transferred and restart the DMA manually before it starts feeding the sound random data! (very critical timing)
| Previous: MOD Format Overview | Contents | Next: Testing Environment |