Lofi Cities

How the music on Lofi Cities is made

Updated

The music on Lofi Cities is composed and synthesized live in your browser by a generative engine built on the Web Audio API: code writes the chords, drums, bass and melody as you listen, with no samples, no recordings and no AI model. Each track is a new piece of lofi hip hop, two and a half to four minutes long, and the stream never runs out.

What generative means here

Nothing is pre-recorded. The page picks a random seed, one of about four billion, and a set of rules turns it into a track plan: key, tempo, chords, drum pattern, instrument settings, song form and title. Each track's seed leads to the next, so in practice the music never repeats. There is no trained model and no server doing the work: the instruments are the browser's own oscillators and filters, plus noise generated in code, scheduled on the audio clock ahead of time (0.3 seconds, or 4 seconds in a background tab), so playback stays steady even there.

Chords, keys and song form

Tracks use 24 keys, major and minor, and 26 four-bar chord progressions (14 major, 12 minor) in jazz harmony: ninths, elevenths, thirteenths, altered dominants such as 7♭9 and half-diminished chords. The electric piano, an FM synth, plays rootless four-note voicings and picks the one that moves least from the last chord.

Each track has an A and a B progression and one of three song forms, with an intro, A and B sections, a breakdown and an outro. The loops don't come back the same: a later pass may end on a ii–V back to the top, swap a dominant for its tritone sub, borrow a minor iv or change a chord's colour. Some tracks play a bridge on a third progression, lift the key a step for the last section, or give the lead a solo. Intros differ too: the chords alone, the beat first, the whole band through the filter, the melody first, or a cold start with a drum roll. The next track usually starts in a related key, over the tail of the last chord, so tracks flow into each other like a mixtape, and it picks a progression the last few tracks didn't play.

Drums, swing and tempo

The drums are synthesized too: a kick that sweeps a sine wave down to about 50 Hz, a snare of triangle tone and filtered noise, noise hi-hats and a rimshot. There are six grooves (boom, bounce, lazy, half-time, rim and shuffle), with fills at the ends of phrases. At the default Balanced vibe the tempo is 68 to 88 BPM, sixteenth notes swing by 54 to 62% and the snare sits 8 to 18 ms behind the beat. Every hit varies a little in timing and velocity, like a drummer rather than a drum machine.

Bass and melody

The bass is a sine and a quieter triangle wave through a filter that closes after each note: a round pluck that still carries on phone speakers. It follows the kick, lands on the root at each chord change and sometimes walks in with an approach note or slides into a note; some tracks walk in quarter notes, lean on fifths and octaves, or add a fill.

At Balanced, about four tracks in five get a lead melody, either a soft sine tone with vibrato or a vibraphone-like FM bell, with a dotted-eighth echo. It uses the key's pentatonic scale and grows from two short motifs per track, the second made from the first for the B sections, each developed as the track goes on: moved up or down a step, shifted off the beat, cut in half and repeated, or answered with an echo.

The lofi texture

The music runs through a virtual tape machine. A saturation curve rounds off the peaks, a wandering delay adds wow and flutter, and a low-pass filter sets the tone, opening from 900 Hz in the intro and closing at the end (at Balanced, each track starts with about 4 to 10 cents of pitch wobble and a tone setting of 5.5 to 9 kHz, and both drift as it plays). Under it runs a 7.2-second loop of vinyl crackle, four turns of a record at 33⅓ rpm, with clicks, pops, a scratch once per turn and a little hiss. One reverb adds space and a limiter keeps the peaks in check.

The city on screen

Each city adds its own sounds under the music: beds of rain, wind, traffic, water, waves, crickets, birds or voices, and one-off sounds timed to the four-minute scene loop, so thunder rolls just after the lightning. They are synthesized too, but skip the tape machine: the city is the room, the music is the record. Bells, chimes and horns are tuned to the key of the current track, so they stay in the music's key.

City sounds have their own volume slider, and the city sounds mixer (A) sets each sound from 0 to 200% in every city that has it. Track titles come from the city as well, from word banks of 16 places, 20 things and 5 kinds of weather per city: "rain over montmartre", "last train, shinjuku".

The Weather chip (W) changes the city's sounds with its sky. Rain brings the rain bed in, or keeps a rainier city's own; snow, autumn leaves and a clear night take it out, and snow and leaves add a little wind. The titles then take that weather's words instead of the city's own: "first snow over shinjuku", "falling leaves on the seine".

