【问题标题】:Playing PCm data in audiotrack在音轨中播放 PCm 数据
【发布时间】:2013-10-14 13:39:40
【问题描述】:

当我尝试通过音轨播放 pcm 数据时,我使用 jLayer lib 解码了 mp3,导致音频失真。

我的解码器代码:

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);     
              }
            }

【问题讨论】:

  • 你为什么不用MediaPlayer?它会自动解码您的音频文件并为您播放。
  • 感谢您的回复,其实我想将数据流式传输到其他设备...
  • 我明白了……也许你应该试试原生 MP3 解码器库。它会比用 Java 编写的解码器更快,也许您还可以摆脱音频失真问题。

标签: android android-mediaplayer jlayer


【解决方案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 文件)& 到目前为止的结果非常奇怪.

所以,如果你有进一步的进步,我很想知道你的表现如何。

【讨论】:

    猜你喜欢
    • 2013-10-02
    • 2018-09-25
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2011-01-16
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多