01-03-2025, 11:21 PM
Hi. I wish everyone all the best in the new year and lots of success not only in programming but also in personal life.
Today I dealt with the fast Fourier transform and signal decomposition. Since this is a topic highly beyond my knowledge, I used all the options available to me and finally created this. The question is: Can anyone speed it up? It would be necessary to set the Blok, RealPart and ImagPart field sizes to at least 1023 and N to 1024, so that the frequency detection would be smoother. Unfortunately, in this implementation with my computer, I had to set the fields as they are to get at least some good results.
On line 2, set your own MP3 audio file. After starting (it is assumed that the MP3 is stereo), only the left track is read. It is run through the FFT, which decomposes it into real and imaginary components, then in the condition on line 34, an adjustment is made so that everything with a frequency higher than 400 Hz is discarded and finally the sound is reconstructed back with this adjustment through the IFFP. However, the sound is significantly distorted precisely because of the low accuracy - due to the low size of the fields. I was wondering if someone might have a better solution, or if they would see a problem that I am overlooking.
Today I dealt with the fast Fourier transform and signal decomposition. Since this is a topic highly beyond my knowledge, I used all the options available to me and finally created this. The question is: Can anyone speed it up? It would be necessary to set the Blok, RealPart and ImagPart field sizes to at least 1023 and N to 1024, so that the frequency detection would be smoother. Unfortunately, in this implementation with my computer, I had to set the fields as they are to get at least some good results.
On line 2, set your own MP3 audio file. After starting (it is assumed that the MP3 is stereo), only the left track is read. It is run through the FFT, which decomposes it into real and imaginary components, then in the condition on line 34, an adjustment is made so that everything with a frequency higher than 400 Hz is discarded and finally the sound is reconstructed back with this adjustment through the IFFP. However, the sound is significantly distorted precisely because of the low accuracy - due to the low size of the fields. I was wondering if someone might have a better solution, or if they would see a problem that I am overlooking.
Code: (Select All)
Zdroj = _SndOpen("s.mp3") 'USE MP3 here (MEM read singles from _Memsound block)
Dim Zvuk As _MEM
Dim A As Long
Dim Blok(31) As Single ' Block for FFT samples. Here is 32 values (0 to 31), is very small so detection is not too accuracy
Dim RealPart(31) As Single, ImagPart(31) As Single ' Real and imaginary signal values for FFT
Dim Shared N As Long
Dim VzorkovaciFrekvence As Single ' SoundRate
N = 32 ' FFT Block size
Zvuk = _MemSound(Zdroj, 0)
VzorkovaciFrekvence = _SndRate
Do Until A& = Zvuk.SIZE
' Načtení bloku vzorků
For i = 0 To N - 1
If A& >= Zvuk.SIZE Then Exit For
LevaStopa = _MemGet(Zvuk, Zvuk.OFFSET + A&, Single)
Blok(i) = LevaStopa ' This demo save left track only. Blok must contins sound data to work
RealPart(i) = LevaStopa ' RealPart must contains sound data
ImagPart(i) = 0
A& = A& + 8 ' go to next sample (8 bytes = 2 * 4 (left, right))
Next i
' Apply FFT to block
Call FFT(RealPart(), ImagPart(), N)
'spectrum filtration - in this case output signal contains just frequency 350 Hz and slower
For k = 0 To N - 1
Frekvence = k * VzorkovaciFrekvence / N 'Frequency calculation (k * _SndRate / N)
If Frekvence > 400 Then 'how killing signal:
RealPart(k) = 0
ImagPart(k) = 0
End If
Next k
'create new audio signal using IFFT (from this block)
Call IFFT(RealPart(), ImagPart(), N)
'Play created signal
For i = 0 To N - 1
_SndRaw RealPart(i), 0
Next i
'wait until is possible playing next block
Do Until _SndRawLen < .1
Loop
Loop
_MemFree Zvuk
Sub FFT (RealPart() As Single, ImagPart() As Single, N As Long)
Dim i As Long, j As Long, k As Long, m As Long, stp As Long
Dim angle As Double
Dim tReal As Double, tImag As Double, uReal As Double, uImag As Double
' Bit-reverse permutation (That sounds really good, doesn't it?) Don't ask me what that means, okay? ))
j = 0
For i = 0 To N - 1
If i < j Then
Swap RealPart(i), RealPart(j)
Swap ImagPart(i), ImagPart(j)
End If
k = N \ 2
Do While (k >= 1 And j >= k)
j = j - k
k = k \ 2
Loop
j = j + k
Next i
' FFT: my loop over the size of the level (N)
m = 1
Do While m < N
stp = m * 2
angle = -3.14159265359 / m
For k = 0 To m - 1
uReal = Cos(k * angle)
uImag = Sin(k * angle)
For i = k To N - 1 Step stp
j = i + m
tReal = uReal * RealPart(j) - uImag * ImagPart(j)
tImag = uReal * ImagPart(j) + uImag * RealPart(j)
RealPart(j) = RealPart(i) - tReal
ImagPart(j) = ImagPart(i) - tImag
RealPart(i) = RealPart(i) + tReal
ImagPart(i) = ImagPart(i) + tImag
Next i
Next k
m = stp
Loop
End Sub
' Inverse FFT (IFFT) for signal reconstruction
Sub IFFT (RealPart() As Single, ImagPart() As Single, N As Long)
Dim i As Long, j As Long, k As Long, m As Long, stp As Long
Dim angle As Double
Dim tReal As Double, tImag As Double, uReal As Double, uImag As Double
'The inverse FFT is the same as the FFT, but with the opposite sign in the exponent
m = 1
Do While m < N
stp = m * 2
angle = 3.14159265359 / m ' opposite sign
For k = 0 To m - 1
uReal = Cos(k * angle)
uImag = Sin(k * angle)
For i = k To N - 1 Step stp
j = i + m
tReal = uReal * RealPart(j) - uImag * ImagPart(j)
tImag = uReal * ImagPart(j) + uImag * RealPart(j)
RealPart(j) = RealPart(i) - tReal
ImagPart(j) = ImagPart(i) - tImag
RealPart(i) = RealPart(i) + tReal
ImagPart(i) = ImagPart(i) + tImag
Next i
Next k
m = stp
Loop
' Normalization for inverse FFT
For i = 0 To N - 1
RealPart(i) = RealPart(i) / N
ImagPart(i) = ImagPart(i) / N
Next i
End Sub