2017-01-09 109 views
1

我通过以太网端口获取PCM流。到目前为止,我能够捕获数据包并从中取出pcm_payload数据。在Android中播放PCM流

如何在android中播放此原始PCM数据? PCM数据是16位2通道,44.1kHZ速率流。

我既是新的android应用程序编程和音频编程。对不起,如果这是一个微不足道的问题。

回答

3

您可以使用AudioTrack播放PCM数据!

也许是这样的:

int bufsize = AudioTrack.getMinBufferSize(44100, 
      AudioFormat.CHANNEL_OUT_STEREO, 
      AudioFormat.ENCODING_PCM_16BIT); 

AudioTrack audio = new AudioTrack(AudioManager.STREAM_MUSIC, 
         44100, //sample rate 
         AudioFormat.CHANNEL_OUT_STEREO, //2 channel 
         AudioFormat.ENCODING_PCM_16BIT, // 16-bit 
         bufsize, 
         AudioTrack.MODE_STREAM); 
audio.play() 

然后调用audio.write()写您的PCM数据。

+0

CHANNEL_CONFIGURATION_STEREO似乎失去Ø日期。我已经使用了CHANNEL_OUT_STEREO。有用。可以吗? –

+0

是的,CHANNEL_CONFIGURATION_STEREO和CHANNEL_OUT_STEREO都是2频道! –

+0

好的。我刚刚编辑了相应的答案。另外,play()必须在写入之前调用..并且只有一个play()足以用于多个write()调用。但是,在写入audioTrack()之前,我必须将数据从big-endian转换为little-endian。编辑后,如果您觉得还需要编辑答案,请这样做。谢谢。 –

0

这是我的溶剂。写流文件和发挥它

public class AudioTrackPlayer { 
private String pathAudio; 
private AudioTrack audioPlayer; 
private Thread mThread; 
private int bytesread = 0, ret = 0; 
private int size; 
private FileInputStream in = null; 
private byte[] byteData = null; 
private int count = 512 * 1024; // 512 kb 
private boolean isPlay = true; 
private boolean isLooping = false; 
private static Handler mHandler; 

public AudioTrackPlayer() { 

} 

public void prepare(String pathAudio){ 
    this.pathAudio = pathAudio; 
    mHandler = new Handler(); 
} 

public void play(){ 
    stop(); 

    isPlay = true; 
    bytesread = 0; 
    ret = 0; 
    if (pathAudio == null) 
     return; 

    audioPlayer = createAudioPlayer(); 
    if (audioPlayer == null) return; 
    audioPlayer.play(); 

    mThread = new Thread(new PlayerProcess()); 
    mThread.start(); 
} 

private final Runnable mLopingRunnable = new Runnable() { 
    @Override 
    public void run() { 
     play(); 
    } 
}; 

private AudioTrack createAudioPlayer(){ 
    int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, 
      AudioFormat.ENCODING_PCM_16BIT); 
    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, 
      AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM); 
    if (audioTrack == null) { 
     Log.d("TCAudio", "audio track is not initialised "); 
     return null; 
    } 

    File file = null; 
    file = new File(pathAudio); 

    byteData = new byte[(int) count]; 
    try { 
     in = new FileInputStream(file); 

    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 

    size = (int) file.length(); 
    return audioTrack; 
} 

private class PlayerProcess implements Runnable{ 

    @Override 
    public void run() { 
     while (bytesread < size && isPlay) { 
      if (Thread.currentThread().isInterrupted()) { 
       break; 
      } 
      try { 
       ret = in.read(byteData, 0, count); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      if (ret != -1) { // Write the byte array to the track 
       audioPlayer.write(byteData,0, ret); 
       bytesread += ret; 
      } else break; 
     } 
     try { 
      in.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     if (audioPlayer!=null){ 
      if (audioPlayer.getState()!=AudioTrack.PLAYSTATE_STOPPED){ 
       audioPlayer.stop(); 
       audioPlayer.release(); 
       mThread = null; 
      } 
     } 
     if (isLooping && isPlay) mHandler.postDelayed(mLopingRunnable,100); 
    } 
} 

public void setLooping(){ 
    isLooping = !isLooping; 
} 

public void pause(){ 

} 

public void stop(){ 
    isPlay = false; 
    if (mThread != null) { 
     mThread.interrupt(); 
     mThread = null; 
    } 
    if (audioPlayer != null) { 
     audioPlayer.stop(); 
     audioPlayer.release(); 
     audioPlayer = null; 
    } 
} 

public void reset(){ 

} 

}