News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

FIR Audio Spectrum Analyzer

Started by Siekmanski, September 03, 2014, 10:14:36 PM

Previous topic - Next topic

Siekmanski

Hi guga,

In my source i synchronize the FIR-filter to the screen-refresh rate because,
it was intended to show the power of the frequency bands on the screen. ( what you hear you see immediately )
If there are glitches in the screen-refresh rate the filter skips samples.
In my case this is wanted. ( sync. ears and eyes  :eusa_dance:)
You need to filter your audio without the screen sync.
Just move the filter window constant forward in your audio data and there will be no cracks in your output.
Creative coders use backward thinking techniques as a strategy.

guga

QuoteJust move the filter window constant forward in your audio data and there will be no cracks in your output.
how i do that ?

You mean to add silence on the beggining of the wave file ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Siekmanski

No need for that.
You could use a ring buffer and write and filter the audio data the number of taps of the filter ahead of the save pointer
and save the audio data then when they are filtered.

You need 2 pointers in your ring buffer, a save pointer and a write pointer. (which is far enough ahead of the save pointer)
When you have written the audio data to the ring buffer you can immediately filter this block of data.
Be sure to have enough distance between the 2 pointers and make the ring buffer large enough.
Creative coders use backward thinking techniques as a strategy.

guga

Hi Marinus.

Tks, but i´m not being able to assemble your file. I recently changed ml.exe with Jwasm and when trying to assembe the code in Radasm, this error shows up:

ml /c /coff /Cp "guga.asm"
JWasm v2.12pre, Nov 27 2013, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

guga.asm(243) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(243): Main line code
guga.asm(243) : Error A2209: Syntax error: __0_5
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(243): Main line code
guga.asm(243) : Error A2150: Missing operator in expression
guga.asm(254) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(254): Main line code
guga.asm(254) : Error A2209: Syntax error: __0_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(254): Main line code
guga.asm(254) : Error A2150: Missing operator in expression
guga.asm(281) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(281): Main line code
guga.asm(281) : Error A2209: Syntax error: __0_46164
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(281): Main line code
guga.asm(281) : Error A2150: Missing operator in expression
guga.asm(282) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(282): Main line code
guga.asm(282) : Error A2209: Syntax error: __0_53836
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(282): Main line code
guga.asm(282) : Error A2150: Missing operator in expression
guga.asm(589) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(589): Main line code
guga.asm(589) : Error A2209: Syntax error: __512_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(589): Main line code
guga.asm(589) : Error A2150: Missing operator in expression
guga.asm(650) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(650): Main line code
guga.asm(650) : Error A2209: Syntax error: __1000_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(650): Main line code
guga.asm(650) : Error A2150: Missing operator in expression
guga.asm(761) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT8(1)[dx9macros.inc]: Macro called from
   guga.asm(761): Main line code
guga.asm(761) : Error A2209: Syntax error: __10000000_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT8(1)[dx9macros.inc]: Macro called from
   guga.asm(761): Main line code
guga.asm(761) : Error A2150: Missing operator in expression
guga.asm(762) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT8(1)[dx9macros.inc]: Macro called from
   guga.asm(762): Main line code
guga.asm(762) : Error A2209: Syntax error: __200_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT8(1)[dx9macros.inc]: Macro called from
   guga.asm(762): Main line code
guga.asm(762) : Error A2150: Missing operator in expression
guga.asm(948) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(948): Main line code
guga.asm(948) : Error A2209: Syntax error: __1024_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(948): Main line code
guga.asm(948) : Error A2150: Missing operator in expression
guga.asm(954) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(954): Main line code
guga.asm(954) : Error A2209: Syntax error: __1_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(954): Main line code
guga.asm(954) : Error A2150: Missing operator in expression
guga.asm(956) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(956): Main line code
guga.asm(956) : Error A2209: Syntax error: __1024_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(956): Main line code
guga.asm(956) : Error A2150: Missing operator in expression
guga.asm(960) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(960): Main line code
guga.asm(960) : Error A2209: Syntax error: __20_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(960): Main line code
guga.asm(960) : Error A2150: Missing operator in expression
guga.asm(961) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(961): Main line code
guga.asm(961) : Error A2209: Syntax error: __2_126033980826655
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(961): Main line code
guga.asm(961) : Error A2150: Missing operator in expression
guga.asm(962) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(962): Main line code
guga.asm(962) : Error A2209: Syntax error: __128_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(962): Main line code
guga.asm(962) : Error A2150: Missing operator in expression
guga.asm(991) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(991): Main line code
guga.asm(991) : Error A2209: Syntax error: __80_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(991): Main line code
guga.asm(991) : Error A2150: Missing operator in expression
guga.asm(992) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(992): Main line code
guga.asm(992) : Error A2209: Syntax error: __112_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(992): Main line code
guga.asm(992) : Error A2150: Missing operator in expression
guga.asm(993) : Error A2209: Syntax error: )
fpc(33)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(993): Main line code
guga.asm(993) : Error A2209: Syntax error: __144_0
fpc(35)[dx9macros.inc]: Macro called from
  FLT4(1)[dx9macros.inc]: Macro called from
   guga.asm(993): Main line code
