Moderator: Moderators (Main)
by random_id; Wed Dec 04, 2013 8:21 am
The issue I am having is specifying the parameters for the sinc filter function. The filter requires the bandwidth and frequency in percentage of the samplerate, and the frequency is the half-amplitude (0.5) point. I am also using the equation found in the book to roughly determine the number of taps (e.g., M = 4/BW). What I would like to do is figure out how use IIR-like parameters. For example, I would like to say that the -3dB point is 20500 kHz, and the level at nyquist should be -96 dB.
Is there a way to do this? It wouldn't have to be exact. I know that the filter tap calculation is only an estimate anyway.
by chi cubed; Wed Dec 11, 2013 2:12 am
this is challenging. the frequency response of a windowed sinc corresponds to the integrated frequency response of the used window and has both pass- and stopband ripple. the -6dB point is at a fixed position (at the point of the sinc-frequency), the -3dB point depends on the used window. so with the rolloff. the bandwidth is fixed, a special -dB point depends on the frequency response of the window.
by mystran; Wed Dec 11, 2013 9:26 am
You can normally just use that half-gain point as the cutoff directly: the fact that the gain is only -6dB at Nyquist doesn't matter. You'll get more or less symmetric pass-band attentuation and stop-band pass-through around that frequency and the latter will fold back down, but it's fine: it'll end up in the largely inaudible region just below Nyquist and as long as the filter is good enough up to around 20kHz or so, you're pretty much safe. If the filter is good, the gain decays really fast after the -6dB point. If you really don't want to do this, then just offset the cutoff down.. just be prepared for a significantly longer filter.
The key to getting good FIR filters (by windowing) is to use a good window. The Hann and Hamming stuff that is always mentioned as examples, but I wouldn't bother. See http://en.wikipedia.org/wiki/Window_function and try something like Nuttall, Blackman-Nuttall, Blackman-Harris... I like Nuttall for most things, but experiment. Kaiser can be tuned to something useable too and there are other options; IIRC Aleksey of Voxengo suggested squaring some window(?), can't remember which one right now.
I also wouldn't really bother with the theoretical bandwidth requirement calculations either. Better strategy for audio is to simply try different lengths and then try them in practice (or plot the response with a direct FFT works too.. it's just too easy to get too critical about it not looking right when in fact it's quite fine). Windowed sinc design is very simple, so it's not hard to write code where you can tweak a parameter and see what happens (it's not like it has to be efficient; just treat shorter kernels as having bunch of zero-valued taps). Same with different windows.. just write them all and see what happens, compare. When you're happy with a particular length and design, you can then write more efficient code for it.
For most applications, you can probably get away somewhere in the 16 to 32 tap (per branch) range, maybe a bit more if you're concerned about transparency.
I can't remember how much this is an issue for short filters (ie small amount of branches), but one thing to remember is that sin(x)/x is numerically unstable near x = 0. The easy way to deal with that is to build the "sinc" in frequency domain (1 until cutoff, then 0) and take IFFT followed by the window. Now people will tell you that IFFT like that can result in a nasty ripple in the response, and it's true.. but when you window it properly afterwards, the window will smooth it out, just like it smooths out the truncation of the time-domain sinc. People will also tell you horror stories of how periodic spectral sampling like that is wrong, but I find that this usually results in slightly better filter performance anyway. YMMV.
by random_id; Wed Dec 11, 2013 1:27 pm
I have something that is working currently with a Blackman window, but I will definitely continue to refine it. I am not convinced that my current implementation is the most efficient. The easiest appears to be to experiment with different window functions with the end goal of reducing the overall filter kernel size.
I was initially using Aleksey's r8brain-free-src. I was very impressed by the speed, especially compared to what I am using now. Unfortunately, (for reasons that are way beyond my feeble dsp-brain comprehension), the code as it stands is not suitable for real-time oversampling. I will probably switch to his code if he releases a real-time oversampling component. However, I really needed to get something working right now for my recent plugin.
by chi cubed; Thu Dec 12, 2013 4:17 am
did some calculations with the result that the attenuation of a blackman-harris windowed sinc is >105 dB above the (cutoff point F + 1 x bandwidth BW) (with windowsize=4/BW). the -3dB point is at around (F-0.15 BW).
for the blackman window i got 75dB (minimum attenuation for frequencies > F+BW) and
the -3B point at F-0.13BW.
the rectangular window has a minimum attenuation of ~30dB only.
here are some frequency responses. the x-axis represents the frequency difference to the cutoff-point in bandwidths as unit.