[futurebasic] Re: [FB] off-topic: algorithmic help

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : September 2010 : Group Archive : Group : All Groups

From: Robert Purves <listrp@...>
Date: Fri, 24 Sep 2010 12:44:06 +1200
Waverly wrote:

> Wow, I like it.  since its a one shot function, it was a great idea to put the coefficients inside the function instead of making the global.
> Its much cleaner.  

This constant seems an open invitation to confusion and error:

> system Float64 kDbFilterFactor // offset required to get the filter calculation to 0db at 1000Hz (by observation)
> #define kDbFilterFactor   3.0


I suggest that you remove it, so that your function GetRMSValues() correctly returns -3 dB for an unfiltered sine wave of peak amplitude -1.0 to +1.0, and 0 dB for a square wave of the same amplitude. (Also, the name GetRMSValues might be better as something like GetRMSdB).

The gain adjustment belongs in the filter itself:

/*
7th-order IIR A-weighting filter.
http://dev.aubio.org/browser/src/temporal/a_weighting.c
http://dev.aubio.org/browser/src/temporal/a_weighting.h
Gain is 1.0 at 1 kHz.
In this simple implementation, inData() and outData() must not be the same array.
*/
local mode
local fn A_WeightingFilter( n as long, inData(_maxLong) as Float64, outData(_maxLong) as Float64 )
'~'1
dim as long    j, k
_filterOrder = 7
dim as double  a(_filterOrder - 1), b(_filterOrder - 1), gain
gain = sqr( 2.0 )
// coefficients for 44.1 kHz sample rate
b(0) =  2.557411252042575133813784304948057979345321655273437500e-01*gain
b(1) = -5.114822504085150267627568609896115958690643310546875000e-01*gain
b(2) = -2.557411252042575133813784304948057979345321655273437500e-01*gain
b(3) =  1.022964500817030053525513721979223191738128662109375000e+00*gain
b(4) = -2.557411252042575133813784304948057979345321655273437500e-01*gain
b(5) = -5.114822504085150267627568609896115958690643310546875000e-01*gain
b(6) =  2.557411252042575133813784304948057979345321655273437500e-01*gain
a(0) =  1.000000000000000000000000000000000000000000000000000000e+00
a(1) = -4.019576181115832369528106937650591135025024414062500000e+00
a(2) =  6.189406442920693862674852425698190927505493164062500000e+00
a(3) = -4.453198903544116404873420833609998226165771484375000000e+00
a(4) =  1.420842949621876627475103305187076330184936523437500000e+00
a(5) = -1.418254738303044160119270600262098014354705810546875000e-01
a(6) =  4.351177233495117681327801761881346465088427066802978516e-03
for j = 0 to n - 1
outData(j) = b(0)*inData(j)
for k = 0 to _filterOrder - 1
long if ( j >= k )
outData(j) += b(k)*inData(j - k) - a(k)*outData(j - k)
end if
next
next 
end fn


Robert P.