Hacker News new | ask | show | jobs
by ChuckMcM 904 days 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.

1 comments

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.
To be fair, I typically use the MAC in an FPGA to implement this with the coefficient as a fixed point value. As a result the entire step is one cycle, depending on how many MACs are available I will parallelize the algorithim to support all available MAC blocks.

But in C I typically compute the coeficent outside the loop and use it in the multiply sample * (1/coefficient) vs sample/coefficient, even the STM32 microcontrollers have single cycle multiply available.

this depends on how many samples you have and what kind of precision you're working with for the accumulator. as floats get bigger they lose precision.