KVR Audio is the Internet's number one news and information resource for open standard audio plugins. We report new releases, product announcements and product updates (major and minor) for all VST Plugins, DirectX Plugins and Audio Units Plugins. We manage a fully searchable audio plugin database (updated daily), and offer many free member services including user reviews, product update notifications and a very active discussion forum. We also host official support forums for many plugin developers plus the official Receptor support forum.
Plug-in Database: Virtual
Instruments, Effects & Hosts
Plug-in
Ranks
Banks & Patches
Download & Upload
Plug-in Ratings
by KVR Members
Wiki: Tutorials,
Audio Lexicon, ...
Listen to Music
by KVR Members
Search
KVR

Google Powered Search:

in new window

KVR Powered Plug-in Search:

Author Topic: help with simple resonant RC_filter in AVR ASM
Nemuri
KVRer
- profile
- pm
- www
PostPosted: Sun Aug 24, 2008 6:59 am reply with quote
hello all,
i started experimenting with some simple DSP routines on an Atmega644
works surprisingly well so far - allready got 1 FM pair and 1 PWM/Saw Osc with separate vol EGs...

my problem is the filter. I decided to implement a simple RC filter:

a += f * ((in - a) + q * (a - b));
b += f * (a - b); 


without resonance the filter is working like a charm. but as soon as i raise Q
i get horrible clipping. since i'm quite new to assembler, heres my source, maybe someone spots my error.

http://chipmusik.de/lp.txt

have a nice day,
nemuri
^ Joined: 25 Aug 2005  Member: #79200  Location: germany/bonn
nollock
KVRian
- profile
- pm
PostPosted: Sun Aug 24, 2008 7:33 am reply with quote

a += f * ((in - a) + q * (a - b));
b += f * (a - b); 


If I understand correctly you have two 1 pole lowpass sections, with the 2nd one taped as highpass (in-out), so the feedback is bandpass?

What looks odd to me is where you actualy adding in the feedback.

I think it'd probably be better like this..

in += q * (a - b);
a += f * (in - a);
b += f * (a - b);

Assuming you dont already know of it, there is a famous dsp version of the State Variable Filter. It's done in the same way, replacing electronic components with digital equivelants. Anyway here's some info on it...

http://www.earlevel.com/Digital%20Audio/StateVar.h tml
http://vellocet.com/dsp/svf/svf-stability.html

plenty of code for filters, a few versions of the SVF

http://www.musicdsp.org/archive.php?classid=3
^ Joined: 09 Dec 2003  Member: #10919  
Nemuri
KVRer
- profile
- pm
- www
PostPosted: Sun Aug 24, 2008 8:52 am reply with quote
how the resonance comes in is explained in the famous thread
here

but thanks for the links
^ Joined: 25 Aug 2005  Member: #79200  Location: germany/bonn
Leslie Sanford
KVRian
- profile
- pm
- e-mail
- www
PostPosted: Sun Aug 24, 2008 9:54 am reply with quote
Nemuri wrote:
how the resonance comes in is explained in the famous thread
here


Heh, I was going to post a link to that thread. Smile Since you're familiar with aciddose's post in the above thread, I'm assuming you're using the provided formula for calculating the 'q' coefficient?


q = feedback + feedback / (1.0 - f);
----
^ Joined: 03 Dec 2006  Member: #131095  
nollock
KVRian
- profile
- pm
PostPosted: Sun Aug 24, 2008 9:58 am reply with quote
Nemuri wrote:
how the resonance comes in is explained in the famous thread
here

but thanks for the links


Ok,

lossy integrator == 1 pole lowpass filter.

Now I understand why the resonance was done like that. He's scaling the resonance / feedback relative to frequency. Likey for stability reasons.

[edit] it'd be like altering what i wrote to this..

in += f * (q * (a - b));

ermm.. so that looks fine, i guess it must be some issue with your assembler.

Looks like you're using an 8 bit microcontroler Shocked

