iir filter implementation

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 »

Have you seen this post to start with ?

http://www.xcore.com/forum/viewtopic.ph ... it=chaotic

Your filters fill probably not be unstable @ 300 Hz , but they will become more and more chaotic since the decay of the impulse response gets longer and longer with a lower fc or a higher Q value, until they finally become unstable.

Yes I have used multi stage filters with different sampling rate on XMOS but that was for adaptive McFxNLMS filters.
I think I used a 10:th order elliptic IIR filter as antialiasing filter before downsampling / after upsampling.

My solution in the asm code is to use extended precision with help of the lmul instruction.
Thus, I calculate a 96 bit accumulator and stores the 64 MSB.

I did some test cases and compared it to a simulation using 128 decimals in base 10 in MATLAB. (Yes that is very slow)
All reasonably filter settings resulted in limited cycle error that was always below -144 dBFS.

I believe you can find several post and plots about that matter from me here on Xcore.


stdefeber
Active Member
Posts: 35
Joined: Wed Dec 18, 2013 9:20 pm

Post by stdefeber »

I will try to improve my filters later on.
First I want to explore what my startKit can do and learn more on how to implement about filters.
So the higher precision filters have to wait a little.

I have cascaded 2 butterworth filters and got a nice response from it.
Next on the list is a low shelf filter.

Filter specs should be:
- 2nd order low shelf
- 12 dB gain
- Fc of 125 Hz
- Sample rate 48000KHz

Octave is not really cooperative ;) and has no command to implement a low shelf filter.
So I got my coefficients from "Digital Filter Designer" app and they match Biquad filter Calculator.

Sorry lilltrol I have not implemented you coefficient calculator yet.

I started of by using my IIR C-model again and octave, instead of calculating them in octave directly I applied the coefficients from the above calculators.
For the C-model I had to scale down my input.
However I used full scale input values (2^30) but since th adc/dac on the audio slice are 24-bit this should not be a problem I guess.

I have no Idea what the impulse response or step response should look like.
The frequency response looks OK though.

Image



best regards

Simon
bearcat
Respected Member
Posts: 283
Joined: Fri Mar 19, 2010 4:49 am

Post by bearcat »

Here's an octave routine for a shelving filter.
x2_shelving.txt
You do not have the required permissions to view the files attached to this post.
stdefeber
Active Member
Posts: 35
Joined: Wed Dec 18, 2013 9:20 pm

Post by stdefeber »

Thanks a lot for the octave routine !
stdefeber
Active Member
Posts: 35
Joined: Wed Dec 18, 2013 9:20 pm

Post by stdefeber »

Can I do a call to the same function from 2 different cores/threads ?

Core 0 is making my input signal (step, impulse)
Core 1 holds the initialisation of the lowpass filter and calls the generic iir function
Core 2 holds the initialisation of the highpass filter and calls the generic iir function
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

If the called function is large in size (bytes), you should consider to just run it on one of the tiles to save program memory, otherwise the call must be replicated on each tile.

Use channels or interface to communicate between the threads.

The interface functionality in XC is very similar to a function call, but will use channels to transfer the input arguments and the return value.
bearcat
Respected Member
Posts: 283
Joined: Fri Mar 19, 2010 4:49 am

Post by bearcat »

Calling the same routine on multiple cores or tiles is not an issue. It will get replicated as needed, in the case of different tiles.

One issue to deal with though, is setting breakpoints inside a common routine. Setting a breakpoint has an issue inside a common routine, since it can get triggered from multiple calling routines or tiles. Some thought is needed to be able to debug a routine to decide what to make common and what to make individual. I suspect your IIR routine can be common, but the code to call that routine needs to be unique for each core so you can set breakpoints there.