Skip to content

Music Guide (m4a engine & porydaw)

Marcus Huderle edited this page Oct 12, 2026 · 1 revision

Composing & Inserting Music for Pokémon Decomp Projects

Table of contents

Part 1: Introduction

The Pokémon games use an audio engine called m4a (a.k.a. Sappy or MusicPlayer2000/MP2K), which was a very popular engine used in many GBA games. This guide will cover the capabilities of m4a, as well as how to insert/modify your own songs using a tool called Porydaw.

Who is this guide for?

This guide assumes you already have a baseline understanding of how to use a Pokémon decomp project (e.g. pokeemerald). Assuming you already know that, then this guide is aimed for people wanting to:

  • Learn about the m4a engine's capabilities and limitations.
  • Import MIDI files into the game, and previewing them with accurate sound.
  • DAW-based music composition and insertion.

What Is Porydaw?

Making/inserting music for pokeemerald used to require going through a tedious process of (1) making modifications to midi/voices, (2) recompiling the ROM, and (3) testing the song in-game and see if it sounds right.

To remove that pain, Porydaw was created. It's a full digital audio workstation that is integrated directly with the decomp projects. It uses an audio synthesizer that emulates the GBA's m4a sound engine and loads audio data directly from your decomp project. This means you can quickly make edits without needing to repeatedly compile your ROM because it sounds just like it does in-game.

Porydaw can be downloaded from its Releases page on GitHub.

Part 2: Understanding the GBA M4A Engine

Before we get into inserting/editing music with the help of poryaaaa, we need to learn about the capabilities of the m4a audio engine. Having a decent grasp on how it works and its limitations are important for making your own music.

How GBA m4a Engine Works

The m4a engine is the standard GBA sound engine used by a large number of GBA games. It's implemented in pokeemerald across several files, including src/m4a.c, src/m4a_1.s, src/m4a_tables.c.

Songs are represented as sequences of m4a bytecode commands, not MIDI. However, those commands are fairly equivalent to MIDI concepts:

  • Note on/off
  • Program change (instrument/voice selection)
  • Volume, panning, pitch bend, pitch modulation

Each song uses a "voicegroup" that defines up to 128 instruments/voices. For example, Littleroot Town's song's voicegroup contains pizzicato strings, fretless bass, piano, and many others. Typically, songs have their own dedicated voicegroups, but it's very possible and reasonable for multiple songs to use the same voicegroup.

For the rest of this document, we'll use the term "voice" to refer to an instrument/voice within a voicegroup.

Voice Types

Voices come in many different types.

  • DirectSound (PCM samples): This is typically the most common and prominent voice type. It plays back pre-recorded audio samples with a volume envelope and optional looping. Most melodic instruments and percussion use this. For example, a violin or piano.
    • DirectSound No-Resample: This plays at a fixed pitch regardless of the note. Used for drums/percussion/sound-effects where you want the sample played as-is.
  • Square Wave 1: CGB (Game Boy Color) synthesizer. It produces a square wave with configurable duty cycle (12.5%, 25%, 50%, 75%). It supports hardware pitch sweep. The hardware unit that produces this square wave is effectively the same as the hardware from the Game Boy Color.
    • See Wikipedia if you don't know what a square wave sounds like or looks like.
  • Square Wave 2: Same as Square 1 but without pitch-sweep capability. Use this for a second square voice.
  • Programmable Wave: CGB synthesizer that plays back a 16-byte (32-nybble) custom waveform. Useful for bass, pads, and other sounds not achievable with square waves. Again, the hardware unit that produces this programmable wave is effectively the same as the Game Boy Color.
  • Noise: CGB noise generator. 15-bit LFSR for white noise, or 7-bit LFSR for metallic/tonal noise. Can be used for percussion like hi-hats, snares, and whooshing sound effects. And once again, this uses the same hardware from the Game Boy Color.
  • Keysplit: A meta-voice that selects different sub-voices based on the note played. Used for voices like piano where different directsound samples cover different pitch ranges.
  • Drum Kit (keysplit_all) — A meta-voice where each MIDI note maps to a completely different voice. This is primarily used for percussion tracks.

ADSR Envelopes

