求解决pcm播放问题

来源:互联网 发布:python安装包怎么下载 编辑:程序博客网 时间:2024/06/05 10:57

7~LHGL`((@G{{1GD2VLVL.jpg (30.48 KB, 下载次数: 0)

工程图

工程图



使用audio来录音,使用AudioTrack来播放,发现播放出来的声音是吱吱的那种杂音。这是怎么回事呢?录音代码中采样率8000的时候播放pcm数据是吱吱的声音;但是44100的时候没有声音;怎么解决播放录的声音;



public class AudioPlayerDemoActivity extends Activity implements OnClickListener{
    /** Called when the activity is first created. */

        private TextView mTextViewState;                                // 播放状态
        
        private Button mBtnPlayButton;                                        // 播放
        
        private Button mBtnPauseButton;                                        // 暂停
        
        private Button mBtnStopButton;                                        // 停止
        
        private AudioPlayer mAudioPlayer;                                // 播放器
        
        private Handler mHandler;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initView();

        initLogic();
    }




    @Override
        protected void onDestroy() {
                // TODO Auto-generated method stub
                super.onDestroy();
                
                mAudioPlayer.release();
        }




        public void initView()
    {
            mTextViewState = (TextView) findViewById(R.id.tvPlayState);
            
            mBtnPlayButton = (Button) findViewById(R.id.buttonPlay);
            mBtnPlayButton.setOnClickListener(this);
            
            mBtnPauseButton = (Button) findViewById(R.id.buttonPause);
            mBtnPauseButton.setOnClickListener(this);
            
            mBtnStopButton = (Button) findViewById(R.id.buttonStop);
            mBtnStopButton.setOnClickListener(this);
    }

    public void initLogic()
    {
            mHandler = new Handler()
            {

                        @Override
                        public void handleMessage(Message msg) {
                                // TODO Auto-generated method stub
                                switch(msg.what)
                                {
                                case AudioPlayer.STATE_MSG_ID:
                                        showState((Integer)msg.obj);
                                        break;
                                }
                        }
                    
                    
            };
            
            mAudioPlayer = new AudioPlayer(mHandler);
            
            // 获取音频参数
            AudioParam audioParam = getAudioParam();
            mAudioPlayer.setAudioParam(audioParam);
            
            // 获取音频数据
            byte[] data = getPCMData();
            mAudioPlayer.setDataSource(data);
            
            // 音频源就绪
            mAudioPlayer.prepare();
            
            if (data == null)
            {
                    mTextViewState.setText(filePath + ":该路径下不存在文件!");
            }
    }


    @Override
        public void onClick(View view) {
                // TODO Auto-generated method stub
                switch(view.getId())
                {
                case R.id.buttonPlay:
                        play();
                        break;
                case R.id.buttonPause:
                        pause();
                        break;
                case R.id.buttonStop:
                        stop();
                        break;
                }
        }

    public void play()
    {
            mAudioPlayer.play();
    }

    public void pause()
    {
            mAudioPlayer.pause();
    }

    public void stop()
    {
            mAudioPlayer.stop();
    }


    public void showState(int state)
    {
            String showString = "";
            
            switch(state)
            {
            case PlayState.MPS_UNINIT:
                    showString = "MPS_UNINIT";
                    break;
            case PlayState.MPS_PREPARE:
                    showString = "MPS_PREPARE";
                    break;
            case PlayState.MPS_PLAYING:
                    showString = "MPS_PLAYING";
                    break;
            case PlayState.MPS_PAUSE:
                    showString = "MPS_PAUSE";
                    break;
            }
            
            showState(showString);
    }


    public void showState(String str)
    {
            mTextViewState.setText(str);
    }  
        
        
         /*
     * 获得PCM音频数据参数
     */
        public AudioParam getAudioParam()
        {
                AudioParam audioParam = new AudioParam();
            audioParam.mFrequency = 44100;
            audioParam.mChannel = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
            audioParam.mSampBit = AudioFormat.ENCODING_PCM_16BIT;
            
            return audioParam;
        }
        
        
        
        String  filePath  = Environment.getExternalStorageDirectory().getAbsolutePath() + "/testmusic.pcm";
    /*
     * 获得PCM音频数据
     */
    public byte[] getPCMData()
    {
            
            File file = new File(filePath);
            if (file == null){
                    return null;
            }
            
            FileInputStream inStream;
                try {
                        inStream = new FileInputStream(file);
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        return null;
                }
                
                byte[] data_pack = null;
            if (inStream != null){
                    long size = file.length();
                    
                    data_pack = new byte[(int) size];
                    try {
                                inStream.read(data_pack);
                        } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                return null;
                        }

            }
            
            return data_pack;
    }

}



下面这个是AudioPlaye
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
        {
                
                // 获得构建对象的最小缓冲区大小                                         一般情况 minBufferSize  会导致播出吱吱声音。
                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中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到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);
                }
                
        }        
        
        
}


···············java代码  AudioParam······················
package com.genius.demo;

public class AudioParam {

        int mFrequency;                                        // 采样率
        
        int mChannel;                                        // 声道
        
        int mSampBit;                                        // 采样精度
        
}




··············java代码 IPlayComplete ···················

package com.genius.demo;

public interface IPlayComplete {

        public void onPlayComplete();
        
}



··················java代码  PlayState·····················

package com.genius.demo;

public interface PlayState {
        
        public static final int MPS_UNINIT = 0;                                // 未就绪
        
        public static final int MPS_PREPARE = 1;                        // 准备就绪(停止)
        
        public static final int MPS_PLAYING = 2;                        // 播放中
        
        public static final int MPS_PAUSE = 3;                                // 暂停
}

原创粉丝点击