1
我通過以太網端口獲取PCM流。到目前爲止,我能夠捕獲數據包並從中取出pcm_payload數據。在Android中播放PCM流
如何在android中播放此原始PCM數據? PCM數據是16位2通道,44.1kHZ速率流。
我既是新的android應用程序編程和音頻編程。對不起,如果這是一個微不足道的問題。
我通過以太網端口獲取PCM流。到目前爲止,我能夠捕獲數據包並從中取出pcm_payload數據。在Android中播放PCM流
如何在android中播放此原始PCM數據? PCM數據是16位2通道,44.1kHZ速率流。
我既是新的android應用程序編程和音頻編程。對不起,如果這是一個微不足道的問題。
您可以使用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數據。
這是我的溶劑。寫流文件和發揮它
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(){
}
}
CHANNEL_CONFIGURATION_STEREO似乎失去Ø日期。我已經使用了CHANNEL_OUT_STEREO。有用。可以嗎? –
是的,CHANNEL_CONFIGURATION_STEREO和CHANNEL_OUT_STEREO都是2頻道! –
好的。我剛剛編輯了相應的答案。另外,play()必須在寫入之前調用..並且只有一個play()足以用於多個write()調用。但是,在寫入audioTrack()之前,我必須將數據從big-endian轉換爲little-endian。編輯後,如果您覺得還需要編輯答案,請這樣做。謝謝。 –