gpt4 book ai didi

c++ - 实时音频处理

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:22:25 28 4
gpt4 key购买 nike

我想使用 Qt 进行实时音频处理,并使用 FFTW3 进行显示基频

我在步骤中做了什么:

  1. 我从计算机设备捕获任何声音并将其填充到缓冲区中。
  2. 我将声音样本分配给 double 数组
  3. 我计算基频。

问题

我的代码总是返回 0 作为基频

QByteArray *buffer;
QAudioInput *audioInput;
audioInput = new QAudioInput(format, this);

//Check the number of samples in input buffer
qint64 len = audioInput->bytesReady();

//Limit sample size
if(len > 4096)
len = 4096;

//Read sound samples from input device to buffer
qint64 l = input->read(buffer.data(), len);

if(l > 0)
{
int input_size = BufferSize;

// Compute corresponding number of complex output samples
int output_size = (input_size/2 + 1);
double *input_buffer = static_cast<double*>(fftw_malloc(input_size * sizeof(double)));
fftw_complex *out = static_cast<fftw_complex*>(fftw_malloc(output_size * sizeof(fftw_complex)));

//Assign sound samples to double array
input_buffer = (double*)buffer.data();
fftw_plan p3;

//Create plan
p3 = fftw_plan_dft_r2c_1d(input_size, input_buffer, out, FFTW_ESTIMATE);

fftw_execute(p3);
double reout[BufferSize];
double imgout[BufferSize];
double magnitude[BufferSize/2];

long ffond = 0.0; // Position of the frequency
double max = 0; // Maximal amplitude

for (int i = 0; i < BufferSize/2; i++)
{
reout[i] = out[i][0];
imgout[i] = out[i][1];
cout << imgout[i] << endl;
magnitude[i] = sqrt(reout[i]*reout[i] + imgout[i]*imgout[i]); //Calculate magnitude of first
double t = sqrt(reout[i]*reout[i] + imgout[i]*imgout[i]);

if(t > max)
{
max = t;
ffond = i;
}
}

qDebug() << "fundamental frequency is :" << QString::number(ffond*static_cast<double>);
fftw_destroy_plan(p3);

最佳答案

我可以看到您有两个紧迫的问题:

  1. 您没有申请 window function ,所以会有相当大的spectral leakage以及相关的频谱“拖尾”(以及可能带有相关“裙边”的大直流 (0 Hz) 分量)

  2. 您假设频谱中的最大幅度是基频,这很可能是不正确的,原因有二:(a) 您很可能有一个大的 0 Hz 分量,它大于您的基频或谐波和 (b) 根据您尝试分析的声音的性质,基波的幅度可能小于谐波(甚至可能完全消失)

我建议您执行以下操作:

  • 申请合适的window function在 FFT 之前 - 这应该使您的峰值更好地定义并且应该减少 0 Hz 和略高于 Hz 的伪影

  • 从适当的 bin 而不是 0 开始搜索,例如如果您感兴趣的最小基频是 50 Hz,则从 50 Hz 的相应 bin 开始,而不是从 0 开始

  • 添加一个调试选项以图形方式显示频谱 - 当您想知道为什么您的结果没有意义时,这种可视化调试辅助工具将大有帮助

  • 如果您真正想要测量的是音高 而不是基频,请继续阅读 pitch detection algorithms ,例如谐波乘积频谱 - 这比尝试识别基波(其频率在一般情况下与音高不同)的天真方法要好得多

关于c++ - 实时音频处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24018607/

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