gpt4 book ai didi

python - NumPy 快速傅立叶变换 (FFT) 对 Audacity 中生成的正弦波不起作用

转载 作者:行者123 更新时间:2023-12-01 15:27:47 25 4
gpt4 key购买 nike

我正在尝试使用 Python 的 NumPy 库进行一些频率分析。我有两个 .wav 文件,它们都包含 440 Hz 正弦波。其中一个是我用 NumPy 正弦函数生成的,另一个是我用 Audacity 生成的。 FFT 在 Python 生成的一个上工作,但在 Audacity 上没有任何作用。

以下是这两个文件的链接:

非工作文件:440_audacity.wav

工作文件:440_gen.wav

这是我用来做傅立叶变换的代码:

import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile as wave

infile = "440_gen.wav"
rate, data = wave.read(infile)

data = np.array(data)

data_fft = np.fft.fft(data)
frequencies = np.abs(data_fft)

plt.subplot(2,1,1)
plt.plot(data[:800])
plt.title("Original wave: " + infile)

plt.subplot(2,1,2)
plt.plot(frequencies)
plt.title("Fourier transform results")

plt.xlim(0, 1000)

plt.tight_layout()

plt.show()

我有两个 16 位 PCM .wav 文件,一个来自 Audacity,另一个使用 NumPy 正弦函数创建。 NumPy 生成的结果如下(正确),峰值为 440Hz:
FFT on the numpy generated file

我用 Audacity 创建的那个,虽然波形看起来相同,但在傅立叶变换上没有给出任何结果:
FFT on the audacity generated file

我承认我在这里不知所措。这两个文件实际上应该包含相同的数据。它们以相同的方式编码,并且波形在上图中显示相同。

这是用于生成工作文件的代码:

import numpy as np
import wave
import struct
import matplotlib.pyplot as plt
from operator import add

freq_one = 440.0
num_samples = 44100
sample_rate = 44100.0
amplitude = 12800

file = "440_gen.wav"

s1 = [np.sin(2 * np.pi * freq_one * x/sample_rate) * amplitude for x in range(num_samples)]

sine_one = np.array(s1)

nframes = num_samples
comptype = "NONE"
compname="not compressed"
nchannels = 1
sampwidth = 2

wav_file = wave.open(file, 'w')
wav_file.setparams((nchannels, sampwidth, int(sample_rate), nframes, comptype, compname))

for s in sine_one:
wav_file.writeframes(struct.pack('h', int(s)))

最佳答案

让我解释一下为什么您的代码不起作用。以及为什么它适用于 [:44100] .
首先,你有不同的文件:

440_gen.wav      = 1 sec and 44100  samples (counts)        
440_audacity.wav = 5 sec and 220500 samples (counts)
自为 440_gen.wav在 FFT 中,您使用引用点数 N=44100 和采样率 44100,频率分辨率为 1 Hz(以 1 Hz 为增量跟随 bin)。
因此,在图中,每个 FFT 样本对应于等于 1 Hz 的增量。 plt.xlim(0, 1000)仅对应于 0-1000 Hz 的范围。
但是,对于 440_audacity.wav在 FFT 中,您使用引用点数 N=220500 和采样率 44100。您的频率分辨率为 0.2 Hz(bin 以 0.2 Hz 的增量跟随) - 在图表上,每个 FFT 样本对应于 0.2 Hz 增量的频率(最小-最大 = +(-) 22500 Hz)。 plt.xlim(0, 1000)仅对应于 1000x0.2 = 0-200 Hz 的范围。
这就是结果不可见的原因——它不在这个范围内。 plt.xlim (0, 5000)将纠正您的情况并将范围扩展到 0-1000 Hz。
解决方案 [:44100]那个 jwalton 引入实际上只强制 FFT 使用 N = 44100。这重复了 440_gen.wav 计算的情况
更正确的解决您的问题的方法是使用 N (Windows Size)代码中的参数和 np.fft.fftfreq()功能。
下面的示例代码。
我也推荐一篇很棒的文章 https://realpython.com/python-scipy-fft/
import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile as wave

N = 44100 # added

infile = "440_audacity.wav"
rate, data = wave.read(infile)

data = np.array(data)

data_fft = np.fft.fft(data, N) # added N
frequencies = np.abs(data_fft)
x_freq = np.fft.fftfreq(N, 1/44100) # added

plt.subplot(2,1,1)
plt.plot(data[:800])
plt.title("Original wave: " + infile)

plt.subplot(2,1,2)
plt.plot(x_freq, frequencies) # added x_freq
plt.title("Fourier transform results")

plt.xlim(0, 1000)
plt.tight_layout()
plt.show()

关于python - NumPy 快速傅立叶变换 (FFT) 对 Audacity 中生成的正弦波不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55971972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com