1
$\begingroup$

I'm trying to decipher the uncommented source code of SoundBox which is a little music tracker written in javascript.

There is an included synthesizer, which applies a filter on the output samples. I'm struggling to understand how it works. You can find where the filter is applied in the source code here (line 251). However it is not commented.

Here is my interpretation of its definition. First, the filter parameters:

a = cutoff/samplerate
f = 1.5 * sin(PI * a)
q = 1.0 - resonance

cutoff is in Hz. The samplerate is fixed at 44100.

then the filter process

low[i] += f * band[i-1]
high[i] = q * (x[i] - band[i-1]) - low[i]
band[i] += f * high[i]

y[i] = low[i]

where x is the input sample array, y the output and low/high/band some other variable whose purpose I don't fully understand yet.

This looks like some kind of IIR filter to me. Do you recognize it? Can you break it down for me? Explain it to me?

This is the low-pass filter version. One is supposed to be able to get a high-pass filter (or a band-pass) by changing the output to y[i] = high[i] (or band[i]).

I've made some experiments and it works pretty well, however the actual cutoff is a bit shifted and is not exactly equal to cutoff. I've been able to correct the problem by changing the definition of f to f = sin(2.0 * PI * a). Now the cutoff is exactly where it is supposed to be, but I don't know why. If you want to see nice pictures of that, you can see the issue I've opened on GitHub, but no response yet.

Thanks.

$\endgroup$
3
$\begingroup$

This is a digital state variable filter. Note that your pseudo-code of the filtering process is not correct. You replaced all += in the original code by =, which results in a filter that wouldn't work as desired.

The actual recursive equations implemented by the code are

$$\begin{align}l[n]&=l[n-1]+fb[n-1]\\ h[n]&=q\big(x[n]-b[n-1]\big)-l[n]\\ b[n]&=fh[n]+b[n-1]\end{align}\tag{1}$$

where $l[n]$, $h[n]$, and $b[n]$ are the low-pass, high-pass, and band-pass outputs, respectively. The equations $(1)$ implement a second-order IIR filter (actually three).

$\endgroup$
  • $\begingroup$ Nice! And with the associated paper, I like it. Thanks a lot! And, oops, you'r right, I forgot the + when I wrote the question. I've edited it. $\endgroup$ – Jingbee Jul 13 '18 at 22:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.