2017-01-09 123 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(){ 

} 

}