繁体   English   中英

WAV的Audio Visualizer看起来不对

[英]Audio Visualizer from wav looks wrong

我无法使音频可视化器看起来准确。 具有大量声音的垃圾箱往往会正确绘制,但我遇到的问题是,所有没有明显声音的频率似乎都以一个通常在-60dB到-40dB反弹的值返回。 这将形成一条平坦的弹跳线(通常在较高的频率中)。

我想以每秒30帧的速度显示512 bins或更少。 我已经连续数周阅读了FFT和音频不间断的信息,到目前为止,我的过程是:

  • 从wav文件加载pcm数据。 这是每秒44100个样本,范围为-/ +32767。我假设将它们传递给FFT时将它们视为实数。
  • 将这些样本分成每帧1470个。 (忽略446)
  • 采集1024个样本并应用Hann窗口。
  • 将样本作为实数[1024]的数组以及大小相同的另一数组传递给FFT,虚部用零填充。
  • 通过遍历(samples / 2)个bin并执行sqrt(real [i] * real [i] + img [i] * img [i])获得幅度。
  • 取20 * log(量级)以获得每个仓的分贝水平
  • 为每个垃圾箱绘制一个矩形。 为每帧绘制这些垃圾箱。

我已经用几首歌曲对其进行了测试,并且生成了一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM