Воспроизведение данных PCM в аудиодорожке

Я декодировал mp3 с помощью jLayer lib, когда я пытался воспроизвести данные PCM через аудиодорожку, что дает много искажений звука.

мой код декодера:

public static void decode(String path, int startMs, int maxMs) 
              throws IOException {
              ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);

              float totalMs = 0;
              boolean seeking = true;

              File file = new File(path);
              System.out.println("the data "+path);
              InputStream inputStream = new BufferedInputStream(new FileInputStream(file), 8 * 1024);
              try {
                Bitstream bitstream = new Bitstream(inputStream);
                Decoder decoder = new Decoder();

                boolean done = false;  
                while (! done) {
                  javazoom.jl.decoder.Header frameHeader = bitstream.readFrame();
                  if (frameHeader == null) {
                    done = true;      
                  } else {
                    totalMs += frameHeader.ms_per_frame();

                    if (totalMs >= startMs) {   
                      seeking = false;
                    }  

                    if (! seeking) {
                      SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);

                      if (output.getSampleFrequency() != 44100
                          || output.getChannelCount() != 2) {
                       // throw new com.mindtherobot.libs.mpg.DecoderException("mono or non-44100 MP3 not supported");
                      }

                      short[] pcm = output.getBuffer();
                      byte[] bs;
                      int index=0;
                      ByteBuffer buffer;
                      buffer = ByteBuffer.allocate(2*pcm.length);

                      for (short s : pcm) {     
//                      outStream.write(s & 0xff);      
//                      outStream.write((s >> 8 ) & 0xff);   


                        buffer.putShort(s);



                      }      

                      byte[] dataaudio = buffer.array();

                      //return buffer.array();






                      track.write(dataaudio, 0, dataaudio.length);

                    }   

                    if (totalMs >= (startMs + maxMs)) {
                      done = true;
                    }
                  }
                  bitstream.closeFrame();
                }

                //return outStream.toByteArray();
              } catch (BitstreamException e) {
                throw new IOException("Bitstream error: " + e);
              } catch (DecoderException e) {  
                Log.w("data", "Decoder error", e);
                ;
              } finally {
               // IOUtils.safeClose(inputStream);     
              }
            }

person user2705259    schedule 14.10.2013    source источник
comment
Почему вы не используете MediaPlayer? Он автоматически декодирует ваш аудиофайл и воспроизводит его для вас.   -  person tiguchi    schedule 14.10.2013
comment
Спасибо за ваш ответ, на самом деле я хочу передать данные на другое устройство...   -  person user2705259    schedule 14.10.2013
comment
Ясно... может быть, вам стоит попробовать нативную библиотеку декодера MP3. Это будет быстрее, чем декодер, написанный на Java, и, возможно, вы также избавитесь от проблемы искажения звука.   -  person tiguchi    schedule 14.10.2013


Ответы (1)


Я бы посоветовал вам не преобразовывать ваш short[] в byte[], а записывать ваш short[] в AudioTrack, т.е. вызывать track.write(pcm, 0, pcm.length) вместо track.write(dataaudio, 0, dataaudio.length).

Я пишу аудиопроцессор для Android, который использует JLayer для чтения файлов MP3, обрабатывает данные, а затем выводит их в AudioTrack. Если я не выполняю никакой обработки данных, а просто отправляю данные из JLayer в AudioTrack, они очень хорошо воспроизводятся на моем Nexus7. Однако, когда я выполняю свою обработку (сдвиг высоты тона и/или сжатие времени), я получаю раздражающее потрескивание.

Странно, когда я читаю один кадр из JLayer и отправляю его в AudioTrack (без обработки), он звучит хорошо, но когда я читаю два кадра из JLayer и отправляю их в AudioTrack (без обработки), я получаю треск!

Я начал проводить некоторые исследования за пределами Android (в основном запуская тот же код, но с моей собственной реализацией AudioTrack, которая либо воспроизводит звук на моем ноутбуке, либо конвертирует в файл WAV), и результаты пока очень странные.

Итак, если вы продвинулись дальше, мне было бы интересно узнать, как у вас дела.

person user3050587    schedule 29.11.2013