我如何使用Python从WAV PCM文件读取频率峰值,然后能够生成它的图像,用于频谱分析?
我正在尝试制作一个程序,允许您读取任何音频文件,将其转换为WAV PCM,然后找到峰值和频率截止.
我正在尝试对用户唱歌进行实时音调检测,但我遇到了很多问题.我已经尝试了很多方法,包括FFT(FFT问题(返回随机结果))和自相关(自相关音调检测返回麦克风输入的随机结果),但我似乎无法获得任何方法来给出好的结果.任何人都可以建议一种实时音高跟踪方法或如何改进我已有的方法?我似乎无法找到任何好的C/C++方法进行实时音高检测.
谢谢,
尼尔.
编辑:请注意,我已经检查过麦克风输入数据是否正确,并且当使用正弦波时,结果或多或少是正确的音高.
编辑:对不起,这是迟到的,但此刻,我通过从结果数组和每个索引中取出值,并在X轴上绘制索引和在Y轴上绘制值来显示自动相关(两者都被除以100000或其他东西,我使用OpenGL),将数据插入VST主机并使用VST插件不是我的选择.目前,它看起来像一些随机点.我正确地做了,或者你能不能指点我做一些代码或者帮助我理解如何可视化原始音频数据和自相关数据.
Python中最快的FFT实现是什么?
似乎numpy.fft和scipy.fftpack都基于fftpack,而不是FFTW.fftpack和FFTW一样快吗?如何使用多线程FFT或使用分布式(MPI)FFT?
我目前正在尝试编写一些傅里叶变换算法.我从一个简单的DFT算法开始,如数学定义中所述:
public class DFT {
public static Complex[] Transform(Complex[] input) {
int N = input.Length;
Complex[] output = new Complex[N];
double arg = -2.0 * Math.PI / (double)N;
for (int n = 0; n < N; n++) {
output[n] = new Complex();
for (int k = 0; k < N; k++)
output[n] += input[k] * Complex.Polar(1, arg * (double)n * (double)k);
}
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
所以我用以下代码测试了这个算法:
private int samplingFrequency = 120;
private int numberValues = 240;
private void doCalc(object …Run Code Online (Sandbox Code Playgroud) Web Audio API有一个分析器节点,允许您在正在使用的音频上获取FFT数据,并具有获取数据的字节和浮点数.字节版本有点意义,返回看起来像标准化(取决于最小和最大分贝值)强度频谱,其中0不是特定频率仓的音频分量而255是最大值.
但是我想要比8位更多的细节,但使用float版本会产生奇怪的结果.
freqData = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(freqData);
Run Code Online (Sandbox Code Playgroud)
这给了我介于-891.048828125和0. -891之间的值对应于静音,因此它在某种程度上是最小值,而我猜0是等于最大值.
这是怎么回事?为什么-891.048828125显着?为什么一个大的负面是沉默,零是最大的?我使用错误的FloatArray还是存在配置错误?Float64给出0值.
我有一个样本保存在DirectX的缓冲区中.这是从乐器演奏和捕捉的音符样本.如何分析样本的频率(如吉他调谐器)?我认为涉及到FFT,但我没有指向HOWTO.
我一直在浏览这篇精彩的文章:http://blogs.zynaptiq.com/bernsee/pitch-shifting-using-the-ft/
虽然太棒了,但它非常艰难而且沉重.这种材料真的让我感到舒服.
我从Stefan的代码模块中提取了数学,该代码模块计算给定bin的确切频率.但我不明白最后的计算.有人能告诉我最后的数学结构吗?
在深入研究代码之前,让我设置一下场景:
假设我们设置fftFrameSize = 1024,所以我们处理512 + 1个bin
例如,Bin [1]的理想频率适合帧中的单个波.在40KHz的采样率下,tOneFrame = 1024/40K秒= 1/40秒,因此Bin [1]理想地将采集40Hz信号.
设置osamp(overSample)= 4,我们以256为步长沿着输入信号前进.因此,第一个分析检查字节0到1023,然后是256到1279等.注意每个浮点数被处理4次.
...
void calcBins(
long fftFrameSize,
long osamp,
float sampleRate,
float * floats,
BIN * bins
)
{
/* initialize our static arrays */
static float gFFTworksp[2*MAX_FRAME_LENGTH];
static float gLastPhase[MAX_FRAME_LENGTH/2+1];
static long gInit = 0;
if (! gInit)
{
memset(gFFTworksp, 0, 2*MAX_FRAME_LENGTH*sizeof(float));
memset(gLastPhase, 0, (MAX_FRAME_LENGTH/2+1)*sizeof(float));
gInit = 1;
}
/* do windowing and re,im interleave */
for (long k = 0; …Run Code Online (Sandbox Code Playgroud) 我有一些数据由一系列视频帧组成,这些视频帧表示相对于移动基线的亮度随时间的变化.在这些视频中,可能会出现两种"事件" - "局部"事件,其中包括小组聚集像素中的亮度变化,以及影响帧中大多数像素的污染"漫反射"事件:

我希望能够从漫反射事件中隔离亮度的局部变化.我打算通过减去每帧的适当低通滤波版本来做到这一点.为了设计一个最佳滤波器,我想知道我的帧的哪些空间频率在漫射和局部事件期间被调制,即我想生成我的电影随时间变化的频谱图.
我可以找到很多关于生成一维数据(例如音频)光谱图的信息,但是我没有太多关于生成二维数据的光谱图.到目前为止我所尝试的是从帧的傅立叶变换生成2D功率谱,然后对DC分量执行极坐标变换,然后跨角度平均以获得1D功率谱:

然后我将它应用于我的电影中的每一帧,并生成随时间变化的光谱功率的光栅图:

这看起来像是一种明智的做法吗?是否有更"标准"的方法对2D数据进行光谱分析?
这是我的代码:
import numpy as np
# from pyfftw.interfaces.scipy_fftpack import fft2, fftshift, fftfreq
from scipy.fftpack import fft2, fftshift, fftfreq
from matplotlib import pyplot as pp
from matplotlib.colors import LogNorm
from scipy.signal import windows
from scipy.ndimage.interpolation import map_coordinates
def compute_2d_psd(img, doplot=True, winfun=windows.hamming, winfunargs={}):
nr, nc = img.shape
win = make2DWindow((nr, nc), winfun, **winfunargs)
f2 = fftshift(fft2(img*win))
psd = np.abs(f2*f2)
pol_psd = polar_transform(psd, centre=(nr//2, nc//2))
mpow = np.nanmean(pol_psd, 0)
stdpow = np.nanstd(pol_psd, 0)
freq_r = fftshift(fftfreq(nr)) …Run Code Online (Sandbox Code Playgroud) 对于我目前在C++/Qt中的项目,我需要一个库(LGPL是首选),它可以根据信号(基本上是双精度数组)计算频谱图.我已经使用Qwt作为GUI部分.
有什么建议?谢谢.
我已经阅读了一些解释,如何使用信号的fft更有效地计算自相关,将实部乘以复共轭(傅里叶域),然后使用逆fft,但我在matlab中实现这一点时遇到了麻烦因为在详细程度上,我真的不知道自己在做什么.:o)那里的任何一种灵魂都在乎分享一些代码和智慧?
谢谢!