使用 Julia 对声音使用 fft

Use of fft on sound using Julia

我刚刚在 Julia 中写了一些代码:

using FFTW
using Plots
using WAV, PlotlyJS

snd, sampFreq = wavread("input.wav")

N, _ = size(snd)
t = 0:1/(N-1):1;
s = snd[:,1]

y = fft(s)

y1 = copy(y)
for i = 1:N
    if abs(y1[i]) > 800
        y1[i] = 0
    end
end

s_new = real(ifft(y1))
wavwrite(s_new, "output1.wav", Fs = sampFreq)

y2 = copy(y)
for i = 1:N
    if abs(y2[i]) <  800
        y2[i] = 0
    end
end

s_new = real(ifft(y2))
wavwrite(s_new, "output2.wav", Fs = sampFreq)

sticks((abs.(y1)))
sticks!((abs.(y2)))

s1,k1 = wavread("output1.wav")
s2,k2 = wavread("output2.wav")

for i = 1:N
    s1[i] += s2[i]
end

wavwrite(s1, "output3.wav", Fs = sampFreq)

这是读取文件 input.wav 的代码,接下来对声音进行 fft,将其分成两个文件输出 1,仅频率 > 800 和输出 2,频率 < 800。

在下一部分中,我将这两个文件合并到 output3 中。我期待与输入类似的东西,但我得到的听起来很糟糕(我的意思是它听起来像输入,但比预期更安静且嗡嗡声更大)。

我的问题是代码的哪一部分丢失了最多关于输入的信息,这是改进它的一种方法,以获得几乎类似于输入的输出3吗?

您似乎没有理解什么是 fft(快速傅里叶变换)returns。它 returns 是振幅矢量,而不是频率矢量。矢量的分量对应于正弦波的幅度,您可以使用 fftfreq() 函数找到该频率,但请务必为 fftfreq() 函数提供其第二个参数,即您的 sampFreq 变量。

然后,要分解声音,您需要根据 fftfreq() 告诉您的与 bin 对应的频率(fft() 返回的向量中的向量位置)将不需要的向量分量归零。

使用 ifft 反转过程时,您仍然会看到音质大幅下降,因为 fft 基本上会通过将信号分成频率维度的 bin 来平均部分信号。

我建议您在进一步修复代码之前阅读有关 fft() 的教程——您可以 google 其中的几个。