Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
72 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Contents
 Introduction
 Direct Sound
 DMA
 Putting it all
 together


 Source code
 Printable version
 Discuss this article

Introduction

Let me preface this article by saying that of all the hobbyist programming I have done, I enjoy developing for the Gameboy Advance the most. It strips away a lot the of the complexity normally associated with developing for the so-called "more powerful" machines. There's no hassling with drivers, complicated graphics APIs, or (cough) unruly operating systems. You get to program directly to the metal. And come on, how often does a hobbyist get to see his or her creation running on an actual commercial game console? On top of that, the dev hardware is reasonably cheap (a flash linker and cartridge will run you about $120), the standard C and C++ libraries are free (see Jason Wilkins Unofficial GameBoy Advance Software Development Kit), and the hardware documentation is abundant. Hmm… Well, maybe not that last one.

While it's true that information about the video hardware of the GBA is plentiful on the 'net, the well appears to dry up as soon as one starts investigating the system's audio capabilities. (The notable exception to this is the Audio Advance website, but even it doesn't provide any examples of sample mixing) As you might have guessed, that's where this series of articles come in. By the time it is finished, I will have documented in careful detail the steps necessary to create a fully functional, eight channel, 22KHz sample mixer that uses (at most) 10% of the CPU. I should note that I will not be covering the Sound Channels 1-4, as they appear to be little more than a holdover from the Gameboy Color, and are not involved in the playback of recorded samples. Instead, I will cover what are called the "Direct Sound" hardware channels.

Layout

There will be three articles in this series by the time it is finished. A rough outline of their content is as follows:

  • The first article (this one) will introduce the different hardware systems that control the playback of digital audio on the GBA. It will touch on the topics of Timers, DMA, and the Direct Sound channels.

  • The second article will cover a C implementation of a multi-channel sound mixer. The focus will be on the logic behind sound mixing on the GBA rather than on performance (ie. it will be slow, but hopefully very easy to understand).

  • The last article will tighten the screws on the implementation presented in Article #2, and will bump up performance quite a bit. The largest change will involve re-writing the core of the mixer in ARM assembly. If assembly coding scares you, don't worry because a) it won't be more than a few simple instructions, and b) it will be heavily commented.

Is everybody ready? Ok then, let's get started.

Some Background

A fundamental concept that any GBA programmer should be familiar with is that all of the specialized functionality of the hardware is memory-mapped. This means that tasks like changing the video mode, reading input from the keypad, playing sounds, etc. can all be performed simply by writing to or reading from specific memory locations. For example, if I wanted to read the state of the keypad (ie. which of the buttons are currently being pressed), I would just read a 16-bit value from memory address 0x4000130 and interpret it accordingly. What makes this such a powerful concept is that it essentially boils down control of the specialized hardware to a few simple "switches." I would suggest checking out either Dovoto's The Pern Project or Brian Sowers GBA Development From the Ground Up for more information about the basic functionality of the GBA.

Turning the thing on

Before we can make any noises with the GBA, we have to tell the hardware to turn the sound chip on. Luckily for you beginners, this is also a classically simple example of the memory-mapping I was just talking about. To enable the audio hardware, all we have to do is set bit 7 of REG_SOUNDCNT_X (a 32-bit value located at address 0x04000084) to 1. It amounts to a simple C statement:

*(u32*)0x04000084 = 0x00000080;

Kind of cryptic, huh? Let's add a couple of #defines to preserve our sanity, like this:

#define REG_SOUNDCNT_X *(u32*)0x04000084
#define SND_ENABLED    0x00000080

Now our statement makes a lot more sense when we look at it.

REG_SOUNDCNT_X = SND_ENABLED;




Next : Direct Sound