An ADSR volume envelope is a ubiquitous strategy in music and sound design to control how an instrument's volume changes while it's being played. Naturally, all m4a voices have an ADSR configured. (A=Attack, D=Decay, S=Sustain, R=Release).

  • Every voice has Attack, Decay, Sustain, Release parameters.
  • DirectSound voices: each parameter ranges from 0–255.
    • Attack: 1 = very slow fade-in, 255 = instant
    • Decay: 0 = no decay, 255 = slowest decay
    • Sustain: 0 = silence, 255 = full volume of the note
    • Release: 0 = instant, 255 slowest fade-out
  • CGB voices (Square, Wave, Noise): limited ranges
    • Attack: 0 = instant, 7 = slowest fade-in
    • Decay: 0 = no decay, 7 = slowest decay
    • Sustain: 0 = silence, 15 = full volume of the note
    • Release: 0 = instant, 7 = slowest fade-out

One limitation with the CBG voices is that m4a is only capable of playing them at 16 distinct volumes (and only 4 for the Programmable Wave voice). This means you can't do perfectly subtle swells or long, smooth fades the way you can with directsound voices. However, in practice, this isn't too limiting.

Polyphony and Channel Limits

"Polyphony" is a fancy way of saying "how many voices can be playing simultaneously". m4a has some hard limits, and if your song exceeds the limit at any given point during playback, it will result in some of those voices being ignored and not making sound.

  • DirectSound channels: Configurable up to a max of 12. By default, pokeemerald's is set to 5.
    • Increasing this value is generally fine, but more channels means the CPU has to do more work, and could contribute to performance issues in the game.
  • CGB channels: Exactly one per type! This is a hardware limitation. For example, the hardware is only capable of playing one programmable wave at a time, so the song can only use one programmable wave voice at a time. Same thing for square 1, square 2, and noise.
    • 1× Square 1, 1× Square 2, 1× Programmable Wave, 1× Noise
    • To be clear, you cannot have two simultaneous Square 1 notes--you would need to use one Square 1 and one Square 2 to have two square waves playing simultaneously.
  • Total tracks: up to 10 MIDI tracks/channels for background music. (sound effects have smaller track limits.)

With 5 directsound voices, a typical song arrangement might be composed of 1 drum kit + 1 bass + 1 melody + 1 harmony + 1 pad. That's already at the 5-simultaneous voice limit! Of course, not all 5 voices would likely be playing throughout the entire song, so you can get creative and use other voices while others aren't playing any notes. Use CGB voices to play more sounds, since they don't contribute to the directsound polyphony limit.

Supported MIDI Controls

In pokeemerald, when you run make to build the ROM, the mid2agb tool is responsible for converting MIDI files to .s files, which are the final representation of the song data that go into the ROM. You don't need to understand how mid2agb works, but you do need to understand the MIDI commands that it supports, so that you can use them in your MIDI songs.

  • Note On / Note Off: This is the most command MIDI event. It plays notes at a given velocity/volume.
  • Program Change: Selects which voice to use (0–127) from the song's voicegroup.
  • CC 1 (Mod Wheel): LFO depth (0-127). Controls how deep the note's vibrato goes.
  • CC 7 (Volume): Current overall track volume (0–127). Note, this is different from Note On/Off's velocity. The note's velocity combines with this overall track volume to produce the actual volume of a note. You can change this Volume MIDI event while a note is playing, too, whereas a note's velocity only applies once when the note is triggered.
  • CC 10 (Pan): Stereo position (64 = center, 0 = hard left, 127 = hard right).
  • CC 20 (Bend Range): Pitch bend range in roughly semitones (default: 2). For example, if set to 12, a full pitch bend would result an octave of pitch change.
  • CC 21 (LFO Speed): Rate of vibrato effect. (0-127, higher means faster)
  • Pitch Bend: How far to bend the current note's pitch down or up (-64 - +63). The extent of the pitch bend is controlled by CC 20 (Bend Range) described above.

Part 3: Understanding Voicegroups

What is a Voicegroup?

A voicegroup is a list of up to 128 voices. Each song references exactly one voicegroup, but it's possible for multiple songs to share the same voicegroup.

As mentioned earlier, the MIDI "Program Change" event selects which voice will be used by the track's notes. So, a Program Change of 0 would mean the midi notes will produce sound using the first voice in the voicegroup (which is usually a drumset), Program Change 17 would use voice index 17, and so on.

How Voicegroups are Organized in pokeemerald

