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.

NES 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.

ChannelRegistersRole
Pulse 1$4000–$4003Square wave, duty, envelope, sweep.
Pulse 2$4004–$4007Second square wave, same features.
Triangle$4008–$400BFixed triangle wave, no volume control.
Noise$400C–$400FPseudo-random noise, envelope.
DMC$4010–$40131-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.

RegisterBitsContents
$4000 / $4004DDLC VVVVDuty, length halt / envelope loop, constant-volume flag, volume or envelope rate.
$4001 / $4005EPPP NSSSSweep enable, period, negate, shift.
$4002 / $4006TTTT TTTTTimer period, low 8 bits.
$4003 / $4007LLLL LTTTLength 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.

RegisterBitsContents
$4008CRRR RRRRLength halt / linear-counter control, linear-counter reload value.
$400ATTTT TTTTTimer period, low 8 bits.
$400BLLLL LTTTLength 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.

RegisterBitsContents
$400C--LC VVVVLength halt / envelope loop, constant-volume flag, volume or envelope rate.
$400EM--- PPPPMode flag, period index (0–15).
$400FLLLL 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.

RegisterBitsContents
$4010IL-- RRRRIRQ enable, loop flag, playback rate index.
$4011-DDD DDDDDirect 7-bit output level.
$4012AAAA AAAASample start address (×64, offset from $C000).
$4013LLLL LLLLSample 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.

RegisterRole
$4015 (write)Enable pulse 1, pulse 2, triangle, noise, DMC (bits 0–4).
$4015 (read)Channel-active flags and interrupt status.
$4017Frame counter: 4- or 5-step mode, interrupt inhibit.