The Vibe settings

The Vibe panel (V) has three settings. Style starts with the next track: Jazzhop is the music described above, and 17 more styles bring their own instruments, chords and grooves. Mix plays every style in turn, a new one every one to three tracks, never one of the last three. Piano is a felt piano whose left hand plays the bass, over soft brushes, at 58 to 86 BPM. Ambient holds long, warm pad chords over a low drone and a soft sub, with no beat at Chill, at 54 to 74 BPM. Bossa is a nylon guitar, synthesized string by string, playing the bossa nova rhythm over upright bass, cross-stick clave and shaker, at 64 to 96 BPM. Synth is 80s city pop: an analog-style poly synth with chorus, a synth bass and a clap backbeat, at 70 to 100 BPM. House is lofi deep house: a soft four-on-the-floor kick, a clap on 2 and 4 and off-beat open hats under organ chords that duck on every kick, over a rolling bass, at 108 to 124 BPM. Guitar is a clean electric guitar, modelled string by string, fingerpicking open chord shapes and strumming softly over a lazy boom-bap beat, with short sliding licks, at 66 to 90 BPM. Sad holds minor chords on a soft, far-away piano over a string pad, with a hushed beat that often rests and a lonely muted trumpet, at 56 to 76 BPM. Medieval is a lute with paired strings and a recorder on old modal chords, without jazz sevenths, over frame drum and tambourine, at 64 to 90 BPM. Neo-soul is a reedy Wurlitzer on lush 9th, 11th and 13th chords that slide by half steps, a warm sliding bass and lazy drums behind the beat, at 68 to 92 BPM. Liquid DnB is a soft, low-passed breakbeat under slow, dreamy pads and a deep, gliding sub, at 160 to 176 BPM. Dub is a one-drop reggae riddim through a dusty tape echo: an offbeat guitar and organ skank, a deep melodic sub bass, echoing cross-sticks and a melodica, at 64 to 84 BPM. Chiptune is cozy 8-bit game music: pulse-wave chords as fast arpeggios, a stepped triangle bass that jumps octaves, a soft noise-channel beat and a pulse lead with an echo, at 76 to 104 BPM. Japanese is a koto plucking open sus and fourth chords with oshide bends, and a breathy shakuhachi in the in and yo scales, over a soft boom-bap with temple wood-block ticks, at 62 to 88 BPM. Oud is a fretless oud trembling and sliding through Hijaz, Nahawand and Kurd maqams over a darbuka, with a breathy ney flute, at 66 to 92 BPM. Sitar is a harmonium and a buzzing tanpura drone under a sitar that glides between the notes of a raga, over a tabla groove, at 60 to 86 BPM. Spooky is a haunted music box on minor and chromatic chords, a creeping upright bass, finger snaps and a ticking clock under a gliding theremin, at 58 to 82 BPM. Classical plays lofi covers of ten pieces by Beethoven (Für Elise, the Moonlight Sonata, the Pathétique, the Fifth Symphony and Ode to Joy) and Mozart (Eine kleine Nachtmusik, the 40th Symphony, the Rondo alla Turca, the Sonata facile and the Twinkle variations), note for note: each track is one piece in the track's key, on a felt piano whose left hand keeps the piece's own accompaniment, over a soft bass and boom-bap, at 60 to 86 BPM, and the player names the piece. Every style keeps the same keys and titles in the Up next list, and plays at about the same loudness. The panel shows each style as a pixel icon, in three groups (Chill, Groove and Themed), as a list, or as a card for the picked one over a grid of icons.

Energy also starts with the next track: in jazzhop, Chill is 60 to 72 BPM, with more swing, softer drums, a darker tone and more held chords; Upbeat is 80 to 94 BPM, brighter and tighter, with busier piano and a lead on nine tracks in ten. The Up next list keeps its keys, progressions and titles at every energy. Band changes on the next bar: Full band, No drums (the bass still follows the silent kick pattern) or Chords only, the chord instrument alone and louder so the city sounds don't bury it.

Why it works offline

Because the music is code rather than audio files, there is nothing to stream. Once the site has been opened, a service worker keeps a copy of the pages and scripts, so every city and the music keep working without a connection, in the browser or as an installed app. Phones and tablets use a lighter setting, with a shorter reverb and fewer piano notes at once.

How the cities are drawn, and where AI comes in: How Lofi Cities is made