Sense of rhythm with Web Audio Api 🤘
Hi everyone!
This summer, I spend my free time in drum school and I have a one story for you. In short, one day I visited drum school and nobody of us did prepare the homework. Our teacher was principled and forced us to play one rhythm at the beginning of the class. There were three of us. And it was simple for me and one guy. But the third man couldn’t do it all the time. Awful! I couldn’t believe my ears! I thought I wasted my time and my money, which I paid for that class.
I was disappointed about that fact. One idea came to me and i decided to change this situation, because I’m frontend developer and I can make life easier for people. This school has a web site of self-study, but this site doesn’t have exercises for learning the rhythms except youtube video clips.

I started to analyze future drums lessons. I suppose they should be simple, understandable and available for everyone. You don’t need to be a drummer to play simple rhythms, but you must have sense of rhythm and inner metronome. It can be difficult for the beginners, if they have no ear for music. If you don’t have the natural talent, only practice can help. So you should play simple rhythms in the web class again and again. If you want to get sense of rhythm, you can get it without drums or special devices.
Browser will help you!
I did not have any drums, that is why I recorded a five simple three seconds rhythms with help of https://patternsketch.com/. And the next challenge was to write the function which will check the similarities of two wav files. For it I used the Web Audio API, which provides a powerful and versatile system for controlling audio on the Web. You can check documentation there https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
The first thing, which we needed to extract from the file was frequency data. For it, we need to initialize AudioContext and our song in application.

After that, when audio will be played, we must create media element source and connect analyzer, context and ScriptProcessorNode used for direct audio processing.

For getting frequency data we add listener onaudioprocess and check currently frequency data of played audio. I decided to save only average values of this spectrum. It saves memory and don’t change the real sounds.

When i tried get audio.currentTime or audioProcessingEvent.playbackTime, I faced a problem. Sometimes time value was constantly with some intervals. I couldn’t resolve that problem, but in most cases, I got right results. After filling of array, we can draw the next analog of spectogram for our audio file. It shows us time dependence on average frequency values.

We can see distinctly beats of this sound. Can you see? Four peaks mean that in this rhythm we have four hits on drums. It’s easy to see, but we must do it programmatically. For it we plan our graphic with cubic-spline which helps to find the peaks of the graphic.

The results of splined function are a little different, than just frequency data. But we have an array which contains about 100 elements. Yeah, it’s my sacrifice for performance of calculations for the web-client’s side. At the correct settings we can get graphics without the difference in beats.
Next step, we iterate over the array and search for peaks.

When I tested my application, I had problems, connected with extra interferences, like a noise from the street, conversations and permanent sounds of keyboards and clicks of my colleagues. Therefore, I do not take into account values, which are less than CLAP_KNOCK_THRESHOLD. It makes the search cleaner, but it can filter real sounds of drums hits. However, I’m sure, that for homework, it should be enough. In the end, we have the array of beats for one sound with time markers and frequency values.

We should get beats from the microphone source and just compare these beats among themselves. I wanted to check frequency values to know which drum was hitting, but for check the coincidence of two rhythms time difference is important. And, if you remember, i have developed this application for everyone, which you can use, even if you don’t have drums.

At the beginning, I check number of hits, because it is very important. If you mix up, you don’t play this rhythm exactly. Besides, it prevents the next calculations. Allowed difference was selected empirically. I think, that it’s like the truth, because, the more beats we have in the sound, the more difficult it is to repeat every beat.
Every song, which I was taught in this school, can be separated into squares, which contains four beats. I added css component of this square.

It helps us to see these beats and hits on the rhythm. The red line is a time marker which goes evenly around the square. You should play the rhythm you listen exactly the same as you feel and hear it. And if you do it, you will see a mark, which means, that the beat was passed. Three of the four passed beats, mean, that you are successful. That’s all.
What I want in the future!
- Make comparison more precisely.
My way to compare the beats is not difficult. But it’s only demo. I want to try to train neural networks in order to make the algorithm more accurate. - Add as opportunity to record and upload any rhythms.
It’s needed for users, who want to learn new rhythms. They could just record rhythms in the classrooms and play them athome.
You can take a look on my github project:
https://github.com/Squirre1/drums-rhythms-demo
And try to check your sense of rhythm with this demo page: https://squirre1.github.io/drums-rhythms-demo
Thank you for attention!
Let’s rock!🤘🤘🤘
