Atomis Development Blog

Recreating "Billie Jean" with Code: A Stress Test for the jdBasic Audio Engine

Billie Jean Oscilloscope

Introduction

I’ve been working hard on the audio subsystem for jdBasic, my custom C++ interpreter. To really test the capabilities of the synthesis engine and the sequencer, I decided to recreate one of the most iconic grooves in history: Michael Jackson’s Billie Jean.

This wasn't just about making noise—it was about testing synchronization between cycle-based drum sequencers and linear melody players, managing polyphony, and synthesizing classic 80s sounds from scratch.

The Challenge: Synchronization

The biggest technical hurdle was syncing two different time domains in the C++ engine:

Initial tests sounded chaotic—the chords would drift out of time with the drums. I had to update the C++ backend (SoundSystem.cpp) to expose the global sequencer phase to the interpreter.

Now, I can manually sync threads in jdBasic like this:

' Wait for the drum loop to restart (Phase close to 0.0)
DO : SLEEP 1 : LOOP UNTIL SOUND.GET_PHASE() < 0.90

The Sound Design

I didn't use any samples for the instruments (except the drums). Everything else is synthesized in real-time using the engine's oscillators and filters.

The Code (seq22.jdb)

Here is the core logic that runs the track. It uses the SQ module to handle the heavy lifting.

' --- 2-Bar Chord Loop ---
' [Chords] ~ ~ [Chords] ~ ~
C_BAR1$ = "[[f#3,a3,c#4] ~ ~ [g#3,b3,d#4] ~ ~ ~ ~]"
C_BAR2$ = "[[a3,c#4,e4] ~ ~ [g#3,b3,d#4] ~ ~ ~ ~]"

' --- The Arrangement ---
' Track 4 gets Chords
SOUND.NOTE "< " + C_BAR1$ + " " + C_BAR1$ + " >", TRUE, 4

The Result

Here is the program running in real-time. You can see the oscilloscope visualizing the stereo mix as the script executes the arrangement.

Source Code

If you want to dive into the C++ engine or try running the script yourself:


What classic track should I try to code next? Let me know in the comments on YouTube!