QB64 Phoenix Edition
Next small EQ step - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Prolific Programmers (https://qb64phoenix.com/forum/forumdisplay.php?fid=26)
+---- Forum: Petr (https://qb64phoenix.com/forum/forumdisplay.php?fid=52)
+---- Thread: Next small EQ step (/showthread.php?tid=2558)



Next small EQ step - Petr - 03-30-2024

The following program performs a sound effect by rapidly changing the frequency of the sound being played. It's a small thing that occurred to me today while traveling by car. It does not have filtered harmonic frequencies, so even lower frequencies creep into the sound above 1000Hz (well, that's how I explain it). I'm writing something completely different now, this was just an escape attempt for distraction.

Try value 10, 300, use MP3 (need single array type created with MemSound)

Code: (Select All)

$NoPrefix

Screen _NewImage(600, 600, 32)
S = SndOpen("belfast.mp3")
Dim m As MEM
Dim As Single L, R, L2, R2
Dim As Long X, f
m = MemSound(S, 0)
If m.ELEMENTSIZE <> 8 Then
    Print "Try another music file, program required SINGLE array. Try MP3."
    Sleep
    SndClose S
    MemFree m
    System
End If
Input "Insert start and end freq (start, end); 2 to 10600:"; U, D

If D > U Then Swap D, U
If D > 10600 Then D = 10600
If U < 2 Then U = 2

'try U = 10, D = 300
X = D
Stp = 4 'frequency step
Y = Stp

Do Until n& >= m.SIZE - SndRate

    If n& Mod SndRate \ 6 = 0 Then 'set speed for setting freq
        X = X + Y
        If X > U Then Y = -Stp
        If X < D Then Y = Stp
    End If

    f = _SndRate / X 'get freqency in samples
    Do Until f Mod 4 = 0 'set f dividible by 4 for use with mem
        f = f + 1
    Loop

    MemGet m, m.OFFSET + n&, L
    MemGet m, m.OFFSET + n& + 4, R
    MemGet m, m.OFFSET + n& + f, L2
    MemGet m, m.OFFSET + n& + f + 4, R2

    SndRaw (L2 - L), (R2 - R)

    Do Until SndRawLen <= .2
        Locate 2
        Print X
        Limit 20
    Loop

    n& = n& + 8

Loop
SndClose S
MemFree m
System



RE: Next small EQ step - Petr - 03-31-2024

I played with it a bit more, so here are two similar outputs.


Rapid anti-phase change - weak "quack" form - best heard on stringed instruments
Code: (Select All)

$NoPrefix

Screen _NewImage(600, 600, 32)
S = SndOpen("08.mp3")
Dim m As MEM
Dim As Single L, R, L2, R2
Dim As Long X, f
m = MemSound(S, 0)
If m.ELEMENTSIZE <> 8 Then
    Print "Try another music file, program required SINGLE array. Try MP3."
    Sleep
    SndClose S
    MemFree m
    System
End If


Stp = 1 'frequency step
Y = 1

Do Until n& >= m.SIZE - SndRate
    OldX = X
    If n& Mod SndRate \ 30 = 0 Then X = X + Y
    If X > 18 Then Y = -1
    If X < 6 Then Y = 1

    'get freqency in samples
    f = _SndRate \ 2 \ X

    So& = n& + 16 * X


    MemGet m, m.OFFSET + n&, L
    MemGet m, m.OFFSET + n& + 4, R
    MemGet m, m.OFFSET + So&, L2
    MemGet m, m.OFFSET + So& + 4, R2

    SndRaw (L2 - L), (R2 - R)


    Do Until SndRawLen <= .1
        Locate 2
        Print "Antiphase Freqency:"; f; "Hz  "
    Loop
    n& = n& + 8
Loop
SndClose S
MemFree m
System


And here is the predecessor:

Code: (Select All)

$NoPrefix

Screen _NewImage(600, 600, 32)
S = SndOpen("103.mp3")
Dim m As MEM
Dim As Single L, R, L2, R2
Dim As Long X, f
m = MemSound(S, 0)
If m.ELEMENTSIZE <> 8 Then
    Print "Try another music file, program required SINGLE array. Try MP3."
    Sleep
    SndClose S
    MemFree m
    System
End If


Stp = 1 'frequency step
Y = 1

Do Until n& >= m.SIZE - SndRate
    OldX = X
    If n& Mod SndRate \ 20 = 0 Then X = X + Y
    If X > 99 Then Y = -1
    If X < 3 Then Y = 1

    'get freqency in samples
    f = _SndRate \ 2 \ X

    So& = n& + 16 * X


    MemGet m, m.OFFSET + n&, L
    MemGet m, m.OFFSET + n& + 4, R
    MemGet m, m.OFFSET + So&, L2
    MemGet m, m.OFFSET + So& + 4, R2

    SndRaw (L2 - L), (R2 - R)


    Do Until SndRawLen <= .1
        Locate 2
        Print "Antiphase Freqency:"; f; "Hz  "
    Loop
    n& = n& + 8
Loop
SndClose S
MemFree m
System


The difference between them is only in the width of the changed antiphase frequency and also in the speed with which the change is made.


RE: Next small EQ step - Petr - 04-07-2024

Next version - Here you can hold the automatically changing audio frequency by tapping the space bar. The program reads the harmonic frequencies to the selected frequency (if I understood the theory correctly) to make the sound more detailed.

So, now for equalization. When this program is taken and the individual bands are read, one should (probably) just set their volume and then via SNDOPENRAW, so that there is no mixing of the signals, the equalizer should be assembled. However, it is still necessary to solve the removal of higher frequencies from the signal with depths.

Code: (Select All)

$NoPrefix
Screen _NewImage(600, 600, 32)
S = SndOpen("10.mp3")
Dim m As MEM
Dim As Single L(5), R(5), L2(5), R2(5), L, R
Dim As Long f, Y(5)
Dim As Single X(5)
m = MemSound(S, 0)
If m.ELEMENTSIZE <> 8 Then
    Print "Try another music file, program required SINGLE array. Try MP3."
    Sleep
    SndClose S
    MemFree m
    System
End If

For a = 1 To 5
    Y(a) = 1 '    increase / decrease frequency    (1 / -1)
    X(a) = a * 2 'frequency indicator. So, if the number is 2, the signal value is read from the MEMSOUND field
    '            by 32 bytes further than the start of the signal
Next

'The program (if written correctly) should read two harmonic frequencies above and two below the selected frequency
'to make the sound denser

FreqChange = -1

Do Until n& >= m.SIZE - SndRate
    If KeyHit = 32 Then FreqChange = Not FreqChange

    If FreqChange Then
        If n& Mod SndRate / 2 = 0 Then
            a = 1
            Do Until a = 5
                X(a) = X(a) + Y(a)
                If X(a) > 300 Then Y(a) = -1 'higher number here = lower minimal frequency
                If X(a) < 2 Then Y(a) = 1 '2 is maximal value for high frequency (1/2 SndRate)
                a = a + 1
            Loop
        End If
    End If


    a = 1
    Do Until a = 5

        'get freqency in samples
        f& = _SndRate \ 2 \ X(a)
        So& = n& + 8 * X(a)
        MemGet m, m.OFFSET + n&, L(a)
        MemGet m, m.OFFSET + n& + 4, R(a)
        MemGet m, m.OFFSET + So&, L2(a)
        MemGet m, m.OFFSET + So& + 4, R2(a)
        L = L - (L(a) - L2(a))
        R = R - (R(a) - R2(a))
        a = a + 1
    Loop

    SndRaw L, R
    L = 0
    R = 0
    Do Until SndRawLen <= .01
        Locate 2
        Print "Antiphase Freqency:"; f&; "Hz  "
        Print "Press space for hold / autochange frequency"
    Loop
    n& = n& + 8
Loop
SndClose S
MemFree m
System



RE: Next small EQ step - Petr - 04-07-2024

So here's something as the equalizer style. I was lazy to do with the graphics and adjust the sliders here.... so I did it using the keyboard, or repeatedly press V to start or end the quick adjustment of the equalization.

Code: (Select All)

$NoPrefix

Screen _NewImage(600, 600, 32)
Title "Equalizer"
S = SndOpen("10.mp3")
Dim m As MEM
Dim Shared As Single L(5), R(5), L2(5), R2(5), Le(10), Ri(10), LVol(10), RVol(10), X(10)
Dim As Long f
Dim As Long Raw(10)
m = MemSound(S, 0)
If m.ELEMENTSIZE <> 8 Then
    Print "Try another music file, program required SINGLE array. Try MP3."
    Sleep
    SndClose S
    MemFree m
    System
End If


eff = 0

X(1) = SetFreq(80)
X(2) = SetFreq(125)
X(3) = SetFreq(180)
X(4) = SetFreq(250)
X(5) = SetFreq(500)
X(6) = SetFreq(1000)
X(7) = SetFreq(2000)
X(8) = SetFreq(4000)
X(8) = SetFreq(8000)
X(9) = SetFreq(12000)
X(10) = SetFreq(16000)

For SetVol = 1 To 10
    LVol(SetVol) = 0.1
    RVol(SetVol) = 0.1
Next

For R = 1 To 10
    Raw(R) = SndOpenRaw
Next


'The program (if written correctly) should read two harmonic frequencies above and two below the selected frequency
'to make the sound denser


FreqChange = -1

Do Until n& >= m.SIZE - SndRate

   eq = 1
    Do Until eq = 10
        a = 1
        Le(eq) = 0
        Ri(eq) = 0

        Do Until a = 5

            'get freqency in samples
            So& = n& + 8 * X(eq)

            MemGet m, m.OFFSET + n&, L(a)
            MemGet m, m.OFFSET + n& + 4, R(a)
            MemGet m, m.OFFSET + So&, L2(a)
            MemGet m, m.OFFSET + So& + 4, R2(a)


            Le(eq) = Le(eq) - (L(a) - L2(a))
            Ri(eq) = Ri(eq) - (R(a) - R2(a))

            a = a + 1
        Loop
        Le(eq) = Le(eq) * LVol(eq)
        Ri(eq) = Ri(eq) * RVol(eq)
        eq = eq + 1

    Loop

    For eq = 1 To 10
        SndRaw Le(eq), Ri(eq), Raw(eq) ', Raw(eq)
    Next

    If eff Then

        If n& Mod SndRate / 20 = 0 Then
            omega = omega + .1
            For eq = 1 To 10
                LVol(eq) = Abs(Sin(omega + eq * Pi / 20))
                RVol(eq) = Abs(Sin(omega + eq * Pi / 20))
            Next
        End If
    End If


    Do Until SndRawLen(Raw(10)) <= .1
        i$ = InKey$
        Select Case LCase$(i$)
            Case "q": SetEqVolP 1
            Case "a": SetEqVolM 1
            Case "w": SetEqVolP 2
            Case "s": SetEqVolM 2
            Case "e": SetEqVolP 3
            Case "d": SetEqVolM 3
            Case "r": SetEqVolP 4
            Case "f": SetEqVolM 4
            Case "t": SetEqVolP 5
            Case "g": SetEqVolM 5
            Case "y": SetEqVolP 6
            Case "h": SetEqVolM 6
            Case "u": SetEqVolP 7
            Case "j": SetEqVolM 7
            Case "i": SetEqVolP 8
            Case "k": SetEqVolM 8
            Case "o": SetEqVolP 9
            Case "l": SetEqVolM 9
            Case "p": SetEqVolP 10
            Case "ů": SetEqVolM 10

            Case "v": eff = Not eff
        End Select


        Locate 2
        Print "First equalizer."
        Print "Press: q,w,e,r,t,y,u,i,o,p for eq volume up"
        Print "      a,s,d,f,g,h,j,k,l,ů for eq volume down"

        For eqva = 1 To 10
            Print "Freq: "; SndRate \ X(eqva); " vol:"; LVol(eqva); "                    "
        Next

    Loop

    n& = n& + 8
Loop
SndClose S
MemFree m
System

Sub SetEqVolM (i)
    LVol(i) = LVol(i) - .1
    If LVol(i) < 0 Then LVol(i) = 0
    RVol(i) = LVol(i)
End Sub

Sub SetEqVolP (i)
    LVol(i) = LVol(i) + .1
    If LVol(i) > 1.4 Then LVol(i) = 1.4
    RVol(i) = LVol(i)
End Sub


Function SetFreq (f)
    SetFreq = SndRate \ 2 \ f
End Function

Finally is used SndOpenRaw too.