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”.
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.
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.
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.