在audiotrack播放PCM数据 [英] Playing PCm data in audiotrack

查看:281
本文介绍了在audiotrack播放PCM数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我去codeD使用jLayer LIB当我试图通过发挥audiotrack是给很多的音频失真的PCM数据的MP3。

我去codeR code:

 公共静态无效德code(字符串路径,INT startMs,诠释maxMs)
              抛出IOException
              ByteArrayOutputStream outStream =新ByteArrayOutputStream(1024);              浮totalMs = 0;
              布尔寻求= TRUE;              档案文件=新的文件(路径);
              的System.out.println(数据+路径);
              的InputStream的InputStream =新的BufferedInputStream(新的FileInputStream(文件),8 * 1024);
              尝试{
                流流=新的比特流(InputStream的);
                德codeR德codeR =新德codeR();                布尔做= FALSE;
                而(!完成){
                  javazoom.jl.de coder.Header frameHeader = bitstream.readFrame();
                  如果(frameHeader == NULL){
                    做= TRUE;
                  }其他{
                    totalMs + = frameHeader.ms_per_frame();                    如果(totalMs> = startMs){
                      寻求= FALSE;
                    }                    如果(!求){
                      SampleBuffer输出=(SampleBuffer)德coder.de codeFrame(frameHeader,比特流);                      如果(output.getSampleFrequency()!= 44100
                          || output.getChannelCount()!= 2){
                       //抛出新com.mindtherobot.libs.mpg.De coderException(单或非44100 MP3不支持);
                      }                      短[] = PCM output.getBuffer();
                      字节[] BS;
                      INT索引= 0;
                      ByteBuffer的缓冲;
                      缓冲液= ByteBuffer.allocate(2 * pcm.length);                      对于(短小号:PCM){
// outStream.write(S&安培; 0xFF的);
// outStream.write((S取代;→8)及0xff的);
                        buffer.putShort(多个);                      }                      字节[] = dataaudio buffer.array();                      //返回buffer.array();
                      track.write(dataaudio,0,dataaudio.length);                    }                    如果(totalMs> =(startMs + maxMs)){
                      做= TRUE;
                    }
                  }
                  bitstream.closeFrame();
                }                //返回outStream.toByteArray();
              }赶上(BitstreamException E){
                抛出新IOException异常(比特流的错误:+ E);
              }赶上(德coderException E){
                Log.w(数据,德codeR错误,E);
                ;
              } {最后
               // IOUtils.safeClose(InputStream的);
              }
            }


解决方案

我建议你不要将您的短[]为byte [],但写你的短[]将AudioTrack即呼叫track.write (PCM,0,pcm.length),而不是track.write(dataaudio,0,dataaudio.length)。

我一直在为Android编写的音频处理器,它采用JLayer读取MP3文件,处理数据,然后输出到AudioTrack。如果我没有做任何的数据处理,而只是从JLayer发送数据到AudioTrack,它起着非常好我的Nexus7。
然而,当我做我的处理(音高换档和/或时间COM pression),我得到一个恼人的噼啪声。

奇怪的是,当我从JLayer读一帧并将其发送到AudioTrack(无处理),这听起来不错,但是当我从JLayer读两帧并将它们发送到AudioTrack(无处理),我得到的裂纹!

我已经开始做Android的(基本上运行在同一code,但AudioTrack我自己的虚拟实现其将播放我的笔记本电脑的声音或转换为WAV文件)及以外的一些调查;迄今为止的结果是非常奇怪的。

所以,如果你有进一步的进展,我很想知道你是怎么做的。

I decoded the mp3 using jLayer lib when i tried to play the pcm data through audiotrack is giving lot of audio distortion.

my decoder code:

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

解决方案

I'd suggest that you don't convert your short[] to byte[], but write your short[] to the AudioTrack i.e. call track.write(pcm, 0, pcm.length) instead of track.write(dataaudio, 0, dataaudio.length).

I have been writing an audio processor for Android which uses JLayer to read MP3 files, processes the data, then outputs to AudioTrack. If I do not do any data processing, but just send the data from JLayer to the AudioTrack, it plays really well on my Nexus7. However, when I do my processing (pitch-shift and/or time compression), I get an annoying crackle.

Strangely, when I read one frame from JLayer and send it to AudioTrack (no processing), it sounds good, but when I read two frames from JLayer and send them to AudioTrack (no processing), I get the crackle!

I've started doing some investigations outside Android (basically running the same code, but with my own implementation dummy of AudioTrack which either plays the sound on my laptop or converts to a WAV file) & the results so far are very odd.

So, if you have progressed further, I'd be interested to know how you are doing.

这篇关于在audiotrack播放PCM数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