我无法使音频可视化器看起来准确。具有大量声音的垃圾箱往往会正确绘制,但是我遇到的问题是,所有没有明显声音的频率似乎都以一个通常在-60dB到-40dB之间反弹的值返回。这将形成一条平坦的弹跳线(通常在较高的频率中)。
我想以每秒30帧的速度显示512 bins或更少。我已经连续几周阅读FFT和音频不间断了,到目前为止,我的过程是:
我已经用几首歌曲对其进行了测试,并且生成了一个wav文件,该文件只播放440Hz的音调。使用wav文件时,确实在440 bin处出现峰值,但是所有其他bin形成的行并不比440 bin短很多。同样,每隔一个帧,与440分开的bin看起来就像是一个图形对数函数,在某个其他bin上有一个倾斜。
我用C ++编写。使用STK仅从音频文件加载左声道:
//put every sample in the song into a temporary vector
for (int i = 0; i < stkObject->getSize(); i++)
{
standardVector.push_back(stkObject->tick(LEFT));
}
我正在使用FFTReal执行FFT:
std::vector<std::vector <double> > leftChannelData;
int numberOfFrames = stkObject->getSize()/samplesPerFrame;
leftChannelData.resize(numberOfFrames);
for(int i = 0; i < numberOfFrames; i++)
{
for(int j = 0; j < FFT_SAMPLE_LENGTH; j++)
{
real[j] = standardVector[j + (i*samplesPerFrame)];
}
applyHannWindow(real, FFT_SAMPLE_LENGTH);
fft_object.do_fft(imaginary,real);
//FFTReal instructions say to run this after an fft
fft_object.rescale(real);
leftChannelData[i].resize(FFT_SAMPLE_LENGTH/2);
for (int j = 0; j < FFT_SAMPLE_LENGTH/2; j++)
{
double magnitude = sqrt(real[j]*real[j] + imaginary[j]*imaginary[j]);
double dbValue = 20 * log(magnitude/maxMagnitude);
leftChannelData[i].at(j) = dbValue;
}
}
我不知道是什么原因造成的。我尝试了各种方法来提取我忽略的446个样本,但结果似乎并没有改变。我想我可能做的是根本错误的事情。我尝试过将pcm数据归一化后再传递给fft,并且尝试过对幅度进行归一化后再找到分贝,但似乎没有用。有什么想法吗?
编辑:我看不到log(magnitude)和log(magnitude / maxMagnitude)之间的任何区别。似乎要做的就是将bin的所有值平均向下移动。
EDIT2:这是他们看上去很像的样子:
歌曲播放声音低-带对数(mag)
歌曲播放低声音-相同但带有对数(mag / maxMag)
同样,log(mag)和log(mag / maxMag)通常看起来相同,但是值范围为负数。就像MSalters所说的那样,分贝可以接近-无限,因此我可以将这些值钳位到-100dB。然后取log(mag / maxMag)并加100。这样矩形的高度范围从0到100,而不是-100到0。
这是我应该做的吗?我已经尝试过了,但是看起来还是错误的。也许这只是一个扩展问题?当我这样做时,当听起来像是应该的时,很多酒吧都不会使其超出线条。如果确实将其设置为大于0,则几乎不会这样做。
长度为1024的Von Hann量化窗口所产生的噪声(阻带纹波)可能约为-40至-60 dB。因此,一种策略是只设置一个阈值,然后忽略(不绘制)低于该阈值的所有值。
另外,请尝试删除rescale(real)函数,因为在采用对数幅度之前,这可能会使您的复数向量失真。
另外,请确保您确实将音频样本正确地加载到真实矢量中(符号,位数和字节序)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句