Ok it's do-able, but rather you than me.

Are you calculating f and q correctly? And it looks like your multiply instructions are only 8 bit? At least you're using the registers in 8 bit add/sub in one part and them in a multiply. I cant see that working very well, if at all.


sub   temp, ZL;\
sbc   r21, ZH   ;/ (a-b) signed

mulsu   r21,r22      ;mul signed:unsigned -> (a-b) * Q


Looks to me like the result of (a-b) is spread across two registers.

"temp|r21"

But you're only using "r21" in the multiply. Which is the just the bottom half of the result and will cause some weirdness. In part cause it's basicly like extreme foldback clipping. Second cause the sign bit is now bit 8 of what was a 16 bit integer. Which actualy means the sign bit is now nothing to do with the sign of the original 16 bit number.

Then again I dont know that particular microcontroler, so i could be completely wrong.

*shrug*
^ Joined: 09 Dec 2003  Member: #10919  
aciddose
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Sun Aug 24, 2008 10:10 am reply with quote
you need a minimum of a twelve-bit register to do a multimode filter if my memory is accurate. (often not, experiment for yourself..)

"Likey for stability reasons."

actually that function adjusts the amplitude of the feedback to account for group-delay in the filter. each integrator introduces one sample of delay in a digital filter (generally) and this means the maximum frequency of the filter is (samplerate/4). "stability" actually is another issue, and the practical range of a filter like this is actually (samplerate/6.5), due to numerical stability issues. (classic newton issue.)

the multimode / "state-variable" (#1) filter generally is uncompensated as it has only a single sample delay in it's feedback path meaning that a full range can be managed with 2x oversample. the first filter which is a sallen-key filter is much more unstable due to two samples of delay in it's feedback path.

it simply isnt possible to correctly calculate a filter in dsp - period. you can only ever approximate the values that you should be getting to the point where noise, quantization and so on make it irrelevant. this is generally achieved via oversampling and a minimum of 2x oversampling is generally needed in every filter. additional oversampling can sometimes help, but it often does not. approximate compensations are generally used instead while the real phase error introduced into the filter is ignored. the only way to absolutely overcome this issue is to use infinite, or practically infinite (1024x or something?) oversample.

1) (this name isnt perfectly accurate as it can refer to other filters as well)

the solution to your PROBLEM however is that you simply must hard-clip the feedback path. a hard-clip will introduce no distortion, avoiding aliasing while the feedback level remains below or equal to 1.0. a waveshaper/saturation will introduce distortion and result in aliasing - you should try to use a band-limited waveshaper.

for example, if you use 2x oversample, you should use a waveshaping function with a band limit of 0.5. if you introduce frequencies above nyquist you will need to filter/convolve your output before decimating.
^ Joined: 07 Dec 2004  Member: #50793  Location: Vancouver, Canada
Nemuri
KVRer
- profile
- pm
- www
PostPosted: Sun Aug 24, 2008 12:24 pm reply with quote
juggled a little bit with the scaling...
now i've got this
AVRfilter

still not exactly resonating, and tends to overshoot, but i will try to limit the feedback like recomended Smile
^ Joined: 25 Aug 2005  Member: #79200  Location: germany/bonn
aciddose
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Sun Aug 24, 2008 12:37 pm reply with quote
btw, i think the "theoretical" frequency limit of a filter like this without oversampling is sr/[2pi].

the "practical" limit however is like i said, sr/[6.5].
^ Joined: 07 Dec 2004  Member: #50793  Location: Vancouver, Canada
Nemuri
KVRer
- profile
- pm
- www
PostPosted: Sun Aug 24, 2008 12:50 pm reply with quote
heres another avr synth demo...
the 2nd channel with the fm pair is working nice
fm+saw

Smile
nemuri
^ Joined: 25 Aug 2005  Member: #79200  Location: germany/bonn
Nemuri
KVRer
- profile
- pm
- www
PostPosted: Sun Aug 24, 2008 1:40 pm reply with quote
@aciddose:

