Attribute VB_Name = "modRender"
Option Explicit

' Old Static Variables for Rendering Engine
Global LastAvg1() As Long
Global LastAvg2() As Long
Global LastAvg3() As Long
Global LastDTMF As Integer
Global NewDTMF As Integer
Global Delay As Integer
Global RenderIsON As Boolean

Global oFFT() As Long

Type RenderPrefs
    oFFT() As Long
    DetectDTMF As Boolean
    min As Integer
    max As Integer
    picFFT As Object
    Mode As Integer
    Compensate As Boolean
    Res As Integer
    c As OLE_COLOR
    nSamples As Long
End Type
Global p As RenderPrefs

Private Const Green = &HFF00&
Private Const Yellow = &HFFFF&
Private Const Red = &HFF&

Public Function RenderFFT() As Long

    Dim Avg As Long
    Dim RMS As Long
    Dim fMin As Long
    Dim fMax As Long
    Dim fTotal As Long
    Dim i As Long
    
    On Error GoTo ExitSub
    
    Do
        With p
            If .nSamples > 0 Then
                fTotal = .nSamples \ 2
                ReDim Preserve LastAvg1(fTotal)
                ReDim Preserve LastAvg2(fTotal)
                ReDim Preserve LastAvg3(fTotal)
                
                If .DetectDTMF Then
                
                    Dim f1 As Integer
                    Dim f2 As Integer
                    Dim MV As Integer
                    
                    MV = 60
                    
                    f1 = 1336 / 22050 * .nSamples
                    f2 = 941 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 0
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1209 / 22050 * .nSamples
                    f2 = 697 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 1
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1336 / 22050 * .nSamples
                    f2 = 697 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 2
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1477 / 22050 * .nSamples
                    f2 = 697 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 3
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1209 / 22050 * .nSamples
                    f2 = 770 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 4
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1336 / 22050 * .nSamples
                    f2 = 770 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 5
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1477 / 22050 * .nSamples
                    f2 = 770 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 6
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1209 / 22050 * .nSamples
                    f2 = 852 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 7
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1336 / 22050 * .nSamples
                    f2 = 852 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 8
                        GoTo SkipOthers
                    End If
                    
                    f1 = 1477 / 22050 * .nSamples
                    f2 = 852 / 22050 * .nSamples
                    If Sqr(Abs(oFFT(f1))) > MV And Sqr(Abs(oFFT(f2))) > MV Then
                        NewDTMF = 9
                        GoTo SkipOthers
                    End If
                    
SkipOthers:
                    If NewDTMF = -1 Then
                        Delay = Delay + 1
                        If Delay >= 20 Then
                            LastDTMF = -1
                            Delay = 0
                        Else
                            NewDTMF = LastDTMF
                        End If
                    ElseIf LastDTMF <> NewDTMF Then
                        Delay = 0
                        LastDTMF = NewDTMF
                        'RaiseEvent DTMF(NewDTMF)
                    End If
                    
                    NewDTMF = -1
                
                End If
                
                fMin = .min / 100 * fTotal + 2
                fMax = .max / 100 * fTotal - 4
                
                .picFFT.Cls
                .picFFT.ScaleWidth = fTotal
                
                Select Case .Mode
                Case 0
                    For i = fMin To fMax Step p.Res
                        With .picFFT
                            .CurrentX = i
                            .CurrentY = .Height
                            Avg = (Abs(oFFT(i - 1)) + Abs(oFFT(i)) + Abs(oFFT(i + 1))) / 3
                            If p.Compensate Then Avg = Avg + (i - fMin * 2) * (Avg / 60)
                            p.picFFT.Line Step(0, 0)-(.CurrentX + p.Res, .Height - Sqr((Avg + LastAvg1(i) + LastAvg2(i) + LastAvg3(i)) / 4) / 60 * .Height), p.c, BF
                            LastAvg3(i) = LastAvg2(i)
                            LastAvg2(i) = LastAvg1(i)
                            LastAvg1(i) = Avg
                        End With
                    Next i
                Case 2
                    With .picFFT
                        Avg = (Abs(oFFT(fMin)) + Abs(oFFT(fMin + 1)) + Abs(oFFT(fMin + 2))) / 3
                        .CurrentX = fMin
                        .CurrentY = .Height - Sqr(Avg) / 60 * .Height
                        For i = fMin To fMax Step p.Res
                            Avg = (Abs(oFFT(i - 1)) + Abs(oFFT(i)) + Abs(oFFT(i + 1))) / 3
                            If p.Compensate Then Avg = Avg + (i - fMin * 2) * (Avg / 60)
                            p.picFFT.Line -(.CurrentX + p.Res, .Height - Sqr((Avg + LastAvg1(i) + LastAvg2(i) + LastAvg3(i)) / 4) / 60 * .Height), p.c
                            LastAvg3(i) = LastAvg2(i)
                            LastAvg2(i) = LastAvg1(i)
                            LastAvg1(i) = Avg
                        Next i
                    End With
                Case 1
                    Dim y, ly As Long
                    For i = fMin To fMax Step p.Res + 1
                        With .picFFT
                            Avg = (Abs(oFFT(i - 1)) + Abs(oFFT(i)) + Abs(oFFT(i + 1))) / 3
                            If p.Compensate Then Avg = Avg + (i - fMin * 2) * (Avg / 60)
                            ly = .Height
                            For y = .Height To .Height - Sqr((Avg + LastAvg1(i) + LastAvg2(i)) / 3) / 60 * .Height Step -.Height / 10
                                If y > .Height / 2 Then
                                    p.c = Green
                                Else
                                    If y > .Height / 4 Then
                                        p.c = Yellow
                                    Else
                                        p.c = Red
                                    End If
                                End If
                                p.picFFT.Line (i, ly)-(i + p.Res, y + 30), p.c, BF
                                ly = y
                            Next y
                            LastAvg2(i) = LastAvg1(i)
                            LastAvg1(i) = Avg
                        End With
                    Next i
                End Select
            End If
        End With
ExitSub:
    Loop

End Function