guga.asm(993) : Error A2150: Missing operator in expression
guga.asm(993) : Fatal error A1113: Too many errors

Error(s) occured.


I`m trying to push from memory masm syntax, but i´m no being able to assemble this. There is a error on FLT4 macro when using jwasm as ml.exe ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Siekmanski

I'm not familiar with Jwasm. Try using this macro instead,


FLT4 MACRO float_number:REQ
LOCAL float_num
    .data
     align 4
     float_num real4 float_number
    .code
    EXITM <float_num>
ENDM
Creative coders use backward thinking techniques as a strategy.

guga

Tks, that worked under the good and old qeditor (I can´t make Radasm assemble the res file:( )

But, the cracking got worst ?

All i did was insert the macros on the asm file (and removed the macro from the .inc one.


FLT4 MACRO float_number:REQ
LOCAL float_num
    .data
     align 4
     float_num real4 float_number
    .code
    EXITM <float_num>
ENDM

FLT8 MACRO float_number:REQ
LOCAL float_num
    .data
     align 4
     float_num real8 float_number
    .code
    EXITM <float_num>
ENDM


Now, how to use the ring buffer to remove the cracking ? I´m trying to follow the ode, but it is hard to figure it out where the audio buffer is stored *and also, i need to remember the masm syntaxes as well)

You meant to increase this value ?
FIR_MaxTaps                 equ 8192 ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Siekmanski

I do not hear any cracking when i run the exe in Audio.zip.

As far as i understand,

1) you want a program that imports a wav file.
2) filter the file.
3) exports the result as a wav file.

Is this correct ?
Creative coders use backward thinking techniques as a strategy.

guga

No cracking ? That´s odd. It must be here something consuming memory. Did you tested on a large file (Like the one i sent by PM) ? If even with a large file you didn´t hear the cracking, iit must be here in my PC. I´ll reboot and try again.

Quote
As far as i understand,

1) you want a program that imports a wav file.
2) filter the file.
3) exports the result as a wav file.

Is this correct ?

Yep. I need the app to fillter the audio with FIR, and then export it, without having to play the audio until the end. Just filtering and exporting.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Siekmanski

Hi guga,

Example:

1.) create filter coefficients. ( see: CalculateFIRcoefficients proc )
2.) import the wav data. ( see: Open_WAVfile proc )
3.) convert left and rigth channel to 32bit floats. ( see: Int16LSBinterleaved_Float32 proc )
4.) filter the 2 audio data channels as explained below.
5.) convert back to interleaved 16bit wav data. ( see: Float32_Int16LSBinterleaved proc )
6.) export filtered audio as wav file. ( see: wav writer-routine )

FIR coeffs for an order 2 high-pass filter. (samplerate = 44100 Hz, cutoff frequency = 1000 Hz)
"use even order numbers, then you have 1 center coefficient"

invoke CalculateFIRcoefficients,2,44100,1000,NULL,FIR_HighPass,addr FIRcoefficients

your fir coeffs: (-0.069, 0.138, -0.069) ; order 2 has 3 taps. ( taps == num. orders + 1)

your audio data: (0.5, 1.0, 0.0, 0.4) ;left channel or right channel.

alloc mem for filtered audio: == audio size
audio mem = audio size + order size = 4 + 2 = 6 ;(all zeros)
audio offset = order / 2 = 1

copy audio channel data to allocated mem, starting at audio offset.

audio mem: (0.0, 0.5, 1.0, 0.0, 0.4, 0.0)

Now everything is set up to do the filtering.

filtering pseudo code:

f = fir coeffs
a = audio mem
b = filtered audio mem

b[0] = a[0]*f[0] + a[1]*f[1] + a[2]*f[2]
b[1] = a[1]*f[0] + a[2]*f[1] + a[3]*f[2]
b[2] = a[2]*f[0] + a[3]*f[1] + a[4]*f[2]
b[3] = a[3]*f[0] + a[4]*f[1] + a[5]*f[2]

note:
For simplicity this example uses order 2.
For a better "Frequency Response" you have to use higher order settings.

Marinus
Creative coders use backward thinking techniques as a strategy.

guga

Hi Marinus, i´ll give a truy. I´ll need to do step by step to understand the terms you are using.

So, i´ll create FIR coefficient as it is create in CalculateAnalyzerFrequencyBands, but i need to create only once, instead using the other bands, right ?

But why using value of 2 as a order in "invoke CalculateFIRcoefficients,2,44100,1000,NULL,FIR_HighPass,addr FIRcoefficients"? Shouldn´t it be a multiple of 4 as described here:
FIR_MaxTaps                 equ 8192 ; "Keep this a multiple of 4" If FIR_MaxTaps == 512 then maximum FIR_Order = 511
                                     ; If Order = 30, == 31 Taps (coefficients), keep the order number even so we have uneven Taps and thus 1 center coefficient
                                     ; Notice that a FIR filter is symmetric

OrdersBand1                 equ 8190 ; Change the order numbers to narrow or widen the frequency band width ( the roll off factor )
OrdersBand2                 equ 4094
OrdersBand3                 equ 2022
OrdersBand4                 equ 1022
OrdersBand5                 equ 510
OrdersBand6                 equ 254
OrdersBand7                 equ 126
OrdersBand8                 equ 62
OrdersBand9                 equ 30
OrdersBand10                equ 14


And the most important....What exactly "order" stands for ? Is it the frequency of the audio ?

What "tap" means ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

Question:

Accordying to wiki, you used those values (0.53836 and 0.46164):

QuoteHamming Window = coefficient * ( 0.53836 - 0.46164 * cos( PI2 * filtercounter / filterorder ))

Where can i find info about this formula to understand what are those values for alpha and beta ? I mean, the precision of those constants are only 5 digits or it can be more precise ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

TouEnMasm

Fa is a musical note to play with CL

guga

Ok, i found the coefficients. The hamming window cancellation is identified here

http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADA034956.

The documentation is entitled as "On the Use of Windows for Harmonic Analysis with the Discrete Fourier Transform"
Quote
The Hamming window can be thought of as a modified Hanning window. (Note the potential source of confusion in the similarities of the two names.) Referring back to Figs. 15 and 18. we note the inexact cancellation of the sidelobes from the summation of the three kernels. We can construct a window by adjusting the relative size of the kernels as indicated in Eq. (26a) to achieve a more desirable form of cancellation. Perfect cancellation of the first sidelobe (at 0 = 2.5 12r/Ni ) corresponds to the Hamming window as indicated in Eq. (26b).

w (n) =a + (l-) cos L
(26a)
W (0)= a D() +0.5 (1-0D-o2Wjr)D (+2)]
w In) = 0.54 + 0.46 cos r n --N
(26b)
or
w (n) = 0.54 - 0.46 cos--] n 0, 1,2, ... N-I

The Hamming window is shown in Fig. 19. Notice the deep attenuation at the missing sidelobe position. Note also that the small discontinuity at the boundary of the window has resulted in a I/w (6.0 dB per octave) rate of falloff. The better sidelobe cancellation does
result in a much lower initial sidelobe level of-42 dB. Table I lists the parameters of this window. Also note the loss of binary weighting: hence the loss of ease of a spectral convolution implementation

The alpha constant of 0.53836 is equivalent to 13459/25000. So, since this is a cancellation, the value of 0.46164 is retrieved by 1-13459/25000.

Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Siekmanski

Hi guga,

QuoteSo, i´ll create FIR coefficient as it is create in CalculateAnalyzerFrequencyBands, but i need to create only once, instead using the other bands, right ?
Yes.

QuoteBut why using value of 2 as a order in "invoke CalculateFIRcoefficients,2,44100,1000,NULL,FIR_HighPass,addr FIRcoefficients"? Shouldn´t it be a multiple of 4 as described here:
No, that is only when you calculate 4 samples at once.

QuoteAnd the most important....What exactly "order" stands for ? Is it the frequency of the audio ?
No, If spoken of a 5th order it has 6 taps, thus 121th order has 122 taps

QuoteWhat "tap" means ?
taps is the number of coefficients in the filter.
Creative coders use backward thinking techniques as a strategy.

guga

Ok, i guess i found the formula. As far i understood, to retrieve the value of the constants it is necessary to find the perfect cancelation in decibal levels.

Accordying to the document a perfect cancelation is around -42db. The formula used to retrieve this is described here:
http://en.wikipedia.org/wiki/Side_lobe

R = 20*log10(sin(X)/X)

Where X = Hamming window constant
R = the perfect cancelation we want to retrieve. In case -42db (or -42/100 if used on the formula)

I used the hamming constants of 13459/25000 in wolframalpha and got the predicted result for the cancellation.

So, to calculate the Hamming constant (X) for a givven decibel cancelattion (R), we can use the reversed formula.

For see the results. I used R = -42/100 for cancelation, and got this results as X
X = +/- (0.536024817009894983757669554)

So, the alpha value for the hamming constant (if used to cancelation of exact -42 db) is: 0.536024817009894983757669554

Now another question. The formula you are using for the hamming constant is supposed to work with a perfect cancelattion of the sidelobe or it is simply the minimum value ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com