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.
Digital IIR Antialias filters
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
You do not have the required permissions to view the files attached to this post.
Probably not the most confused programmer anymore on the XCORE forum.
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
Some interesting stuff here. Can I ask how you're generating the filter coefficients? Also is the code in asm or XC?
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
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.
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.
-
- Respected Member
- Posts: 279
- Joined: Fri Dec 11, 2009 1:34 pm
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.
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
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.
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
After I found the (O3) option in debug mode I often see nice compiled filter code.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.
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.
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
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.
Problably the gain should be distributed in the filterbanks on the interpolation side.
Probably not the most confused programmer anymore on the XCORE forum.
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
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. 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): 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. B2[][3]={ {342136134, 312894692, 342136134} , {412620160, 7158710, 412620160} , {530976482, 961921271, 530976482} , {866519237, 241511240, 866519237} };
A2[][2]={ {998846696, -1054249283} , {779872271, -1944066079} , {1141899540, -687391985} };{844231967, -1523502542} };
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. 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): 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. B2[][3]={ {342136134, 312894692, 342136134} , {412620160, 7158710, 412620160} , {530976482, 961921271, 530976482} , {866519237, 241511240, 866519237} };
A2[][2]={ {998846696, -1054249283} , {779872271, -1944066079} , {1141899540, -687391985} };{844231967, -1523502542} };
You do not have the required permissions to view the files attached to this post.
Probably not the most confused programmer anymore on the XCORE forum.
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
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.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.
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
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.Woody wrote: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.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.
Probably not the most confused programmer anymore on the XCORE forum.