2017-01-09 5 views
1

Я получаю потоки PCM через порт Ethernet. До сих пор я смог захватить пакеты и извлечь из них данные pcm_payload.Play PCM stream в Android

Как играть в эти необработанные данные PCM в android? Данные PCM представляют собой 16-битный 2-канальный, 44,1-килотонковый поток скорости.

Я оба новичок в программировании приложений для 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 - оба канала! –

+0

Хорошо. Я просто отредактировал ответ соответственно. Кроме того, play() нужно было вызывать перед записью .. и только один play() был достаточным для нескольких вызовов write(). Однако перед записью в audioTrack() мне пришлось преобразовать данные с большого конца в 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(){ 

} 

}