我在 DSP 和滤波领域非常陌生。就像我一周前开始的一样。无论如何,我一直在寻找在我得到的一些数据上使用滤波器(低通、高通、陷波等)的方法。数据来自一个双精度数组,我可以在这个数组中获得超过 100 万个点。我试图过滤掉给定某个截止频率的声音,但无法使任何算法起作用。我一直在互联网上下并尝试了一堆不同的库和方法,但我无法得到任何结果。我偏爱 NAudio 库,因为它似乎拥有我需要的一切(通过 BiQuadFilter 类进行 FFT 和过滤)。我很确定我的问题是我极度缺乏获得所需输出的知识和数学。从我所读到的内容来看,我认为这个过程应该如何进行:
这是过滤音频的正确方法吗?我可以将整个阵列推入 FFT 还是必须将其分解成更小的块?我如何处理我在 FFT 结果中得到的复数(即只使用实部并丢弃虚部,或者使用幅度和相位)?我真的不知道什么是“正确的方式”。
编辑
我终于让它工作了!这是我所做的:
byte[] data = doubleArray.SelectMany(value => BitConverter.GetBytes(value)).ToArray();
wms = new WaveMemoryStream(data, sampleRate, (ushort)audioBitsPerSample, (ushort)channels);
WaveFileReader wfr = new WaveFileReader(wms);
SampleChannel sample = new SampleChannel(wfr, false);
LowPassSampleProvider sampleProvider = new LowPassSampleProvider(sample);
WaveOutEvent player = new WaveOutEvent();
player.Init(sampleProvider);
player.Play();
Run Code Online (Sandbox Code Playgroud)
doubleArray 是我的加速度计数据的数组,目前拥有 100 万个点,每个点都在 1.84 左右......
WaveMemoryStream是我在另一篇文章中找到的课程
LowPassSampleProvider 是我创建的一个类,它实现了 ISampleProvider 并将样本传递给 BiQuadFilter.LowPassFilter 函数。
我正在通过 FFT 分析加速度计数据,因为有人建议我从 FFT 的输出中获取有关频率的信息。FFT 的输出如何与频率信息相关。
FFT 函数被传递一个值数组(所有实数)。FFT 函数返回 2 个相同大小的数组 - 对于实数和复数部分。
我阅读了之前的一些帖子,但仍然对如何从 FFT 的输出数组中提取频率信息感到困惑。1. 输出数组是一个频率数组吗?数组是有序的吗?1.输出数组的每个索引是什么意思?有人建议您可以计算每个索引的大小 - sort (real[i]* real[i] + img[i] * img[i]) 2. 每个索引的大小是否与索引中的索引有关输入数组 - 或者这是一个频率?3. 如何找到主频?
我使用fftw_plan_dft_2d(). 据我了解,输出表示复数的二维数组(宽x高)。
有人可以向我解释我应该如何解释这个数组吗?每个点代表什么?每个点的值代表什么?
如果我想应用高通滤波器,我该怎么做?我尝试了下面的代码,但是当我做反向 FFT 时,我得到的只是重叠的移位图像。
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
xx = ABS(x - width / 2);
yy = ABS(y - height / 2);
if (sqrt(xx * xx + yy * yy) > width / 2)
{
fft[y * width + x][0] = 0;
fft[y * width + x][1] = 0;
}
}
Run Code Online (Sandbox Code Playgroud) 我已经做了很多谷歌搜索,但还没有找到一个关于如何确定 mp3 文件音符的例子。
到目前为止,我已经阅读了一些关于 FFT(快速傅立叶变换)的内容,从中可以计算音频文件的音高,并根据音高符号可以得出音符。
但是后来我读到mp3 文件格式在时域中,由于有损压缩格式不包含频率分析所需的样本值……这是否意味着您必须将 mp3 转换为 wav文件以计算密钥?
我找到了几个用于视觉目的的实时音高检测示例,但不是用于分析整个 mp3 文件并输出音乐键。
我希望有人能指出我正确的方向。
谢谢。
我正在努力将我的代码从 python 转换为目标 c。在 matplotlib.mlab.specgram 函数中,我在 fft 之前看到了 3 个重要的函数:
result = stride_windows(x, NFFT, noverlap, axis=0)
result = detrend(result, detrend_func, axis=0)
result, windowVals = apply_window(result, window, axis=0,
return_window=True)
result = np.fft.fft(result, n=pad_to, axis=0)[:numFreqs, :]
Run Code Online (Sandbox Code Playgroud)
我试图调试以了解每个的目的。例如我有输入数组:
x = [1,2,3,4,5,6,7,8,9,10,11,12]
Run Code Online (Sandbox Code Playgroud)
在第一个函数 stride_windows 之后(这个是为了防止泄漏?),如果 NFFT = 4,noverlap = 2 那么:
x = [ [1,3,5,7,9],
[2,4,6,8,10],
[3,5,7,9,11],
[4,6,8,10,12]
]
Run Code Online (Sandbox Code Playgroud)
在 detrend 之后没有任何变化(我了解 fft 之前的 detrend)
在 apply_window 里面(我不明白这一步):
xshape = list(x.shape)
xshapetarg = xshape.pop(axis) // =4
windowVals = window(np.ones(xshapetarg, dtype=x.dtype))
//result of 4 elements …Run Code Online (Sandbox Code Playgroud) 出于项目目的,我正在录制舞台附近不同区域的音频剪辑(波形文件)。我需要检查源音频,即;使用从附近地点录制的音频,来自舞台的音频在舞台附近的位置具有很高的可听性。
更清楚的是,我在舞台附近的地方有麦克风,我有舞台和附近这些地方的音频剪辑。我如何检查来自舞台的声音是否被接收到附近的位置,或者我如何理解来自舞台的声音正在对附近的地方造成干扰。
我正在寻找一种从信号中获取频率的方法。下面是一个例子:
signal = [numpy.sin(numpy.pi * x / 2) for x in range(1000)]
Run Code Online (Sandbox Code Playgroud)
此数组将代表录制声音的样本(x = 毫秒)
sin(pi*x/2) => 250 赫兹
我们如何从信号(点列表)到从这个数组中获取频率?
注意: 我阅读了许多 Stackoverflow 线程并观看了许多 youtube 视频。我还没有找到答案。请用简单的词。(我很感激每一个回答)
我需要计算一个 256 个元素的 float64 信号的傅立叶变换。要求是我需要从 cuda.jitted 部分内部调用这些 FFT,并且必须在 25 秒内完成。唉,cuda.jit 编译的函数不允许调用外部库 => 我自己写的。唉,我的单核代码还是太慢了(在 Quadro P4000 上约为 250 微秒)。有没有更好的办法?
我创建了一个可以提供正确结果的单核 FFT 函数,但是速度太慢了 10 倍。我不明白如何充分利用多核。
---fft.py
from numba import cuda, boolean, void, int32, float32, float64, complex128
import math, sys, cmath
def _transform_radix2(vector, inverse, out):
n = len(vector)
levels = int32(math.log(float32(n))/math.log(float32(2)))
assert 2**levels==n # error: Length is not a power of 2
#uncomment either Numba.Cuda or Numpy memory allocation, (intelligent conditional compileation??)
exptable = cuda.local.array(1024, dtype=complex128)
#exptable = np.zeros(1024, np.complex128)
assert (n // …Run Code Online (Sandbox Code Playgroud) 有人可以解释为什么 fft 的结果需要除以采样点的数量(信号的长度)?
该示例可以在此页面上找到:https : //fr.mathworks.com/help/matlab/ref/fft.html
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1500; % Length of signal
t = (0:L-1)*T; % Time vector
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
Y = fft(S);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
Run Code Online (Sandbox Code Playgroud)
为什么他们包括这个操作:P2 = abs(Y/L);?
他们为链接中的每个示例执行此操作。
另外,如果他们必须在每次 fft 计算后执行该操作,他们为什么不直接在内置 fft 函数中包含该操作?在某些情况下,最好不要执行该额外操作吗?
谢谢!
我有一个问题,numpy fft 没有给我 fft 图中的预期幅度。这仅在某些时期作为输入发生。
我正在使用一个干净的正弦信号,周期为 25 个点,超过 240 个数据点。
np.fft.rfft 给出的峰值为 24。

我想知道什么可能导致这种情况。我认为干净的信号应该产生一个 dirac-delta 函数,比如 25 左右的结果。我在某些时期得到这种类型的结果,但不是全部。是否需要多次重复此期间才能准确指定期间?这对我来说没有意义。fft 以下列方式完成,其中 y=my sine datapoints with period 25:
fft = np.fft.rfft(y)
fft = abs(fft)
x=np.fft.rfftfreq(len(y),d=1./1)
x = 1/x # to convert from freq to periods. T = 1/f
plt.plot(x,fft)
Run Code Online (Sandbox Code Playgroud)