great! the tip with the harclipping really solved the problem Very Happy

ringin-filter

finally Smile

thank you very much!
^ Joined: 25 Aug 2005  Member: #79200  Location: germany/bonn
aciddose
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Sun Aug 24, 2008 1:47 pm reply with quote
if the chip doesn't have a clipping function, you should try something like this for fast clipping without a branch:

#define _B (15) //bits - 1
#define _SIGN(N) ((N)>>(_B))

#define _ABS(N) ((N)^_SIGN(N))
#define _CLIP(N,R) ((_ABS((N)+(R))-_ABS((N)-(R)+1))/2)

lots of instructions though, (should be 12) you might want to use a branch (4 inst) if the chip does branching OK.
^ Joined: 07 Dec 2004  Member: #50793  Location: Vancouver, Canada
nollock
KVRian
- profile
- pm
PostPosted: Sun Aug 24, 2008 2:40 pm reply with quote
aciddose wrote:

"Likey for stability reasons."

actually that function adjusts the amplitude of the feedback to account for group-delay in the filter. each integrator introduces one sample of delay in a digital filter (generally) and this means the maximum frequency of the filter is (samplerate/4). "stability" actually is another issue, and the practical range of a filter like this is actually (samplerate/6.5), due to numerical stability issues. (classic newton issue.)


What I meant was that the point at which resonance occurs in your filter, and the SVF, and the moog variations you'll find online, doesnt stay fixed at the 3db point. (or 12 db in 4 pole ect) The gain at which resonance occurs varies with cutoff frequency. So you have to adjust the resonance gain in respect to frequency in order to keep the the resonance steady, and to stop it tipping over into a chaotic exploding filter.

This is not instability because of numerical issues, truncation / rounding or such like. This is instability because mapping of the input parameters to the actual coeficients took them into unstable teritory. I mean you only have to go from an overall feedback gain of 0.99 to 1.01, to go from a 40db resonant peak, to broken tweeters and bleeding eardrums.

The problem is that the resonance & frequency controls are never completely uncoupled. At least not in any of the filters whose code you'll find online.

For example the way you tap the second pole to grab a highpass from it results in a filter that looses overall gain as it gets near to nyquist. Which actualy means the 3db point of the first pole and the 3db point of the highpass tap off the 2nd pole actualy start to drift apart the nearer you get to nyquist. Add into that mix the extra phase shift of the 1 sample delay, and the gain needed for a certain level of resonance is no longer the same across all frequencys.
^ Joined: 09 Dec 2003  Member: #10919  
Leslie Sanford
KVRian
- profile
- pm
- e-mail
- www
PostPosted: Sun Aug 24, 2008 8:58 pm reply with quote
I ran the formulas for calculating the aciddose's filter in Excel:


f = 1.0 - exp(-2*pi * hz/rate);
q = resonance + resonance / (1.0 - f);



Freq    f               q               Resonance
0       0               1.5             0.75
500   0.068759647   1.555377471      
1000   0.132791405   1.614843827      
1500   0.192420362   1.678700978      
2000   0.247949252   1.747273126      
2500   0.299659996   1.82090841      
3000   0.347815128   1.899980676      
3500   0.392659129   1.98489137      
4000   0.434419673   2.076071584      
4500   0.473308777   2.173984238      
5000   0.509523879   2.279126431      
5500   0.543248844   2.39203197      
6000   0.574654892   2.513274072      
6500   0.603901472   2.643468283      
7000   0.631137067   2.783275595      
7500   0.656499952   2.933405808      
8000   0.680118894   3.094621129      
8500   0.702113806   3.267740045      
9000   0.722596355   3.453641479      
9500   0.741670532   3.653269247      
10000   0.759433175   3.867636857      


The sample rate is 44100.

What I notice is that q increases as cutoff frequency increases.

nollock wrote:

