Overview
LoFi Engine uses a sophisticated procedural generation system to create unique LoFi tracks in real-time. The system is based on music theory principles and implemented using Tone.js, a powerful Web Audio framework.Every playback session generates a unique track—no two listening experiences are exactly the same.
Music Theory Foundation
The music generation system is built on three core concepts:Major Scale
7-note diatonic scale: C, D, E, F, G, A, B
Chord Progressions
Movement between I, ii, iii, IV, V, vi, vii chords
Voicing
How chord notes are distributed across octaves
System Architecture
The music generation happens in three stages:Chord Progression System
Major Scale Definition
The system uses the major scale as its foundation:src/lib/engine/Chords/MajorScale.ts
How it works
How it works
- singleOct: Major scale intervals in semitones [0,2,4,5,7,9,11]
- doubleOct: Two octaves for wider range
- tripleOct: Three octaves for bass to treble
- fiveToFive: Five notes below to five above for voicing
Key Selection
LoFi Engine supports all 12 chromatic keys:src/lib/engine/Chords/Keys.ts
Chord Definitions
Each chord in the major scale has specific intervals and allowed progressions:src/lib/engine/Chords/Chords.ts
Understanding the chord structure
Understanding the chord structure
- degree: Roman numeral position in scale (I = 1, V = 5, etc.)
- intervals: Semitone offsets for each note in the chord
- nextChordIdxs: Valid next chords (based on music theory)
Chord Progression Generation
The system generates progressions by randomly walking through valid chord changes:src/lib/engine/Chords/ChordProgression.ts
Dynamic Voicing
Each chord generates a unique voicing (note arrangement):src/lib/engine/Chords/Chord.ts
This creates variation by rearranging chord notes across octaves while keeping the root note at the bottom.
Instrument System
Piano
The piano uses sampled audio files processed through effects:src/lib/engine/Piano/Piano.ts
Audio effects explained
Audio effects explained
- Lowpass Filter (1000 Hz): Removes harsh high frequencies for warmer tone
- Stereo Widener (0.5): Adds spatial width to the sound
- Chain: Routes signal through effects to master output
Drums
Each drum element is a separate sampler with unique effects:- Kick
- Hi-Hat
- Snare & Noise
src/lib/engine/Drums/Kick.ts
Melodic Generation
Interval Weighting
Not all chord tones are played equally—some intervals sound more “LoFi”:src/lib/engine/Chords/IntervalWeights.ts
Weight distribution
Weight distribution
- Root (0.10): Stable but not overused
- 3rd (0.30): Defines major/minor quality—played often
- 7th (0.20): Adds jazzy color
- Extensions (0.025): 9ths, 11ths for sophisticated harmony
- 5th (0.15): Consonant support
Mode Generation
Each chord can generate its mode (scale) for melodic improvisation:src/lib/engine/Chords/Chord.ts
Audio Processing Pipeline
The complete signal flow:Randomization & Variation
The system creates variety through:Random Chord Selection
Each progression starts with a random chord
Weighted Progressions
Some progressions are more likely (V→I vs V→iii)
Dynamic Voicings
Notes rearranged across octaves each time
Interval Weighting
Melodic notes chosen by probability
Performance Optimization
Efficient Scheduling
- Tone.js schedules events ahead of time
- Samples are preloaded (callback on load)
- Minimal garbage collection during playback
Sample Management
All samples are loaded once at startup:Future Enhancements
Planned improvements to the music generation system:- More sophisticated chord voicing algorithms
- Bass line generation
- Additional instrument types
- User-adjustable music parameters
- Machine learning-based pattern variation
References
Source Code
View the engine implementation
Tone.js Docs
Learn about the audio framework