Sega Genesis / Mega Drive YM2612 FM Introduction with JavaScript
FM synthesis can be difficult at first. It asks you to learn both parameter design and performance technique.
The Sega Genesis / Mega Drive is a retro game console, but it includes the YM2612, a 4-operator, 6-channel FM sound chip. Compared with modern synth setups, that may look small, but it created a huge amount of memorable music and sound.
A lot of that know-how still survives in VGM files made and preserved by enthusiasts. By reading and replaying them, we can study how people actually used the chip and how they shaped its sound.
Today, even this small 4-operator, 6-channel setup feels like an interesting starting point for learning FM. With Tetorica, we prepared an environment where you can try it directly from JavaScript.
If that sounds interesting, let's keep going.
Experimental reference images for the introduction page: Genesis / Mega Drive branding and one iconic FM-era game image.
Source reference for the imported images: Sega Genesis - Wikipedia
Hello, YM2612 FM Sound!!
Let's hear Sega Genesis sound first. The Sega Genesis / Mega Drive uses Yamaha's YM2612 sound chip.
With ymfm, a library created by Aaron Giles, we can reproduce that chip sound in a web browser too.
So let's begin with something simple: Do Re Mi Fa Sol La Si Do.
Welcome to the world of YM2612.
Open the full Playground (with console, examples, and the operator editor) →
FM Sound Magic.
A good next step is ADSR: Attack, Decay, Sustain, and Release. This is the part that makes a sound feel like a pluck, a bell, an organ, a brass hit, or something soft and slow.
On the YM2612, those ideas are controlled with parameters such as
AR, D1R, D2R, SL, and RR.
They control the rise, the fall after the peak, the later decay while a note is held,
and the fade after key off. Unlike a simple ADSR with a flat sustain stage,
the YM2612 can keep fading while the key is held: that later decay is controlled by D2R.
AR, D1R, D2R and RR are rates; SL marks the transition from D1R to D2R. This schematic shows D2R greater than zero, not measured time or level values.
There are more parameters too, such as DT, MULTI, and TL.
But first, here is a small example patch so you can see what "setting a sound" looks like in code.
One Operator Magic
The YM2612 makes sound by combining 4 operators in each channel. But if you change all 4 operators at the same time, the result can feel too unpredictable, and it becomes hard to build an intuitive sense for ADSR.
So why not start with just one operator first?
Try this: shape one sound
Change one setting at a time, then press and hold Hold to Play to compare. Let go to hear the release; use Stop when you want to stop playback.
- Change the attack. In OP1, compare
AR = 31withAR = 12. Listen for a sharp start versus a slower rise, and compare the Envelope display. - Hear the release. Set
AR = 31,D1R = 0, andD2R = 0so the sound stays audible while held. CompareRR = 15withRR = 4, releasing the button each time. Which leaves a longer tail? - Separate pitch from level. Compare
MULTI = 1andMULTI = 2, then restoreMULTI = 1and raiseTLfrom 0 to 32. Listen for the difference between changing pitch and making the sound quieter.
Reading the numbers: TL is attenuation, so a larger value means a quieter operator. AR, D1R, D2R, and RR are rates, not durations in seconds: larger values generally mean faster changes. SL sets the level where the first decay gives way to the later decay; it does not set a hold time. The Envelope drawing is a guide to the shape, not a measured time or volume scale.
Load the 1 Operator Demo when you want to explore a single operator's sound and envelope.
Open in its own page →Build an FM sound yourself
Next, calculate a waveform in JavaScript and play it. Start with a sine wave, then add another sine wave inside the formula and listen to the difference. The calculated waveform plays through the YM2612 DAC.
1. Play a sine wave
Use Math.sin() to create a 440 Hz sine wave. Press Run to play it for two seconds. Change frequency to change the pitch.
Use View in the bottom Audio tab to switch between level history (Envelope), waveform (Oscilloscope), and frequency content (Spectrum). Drag the divider above it to resize the code and audio panels.
2. Try modulation
Change Math.sin(p) to Math.sin(p2 + a1 * Math.sin(p1)). Add the output of another wave to the original wave's position, p2. Set a1 to 0, 1, and 3, pressing Run each time to compare. At 0, you get the same sine wave as before.
Next, change only frequency1 to 880. The ratio between the two frequencies changes the tone, as does the modulation strength. This example adds a wave to the phase. The YM2612 FM sound chip also uses this kind of phase modulation between operators.
Operators: the building blocks of sound
In the previous example, op1 generated a wave, and its output was added inside another wave's sin(). In the YM2612, a wave generator and the controls that adjust its output level through TL and an envelope together form an operator.
Math.sin(p2 + op1).op1 in the previous example. Its output is added to the carrier's phase.The strength represented by a1 is controlled by the modulator's TL and envelope. Lowering TL increases the modulation strength; the envelope changes that strength over time.
The YM2612 has four operators in each of its six channels. Their connections — who modulates whom, and who reaches the output — form an algorithm. Each channel offers eight choices. In algorithm 7, all four operators connect directly to the audio output without modulating each other.
Try this: connect two operators
Load the Plain Dual preset in Common, then use the Common / OP1 / OP2 tabs. The routing label shows the active pair using the demo's OP1 and OP2 names.
- Compare the connection. With
FB = 0, switch between Parallel and Serial, playing after each change. Parallel mixes two audible operators; Serial sends OP1 into OP2. - Change the modulator. In Serial, vary OP1's TL, then its MULTI. OP1 now shapes the sound of OP2 instead of being mixed directly into the output. Return to Parallel and repeat the TL comparison.
- Add feedback. Return to Serial and compare
FB = 0, 3, and 6 in Common. Listen to how the texture changes while leaving the operator settings alone.
Feedback sends some of OP1's output back into itself. The FB value controls its strength; zero turns it off. Its audible effect depends on the operator settings and the connection, so compare it in both modes.
Load the 2 Operator Demo when you want to compare carrier/modulator behavior more directly.
Open in its own page →Compare the 8 Algorithms
The same 4-operator patch below is wired 8 different ways — nothing changes except the algorithm. Click a button to hear it. Notice how algorithms with more operators feeding into a single carrier (like ALGO 0) sound more metallic and complex, while algorithms with more operators reaching the output in parallel (like ALGO 7) sound closer to layered plain tones.
Click a button to load audio and play.
Load the full Synth app when you want to try the same ideas with a larger hands-on control surface.
Open in its own page →Analyze a Real Sound with the Analyzer
Everything above used hand-written parameters. The FM2612 VGM Analyzer works the other way: load a real VGM recording and see the actual register writes a game sent to the chip — inspect parsed commands, watch all 6 YM2612 channels live, and export a channel's current operator/algorithm state as a snapshot or TFI patch.
VGM files for real Mega Drive / Genesis game music are available from sites like vgmrips.net and zophar.net, smspower.org, or from project2612.org (archived) and its bulk archives: Project 2612 Complete Archive (2018-06-23, 681 sets) and Project 2612 Complete Archive (2021-07-12, 704 sets).
Try this: follow a sound back to its settings
- Find a sound. Load a VGM or VGZ file, play it, and watch which channels become active. Pause during a sound you want to study.
- Inspect its construction. Look at that channel's algorithm, operator levels, and envelope parameters. Identify which operators feed the output and which shape another operator.
- Bring it back to sound design. Click Export Snapshot TFI, unzip the download, and select the channel's TFI file. Load it into the Synth using its TFI file input. Play a note, change one parameter, and compare it with the original.
A patch captures settings at one moment. The original performance may also change pitch, levels, and other registers over time, so a TFI patch alone does not reproduce the whole phrase.
Load the Analyzer when you want to inspect real VGM files, watch register changes, and extract patches.
Open in its own page →How Software Talks to the Chip
The real chip only has an 8-bit data bus and two address-select pins (A0, A1),
so every parameter change is really just two writes: pick a register address, then write a value into it.
ymfm and this repository's JavaScript layer hide that two-step dance behind readable method
calls, but underneath it is always the same pattern:
0x30-0x3c— detune and frequency multiplier, per operator0x40-0x4c— total level (volume), per operator0x50-0x5c/0x80-0x8c— envelope rates (attack, sustain, release), per operator0xa0/0xa4— frequency, per channel0xb0— algorithm and feedback, per channel0x28— key on / key off, to start and stop a note
The YM2612 Basics page walks through this register map and the pin layout in more detail, down to the exact bytes used to make a single beep.
Keep Reading
Sega Genesis / Mega Drive Sega PSG Introduction with JavaScript →
Sega Mega CD RF5C164 Introduction with JavaScript →
Game Boy: Compare pulse widths, sounds, and waveforms →
Game Boy: Hear envelope volume changes → / Edit a 32-sample waveform →
SID: Change a sound’s brightness with one shared hardware filter →
From sound chip to beep: YM2612 register control in JavaScript →
Start with one sound: just intonation and equal temperament with YM2612 →
Explore frequency ratios, pure thirds, equal steps and fractional pitches in editable Playground examples.
BackFX Introductions — Work in progress
Learn by listening in the Playground and writing code that processes PCM. Explore drafts of 15 chapters, from Gain to Reverb and effect combinations, through the FX contents page.