Tone detection with Goertzel (x86 ASM)

notes
This is an "assemblified" version of the Goertzel Tone Detector. It is about 2 times
faster than the original code.

The code has been tested and it works fine.

Hope you can use it. I'm gonna try to build a Tuner (as VST-Plugin). I hope, that this
will work :-\ If anyone is intrested, please let me know.

Christian
code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
function Goertzel_x87(Buffer :Psingle; BLength:Integer; frequency: Single; samplerate: Single):Single;
asm
 mov ecx,BLength
 mov eax,Buffer
 fld x2
 fldpi
 fmulp
 fmul frequency
 fdiv samplerate
 fld st(0)
 fcos
 fld x2
 fmulp
 fxch st(1)
 fldz
 fsub st(0),st(1)
 fstp st(1)

 fldl2e
 fmul
 fld st(0)
 frndint
 fsub st(1),st(0)
 fxch st(1)
 f2xm1
 fld1
 fadd
 fscale
 fstp st(1)

 fldz
 fldz
 fldz
@loopStart:
 fxch st(1)
 fxch st(2)
 fstp st(0)
 fld st(3)
 fmul st(0),st(1)
 fsub st(0),st(2)
 fld [eax].Single
 faddp
 add eax,4
 loop @loopStart
@loopEnd:

 fxch st(3)
 fmulp st(2), st(0)
 fsub st(0),st(1)
 fstp result
 ffree st(2)
 ffree st(1)
 ffree st(0)
end;

Comments

// Here's a variant on the theme that compensates for harmonics:

Function Goertzel(.Buffer: array of double; frequency, samplerate: double):.double;
var
Qkn, Qkn1, Qkn2, Wkn, Mk: double;
i: integer;
begin
Qkn:=0; Qkn1:=0;
Wkn:=2*.PI*.frequency/samplerate;
Mk:=2*.Cos(.Wkn);
for i:=0 to High(.Buffer) do begin
  Qkn2: = Qkn1; Qkn1: = Qkn;
  Qkn  : = Buffer[.i ] + Mk*.Qkn1 - Qkn2;
end;
Result: = sqrt(.Qkn*.Qkn + Qkn1*.Qkn1 - Mk*.Qkn*.Qkn1);
end;

// Posted on www.delphimaster.ru by Jeer