Voicegroups are defined in individual files (e.g. sound/voicegroups/<name>.inc).

Sometimes, voices can have sub-voicegroups, like drumsets: sound/voicegroups/drumsets/<name>.inc

For keysplit sub-voicegroups (like trumpet or piano): sound/voicegroups/keysplits/<name>.inc

All voice groups are included via sound/voice_groups.inc. So if you add your own voice group, you need to make sure it's included there.

Note, pokefirered and pokeruby currently use a different layout, which is one giant voicegroups file: sound/voice_groups.inc

Reading a Voicegroup File

Let's take a look at a real voicegroup file, sound/voicegroups/petalburg.inc, and see some examples of voice definitions. The first thing you'll notice is that there are many identical voices, all with type voice_square_1. Songs in pokeemerald tend to define all 128 voices, with instruments somewhat mapped to traditional MIDI programs (e.g. piano at index 1, strings at index 48). The unused voices tend to be set to voice_square_1.

Let's look at the interesting voices:

voice_group petalburg
    voice_keysplit_all voicegroup_petalburg_drumset
    voice_keysplit voicegroup_piano_keysplit, keysplit_piano
    ...
    voice_square_1 60, 0, 0, 3, 0, 2, 0, 0
    voice_square_2 60, 0, 3, 0, 6, 0, 0
    ...
    voice_directsound 60, 0, DirectSoundWaveData_sc88pro_fretless_bass, 255, 253, 0, 149
    voice_programmable_wave 60, 0, ProgrammableWaveData_1, 0, 7, 15, 1

These voice definition are created with the voice_ macros, which can be found in asm/macros/music_voice.inc. Each macro controls the configuration of the voice type. The last 4 numbers are the ADSR (Attack, Sustain, Decay, Release) volume envelope described earlier in this guide. The rest are fairly self-explanatory, and can be referenced in music_voice.inc if necessary.

Personally, when I create new songs, I create minimally-sized voice groups, with no regard for traditional MIDI program instrument numbers. However, that means that listening to the MIDI with a standard audio player will result in gibberish. Whether or not that's important is up to you.

Finding Which Voicegroup a Song Uses

To find or configure which voicegroup a song uses, simply look at sound/songs/midi/midi.cfg. This file controls how mid2agb converts each .mid file. The -G parameter specifies the voicegroup name. This is also where things like the master volume (-V) and reverb (-R) are configured for each song.

Adding Custom Instrument Samples the Old Fashioned Way

(Porydaw is the easiest way to add custom instrument samples, but below is how you'd do it the old fashioned way.)

As described earlier, the "directsound" voice plays a pre-recorded sample (e.g. a short looped recording of a trumpet). The sample files are all .wav files located in sound/direct_sound_samples/. If a sample is meant to be looped in order to play a held note, then the .wav file must contain a loop marker (more on that in a second).

  • Prepare/create/obtain your .wav file: it should be 8-bit and mono channel.
    • Typically, you'd want to use a low-ish sample rate like 13379Hz, to keep ROM size smaller.
    • To add looping, I recommend using Wavosaur.
      1. Open your .wav file.
      2. Choose Tools -> Loop -> Create loop points.
      3. Adjust the loop start and end until you're happy with how it sounds when looping during playback.
      4. Save the new .wav file.
  • Place your .wav file in sound/direct_sound_samples/.
  • Add an entry for it in sound/direct_sound_data.inc.
  • Add it to your voicegroup with voice_directsound.

When you compile the ROM with make, the .wav file is automatically converted to a .bin file, which is what actually goes into the ROM. The wav2agb tool is what performs that conversion.

Keysplit Tables

Keysplit tables allow mapping different MIDI note ranges to directsound samples. This is used when a single sample doesn't sound good across the entire range of notes. For example, piano and trumpet both use keysplit tables.

Rather than going into details here, it's pretty easy to copy those existing examples if you need to make your own.

Part 4: Porydaw

As mentioned earlier, Porydaw is an all-in-one digital audio workstation for the gen 3 decompilation projects. You can listen, edit, import, and compose music all within Porydaw. This page won't go into detail about how to actually use Porydaw. It's a pretty easy-to-use program, even if you haven't use a DAW before. For help, please see Porydaw's own documentation or ask in the #porydaw discord channel.

Porydaw

Clone this wiki locally