Wat je dus moet doen als je het spectrum in banden wil weergeven is die banden eerst berekenen.
Je hebt dus nu 256 waardes, als je die gewoon tekent zou je normaal een tekening moeten krijgen waar de eerste waarden altijd veel groter zijn dan de laatste waarden.
Indien je die wilt verdelen in banden moet je eigenlijk gewoon wat optellingen maken.
Je tekent de waarde 1 voor band 1, waarde 2 + waarde 3 voor band 2, waarde 4 + waarde 5 + waarde 6 voor band 3, ...
De volgende code gebruik ik zelf (voor vb6). De code is wel bedoeld voor fft's op 1024 samples, dus 512 waardes.
Als je ze wil toepassen op 256 waardes zal je de waardes d moeten delen door 2 om geen index out of bounds error te krijgen.
De reden dat al die waardes voor d er zo los instaan is omdat ik deze waardes op een ander forum gevonden heb, en dat deze waardes ook door winamp zouden gebruikt worden.
Visual Basic:
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
| Public Function vis_GetSpectrumCount(ByVal a As Long, Optional ByVal Width = 32)
Dim d As Long
If Width = 32 Then
If a = 0 Then d = 1
If a = 1 Then d = 1
If a = 2 Then d = 1
If a = 3 Then d = 1
If a = 4 Then d = 1
If a = 5 Then d = 2
If a = 6 Then d = 2
If a = 7 Then d = 2
If a = 8 Then d = 2
If a = 9 Then d = 3
If a = 10 Then d = 3
If a = 11 Then d = 4
If a = 12 Then d = 4
If a = 13 Then d = 5
If a = 14 Then d = 5
If a = 15 Then d = 6
If a = 16 Then d = 6
If a = 17 Then d = 8
If a = 18 Then d = 8
If a = 19 Then d = 9
If a = 20 Then d = 10
If a = 21 Then d = 11
If a = 22 Then d = 12
If a = 23 Then d = 14
If a = 24 Then d = 15
If a = 25 Then d = 17
If a = 26 Then d = 18
If a = 27 Then d = 20
If a = 28 Then d = 21
If a = 29 Then d = 24
If a = 30 Then d = 25
If a = 31 Then d = 27
ElseIf Width = 16 Then
If a = 0 Then d = 2
If a = 1 Then d = 2
If a = 2 Then d = 3
If a = 3 Then d = 4
If a = 4 Then d = 5
If a = 5 Then d = 7
If a = 6 Then d = 9
If a = 7 Then d = 11
If a = 8 Then d = 14
If a = 9 Then d = 17
If a = 10 Then d = 21
If a = 11 Then d = 30 '26
If a = 12 Then d = 35 '32
If a = 13 Then d = 40 '38
If a = 14 Then d = 50 '45
If a = 15 Then d = 60 '52
End If
vis_GetSpectrumCount = d
End Function
Public Sub vis_SimplifySpectrum(ByRef src() As Single, ByRef dst() As Single)
Dim up As Long, a As Long, b As Long, d As Long, c As Long, cnt As Double, wdth As Long
Static max16(15) As Double
Static max32(31) As Double
Dim tmpDbl As Double
up = UBound(dst)
If up >= 31 Then
wdth = 32
ElseIf up >= 15 Then
wdth = 16
Else
Exit Sub
End If
For a = 0 To UBound(dst)
d = vis_GetSpectrumCount(a, wdth)
cnt = 0
For c = 1 To d
If UBound(src) >= b Then
cnt = cnt + src(b)
End If
b = b + 1
Next
If cnt > 0 Then
If cnt > 0 Then tmpDbl = sqr(cnt)
If wdth = 16 Then
If tmpDbl > max16(a) Then max16(a) = tmpDbl
If max16(a) > 0 Then
tmpDbl = tmpDbl / max16(a)
Else
tmpDbl = 0
End If
ElseIf wdth = 32 Then
If tmpDbl > max32(a) Then max32(a) = tmpDbl
If max32(a) > 0 Then
tmpDbl = tmpDbl / max32(a)
Else
tmpDbl = 0
End If
End If
Else
tmpDbl = 0
End If
dst(a) = tmpDbl
Next
End Sub |
Edit: Deze code normalizeert de waardes ook. Dit geeft vind ik persoonlijk het mooiste resultaat, maar als je originele fft functie goed was zou het ook zonder normalizatie goed moeten gaan, en dan ook een juister resultaat geven.
[
Voor 5% gewijzigd door
Adion op 26-03-2003 17:14
]