Декодируйте MP3 в PCM, используя JLayer для определения амплитуды

Фон: я использую JLayer, чтобы играть MP3 файл. Я пытаюсь проанализировать различные уровни амплитуды / звука в MP3, С моим анализом я хотел бы определить продолжительность молчания в начале и в конце MP3, Кроме того, как MP3 Сейчас я хочу, чтобы график отображал уровень звука (например, визуальную звуковую волну).

Проблема: для эффективного анализа мне нужно уметь анализировать сырье PCM данные. В настоящее время я анализирую байт [], полученный через AudioInputStream и отправлено SourceDataLine, PCM является коротким [], а не байтовым [], что означает, что я не получаю полных данных.

я использую Root-Mean Square (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);
    }
}

По сути: как мне декодировать PCM данные на месте, как я играю MP3 , чтобы я мог показать уровни громкости и, следовательно, обнаружить тишину?

1 ответ

Решение

Во-первых, вы получаете все данные PCM в буфере []. Но вам, вероятно, придется собирать байты в данные PCM. Ваш аудио формат скажет вам, сколько бит кодирования используется. Наиболее распространенными являются 16-битные, но иногда отображаются 24- или 32-битные данные. С 16-битными данными вы добавляете два смежных байта для создания короткого замыкания. Порядок двух байтов зависит от формата с прямым порядком байтов или с прямым порядком байтов. Я заметил, что в правой части этого экрана, в столбце "Связанные", есть ссылка: как получить данные PCM из wav-файла - эта ссылка или другая аналогичная должна дать вам пример кода, который вам понадобится.

Во-вторых, я не думаю, что работа с RMS для отдельных массивов buffer[] является абсолютно правильной. Я могу ошибаться в этом. Я думаю, что это больше похоже на скользящее среднее, где некоторые данные из начала одного буфера [] должны включать некоторые данные из конца предыдущего буфера []. Требует ли формула, что вы "вернетесь назад" или "усреднитесь по" количеству кадров? Если это так, вы захотите сохранить предыдущий буфер [] удобным для ситуаций, когда количество N охватывает два кадра. И вы будете перебирать текущий буфер [], по одному "кадру" за раз (или передавать буфер [] подпрограмме, которая фактически делает это).

Другие вопросы по тегам