Java 使用JLayer将MP3解码到PCM中以检测振幅
背景:我正在播放一个Java 使用JLayer将MP3解码到PCM中以检测振幅,java,mp3,javasound,pcm,javax.sound.sampled,Java,Mp3,Javasound,Pcm,Javax.sound.sampled,背景:我正在播放一个MP3文件。我试图分析MP3中不同的振幅/音频电平。通过我的分析,我想确定MP3开始和结束时的静默时间。此外,在播放MP3时,我想用一个图表来显示音频级别(如可视声波) 问题:为了进行有效分析,我需要能够分析原始PCM数据。目前,我正在分析通过AudioInputStream检索并发送到SourceDataLine的字节[]PCM是短[]而不是字节[],这意味着我没有获得完整数据 我使用均方根(RMS)来确定音量水平 处理字节[]的播放代码: AudioInputStream
MP3
文件。我试图分析MP3
中不同的振幅/音频电平。通过我的分析,我想确定MP3
开始和结束时的静默时间。此外,在播放MP3时,我想用一个图表来显示音频级别(如可视声波)
问题:为了进行有效分析,我需要能够分析原始PCM
数据。目前,我正在分析通过AudioInputStream
检索并发送到SourceDataLine
的字节[]<代码>PCM是短[]而不是字节[],这意味着我没有获得完整数据
我使用均方根
(RMS
)来确定音量水平
处理字节[]的播放代码:
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);
}
}
本质上:如何在播放
MP3
时当场解码PCM
数据,以便显示音量水平,从而检测静音?首先,您将在缓冲区[]中获取所有PCM数据。但您可能必须将字节组合成PCM数据。您的音频格式将告诉您使用了多少位编码。最常见的是16位,但有时会显示24位或32位数据。对于16位数据,可以附加两个连续的字节来构建一个短字节。两个字节的顺序取决于格式是小端还是大端。我注意到屏幕右侧的“相关”列中有一个链接:如何从wav文件中获取PCM数据——该链接或其他类似链接将为您提供所需代码的示例
第二个问题,我认为在单独的缓冲区[]数组上执行RMS并不完全正确。我可能错了。我认为它更像一个移动平均值,其中一个缓冲区[]开头的一些数据应该包括前一个缓冲区[]结尾的一些数据。公式是否要求“返回”或“平均”N帧数?如果是这样,您将希望在N个量跨越两个帧的情况下,将前一个缓冲区[]保持在手边。您将在当前缓冲区[]中一次迭代一个“帧”(或将缓冲区[]交给实际上执行此操作的子例程)。要更快获得更好的帮助,请发布一个。