Bessel

A “non-physical” physical modeling instrument!

Bessel started out as an idea for a fast approximation of Bessel functions of the first kind, a type of function that shows up a lot in physical modeling synthesis. Around the time I was working on this approximation, I got to visit my (at the time) 9-year-old cousins, and when I showed them some of my other digital instruments, they immediately went chaotic in a different sense of the word, and tried to press every key at once, which struck me as a really fun way to interact with this type of sound. Because of this, my instrument flashes keys all over the place whenever you press them, rewarding a very reckless sort of exploring as you intuitively learn what these keys do or don’t do. Before you read any further, I encourage you to download this instrument and play it for yourself!

Now, an explanation: On the audio end, this is just a model for a circular membrane (like in a drum) that uses my Bessel function approximation and feeds the output at some point on the drum back into itself through a specifically chosen nonlinearity. This nonlinearity can be thought of as a version of the logistic map with a variable width, which causes the “drum” to oscillate chaotically, doing all sorts of fun noisy stuff while still loosely sticking to a pitched note. But how does the Bessel function approximation in our fun little chaotic resonator actually work?

Bessel functions of the first kind, written as Jn(x) for each order n, look like a sine wave that varies in frequency and amplitude over time, so they can easily be approximated by taking the sine of some function and multiplying that result by some other function. This second amplitude function is of the form ax-0.5, a common approximation for the amplitude of Jn(x) when x is very large. We want small values of x too, however! Thus, the approximation gets shifted slightly so that it doesn’t blow up to infinity when x is zero.

Meanwhile, the “phasor” function that goes inside a sine function to approximate the changing frequency of Jn(x) is simply a polynomial, fit as best as possible to the zeros and relative extrema of scipy’s Bessel functions in python. Because this approximation isn’t 100% perfect, we lastly need to calculate new zeros of our approximated Bessel function for use in the modeled instrument.

But wait! What are the actual effects of all these approximations? For starters, the overtones of our generated sound will be slightly different than if we used a perfect circle, but similar imperfections show up in perfectly-useable “real world” instruments as well, and they don’t sound egregious to my ears. Visually, the instrument relies on this approximation as well, taking only the first couple of harmonics at each position along the digital circle to wobble it up and down convincingly. The action of this wobble is biased very slightly towards the center of the circle by our approximation, but only imperceptibly-so.

Tools

ChucK, the ChuGL ChuGin,  and math done in Python

Link:

https://ccrma.stanford.edu/~jomitch/bessel/bessel.zip

Requires:

The latest versions of ChucK and ChuGL

To start Bessel, navigate to the folder in your computer’s terminal and run the command chuck –bufsize:2048 run.ck