gpt4 book ai didi

c++ - 如何对 WAV 文件数据执行 FFT?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:51:45 26 4
gpt4 key购买 nike

我正在尝试通过检测存在的最高频率来分析文件的音频质量(压缩音频通常会被过滤到低于 20KHz 的频率)。

我正在使用 soundstretch 库中的一个类读取 WAV 文件数据,该类将 PCM 样本作为 float 返回,然后使用 fftw3 库对这些样本执行 FFT。然后对于每个频率(四舍五入到最接近的 KHz),我将计算该频率的振幅。

因此对于不包含高于 16KHz 频率的低质量文件,我希望在 16KHz 以上没有或只有很小的幅度,但是我没有得到我期望的结果。下面是我的代码:

#include <iostream>
#include <math.h>

#include <fftw3.h>
#include <soundtouch/SoundTouch.h>
#include "include/WavFile.h"

using namespace std;
using namespace soundtouch;

#define BUFF_SIZE 6720
#define MAX_FREQ 22//KHz

static float freqMagnitude[MAX_FREQ];

static void calculateFrequencies(fftw_complex *data, size_t len, int Fs) {
for (int i = 0; i < len; i++) {
int re, im;
float freq, magnitude;
int index;

re = data[i][0];
im = data[i][1];

magnitude = sqrt(re * re + im * im);
freq = i * Fs / len;

index = freq / 1000;//round(freq);
if (index <= MAX_FREQ) {
freqMagnitude[index] += magnitude;
}
}
}

int main(int argc, char *argv[]) {
if (argc < 2) {
cout << "Incorrect args" << endl;
return -1;
}

SAMPLETYPE sampleBuffer[BUFF_SIZE];
WavInFile inFile(argv[1]);

fftw_complex *in, *out;
fftw_plan p;

in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * BUFF_SIZE);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * BUFF_SIZE);

p = fftw_plan_dft_1d(BUFF_SIZE, in, out, FFTW_FORWARD, FFTW_ESTIMATE);

while (inFile.eof() == 0) {
size_t samplesRead = inFile.read(sampleBuffer, BUFF_SIZE);

for (int i = 0; i < BUFF_SIZE; i++) {
in[i][0] = (double) sampleBuffer[i];
}

fftw_execute(p); /* repeat as needed */

calculateFrequencies(out, samplesRead, inFile.getSampleRate());
}

for (int i = 0; i < MAX_FREQ; i += 2) {
cout << i << "KHz magnitude: " << freqMagnitude[i] << std::endl;
}

fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}

可以编译:-(你需要 soundtouch 库和 fftw3 库)

g++ -g -Wall MP3.cpp include/WavFile.cpp -lfftw3 -lm -lsoundtouch -I/usr/local/include -L/usr/local/lib

这是我正在测试的文件的频谱分析:

Spek screenshot

如您所见,它在 16KHz 处被削波,但我的结果如下:

0KHz magnitude: 4.61044e+07
2KHz magnitude: 5.26959e+06
4KHz magnitude: 4.68766e+06
6KHz magnitude: 4.12703e+06
8KHz magnitude: 12239.6
10KHz magnitude: 456
12KHz magnitude: 3
14KHz magnitude: 650468
16KHz magnitude: 1.83266e+06
18KHz magnitude: 1.40232e+06
20KHz magnitude: 1.1477e+06

我预计不会有超过 16KHz 的振幅,我这样做对吗?我的频率计算正确吗? (我从另一个 stackoverflow 答案中抢走了它)会不会是因为有 2 个 channel 而我没有分开 channel ?

为任何帮助的人干杯。

最佳答案

您可能正在测量两个立体声 channel 之间的交错差异,其中可能包括由于混音和声相不均而导致的高频。再次尝试将 channel 分离或混合为单声道,并使用平滑窗口函数来减少 FFT 孔径边缘伪影,由于矩形窗口,这也会引入少量高频噪声。

关于c++ - 如何对 WAV 文件数据执行 FFT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35484919/

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