我被困住了。现在已经搜索了一段时间,尝试了几种不同的方法,最后我发现的最好的东西是Qt(Spectrum)的一个例子,但是对我来说太复杂了我把它减少到我需要的东西:
目标是实时音频处理,更具体地说,应用FFT以条形图显示它。
这是我的代码(来自QThread的worker类的代码段):
//initialize the recording
void Worker::process() {
QAudioEncoderSettings settings;
settings.setCodec("audio/PCM");
settings.setQuality(QMultimedia::HighQuality);
settings.setChannelCount(2);
QAudioRecorder* recorder = new QAudioRecorder(this);
recorder->setEncodingSettings(settings);
QAudioProbe* probe = new QAudioProbe();
probe->setSource(recorder);
connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(onAudioBufferProbed(QAudioBuffer)));
recorder->record();
}
//process chunks of audio stream data
void Worker::onAudioBufferProbed(QAudioBuffer buffer) {
int n = buffer.frameCount();
double *data = buffer.data<double>();
double x[n];
fftw_complex y[n];
//apply Hann Window to data to account for artifacts
for (int i=0; i<n; i++) {
double hannWindow = 0.5 * (1 - cos((2 * M_PI * i) / (n - 1)));
x[i] = hannWindow*data[i];
}
fftw_plan myPlan = fftw_plan_dft_r2c_1d(n, x, y, FFTW_ESTIMATE);
fftw_execute(myPlan);
//sum result into 44 bins for visualization
int steps = n/44;
std::vector<double> bins;
for (int i=0; i<44; i++) {
double bin = 0;
for (int q=0; q<steps; q++) {
//calculate amplitude = sqrt(re*re+im*im)
double amplitude = sqrt(y[i*steps+q][0]*y[i*steps+q][0]+y[i*steps+q][1]*y[i*steps+q][1]);
//overwrite NaN with 0. Got a lot of them apparently, without these two lines it crashes immediatly, I guess somewhere downstream
if (amplitude != amplitude) bin += 0;
//convert to dB
else bin += 20*log10(amplitude);
}
bins.push_back(bin);
qDebug() << bins[i];
}
}
我正在使用Qt 5.10,C ++和FFTW。 问题是我只在qDebug行的输出中得到一堆NaN,-inf和0,QAudioBuffer的输入似乎也是非常低的数字(大约在e-300)。老实说,我不能想出什么是错的,我对Qt的了解太少了,而且这是第一次使用FFTW而且我真的不知道这些数字应该是什么样的。你能找到这个bug吗?我的目标是获得0到1之间的数字,或者处理好的数字,以便在简单的情节中将它们可视化。