Digital IIR Antialias filters

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Maybe a multistage polyphase IIR filter :idea:
Never implemented such a filter before, but that should be possible with the XMOS instruction list !?
This one is intended for 16 times decimation.
Attachments
polyphase.png
polyphase.png (8.64 KiB) Viewed 5073 times
polyphase.png
polyphase.png (8.64 KiB) Viewed 5073 times


Probably not the most confused programmer anymore on the XCORE forum.
User avatar
Woody
XCore Addict
Posts: 165
Joined: Wed Feb 10, 2010 2:32 pm

Post by Woody »

Some interesting stuff here. Can I ask how you're generating the filter coefficients? Also is the code in asm or XC?
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

I start in MATLAB, generating the filtercoeffs from existing MATLAB tools and create a SOS structure with double prec. You will need some of the MATLAB toolboxes.

Thereafter I run my own MATLAB code that transforms the MATLAB double float to C style (int32) arrays that can be directly used in XC.

Right now it's XC code, but I hope to transform code that have been proven to work correctly to ASM code.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
Andy
Respected Member
Posts: 279
Joined: Fri Dec 11, 2009 1:34 pm

Post by Andy »

Doesn't MATLAB have built in capability to export fixed point precision coefficients? Or are you doing the conversion differently?
Last edited by Andy on Wed Mar 10, 2010 4:04 pm, edited 1 time in total.
User avatar
Woody
XCore Addict
Posts: 165
Joined: Wed Feb 10, 2010 2:32 pm

Post by Woody »

I'd be interested to hear how you think XC performs compared to hand crafted assembler for filters. We're aiming to come close and we're getting quite good results internally, so I'd appreciate an independent view.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Woody wrote:I'd be interested to hear how you think XC performs compared to hand crafted assembler for filters. We're aiming to come close and we're getting quite good results internally, so I'd appreciate an independent view.
After I found the (O3) option in debug mode I often see nice compiled filter code.
When I see performance possibillities it's of the cost of much longer inlined code - but that might not be a problem in a filter - the code is small anyway.

Also I realize more and more, that by writing the XC code in another better way - I get the same ASM code as by writing it by hand.

What I really would love is that XC could help me with VPA (variable precision arithmetic)
Sine the instruction set has maccs, macc, lmul, ldiv, ladd, lsub; I would love to be able to define any struct/array that acted as a int(32*n) or uint(n*32) where n is 2,3,4... togheter with the possibillity to apply + - * /

For an example it should be able to handle:

int32 * int64 + int96 -> int96
int64 * int64 ->int 128

and you should be able to choose between a short-code lower performance option (using it only once in a code - like during an init) and a longer-code high performance option (using it in a filter loop with inlined code whitout filling the stack/eating instructions between a call to each sub-function.)
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Found out that the filter works good for decimation, but poorly for interpolation based on zero-inserts. The zeros makes the overall gain to decrease wich results in a much worse SNR.

Problably the gain should be distributed in the filterbanks on the interpolation side.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Here comes my first XMOS multi-step digital resampling.

A dual-step approach:

In the first step some aliasing can be allowed and filtered out in the next step.

In this case I'm using 22050 Hz as the real sampling frequency of the CODEC.
This filter is used before a 8 time downsample with a 500 Hz passband.
f1.png
f1.png (6.63 KiB) Viewed 5004 times
f1.png
f1.png (6.63 KiB) Viewed 5004 times
The 6:th order filter an be implemented without any cirular buffers.
B1[][3]={ {5211698, 804670, 5211698} , {44190182, -74352548, 44190182} , {96854238, -140671055, 96854238} };
A1[][2]={ {2016605248, -1896954915} , {2090263096, -2081242357} , {2042115528, -1966289752} };

Adding the energy of all aliased components should sum up to something like this (after downsampling):
f1a.png
f1a.png (8.17 KiB) Viewed 5004 times
f1a.png
f1a.png (8.17 KiB) Viewed 5004 times
where the aliased components are less than -100 dB below fs/32 = 690 Hz

In step II, we need a filter that attenuates at least 85 dB at 690 Hz, without affecting the 500Hz passband, if we would like to do a 1:2 downsampling in the end.
f2.png
f2.png (7.48 KiB) Viewed 4995 times
f2.png
f2.png (7.48 KiB) Viewed 4995 times
B2[][3]={ {342136134, 312894692, 342136134} , {412620160, 7158710, 412620160} , {530976482, 961921271, 530976482} , {866519237, 241511240, 866519237} };
A2[][2]={ {998846696, -1054249283} , {779872271, -1944066079} , {1141899540, -687391985} };{844231967, -1523502542} };
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
Woody
XCore Addict
Posts: 165
Joined: Wed Feb 10, 2010 2:32 pm

Post by Woody »

lilltroll wrote:Found out that the filter works good for decimation, but poorly for interpolation based on zero-inserts. The zeros makes the overall gain to decrease wich results in a much worse SNR.

Problably the gain should be distributed in the filterbanks on the interpolation side.
That's right: when interpolating you should increase the filter coefficients by the factor equal to the interpolation rate to maintain the signal magnitude. This is what has been done on FIR interpolation filters in the classD Power amplifier code published here http://www.xmos.com/support/software.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Woody wrote:
lilltroll wrote:Found out that the filter works good for decimation, but poorly for interpolation based on zero-inserts. The zeros makes the overall gain to decrease wich results in a much worse SNR.

Problably the gain should be distributed in the filterbanks on the interpolation side.
That's right: when interpolating you should increase the filter coefficients by the factor equal to the interpolation rate to maintain the signal magnitude. This is what has been done on FIR interpolation filters in the classD Power amplifier code published here http://www.xmos.com/support/software.
Thats the easy part, with fixed IIR filter, the gain cannot be deployed as a pre gain or a post gain in the filter. Instead in has to be distributed in such a way that it optimises the SNR without any overflow for a worst case input signal.
Probably not the most confused programmer anymore on the XCORE forum.
Post Reply