Intro to Computational Media - Sound

BYO 808

Link to sound homework [sequencer/drum machine] in the p5 web editor.

My chief goal with this assignment was to create a sequencer with enough functionality to be fun to play with for, oh, at least a minute. I also wanted to push my understanding of classes and objects as well as provide some kind of engaging visualization to go along with the sound output.

I started relatively early on this project because I wanted to make sure I had at least the basics working before class last week in case I had any questions that would fit in our discussion. That first version can be found here.

The first pass, with four rows of instrument buttons under a row of timing indicators.

All of the sounds used in this project are sourced from drumkito’s free pack of Roland TR-808 drum machine samples. At first, leaping off from Allison Parrish’s drum loop with framecount example, I got one instrument working as an 8-length sequence controlled by the frame rate of the sketch. With frame rate set to 32, I incremented a counter variable by one on each frame. Every 16 frames, one of the instrument button objects checks to see if its position (this.pos) matches the counter variable, and if it does, it plays the sound. After 128 frames, the counter resets to zero and begins the sequence again.

Thankfully, adding rows for additional instruments was trivial since I’m beginning to feel like I’m getting the hang of classes and objects. I also tweaked the button class to create an indicator light class that doesn’t behave exactly how I’d want it to (across any iteration of this project), but at least stays in time with the sound as it switches the indicators on/off.

This is more or less where I left the project heading into Thanksgiving break, during which I came down with Covid. That derailed my larger plans for the project. I picked it back up on Monday the 28th.

I had already started experimenting with how to decouple the timing from framecount before then, but my early attempts saw sounds triggered rapid-fire once per frame. Resources that helped me from here include Dan Shiffman’s Coding Train video on setInterval() and these two Ellen Nickles examples of using setInterval() and millis() for timing that I came across while Googling for p5 documentation of both.

First I tried using setInterval() to control the tempo–I had a feeling it wouldn’t be the best solution, but I felt like it made more intuitive sense to me. Each time the interval is tripped, a function switches a boolean variable. Then, in the draw loop, an if statement checks to see if that boolean state matches another variable logged as the previous state, and in the event it doesn’t, the sequence advances by one position to play the sound and flips the previous state. To fix the issue of rapid-fire sound triggers, I added a “played” boolean to the button constructor that gets flipped immediately after a sound plays once.

This worked alright, but because setInterval is called in setup, to my knowledge there’s no way to tweak the interval on the fly to control tempo. So I moved on to make the final version using millis() for timing.

Screenshot of the final version.

The “played” boolean in the sound/button constructor still ended up being necessary here, and achieving similar timing using an if statement to see if a certain interval has been crossed only tripped me up for a moment. The bigger problem I encountered was trying to then modify that interval using a slider–I thought that’d be easy, but my attempts to get it working failed. At this point I was texting back and forth with my brother, a musician and developer, to see what he thought of the project. He suggested I add a simple pause button to see if I could then modify the tempo while the sequence was not actively playing.

Adding buttons for play/pause and increasing or decreasing the tempo was straightforward, with the tempo modification even working as the sequence plays. I’m really not sure why that’s the case while the slider wouldn’t cooperate. At any rate, with that working I decided to expand the functionality a bit more (add the hihat, rezero button, tempo indicator, and lengthen the sequencer to 16 places). I also went back to Shiffman’s video on FFT for visualization and added in a basic visualizer since I had tried to get one working earlier and was confused as to why it wasn’t–may have just been a matter of how I was trying to draw it before.

I had higher aims for this, but it’s at least close to what I wanted to build and I hope it might be a good basis to build upon for the final. I know there are also a few odd behaviors and performance issues: on my laptop, if you tweak the sequence and tempo a bunch or leave it running for a long while, it can start to sound pretty crunchy. My brother’s guess is that it’s a buffer issue, and if I recall correctly we discussed that as a problem doing sound with Javascript back when Spencer did a sound-based project in the early weeks of ICM’s first half.–11/29/22

[Return to ITP blog portal]