Explore the sonic territory of FM synthesis from your browser! The Marlotron Duo pays homage to Korg, aiming to deliver the authentic experience of their Monotron Duo pocket synthesizer in a browser environment. The distinctive character of the original hardware has been meticulously recreated based on the electrical schematic, and all parameters have been carefully tuned by ear, using JavaScript, the Web Audio API, Tone.js, and math. Many thanks to Korg for the musical inspiration. This was CS50!
Based on the audio routing in the hardware’s schematic drawing, this emulation aims to capture the nuances of the original analog sound and functionality, including real-time LED feedback showing modulation intensity, and DAW-like zero-latency parameter controls.
The voice of the synth originates from two voltage-controlled oscillators: VCO1 (the carrier) serves as the primary voice, delivering rich sawtooth waves, while VCO2 (the modulator) features an asymmetric pitch range (-3/+1 octaves), achieving both deep bass modulation and subtle de-tuning. A cross-modulation (X-MOD) system creates sounds ranging from vibratos to extreme FM textures.
VCFs are modelled after Korg's famous MS-20 filter, with a classic -12dB/octave lowpass design and peak resonance response matched to their original (20Hz - 8kHz) hardware. Dynamic gain compensation is used to maintain a consistent volume at high resonance at any pitch.
Closely mimicking the analog voltage divider’s behaviour, the ribbon controller features four play modes which change how the keys are quantized by scale: Chromatic, Major, Minor and Bypass. The continuous pitch keyboard allows for expressive slides, and a drone button has been added to allow for for sustained sounds (note: the drone button is the only synth component that does not exist on the original hardware).
I hope that this web synth can serve both as a practical learning tool for web audio synthesis and a fun and playable instrument for anyone interested in sound design on the web.
The codebase is freely available on my GitHub, as I hope others might find it a valuable resource for translating analog synthesis concepts to digital browser-based synthesis. It is thoroughly documented inline with comments to describe the implementation details and to serve as a reference for similar projects. It is designed as a self-contained web component, so you can drop it into your own website to play around! See the README for details.
The codebase demonstrates several key concepts in web audio programming:
marlotron-duo/
│
├── index.html # Main landing page with project description and synth embed
├── main.css # Global styles for the landing page
│
└── components/
└── marlotron-duo/ # Self-contained synth component
├── index.js # Component initialization and registration
├── template.html # Synth interface HTML template
├── styles.css # Synth-specific styling
│
└── lib/ # Core synth functionality
├── dial.js # Custom dial/knob control implementation
├── interface.js # UI event handling and parameter management
└── synth-core.js # Audio engine and synthesis implementation
index.html: Landing page that introduces the project and embeds the synthmain.css: Global styles for the landing page layout and typographymarlotron-duo/:
index.js: Component initialization and registrationtemplate.html: Synth interface HTML templatestyles.css: Synth-specific stylingmarlotron-duo/lib/:
dial.js: DAW-like dial/knob control implementationinterface.js: UI event handling and parameter managementsynth-core.js: Audio engine and synthesis implementation
VCO2 (Modulator)─→[VCA2]────→[Mixer]
sawtooth │ │
│ │
VCO1 (Carrier)─→[VCA1]─┘ │
sawtooth │
↓
[MS-20 VCF]
-12dB/octave
│
↓
[Filter Compensation]
│
↓
[Destination]
(Speakers)
[Ribbon Position]───→[Note Calculator]───→[VCO1 Frequency]
│
└──→[Base Frequency]
↑
[VCO2 Pitch Slider]───→[Pitch Scaling]───┬──→[VCO2 Frequency]
(-3/+1 octaves) │
│
[VCO1 Pitch Slider]───→[Pitch Scaling]───┘
(±1 octave)
[X-MOD Slider]───→[Exponential Scaling]───→[xModGain]
(^1.5) │
↓
VCO2 Output───────→[VCO1 Frequency]
[VCF Cutoff Slider]───→[Exponential Scaling]───→[VCF Frequency]
(20Hz - 8kHz)
[VCF Peak Slider]───→[Exponential Scaling]───→[VCF Resonance]
(Q: 0.5 - 50) │
↓
[Filter Compensation Gain]
[Synth Mode]───→[VCA Gating]───→[VCA1/VCA2 Gains]
[Drone Mode]──┘
My journey into learning more JavaScript started out as a final project for CS50x 2024, and quickly became a deep dive into web audio and synthesis. With serious time constraints, I decided to choose the idea that was most connected to my personal passion for electronic music and how it relates to programming. I had to pick something that would keep me burning the midnight oil as the deadline loomed closer, and FM synthesis was a sure bet.
I aimed to create a JavaScript replica of a small, simple, analog synthesizer I love made by Korg (the Monotron Duo) using the Web Audio API and Tone.js, emulating the hardware specifications as closely as possible. I did bite off as much as I could chew without realizing it!
Following my heart allowed me to really engage with JavaScript, learn all about Tone.js and Web Audio API, and completely dissect an FM synthesizer based on its electrical schematic. This is very exciting!
After spending every spare moment fine tuning by ear the ranges of the oscillators and filters and translating that to code and mathematical calculations, I have never felt so intimate with an electronic instrument as I now do with my little synth. CS50 and Korg, thank you!
“Do what you love, you’ll never work a day in your life!”
~ Letterkenny
Note that AI was used to create this synth. It would be impossible to comment the code where it was used, since it helped me with everything. From assisting me to debug complex event listeners, to teaching me more concise syntax, to painstakingly reviewing the electrical schematics over and over again, to guiding me with the frequency and modulation calculations, to reviewing the code for best and DRYest practices, Claude 3.5 Sonnet was my invaluable co-pilot.