Skip to content
Techniques & Technology

Pulse Width Modulation

Shaping square waves

Pulse width modulation varied the duty cycle of square waves, transforming simple bleeps into rich, evolving tones that defined the sound of chip music.

commodore-64nintendo-entertainment-systemcommodore-amiga audiochiptunesynthesis 1980–present

Overview

A square wave at 50% duty cycle sounds hollow and thin. Change that ratio—make the high portion wider or narrower—and the harmonic content shifts dramatically. The SID chip could sweep through duty cycles in real-time, creating dynamic, living sounds from simple waveforms.

Understanding duty cycle

Duty cycleSound character
12.5%Thin, nasal, clarinet-like
25%Hollow, woody
50%Pure square, hollow
75%Same as 25% (inverted)

The duty cycle determines which harmonics are present:

  • 50%: Only odd harmonics (1, 3, 5, 7...)
  • Other ratios: Mix of odd and even

SID implementation

Register layout

The SID stores pulse width as a 12-bit value across two registers per voice. The high register only uses bits 0-3:

RegisterBitsFunction
$D402 (PWLO1)7:0Voice 1 pulse width, low 8 bits
$D403 (PWHI1)3:0Voice 1 pulse width, high 4 bits
$D409 (PWLO2)7:0Voice 2 pulse width, low 8 bits
$D40A (PWHI2)3:0Voice 2 pulse width, high 4 bits
$D410 (PWLO3)7:0Voice 3 pulse width, low 8 bits
$D411 (PWHI3)3:0Voice 3 pulse width, high 4 bits

The duty cycle is PW / 4096. Values of 0 or 4095 cause the pulse output to stick high or low — silence. Stay clear of the edges if you're modulating right up to the rails.

Setting pulse width

    lda #$00
    sta $d402        ; PW low byte
    lda #$08         ; 50% duty cycle ($800 = 2048 = 4096/2)
    sta $d403        ; PW high nibble

Sweeping (PWM)

pulse_sweep:
    lda pulse_lo
    clc
    adc #$10         ; Increment
    sta pulse_lo
    sta $d402
    lda pulse_hi
    adc #$00
    and #$0f         ; Keep in range
    sta pulse_hi
    sta $d403
    rts

Musical applications

Brass sounds

Fast PWM sweep creates brassy attack:

Attack:  Sweep 12% → 50% quickly
Sustain: Hold at 50% or slow sweep

String pads

Slow, subtle PWM creates warmth:

Continuous slow sweep: 25% ↔ 50% over 2-4 seconds

Lead sounds

Moderate PWM adds movement and interest to melodic lines.

NES pulse channels

The NES has four fixed duty selections per pulse channel. Hardware-wise the four sequences are 12.5%, 25%, 50%, and "25% negated" — the 25-negated waveform is 1 0 0 1 1 1 1 1, which sounds the same as a 75%-duty pulse (six-eighths high) and is universally referred to as "75%" in tracker UIs.

DD bitsSequence (8 steps)Audible duty
000 1 0 0 0 0 0 012.5%
010 1 1 0 0 0 0 025%
100 1 1 1 1 0 0 050%
111 0 0 1 1 1 1 125% negated (= 75% audible)

There is no continuous sweep: the duty selector is two bits in $4000 (or $4004 for pulse 2), so you can only switch between the four presets. Famicom musicians fake PWM-like motion by alternating between 25% and 50% on adjacent rows.

Tracker notation

Pulse-width commands vary by tracker:

TrackerCommandNotes
GoatTracker (C64)WxxSets pulse width directly (high nibble of PWHI:PWLO)
GoatTracker (C64)1xx / 2xxPulse width slide up / down at speed xx
FamiTracker (NES)VxySets duty cycle preset (0-3)

Combining with other effects

PWM layers beautifully with:

CombinationResult
PWM + Filter sweepRich, evolving pads
PWM + VibratoOrganic lead sounds
PWM + ArpeggioShimmering chords

The "SID sound"

PWM is central to the distinctive SID character:

  • Rob Hubbard's brass stabs
  • Martin Galway's warm pads
  • Tim Follin's aggressive leads

See also