top | item 38758707

(no title)

ReactiveJelly | 2 years ago

For a couple years I've wanted to write a subtractive synth from scratch in software. But I _cannot_ find any source that explains how to write a low-pass filter, in code, without assuming tons of knowledge about calculus and these odd things like Z-transforms?

Like, I understand FFTs and DCTs. But the explanation for how to construct filters in software is pathetic.

I looked at the code for VCVRack but could not understand it. It's already optimized for SIMD, processing 4 signals at once, which didn't help readability. (I'm sure it's very fast though)

discuss

order

ChuckMcM|2 years ago

This was one of the things that was most surprising to me doing software defined radio. It was "how does a finite impulse response filter work?" and "how to I make it work in a specific way?" The interesting question for synths would be how to give it an input that that changes its cut off frequency.

For me, the "aha" moment was when I connected the dots between "averaging" (which is a common way to filter noise out in an embedded computer) and "rolling average" is just summing the previous 'n' samples as sample * 1/n, and a picture of a fir filter that was (C code but it's pretty readable)

   out = 0;
   for (i = 0; i < n; i++) {
     out = out + sample[n-i]/n;
   }
   return(out);
That is a "FIR" filter where the coefficients are all 1/n. Now take that and do the FFT of n samples of n/1 (adding zeros to get the resolution you want). And that is the frequency response of your filter for frequencies between 0 (DC) and sample_rate/2.

For me at least that connected a lot of dots in what I was reading.

o11c|2 years ago

You probably want to defer the division until output, and not do the loop each time - instead, just subtract back N samples when adding the current sample.

thepjb|2 years ago

https://github.com/ThePJB/okiir/blob/a356b5b09917c0dbd856c9b...

Here's mine lol

Yeah I can't help but think there might be a niche for intermediate level discussion of these topics. I have a burning desire to wrap my head around z transform and other dsp black magic... (Like for example application of Hilbert transform to synthesis, anyone?) A lot of it comes back to understanding the complex plane. Like, I think Z transform relies on the fact that every *e^j2pi wraps around the unit circle again for one sample period.

benrow|2 years ago

I wrote a subtractive synth in java for my masters project. It was a fascinating domain to learn. For example, how to manage the independent voices, wavetable interpolation, envelopes. I was probably in over my head, and if I recall correctly, my supervisor was warning me about the complexity, since it was a software engineering programme.

The filter was the weirdest, least intuitive part. I ended up porting some open source code to java. This eventually worked, but was essentially impossible to debug without some sort of software oscilloscope.

That was about 18 years ago (yikes), and I still think about DSP from time to time.

The best intuition I have of low pass filters is to imagine it like an averaging, smoothing function which operates on the sample values as a sliding window. But that's not really true - it's not a straight rolling average, instead the sinc function (sin x / x) is used to scale the sample values with respect to time.

The way FIR filters work assumes a finite amount of samples (otherwise it would be technically impossible to know all past and future samples), so instead you pick a time period over which to calculate the output. Since there are always past and future samples included, this leads to a delayed output. Eg for a 100 sample filter window, you'd need to first have 100 samples in order to calculate the first output sample. This is intuitive, since a filter is sort of a smoothing, averaging function.

rcxdude|2 years ago

DSP is mainly mathematics, and so there's not much substitute for understanding someof the theory if you actually want to understand what's going on. It may look intimidating with all the calculus but it's not actually that bad if you just want to understand how the mathematical description of a filter relates to the implementation in terms of the multiplications and additions that are happent.

bigbillheck|2 years ago

> But the explanation for how to construct filters in software is pathetic.

Pick your favorite FIR filter, set up a ring buffer, input samples go in, at each step you multiply the buffer elements by your filter coefficients, sum, and output the result.

ahartmetz|2 years ago

The hard part is calculating the coefficients.

AtomicOrbital|2 years ago

A intuition for creating a lowpass filter ... audio happens in the time domain ... Fourier transform outputs the frequency domain representation of the audio you feed it ... number of audio samples you feed into the FFT call determines the element count of the array returned ... now you have an array of your audio in the frequency domain ... for lowpass crank down to zero array elements above the first quarter of them ... this silences those frequencies ... to render the audio ( generate sound ) feed your edited frequency domain array into an IFFT ( inverse Fourier transform )

samdafi|2 years ago

This does work, but the sound of it isn’t super pleasing and it limits your filter design options. Checking out time domain IIR filters and methods for generating coefficients gets you flexibility and efficiency with no latency. I posted some links above but the RBJ Cookbook is a good place to start.

ViktorV|2 years ago

Z-transform is very similar to Fourier or Laplace transform, but in discrete time. These things are not that hard, if you get FFT already then you can get there if you want.

Scene_Cast2|2 years ago

https://fiiir.com/ will help you design a filter. Select "Python script" to get some comments on how to apply that filter on your data (look for "convolve").

For more understanding, I do recommend reading up on DSP and Signals concepts, they're pretty critical to know if you're designing filters.

voidhorse|2 years ago

Will Pirkle's books might be close to what you're looking for. He covers Z transforms (which you do ultimately need to understand to code up filters) but also provides implementations you can use as a starting point/to get a better idea of what to do concretely in software.