What I meant was that the point at which resonance occurs in your filter, and the SVF, and the moog variations you'll find online, doesnt stay fixed at the 3db point. (or 12 db in 4 pole ect) The gain at which resonance occurs varies with cutoff frequency. So you have to adjust the resonance gain in respect to frequency in order to keep the the resonance steady, and to stop it tipping over into a chaotic exploding filter.


So the formula is designed so that q will increase the resonance gain with respect to the cutoff frequency to keep the overall resonance gain even?

I've used this filter quite a bit. Can someone enlighten me as to how this formula:


q = resonance + resonance / (1.0 - f);


is arrived at? Could be the answer is over my head, but I'd love to hear it anyway.
----
^ Joined: 03 Dec 2006  Member: #131095  
nollock
KVRian
- profile
- pm
PostPosted: Mon Aug 25, 2008 5:21 am reply with quote
Leslie Sanford wrote:

So the formula is designed so that q will increase the resonance gain with respect to the cutoff frequency to keep the overall resonance gain even?


Yes. Although the problem is different with different filters. The basic issue is that it's the phase of the feedback that defines where the resonance peaks. With positive feedback the peak will be where the feeback signal is in phase (phase = 0, 2PI, 4PI ect), with negative feeback it is where the feedback signal is out of phase (phase = PI, 3PI, 5PI ect)

But that point doesnt stay at a fixed gain. With ADs filter, it moves to lower gain as cuttoff increases so you need to bump the resonance up to compensate.

With the 4 pole moog variants it increases gain with higher cutoff. This is basicly because as cuttoff frequency increases, the one sample delay in the feedback path add's more and more phase shift, so the point at which the total pahse shift = PI starts to lag behind the 12db point of the filter.

ADs filter is a bit more complicated as it's a bandpass feedback, and the highpass off the 2nd pole causes different gain issues.

So it's a combination of the filters phase/magnitude not tracking properly, and of the extra phase shift from the delay in the feedback.


Quote:

I've used this filter quite a bit. Can someone enlighten me as to how this formula:

q = resonance + resonance / (1.0 - f);

is arrived at? Could be the answer is over my head, but I'd love to hear it anyway.


I dont know how AD came up with that, but I've been using pole/zero analysis to map the phase/gain which is then used to generate lookup tables. By that i mean I wrote a program that that does all the number crunching. It locates where the resonance occurs and what the overall gain in the feedback path is at that point. Thats basicly what it does anyway.
^ Joined: 09 Dec 2003  Member: #10919  
mystran
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Mon Aug 25, 2008 7:12 am reply with quote
aciddose wrote:
btw, i think the "theoretical" frequency limit of a filter like this without oversampling is sr/[2pi].

the "practical" limit however is like i said, sr/[6.5].


Well, you can take it higher, but once you put in clipping, the aliasing starts causing trouble. Pink has essentially a tweaked version (more non-linearities and some minor tweaks) and oversamples by two times (with crappy filtering); at 44.1kHz it'll lose self oscillation at around 6k or so which means around sr/(7.35). It's damped down on purpose though, but back when I played with it, there was simply no reasonable way to make it track properly much higher so who cares.

It's a nice filter though; here is a old test of my somewhat tweaked version in self-oscillation, with some white noise added (it would self-oscillate just as well without, but then it wouldn't sound so much like a whistle; live played from keyboard with oscillators fully turned off).
^ Joined: 11 Feb 2006  Member: #97939  Location: Helsinki, Finland
Reply to topic KVR Forum Index » DSP and Plug-in Development All times are GMT - 8 Hours

Printable version
Page 1 of 1
Display posts from previous:   
Post new topic
Previous Topic
Next Topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Disclaimer: All communications made available as part of this forum and any opinions, advice, statements, views or other information expressed in this forum are solely provided by, and the responsibility of, the person posting such communication and not of kvraudio.com (unless kvraudio.com is specifically identified as the author of the communication).