[英]Audio Visualizer from wav looks wrong
我无法使音频可视化器看起来准确。 具有大量声音的垃圾箱往往会正确绘制,但我遇到的问题是,所有没有明显声音的频率似乎都以一个通常在-60dB到-40dB反弹的值返回。 这将形成一条平坦的弹跳线(通常在较高的频率中)。
我想以每秒30帧的速度显示512 bins或更少。 我已经连续数周阅读了FFT和音频不间断的信息,到目前为止,我的过程是:
我已经用几首歌曲对其进行了测试,并且生成了一个wav文件,该文件只播放440Hz的音调。 使用wav文件时,我确实在440纸槽处出现尖峰,但所有其他纸槽形成的线并不比440纸槽短很多。 同样每隔一帧,与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,则几乎不会这样做。
您必须了解,您并没有采用无限信号的傅立叶变换,而是采用了其窗口版本的FT。 而且您的窗口甚至不是普通的Hann窗口。 舍弃446个点实际上是一个矩形窗口函数。 窗口功能的FT都将显示在输出中。
其次,dB标度是对数的。 这确实意味着在没有信号的情况下它可能会变得很低。 您提到-60 dB,但实际上它可能达到负无穷大。 唯一可以避免这种情况的是窗口功能,它将在-110 dB左右引入拖影。
长度为1024的Von Hann量化窗口所产生的噪声(阻带纹波)可能约为-40至-60 dB。 因此,一种策略是只设置一个阈值,然后忽略(不要绘制)低于该阈值的所有值。
另外,请尝试删除rescale(real)函数,因为在采用对数幅度之前,这可能会使您的复数向量失真。
另外,请确保您确实将音频样本正确地加载到真实矢量中(符号,位数和字节序)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.