NES Audio
Sound on the NES comes from the Audio Processing Unit (APU), built into the CPU. It has five channels: two pulse waves, a triangle, a noise source and a sample player (DMC). Each channel is a small block of registers in the CPU’s I/O range, and a status register and frame counter tie them together.
- Overview
- The pulse channels
- Triangle and noise
- The DMC channel
- Status and frame counter
- Sequencer commands
- Sampled audio
Overview
The five channels each occupy four bytes of the APU register range from $4000 upward, apart from a shared status and frame-counter pair. The pulse channels play square waves with selectable duty, a volume envelope and a pitch sweep. The triangle plays a fixed-shape wave an octave low, the noise channel makes pitched hiss for percussion, and the DMC streams 1-bit delta samples for drums and speech.
| Channel | Registers | Role |
|---|---|---|
| Pulse 1 | $4000–$4003 | Square wave, duty, envelope, sweep. |
| Pulse 2 | $4004–$4007 | Second square wave, same features. |
| Triangle | $4008–$400B | Fixed triangle wave, no volume control. |
| Noise | $400C–$400F | Pseudo-random noise, envelope. |
| DMC | $4010–$4013 | 1-bit delta sample playback. |
The pulse channels
Each pulse channel is four registers. The first sets the duty cycle (which of four pulse widths), whether the length counter is held, and either a constant volume or an envelope rate. The second controls the sweep unit, which slides the pitch up or down over time. The last two hold the 11-bit timer period, the low 8 bits in one register and the top 3 bits plus a length-counter load in the next.
| Register | Bits | Contents |
|---|---|---|
| $4000 / $4004 | DDLC VVVV | Duty, length halt / envelope loop, constant-volume flag, volume or envelope rate. |
| $4001 / $4005 | EPPP NSSS | Sweep enable, period, negate, shift. |
| $4002 / $4006 | TTTT TTTT | Timer period, low 8 bits. |
| $4003 / $4007 | LLLL LTTT | Length counter load, timer period high 3 bits. |
The duty bits select a pulse that is 12.5%, 25%, 50% or 75% high, giving each channel its tone colour. The timer period sets the pitch: a smaller value is a higher note.
Triangle and noise
The triangle channel plays a 32-step triangle wave at the pitch set by its 11-bit timer. It has no volume control, so it is either on or off, and it is clocked twice as often as the pulses, which puts it an octave lower for a given period. It is gated by a linear counter as well as the length counter.
| Register | Bits | Contents |
|---|---|---|
| $4008 | CRRR RRRR | Length halt / linear-counter control, linear-counter reload value. |
| $400A | TTTT TTTT | Timer period, low 8 bits. |
| $400B | LLLL LTTT | Length counter load, timer period high 3 bits. |
The noise channel makes a pseudo-random square from a shift register. Its first register holds volume or envelope like the pulses; the next picks one of 16 period values and a mode bit that switches between a tonal buzz and a broad hiss.
| Register | Bits | Contents |
|---|---|---|
| $400C | --LC VVVV | Length halt / envelope loop, constant-volume flag, volume or envelope rate. |
| $400E | M--- PPPP | Mode flag, period index (0–15). |
| $400F | LLLL L--- | Length counter load. |
The DMC channel
The delta modulation channel plays back samples as a stream of 1-bit deltas: each bit nudges the output level up or down by two, tracing a waveform. It reads sample bytes straight from CPU memory, can loop, and can raise an interrupt when a sample ends. It is used for drums, bass and rough speech.
| Register | Bits | Contents |
|---|---|---|
| $4010 | IL-- RRRR | IRQ enable, loop flag, playback rate index. |
| $4011 | -DDD DDDD | Direct 7-bit output level. |
| $4012 | AAAA AAAA | Sample start address (×64, offset from $C000). |
| $4013 | LLLL LLLL | Sample length (×16, plus 1 bytes). |
Status and frame counter
The status register at $4015 enables and disables channels and reports which are still sounding. Writing it turns each channel’s length counter on or off; reading it tells which channels are active and whether the frame or DMC interrupt has fired. The frame counter at $4017 clocks the envelopes, sweeps and length counters at a steady rate and chooses a 4-step or 5-step sequence, optionally raising a frame interrupt.
| Register | Role |
|---|---|
| $4015 (write) | Enable pulse 1, pulse 2, triangle, noise, DMC (bits 0–4). |
| $4015 (read) | Channel-active flags and interrupt status. |
| $4017 | Frame counter: 4- or 5-step mode, interrupt inhibit. |
Sequencer commands
The native operations a sequence drives on the APU, and whether each runs on its own once set or must be updated every tick. A frame counter clocks the envelopes, sweeps and length counters in hardware, so once set they play without the CPU. Only the direct sample DAC and software effects need per-tick driving.
| Command | What it does | Automatic or driven |
|---|---|---|
| Note / pitch | 11-bit timer per channel | Automatic |
| Duty | One of four pulse widths | Automatic |
| Volume / envelope | Constant level or hardware decay | Automatic |
| Sweep | Hardware pitch slide on the pulses | Automatic |
| Length counter | Times an automatic note-off | Automatic |
| Noise | Period and white or periodic mode | Automatic |
| DMC sample | DPCM playback, or the $4011 direct DAC | Automatic (DPCM); driven ($4011) |
Sampled audio
The NES has real sample hardware plus a software route, both on the DMC channel. In its normal mode the channel plays DPCM: 1-bit deltas that step the 7-bit output up or down, read straight from memory at one of sixteen fixed rates, so drums, bass and rough speech cost the CPU almost nothing (the channel fetches its own bytes, stealing an occasional cycle from the program). For cleaner or arbitrary-rate playback the same channel's output register $4011 is a direct 7-bit DAC: a routine writes successive sample values into it from a cycle-counted loop or a timer, playing 7-bit PCM at whatever rate the code runs, at the cost of the whole CPU.
DPCM is the cheap, native path and the one music engines use; the $4011 method trades CPU time for fidelity and is used for set-piece speech. Either way the DMC's own DMA fetches can nudge game timing, a quirk worth knowing when driving sprites at the same time.
| Method | How it works | Depth | Max sample rate |
|---|---|---|---|
| DPCM (DMC) | Delta samples fetched from memory at 16 fixed rates | 1-bit delta, 7-bit range | 33.1 kHz (fixed top rate) |
| $4011 direct DAC | CPU writes 7-bit values in a timed loop | 7 bits | ~16 kHz (CPU-bound) |