簡體   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