|
| Notices |
Welcome to the DriverHeaven.net forums. You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today! If you have any problems with the registration process or your account login, please contact contact us. |
 |
|
Mar 3, 2005, 10:15 AM
|
#1 (permalink)
|
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
|
Need help with filter implementation
Hi,
I need help with the implementation of a digital inverse RIAA (phono)
equalizer filter. In a forum-search I found two old threads on this topic,
but no solution
I found filter coefficients for the RIAA-curve in a post of one Frederick
Umminger at
http://www.musicdsp.org/showone.php?id=122
the coefficients are
b=[0.02675918611906 -0.04592084787595 0.01921229297239]
a=[1.00000000000000 -0.73845850035973 -0.17951755477430]
but unfortunately, these values form the original curve and not the
inverse curve needed to deemphasize the signal for playback.
Now I am trying to invert the filter, but when I normalize the values so
a0=1, then abs(a1) will become > 1:
b=[0.5839116305884448 -0.4311945070669476 -0.1048223881275120]
a=[1.0000000000000000 -1.7160778983199925 0.7179700042784745]
How can I implement this filter in Dane when the absolute value of a coefficient
is > 1? Is there any way to implement an unnormalized filter with a0 <> 1?
Any help will be appreciated!
Thanks,
Hannes
|
|
|
Mar 3, 2005, 07:51 PM
|
#2 (permalink)
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,076
|
One possibilty is to scale the coefficient value down (i.e. multiply it by .1), so that it is between -1 and 1, and then (at a point where the expected result of using the unscaled values would result in a number bewteen -1 and 1) scale the result back up (i.e. multiply by 10). Of course you would probably lose some precision doing it this way.
Another option is to use two registers. One register for the integer part of the number, and another register for the fractional part of the number. If the absolute value of the expected result of the math operations is > 1, then you will need two registers for the result as well (do the integer math, and fractional math seperatley), and only combine the values into one register at the point where the expected result is between -1 and 1, etc. Of course this can get tricky, depending on what type of math operations you need to do using these values, etc.
I am not an expert or anything, but hopefully this will give you some ideas to get you started.
|
|
|
Mar 4, 2005, 05:49 PM
|
#3 (permalink)
|
|
S-3D enthusiast
Join Date: Sep 2004
Location: Canada
Posts: 1,405
|
I'll try to help but I can't promise you I'll be successful. From the information you've posted it seems the the data you have is to be used in a IIR filter. I can't be 100% because I don't know much about it. I'll try to make a IIR filter with the values you gave. It should not be much harder than making a FIR filter. I think that the hardest part with IIR filters is determining the coefficients.
I tried to implement a FIR filter to do the equalization but it needed too many coefficients to have a good curve. IIR is supposed to take less coefficients than FIR. If it works, it might give a acceptable curve.
On a sidenote, I'm having problems with copy&pasting code in Dane and it's slowing my coding efforts. If you can help me, answer to the thread
Error: invalid plugin library when copy&pasting in Dane
|
|
|
Mar 5, 2005, 03:34 AM
|
#4 (permalink)
|
|
kX Project DSP Engineer
Join Date: Dec 2002
Location: Denmark
Posts: 94
|
Hi,
You can use the EQs in the kX package (lowpass, highpass, peaking... all beginning with EQ). They all use the same DSP code which is a biquad implementation, and you should be able to replace the default coefficients in the DSP code with scaled versions of the ones mentioned above except a0 (if I've read it correct)
In the existing EQs the coefficients are downscaled with a factor of 2 (divided by 2 in the GUI code, so you should do the same) and is upscaled before output. If you need to scale it even further to get the coefficients between +/- 1 increase "sca" accordingly.
HTH
Soeren
|
|
|
Mar 5, 2005, 05:30 AM
|
#5 (permalink)
|
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
|
Hi everyone, thanks for the replies so far!
@ Soeren:
As I understood it, simply scaling is not allowed: in all formulas I found so far,
the coefficient a0 is assumed to be '1'. When I scale the coefficients, all values
are affected - a0, too. I am not sure what the filter implementation is supposed
to do in this case, cause a0 does not appear in the normal biquad code.
@ Tril:
Yes, this is supposed to be a IIR filter with b[] defining the zeroes and a[]
defining the poles of the magnitude response H(z). You are right that the
hardest part is determining the coefficients - without mathlab or some other
expensive software, this is really difficult 
If you want to design a filter and test the response, I can post some c code
here that calculates the magnitude response of the digital filter and reports
the error vs. the analogue reference riaa filter.
@ Russ: The idea with the two registers sounds promising, I did not think of
this so far. I will try it and report here...
Bye,
Hannes
|
|
|
Mar 5, 2005, 02:56 PM
|
#6 (permalink)
|
|
kX Project DSP Engineer
Join Date: Dec 2002
Location: Denmark
Posts: 94
|
I am not sure that Frederick Umminger makes sense in saying that:
All you should need to do to get the complementary curve is swap the a and b
vectors, and then multiply both vectors by 1/a(0) to normalize. That will
give the coefficients for the inverse filter.
( http://aulos.calarts.edu/pipermail/m...er/017849.html - I assume that is where you get your inversion method from)
It seems that a0 of the coefficients he calculates has already been normalized to 1, so I don't it makes sense to just inverse the coefficients and normalize them again (correct me if I am wrong).
Using Umminger's coefficients for the cutter gives some kind of aggressive highpass filter, but I have no idea if it is correct.
He doesn't ever seem to actually test these coefficients, though.
/Soeren
|
|
|
Mar 5, 2005, 04:53 PM
|
#7 (permalink)
|
|
S-3D enthusiast
Join Date: Sep 2004
Location: Canada
Posts: 1,405
|
This Frederick Umminger said t hat he used http://www.hagtech.com/pdf/riaa.pdf as a reference.
I've looked at that document and it looks well made and professionnal. There should not be any errors in the document.
At http://www.hagtech.com/ on the main page you can read :
Quote:
Who We Are
Hagerman Technology LLC is a small company focused on the design and manufacture of audiophile-grade electronics. We offer unique products that provide true value through innovation and elegance - from the fertile and creative imagination of designer Jim Hagerman. All products are handcrafted in the USA and come with a lifetime warranty. Free shipping on all half-kits!
|
If you want to make an RIAA filter, I think you should use this pdf as a starting point. Frederick Umminger might have made errors.
|
|
|
Mar 7, 2005, 09:18 AM
|
#8 (permalink)
|
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
|
Hi,
you are right in saying that it's probably best to go back to the reference filter...
The coefficients of Mr. Umminger might have be off... one small problem is quite
obvious: the posted filter coefficients for 44.1 and 48 kHz are the same - so I
guess one of the sets is not quite right anyway.
However, I had big difficulties finding any easy methods to design an IIR filter
from an analog response curve. This seems to be a problem that can only be
solved numerically, and I have no software that will do this for me...
That's the reason why I am still trying to make use of the Frederick's coefficients - after all, his non-inverted filter curve looked good in a plot, and it would save me the work of having to design my own filter.
Maybe tomorrow I will have some time and try Russ' idea with the coefficient-
splitting...
Bye,
Hannes
|
|
|
Mar 7, 2005, 12:35 PM
|
#9 (permalink)
|
|
DriverHeaven Addict
Join Date: Dec 2002
Posts: 259
|
If you know the curve properties and the type of IIR filter, there are many pages on Internet with java apps that calculates the coeffeccients. The program Matlab also has a very good module for IIR filter design.
|
|
|
Mar 7, 2005, 01:54 PM
|
#10 (permalink)
|
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
|
Hi everyone,
I got stuck with my daywork, so I fiddled with the riaa eq again. Using the
hints from Russ, I decided to divide the large coefficient a1 by two and add
the term y[n-1]*a1 two times in the summation.
Result: working inverse RIAA filter, and sounds good, too!
I know that it's bad practise to do heavy signal amplification (+42dB) in the
dsp, but I am right now listening to my turntable, connected to the line-in of
my audigy 2 zs.
If anyone wants to test the filter, you can get it here:
http://www.buchrecycling.de/kx/inverse_riaa_v1.zip
Oh, I tested the response vs the reference curve: max deviation is -0.6dB
at 5500Hz. I think that's ok... I didn't test phase response, though...
Edit: here is a picture of the response curve (measured with 'HobbyBox')
Now, back to my other project (diploma thesis  )
Bye,
Hannes
Last edited by 2ndhannes; Mar 9, 2005 at 07:16 AM.
|
|
|
Mar 4, 2007, 08:28 AM
|
#11 (permalink)
|
|
DriverHeaven Addict
Join Date: Apr 2005
Location: FI
Posts: 380
|
Old thread but, I implemented this RIAA filter as a VST plugin recently. The RIAA EQ curve looks good ...
http://img73.imageshack.us/my.php?im...gnitudegb6.png
but, ... what 'bout phase results
http://img297.imageshack.us/img297/9...aaphaseiv7.png
jiitee
__________________
VST/DX (effect) plug-ins with Winamp, MediaMonkey and Foobar 0.8.x-0.9.x - needed components :
Winamp and MediaMonkey: VST support - VST Host DSP for Winamp, DirectX support - FFX-4 for WinAmp
Foobar: Bridge Plug-in for winamp DSP for Foobar 0.8.x-0.9.x or for Foobar 0.9.x + VST Host DSP for Winamp and/or FFX-4 for Winamp (see above)
Additional plug-ins: (use multiple plug-ins, etc.) Acon EffectChainer (DX/VST), CTAF MultiFXVST (VST), XLUTOP Chainer (VST), energyXTEffect (VST)
Output plug-ins: Foobar: ASIO and KernelStreaming (0.9.x), ASIO (0.8.x) ... Winamp and MediaMonkey: ASIO and KernelStreaming
3rd party ASIO drivers: Asio4All, (ASIOx , discontinued.?) ASIO2KS, USB-ASIO, FireWire-Universal and Ideal (+ OEM), ..... !!! ASIO Control panel
Last edited by jiiteepee; Mar 30, 2007 at 01:07 PM.
|
|
|
Mar 30, 2007, 01:17 PM
|
#12 (permalink)
|
|
DriverHeaven Addict
Join Date: Apr 2005
Location: FI
Posts: 380
|
These coefficients are maybe a bit more accurate than those F. Ummingers which ones Hannes used in this implementation (and these are surely made for 48kHz  ):
a0= 1.00000000000000000
a1=-1.73276550000000020
a2= 0.73455344362250008
b0= 1.00000000000000000
b1=-0.75555209999999995
b2=-0.16462571129709999
Maximum error from 0.00 Hz TO 20000.00 Hz is 0.1395898dB
Maximum Phase error from 0.00 Hz TO 20000.00 Hz is ~± 24 degrees
Hmm.. do you really need to 'split' the a1 and then calculate twice in formula ? ... this is not necessarily needed in VST implementation.
EDIT: These coefficients gives +12.5dB higher level than the standard is so you need to divide b0, b1 and b2 with ~4.3 to get the 0dB line crossed @ 1kHz. It's not necessary to do this 'transfer' if you don't start getting too high signal levels.
jiitee
__________________
VST/DX (effect) plug-ins with Winamp, MediaMonkey and Foobar 0.8.x-0.9.x - needed components :
Winamp and MediaMonkey: VST support - VST Host DSP for Winamp, DirectX support - FFX-4 for WinAmp
Foobar: Bridge Plug-in for winamp DSP for Foobar 0.8.x-0.9.x or for Foobar 0.9.x + VST Host DSP for Winamp and/or FFX-4 for Winamp (see above)
Additional plug-ins: (use multiple plug-ins, etc.) Acon EffectChainer (DX/VST), CTAF MultiFXVST (VST), XLUTOP Chainer (VST), energyXTEffect (VST)
Output plug-ins: Foobar: ASIO and KernelStreaming (0.9.x), ASIO (0.8.x) ... Winamp and MediaMonkey: ASIO and KernelStreaming
3rd party ASIO drivers: Asio4All, (ASIOx , discontinued.?) ASIO2KS, USB-ASIO, FireWire-Universal and Ideal (+ OEM), ..... !!! ASIO Control panel
Last edited by jiiteepee; Mar 31, 2007 at 02:20 PM.
|
|
|
Mar 30, 2007, 04:36 PM
|
#13 (permalink)
|
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 3,668
|
Quote:
|
Hmm.. do you really need to 'split' the a1 and then calculate twice in formula ? ... this is not necessarily needed in VST implementation.
|
'split' - I thought you need to 'scale' all those coefficients down to be < 1.. ??
Or is that what you mean? - but I think you do that before writing DSP code.. ??
Or are you hinting at some way of making use of those coefficients that are > 1 with out needing to 'scale' them??
As I imagine scaling the coefficients would cause additional errors in tests you posted??
|
|
|
Mar 30, 2007, 06:54 PM
|
#14 (permalink)
|
|
DriverHeaven Addict
Join Date: Apr 2005
Location: FI
Posts: 380
|
Quote:
Originally Posted by Maddogg6
'split' - I thought you need to 'scale' all those coefficients down to be < 1.. ??
Or is that what you mean? - but I think you do that before writing DSP code.. ??
Or are you hinting at some way of making use of those coefficients that are > 1 with out needing to 'scale' them??
As I imagine scaling the coefficients would cause additional errors in tests you posted??
|
Split means just what Hannes have done ... he did split (divide) "a1" into two parts to get the "abs(a1/2)<1" and then changed the formula a bit to get both of these stored (check the code, it's there).
I've read that "normalizing is a convenience, not an inherent need" written by some DSP engineer who designs/builds filters as his profession. I've also read that "scaling is used to reduce the possibility of overflows when your filter operates in fixed-point arithmetic mode". It looks that there are couple scaling methods you could use but, those maybe effects negatively on SNR.
I don't know how the SB DSP works internally or/and acts with these 'oversized' coefficients but, the filter as software version does not pay attention for this. It is all the same if those a's and b's are in range -1 and 1 or in range -100 and 100?
As we're calculting only value of y[n] ... if the formula b0*x[n] + b1*x[n-1] + b2*x[n-2] - a1*y[n-1] - a2*y[n-2] results abs(y[n])<1 then the filter should be stable. It's all the same what size those a/b coefficients were ... the only important factor is the result for y[n] (and of course that those coefficients produces a stable filter either as normalized or not).
So, in software filter, these coefficients
b = [ 20.5245880391493 -17.4865098741392 -2.24152539814392]
a = [ 1.00000000000000 -1.86300261413672 0.86250080415614]
used in formula y[n] = b0*x[n] + b1*x[n-1] + b2*x[n-2] - a1*y[n-1] - a2*y[n-2]
results equally with these
b = [ 1.00000000000000 -0.851978604432149 -0.10921171201431]
a = [ 1.00000000000000 -0.93150130706836 0.86250080415614] // a1/2 -> twice in formula
used in formula y[n] = b0*x[n] + b1*x[n-1] + b2*x[n-2] - a1*y[n-1] - a1*y[n-1] - a2*y[n-2] (this is the method Hannes used (though, he also swapped the sign for a1 and a2 in his code so he could use adding only)).
Those 1st coefficients just gains the output ~+26.7dB from ~+14.6dB which the latter coefficients gain is (i.e. tot. gain becomes ~+41.3dB).
I have not tried how scaling would effect in these.
NOTE: Actually, above F.Ummingers coefficients for 88.2kHz won't produce a stable filter so it won't work in this case (but it's not because of the values are out of range ">-1" - "<1" but because of [- "a1" - "a2" > 1] --> after a while y[n] > 1 and starts to grow very fast) (--> as by the coefficient signs in this case, b0+b1+b2--a1-a2 = b0+b1+b2+a1-a2).
Since I don't know the SB DSP, you could easily test if those 'oversized' coefficients for 48kHz filter, which I gave in my previous post, works in Hannes code (remember change those signs for a1 and a2).
jiitee
__________________
VST/DX (effect) plug-ins with Winamp, MediaMonkey and Foobar 0.8.x-0.9.x - needed components :
Winamp and MediaMonkey: VST support - VST Host DSP for Winamp, DirectX support - FFX-4 for WinAmp
Foobar: Bridge Plug-in for winamp DSP for Foobar 0.8.x-0.9.x or for Foobar 0.9.x + VST Host DSP for Winamp and/or FFX-4 for Winamp (see above)
Additional plug-ins: (use multiple plug-ins, etc.) Acon EffectChainer (DX/VST), CTAF MultiFXVST (VST), XLUTOP Chainer (VST), energyXTEffect (VST)
Output plug-ins: Foobar: ASIO and KernelStreaming (0.9.x), ASIO (0.8.x) ... Winamp and MediaMonkey: ASIO and KernelStreaming
3rd party ASIO drivers: Asio4All, (ASIOx , discontinued.?) ASIO2KS, USB-ASIO, FireWire-Universal and Ideal (+ OEM), ..... !!! ASIO Control panel
Last edited by jiiteepee; Apr 4, 2007 at 04:55 AM.
|
|
|
Mar 30, 2007, 07:16 PM
|
#15 (permalink)
|
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 3,668
|
Quote:
|
Since I don't know the SB DSP, you could easily test if those 'oversized' coefficients for 48kHz filter, which I gave in my previous post, works in Hannes code (remember change those signs for a1 and a2).
|
well without trying - Im 99.99% certain the kX DSP being 'fixed' point will choke on any #'s > 1.0 in magnitude (-1.0 included) - unless they are integers.
Now my point with scaling affecting test results - I imagine (read: Im an idiot and don't know anything for certain) - that the simple act of multiplying/scaling those coefficients - will cause some rounding in arithmetic and thus a loss of accuracy in the end - which I also imagine would have to equate to *some* sort of difference - most likely in the form of error.
But you answered my original Q about the split - I don't understand completely - but I get the idea anway.
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
| |