2013-09-21 54 views
0

背景:我正在使用JLayer播放MP3文件。我試圖分析MP3中不同的幅度/音頻電平。通過我的分析,我想確定MP3開始和結束時的靜音持續時間。另外,當正在播放MP3時,我想要一個圖形來顯示音頻電平(如視覺聲波)。使用JLayer將MP3解碼爲PCM來檢測幅度

問題:爲了進行有效的分析,我需要能夠分析原始PCM數據。目前,我正在分析通過AudioInputStream檢索到的字節[],並將其發送到SourceDataLinePCM短[]不是字節[],這意味着我沒有得到完整的數據。

我正在使用Root-Mean SquareRMS)來確定音量級別。

回放代碼,其中所述字節[]進行處理:

AudioInputStream in = null; 
AudioFile af = null; //Custom class which holds some data about mp3. 
SourceDataLine line = null; 

// Set current audio file. 
af = musicPlaylist.get(0); 

line = (SourceDataLine) AudioSystem.getLine(af.getLineInfo()); 
line.open(af.getAudioFormat()); 
line.start(); 

in = getAudioInputStream(af.getAudioFormat(), af.getAudioStream()); 

int bR = playbackBufferSize; 

final byte[] buffer = new byte[bR]; 
int n = 0; 
while (playMedia) { 
    if ((n = in.read(buffer, 0, buffer.length)) == -1) { 
     break; 
    } 

    if (line != null) { 
     line.write(buffer, 0, n); 

     int amp = (int) Math 
       .ceil((rmsAudioLevel(decode(buffer))/32767) * 100); 
     mainScreen.setAmpDisplayLevel(amp, String.valueOf(amp)); 
     mainScreen.updateGraph(amp); 
    } 
} 

本質:如何在現場的PCM數據進行解碼,因爲我玩MP3,使我可顯示音量等級並因此檢測到沉默?

+0

爲了更快提供更好的幫助,請發佈[SSCCE](http://sscce.org/)。 –

回答

1

首先,您將獲取緩衝區[]中的所有PCM數據。但是你可能不得不將這些字節組裝成PCM數據。您的音頻格式會告訴您正在使用多少位編碼。最常見的是16位,但有時會顯示24位或32位數據。使用16位數據,您可以附加兩個連續的字節來構建短路。兩個字節的順序取決於格式是小端還是大端。我注意到這個屏幕的權利,在「相關」欄中,是一個鏈接:如何從wav文件獲取PCM數據 - 該鏈接或其他類似應該爲您提供您需要的代碼示例。

第二個問題,我不認爲在單獨的緩衝區[]數組上做RMS是完全正確的。我可能是錯的。我認爲它更像是一個移動平均值,其中一個緩衝區[]開頭的一些數據應該包含前一個緩衝區[]的末尾的一些數據。公式是否要求您「返回」或「平均超過」N幀?如果是這樣的話,那麼在N量跨越兩幀的情況下,您會希望保留前一個緩衝區[]。你將迭代當前緩衝區[],一次一個「幀」(或者將緩衝區[]傳遞給子程序,實際上是這樣做的)。