|
|||||||
![]() |
|
|
Thread Tools |
|
|
#1 |
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
Rep Power: 0 ![]() |
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 [color=red] b=[0.02675918611906 -0.04592084787595 0.01921229297239] a=[1.00000000000000 -0.73845850035973 -0.17951755477430][/color] 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: [color=Red] b=[0.5839116305884448 -0.4311945070669476 -0.1048223881275120] a=[1.0000000000000000 -1.7160778983199925 0.7179700042784745] [/color] 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 |
|
|
|
|
|
#2 |
|
HardwareHeaven Extreme Member
Join Date: Jan 2005
Posts: 5,561
Rep Power: 62 ![]() ![]() ![]() ![]() ![]() ![]() |
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. |
|
|
|
|
|
#3 |
|
S-3D enthusiast
|
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 http://www.hardwareheaven.com/effects-dsp/69774-error-invalid-plugin-library-when-copy-pasting-dane.html |
|
|
|
|
|
#4 |
|
kX Project DSP Engineer
Join Date: Dec 2002
Location: Denmark
Posts: 94
Rep Power: 0 ![]() |
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 |
|
|
|
|
|
|
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
Rep Power: 0 ![]() |
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 |
|
|
|
|
|
#6 |
|
kX Project DSP Engineer
Join Date: Dec 2002
Location: Denmark
Posts: 94
Rep Power: 0 ![]() |
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 |
|
|
|
|
|
#7 | |
|
S-3D enthusiast
|
This Frederick Umminger said t[color=white]hat he used http://www.hagtech.com/pdf/riaa.pdf as a reference.[/color]
[color=#ffffff][/color] [color=#ffffff]I've looked at that document and it looks well made and professionnal. There should not be any errors in the document. [/color] [color=#ffffff][/color] At http://www.hagtech.com/ on the main page you can read : Quote:
|
|
|
|
|
|
|
|
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
Rep Power: 0 ![]() |
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 |
|
|
|
|
|
#9 |
|
DriverHeaven Addict
Join Date: Dec 2002
Posts: 259
Rep Power: 0 ![]() |
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.
|
|
|
|
|
|
|
|
DriverHeaven Junior Member
Join Date: Jan 2005
Posts: 37
Rep Power: 0 ![]() |
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 12:16 PM. |
|
|
|
|
|
#11 |
|
HardwareHeaven Senior Member
Join Date: Apr 2005
Location: FI
Posts: 400
Rep Power: 0 ![]() |
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 Last edited by jiiteepee; Mar 30, 2007 at 07:07 PM. |
|
|
|
|
|
#12 |
|
HardwareHeaven Senior Member
Join Date: Apr 2005
Location: FI
Posts: 400
Rep Power: 0 ![]() |
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 Last edited by jiiteepee; Mar 31, 2007 at 08:20 PM. |
|
|
|
|
|
#13 | |
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 4,027
Rep Power: 0 ![]() ![]() |
Quote:
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?? |
|
|
|
|
|
|
#14 | |
|
HardwareHeaven Senior Member
Join Date: Apr 2005
Location: FI
Posts: 400
Rep Power: 0 ![]() |
Quote:
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 Last edited by jiiteepee; Apr 4, 2007 at 10:55 AM. |
|
|
|
|
|
|
#15 | |
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 4,027
Rep Power: 0 ![]() ![]() |
Quote:
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. |
|
|
|
|
|
|
#16 | |||
|
HardwareHeaven Senior Member
Join Date: Apr 2005
Location: FI
Posts: 400
Rep Power: 0 ![]() |
Quote:
Quote:
http://img134.imageshack.us/img134/4356/dectestxv4.png Quote:
- the sum of those keeps equal w/ the original value, - you multiply the right sample with all these and - the ratio keeps equal (as for an example, a0:a1:a2). jiitee Last edited by jiiteepee; Mar 31, 2007 at 11:41 AM. |
|||
|
|
|
|
|
#17 | |
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 4,027
Rep Power: 0 ![]() ![]() |
Quote:
AFAIK - they (10K1 and 10K2) operate the same way.. ?? but - as I mention before - I'm not certain about anything. Now, I always thought the differences between 10K1 (live/APS) and 10K2 (Audigy) where resources (instructions/cycle, GPR's, TRAM and I/O - for 7.1) Microcode looks identical - BUT its also 'compiled' or loaded (or what ever??) - I'm confident we're not exposed to 'raw' DSP assembly code either... if there are differences - Im not aware of anything more than I mentioned. The 'PRO' - I assume your referring to the EMU APS - AFAIK uses the same 10K1 DSP as SBLives - in fact those cards are sooo much like SBLives that a hacked EMU APS driver was made that allowed SBLives to use the APS drivers. (re: APS-Live drivers - I used very happily with my SBLive Value OEM CT4832 before I found KX - I found kX as a referral from the old APSLive web site here: http://freenet-homepage.de/apslive/) The differences between SBLives and APS were in codecs and connectivity, but electronically very similar. Last edited by Maddogg6; Mar 31, 2007 at 10:39 AM. Reason: cleared up some points |
|
|
|
|
|
|
#18 | |
|
HardwareHeaven Senior Member
Join Date: Apr 2005
Location: FI
Posts: 400
Rep Power: 0 ![]() |
Quote:
I meant those pro cards from Creative E-MU: 0404, 1212M, 1616/1616M, 1820/1820M - http://kb.kxproject.lugosoft.com/list.html jiitee |
|
|
|
|
|
|
#19 | |
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 4,027
Rep Power: 0 ![]() ![]() |
Quote:
Assuming the '10K2 Pro grade' - means they are diffrent enough that kX wont work with them, but imagine they otherwise operate the same internally as fixed point. My guess the only difference is in information released and subtle changes to prevent another 'APSLive hack' from happening on EMUs 10K2 based cards drivers for the CL 10K2 based cards... ?? I would think that if say; the 'Pro' 10K2 handled 24/96 directly in the DSP (and eliminated the P16V 'hack' to support 24/96 - or something significant like this) - they would have named the chip differently than 10K2... ?? |
|
|
|
|
![]() |
| Thread Tools | |
|
|