How I built the ultimate practice tool for music using Vanilla JS!

For our fourth phase at Flatiron School, we were required to build a web application using a Rails API backend and JS frontend. I have been a professional bassist for the past 10+ years, and decided it would be great to build a tool that I would use to practice with for my JS project. This is a short summary of my app called “In The Shed”.

In the shed

As a professional musician, I’ve had to practice. A LOT. I’ve always wanted to have a tool that would allow me to play the chords of a song at any tempo, and loop the songs’ form so that I can practice playing their associated arpeggios, melodies, and bass lines on top of them, and be able to hear the harmony of the chord progressions. So now that I had the skills to do it, I went ahead and built it!

My first objective was to build a metronome. In order to have a metronome, I first had to build an accurate Timer, which would be the invisible “skeleton” of my metronome. After a good amount of research, this is how I built my Timer.

I used Date.now(), which is the number of milliseconds that have passed since January 1st, 1970, and used it to calculate a steady event timer that is almost exactly steady. I calculated the “drift”, a 2–10ms lag that can occur from event to event, and subtracted it from the next event to ensure that even if there is a bit of drift, the next click will land exactly where it is expected.

I played around with the structure of this Timer class a bit and finally settled on having all of its logic in the constructor, which is a bit unconventional. BUT! When I pulled the logic outside the constructor, it actually INCREASED the drift, making the metronome a little extra wobbly.

Timer Instance

So, to calculate the interval of time on which the timer will fire events, I simply divide 60000 ms by the BPM (Beats Per Minute, which the user defines using the UI), and pass it into the constructor of my Timer Class. Using this interval, I can calculate the “expected time” that should pass between events, and create a “cycle” using setTimeout.

Once I had this Timer class in place, I built my metronome. Here’s a snippet of the code from my Metronome class:

This essentially allows you to start and stop the metronome using the button on my metronome! Pretty cool.

Next, I wanted to be able to play any chord (within reason), and drag and drop it onto the song's form, so I built a tool that generates a chord, and allows you to pull it into the desired position in the form.

Chord Builder

Now, this is all great, but the next step is where the magic really happens. I built a SoundEngine class to handle processing the logic of making sounds out of these chord icons.

I first had to record all of my samples….. almost 250 of them, using my DAW (Digital Audio Workstation) Ableton Live. Here’s a snippet of what that looks like for just a few chords!

Once I had rendered my samples as WAV files, I pulled them all into a folder in my frontend called “sounds”.

After this, it was just a matter of using a few different counters, and some conditional logic to process which one is to be played at which time. To actually play the sounds, I am simply using HTML Audio, which takes in the URL of the sample you want to be played!

In summary, this was an extremely challenging build, but I loved every second of it. It was really cool to build something that I will use for the rest of my career, and that I am sure many other musicians will benefit from. I learned a ton about JS in the process, and have really learned to love the language.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Zac Flynn

Zac Flynn

Full Stack Web Developer and Bassist based in Longmont, Co