JLayer Mono Mp3 в декодирование PCM

В настоящее время я работаю над декодированием mp3 с помощью javalayer 1.1.

Итак, я хочу получать необработанные данные PCM от моих 44100 Гц, 16 бит, Mp3. Он отлично работает со стерео mp3, но у меня странные проблемы с моно mp3.

Вот код.

InputStream data = c.getResources().openRawResource(resId);
Bitstream bitstream = new Bitstream(data);
Decoder decoder = new Decoder();
while(thereIsData) {
  Head frameHeader = bitstream.readFrame();
  SampleBuffer buffer = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
  short[] pcmBuffer = buffer.getBuffer();

  // Do some stuff with pcm (For example creating a wav file )

  bitstream.closeFrame();
}

buffer.getChannelCount () == 1, buffer.getFrequency () == 41000

Итак ... Проблема в том. Если я создам моноканальный 16-битный волновой файл с частотой 44100 Гц и помещаю его в Audacity, чтобы увидеть волны. Звук периодически 0, например: (200 мс звук) ... (200 мс без звука) ... (200 мс звук) ... (200 мс без звука)

Это касается и данных ПКМ перед записью в .wav ... (Да уж, syso, все такое)

Таким образом, можно подумать, что там должны быть нулевые кадры или что-то в этом роде. там ... Итак, я вырезал все кадры, в которых было только 0 значений. Это приводит к несколько более коротким нулевым разрывам в файле wav. Значит, по мне, должны быть частичные нулевые кадры. Поэтому я вырезал ВСЕ нулевые значения из данных ПКМ ... И, как ни странно, это сработало. Файл звучит нормально.

Но это не может быть решением. Я до сих пор не знаю, почему есть эти ложные нулевые значения. И в mp3 мне тоже нужна тишина.

Буду признателен за каждый намек в объяснении. Спасибо


person xeed    schedule 19.12.2012    source источник
comment
Удалось ли вам решить эту проблему?   -  person ajacian81    schedule 04.03.2013
comment
Я полагаю, что параметр thereIsData является логическим? А где выставить false? Я пытаюсь сделать то же самое, но не могу заставить это работать   -  person DijkeMark    schedule 07.06.2013
comment
В данном случае это просто заполнитель для проверки наличия дополнительных данных. Я не могу вспомнить, но думаю, вы можете проверить, действителен ли следующий фрагмент, после того, как прочитаете заголовок следующего кадра. Там вы можете позвонить кому-нибудь. который определяет, является ли этот заголовок недействительным и, следовательно, это EOS.   -  person xeed    schedule 09.06.2013


Ответы (2)


Я заставил его работать, преобразовав в byte [], используя этот код:

ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
int divider = 1;
if (SAMPLE_RATE < 44100) divider *= 2;
if (CHANNELS == 1) divider *= 2;

[...]

short[] pcmBuffer = buffer.getBuffer();    
for (int i=0; i<pcm.length/divider; i++) {
    outStream.write(pcm[i] & 0xff);
    outStream.write((pcm[i] >> 8 ) & 0xff);
}

Ключевым был параметр divider, то есть 1 в стерео-44, 2 в моно-44 и 4 в моно-22. Других комбинаций пока не пробовал.

person drodsou    schedule 11.09.2013
comment
вы, сэр, спасаете жизнь - person Dexter; 26.06.2015

Хм ... Я немного запоздал с ответом .. Извините за это.

Полностью решил проблему.

JLayer делал странные вещи. Если входной mp3 - стерео, значения в pcmbuffer кодируются следующим образом: leftchannel, rightchannel, leftchannel, ... Так должно быть. Но если входной mp3 - это Mono, я получаю такое же количество сэмплов в pcmbuffer. Но это не так: monochannel, 0, monochannel, 0 Все данные находятся в первой половине pcmbuffer, а вторая половина - это все 0. Так что вам просто нужно отрезать вторую половину.

person xeed    schedule 15.03.2013
comment
вы, сэр, спасаете жизнь - person Dexter; 26.06.2015