package com.genius.demo; import android.media.AudioManager; import android.media.AudioTrack; import android.os.Handler; import android.os.Message; import android.provider.ContactsContract.Contacts.Data; import android.util.Log; public class AudioPlayer implements IPlayComplete{ private final static String TAG = "AudioPlayer"; public final static int STATE_MSG_ID = 0x0010; private Handler mHandler; private AudioParam mAudioParam; // ��Ƶ���� private byte[] mData; // ��Ƶ���� private AudioTrack mAudioTrack; // AudioTrack���� private boolean mBReady = false; // ����Դ�Ƿ���� private PlayAudioThread mPlayAudioThread; // �����߳� public AudioPlayer(Handler handler) { mHandler = handler; } public AudioPlayer(Handler handler,AudioParam audioParam) { mHandler = handler; setAudioParam(audioParam); } /* * ������Ƶ���� */ public void setAudioParam(AudioParam audioParam) { mAudioParam = audioParam; } /* * ������ƵԴ */ public void setDataSource(byte[] data) { mData = data; } /* * ��������Դ */ public boolean prepare() { if (mData == null || mAudioParam == null) { return false; } if (mBReady == true) { return true; } try { createAudioTrack(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } mBReady = true; setPlayState(PlayState.MPS_PREPARE); return true; } /* * �ͷŲ���Դ */ public boolean release() { stop(); releaseAudioTrack(); mBReady = false; setPlayState(PlayState.MPS_UNINIT); return true; } /* * ���� */ public boolean play() { if (mBReady == false) { return false; } switch(mPlayState) { case PlayState.MPS_PREPARE: mPlayOffset = 0; setPlayState(PlayState.MPS_PLAYING); startThread(); break; case PlayState.MPS_PAUSE: setPlayState(PlayState.MPS_PLAYING); startThread(); break; } return true; } /* * ��ͣ */ public boolean pause() { if (mBReady == false) { return false; } if (mPlayState == PlayState.MPS_PLAYING) { setPlayState(PlayState.MPS_PAUSE); stopThread(); } return true; } /* * ֹͣ */ public boolean stop() { if (mBReady == false) { return false; } setPlayState(PlayState.MPS_PREPARE); stopThread(); return true; } private synchronized void setPlayState(int state) { mPlayState = state; if (mHandler != null) { Message msg = mHandler.obtainMessage(STATE_MSG_ID); msg.obj = mPlayState; msg.sendToTarget(); } } private void createAudioTrack() throws Exception { // ��ù����������С��������С int minBufSize = AudioTrack.getMinBufferSize(mAudioParam.mFrequency, mAudioParam.mChannel, mAudioParam.mSampBit); mPrimePlaySize = minBufSize * 2; Log.d(TAG, "mPrimePlaySize = " + mPrimePlaySize); // STREAM_ALARM�������� // STREAM_MUSCI��������������music�� // STREAM_RING������ // STREAM_SYSTEM��ϵͳ���� // STREAM_VOCIE_CALL���绰���� mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, mAudioParam.mFrequency, mAudioParam.mChannel, mAudioParam.mSampBit, minBufSize, AudioTrack.MODE_STREAM); // AudioTrack����MODE_STATIC��MODE_STREAM���ַ��ࡣ // STREAM����˼�����û���Ӧ�ó���ͨ��write��ʽ������һ��һ�ε�д��audiotrack�С� // �����������socket�з�������һ����Ӧ�ò��ij���ط���ȡ���ݣ�����ͨ�������õ�PCM���ݣ�Ȼ��write��audiotrack�� // ���ַ�ʽ�Ļ�������������JAVA���Native�㽻����Ч����ʧ�ϴ� // ��STATIC����˼��һ��ʼ������ʱ�򣬾Ͱ���Ƶ���ݷŵ�һ���̶���buffer��Ȼ��ֱ�Ӵ���audiotrack�� // �����Ͳ���һ�δε�write�ˡ�AudioTrack���Լ��������buffer�е����ݡ� // ���ַ��������������ڴ�ռ�ý�С����ʱҪ��ϸߵ�������˵�����á� } private void releaseAudioTrack(){ if (mAudioTrack != null){ mAudioTrack.stop(); mAudioTrack.release(); mAudioTrack = null; } } private void startThread() { if (mPlayAudioThread == null) { mThreadExitFlag = false; mPlayAudioThread = new PlayAudioThread(); mPlayAudioThread.start(); } } private void stopThread() { if (mPlayAudioThread != null) { mThreadExitFlag = true; mPlayAudioThread = null; } } private boolean mThreadExitFlag = false; // �߳��˳���־ private int mPrimePlaySize = 0; // ���Ų��ſ��С private int mPlayOffset = 0; // ��ǰ����λ�� private int mPlayState = 0; // ��ǰ����״̬ /* * ������Ƶ���߳� */ class PlayAudioThread extends Thread { @Override public void run() { // TODO Auto-generated method stub Log.d(TAG, "PlayAudioThread run mPlayOffset = " + mPlayOffset); mAudioTrack.play(); while(true) { if (mThreadExitFlag == true) { break; } try { int size = mAudioTrack.write(mData, mPlayOffset, mPrimePlaySize); mPlayOffset += mPrimePlaySize; } catch (Exception e) { // TODO: handle exception e.printStackTrace(); AudioPlayer.this.onPlayComplete(); break; } if (mPlayOffset >= mData.length) { AudioPlayer.this.onPlayComplete(); break; } } mAudioTrack.stop(); Log.d(TAG, "PlayAudioThread complete..."); } } @Override public void onPlayComplete() { // TODO Auto-generated method stub mPlayAudioThread = null; if (mPlayState != PlayState.MPS_PAUSE) { setPlayState(PlayState.MPS_PREPARE); } } }