JavaScript Web Synth From Scratch — Adding a Keyboard to The Sine Wave Oscillator

Alex Jilkin
Level Up Coding
Published in
2 min readJan 27, 2021

--

At the previous part we created a simple sine wave and played it.

This time we will use the browser and React to create a simple virtual keyboard to play our sine wave. You can find the full source code here

The basics of playing different notes with a semitone difference from 440 hertz which is the pitch standard is just multiplying 440 by 2^(n/12)
when n is how many semitones is it above or below A.

Implementation

I won't go into much detail about how the React app works, but our basic will be a keyboard component which you can see at input/Keyboard.jsx whose job is to draw a nice looking keyboard, and capture which keys the user has pressed.

When input/KeyboardManager.js records all those triggers in a triggers object.

Our engine will be the synth modules that takes those triggers and generates a “wave” from them that we later could play

Here we have our master clock variable, and a wave generator that yields the next value to play.

For every trigger, the generator accumulates a sine wave with a different frequency thus allowing us to play different notes at the same time (or polyphony in synth jargon)

Now to play this we will have our browserPlayer module

The browser allows us to create a buffer from values, and play them.
Don’t know what is the best practice in creating this stream to output (maybe you can write and suggest something different?)
But this way works great for me, it takes the next value from our wave generator from before and sends it to the output.

What we got?

Cutting short to the result of this project — we get a simple synthesizer that we can play with the keyboard that creates sounds from scratch and we can manipulate it’s values easily.
Adding a distortion? no problem just pass the values through a distortion simulating equation.
Adding a delay? no problem, just save values from previous states and add them again to the current value.

Check out the demo
Read the next step where we add a
delay module

--

--