Декодируйте 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 охватывает два кадра. И вы будете перебирать текущий буфер [], по одному "кадру" за раз (или передавать буфер [] подпрограмме, которая фактически делает это).