[英]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.