【问题标题】:Decode MP3 into PCM using JLayer to detect amplitude使用 JLayer 将 MP3 解码为 PCM 以检测幅度
【发布时间】:2013-09-21 23:09:58
【问题描述】:

背景:我正在使用JLayer 播放MP3 文件。我正在尝试分析MP3 中不同的幅度/音频电平。通过我的分析,我想确定MP3 开头和结尾处的沉默持续时间。此外,在播放MP3 时,我想要一个图表来显示音频电平(如视觉声波)。

问题:为了有效分析,我需要能够分析原始PCM 数据。目前,我正在分析通过AudioInputStream 检索并发送到SourceDataLine 的byte[]。 PCM 是 short[] 而不是 byte[],这意味着我没有得到完整的数据。

我正在使用Root-Mean Square (RMS) 来确定音量。

处理byte[]的播放代码:

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 数据,以便我可以显示音量级别并因此检测静音?

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE

标签: java mp3 javasound pcm javax.sound.sampled


【解决方案1】:

首先,您将获得缓冲区[] 中的所有 PCM 数据。但是您可能必须将字节组装成 PCM 数据。您的音频格式将告诉您正在使用多少位编码。最常见的是 16 位,但有时会显示 24 位或 32 位数据。对于 16 位数据,您附加两个连续的字节来构建一个短字节。两个字节的顺序取决于格式是 little-endian 还是 big-endian。我注意到在此屏幕右侧的“相关”列中,有一个链接:如何从 wav 文件中获取 PCM 数据——该链接或其他类似链接应该为您提供所需的代码示例。

第二个问题,我不认为在单独的 buffer[] 数组上执行 RMS 是完全正确的。我可能错了。我认为它更像是一个移动平均线,其中一个缓冲区 [] 开头的一些数据应该包括前一个缓冲区 [] 结尾的一些数据。该公式是否要求您“返回”或“平均超过”N 帧?如果是这样,您将希望在 N 数量跨越两帧的情况下保持先前的 buffer[] 方便。你将遍历当前的缓冲区[],一次一个“帧”(或将缓冲区[]交给实际上执行此操作的子例程)。

【讨论】:

    猜你喜欢
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2013-06-06
    • 2021-06-24
    • 1970-01-01
    • 2013-01-17
    相关资源
    最近更新 更多