android AudioTrack不能播放awr – Android移動開發技術文章_手機開發 Android移動開發教學課程

我用AudioTrack播放MP3 awr都是不成功的 隻會傳出一堆的噪聲,但是播放wav是沒有問題的,因為wav就相當於原生態的pcm

 

這時候 我有兩個選擇

 

1、從3gp網站上下載awr解碼算法 用jni調用 把awr解碼成pcm

2、可以用AudioRecord來錄制pcm 並用AudioTrack來播放

 

我用的時後者

Java代碼

package com.lp; 

 

 

import java.io.BufferedInputStream; 

import java.io.BufferedOutputStream; 

import java.io.DataInputStream; 

import java.io.DataOutputStream; 

import java.io.File; 

import java.io.FileInputStream; 

import java.io.FileOutputStream; 

import java.io.IOException; 

import android.app.Activity; 

import android.media.AudioFormat; 

import android.media.AudioManager; 

import android.media.AudioRecord; 

import android.media.AudioTrack; 

import android.media.MediaRecorder; 

import android.os.AsyncTask; 

import android.os.Bundle; 

import android.os.Environment; 

import android.util.Log; 

import android.view.View; 

import android.view.View.OnClickListener; 

import android.widget.Button; 

import android.widget.TextView; 

 

public class MainActivity extends Activity implements OnClickListener{ 

     

    private TextView stateView; 

     

    private Button btnStart,btnStop,btnPlay,btnFinish; 

     

    private RecordTask recorder; 

    private PlayTask player; 

     

    private File audioFile; 

     

    private boolean isRecording=true, isPlaying=false;  

     

    private int frequence = 44100;  

    private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; 

    private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 

     

     

    public void onCreate(Bundle savedInstanceState){ 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.main_pcm); 

         

        stateView = (TextView)this.findViewById(R.id.view_state); 

        stateView.setText("準備開始"); 

        btnStart = (Button)this.findViewById(R.id.btn_start); 

        btnStop = (Button)this.findViewById(R.id.btn_stop); 

        btnPlay = (Button)this.findViewById(R.id.btn_play); 

        btnFinish = (Button)this.findViewById(R.id.btn_finish); 

        btnFinish.setText("停止播放"); 

        btnPlay.setEnabled(false); 

        btnFinish.setEnabled(false); 

        btnStart.setOnClickListener(this); 

        btnStop.setOnClickListener(this); 

        btnPlay.setOnClickListener(this); 

        btnFinish.setOnClickListener(this); 

         

//      File fpath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/11"); 

//      fpath.mkdirs(); 

        try { 

            //audioFile = File.createTempFile("test", ".pcm", fpath); 

            audioFile = new File("/mnt/sdcard/1.pcm"); 

        } catch (Exception e) { 

            // TODO Auto-generated catch block 

            e.printStackTrace(); 

        }        

    } 

     

     

    public void onClick(View v){ 

        int id = v.getId(); 

        switch(id){ 

        case R.id.btn_start: 

             

            recorder = new RecordTask(); 

            recorder.execute(); 

             

            break; 

        case R.id.btn_stop: 

            this.isRecording = false; 

            System.out.println(isRecording); 

            break; 

        case R.id.btn_play: 

             

            player = new PlayTask(); 

            player.execute(); 

            break; 

        case R.id.btn_finish: 

            this.isPlaying = false; 

            break; 

             

        } 

    } 

     

    class RecordTask extends AsyncTask<Void, Integer, Void>{ 

        @Override 

        protected Void doInBackground(Void… arg0) { 

            //isRecording = true; 

            try { 

                //開通輸出流到指定的文件

                DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(audioFile))); 

                //FileOutputStream fos = new FileOutputStream(audioFile); 

                //根據定義好的幾個配置,來獲取合適的緩沖大小

                int bufferSize = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding); 

                //實例化AudioRecord 

                AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, frequence, channelConfig, audioEncoding, bufferSize); 

                //定義緩沖

                short[] buffer = new short[bufferSize]; 

                //byte[] buffer = new byte[bufferSize]; 

                 

                //開始錄制

                record.startRecording(); 

                 

                int r = 0; //存儲錄制進度

                //定義循環,根據isRecording的值來判斷是否繼續錄制

                while(isRecording){ 

                    //從bufferSize中讀取字節,返回讀取的short個數

                    //這裡老是出現buffer overflow,不知道是什麼原因,試瞭好幾個值,都沒用,TODO:待解決

                    int bufferReadResult = record.read(buffer, 0, buffer.length); 

                    //循環將buffer中的音頻數據寫入到OutputStream中

                    for(int i=0; i<bufferReadResult; i++){ 

                        dos.writeShort(buffer[i]); 

                    } 

                     

//                  byte[] tmpBuf = new byte[bufferReadResult];   

//                    System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);  

//                    fos.write(tmpBuf, 0, bufferReadResult); 

//                    fos.flush(); 

                    publishProgress(new Integer(r)); //向UI線程報告當前進度

                    r++; //自增進度值

                } 

                //錄制結束

                record.stop(); 

                System.out.println("The File length::"+audioFile.length()); 

                dos.close(); 

                //fos.close(); 

            } catch (Exception e) { 

                // TODO: handle exception 

            } 

            return null; 

        } 

         

        //當在上面方法中調用publishProgress時,該方法觸發,該方法在UI線程中被執行

        protected void onProgressUpdate(Integer…progress){ 

            stateView.setText(progress[0].toString()); 

        } 

          

        protected void onPostExecute(Void result){ 

            btnStop.setEnabled(false); 

            btnStart.setEnabled(true); 

            btnPlay.setEnabled(true); 

            btnFinish.setEnabled(false); 

        } 

         

        protected void onPreExecute(){ 

            //stateView.setText("正在錄制"); 

            btnStart.setEnabled(false); 

            btnPlay.setEnabled(false); 

            btnFinish.setEnabled(false); 

            btnStop.setEnabled(true);        

        } 

         

    } 

     

    class PlayTask extends AsyncTask<Void, Integer, Void>{ 

        @Override 

        protected Void doInBackground(Void… arg0) { 

            isPlaying = true; 

            int bufferSize = AudioTrack.getMinBufferSize(frequence, channelConfig, audioEncoding); 

            short[] buffer = new short[bufferSize/4]; 

            //byte[] buffer = new byte[bufferSize]; 

            try { 

                //定義輸入流,將音頻寫入到AudioTrack類中,實現播放

                DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(audioFile))); 

                //FileInputStream fis = new FileInputStream(audioFile); 

                //實例AudioTrack 

                AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, frequence, channelConfig, audioEncoding, bufferSize, AudioTrack.MODE_STREAM); 

                //開始播放

                track.play(); 

                //由於AudioTrack播放的是流,所以,我們需要一邊播放一邊讀取

                while(isPlaying && dis.available()>0){ 

                    int i = 0; 

                    while(dis.available()>0 && i<buffer.length){ 

                        buffer[i] = dis.readShort(); 

                        i++; 

                    } 

                    //然後將數據寫入到AudioTrack中

                    track.write(buffer, 0, buffer.length); 

                     

                } 

                 

                //播放結束

                track.stop(); 

                dis.close(); 

            } catch (Exception e) { 

                // TODO: handle exception 

            } 

            return null; 

        } 

         

        protected void onPostExecute(Void result){ 

            btnPlay.setEnabled(true); 

            btnFinish.setEnabled(false); 

            btnStart.setEnabled(true); 

            btnStop.setEnabled(false); 

        } 

         

        protected void onPreExecute(){   

             

            //stateView.setText("正在播放"); 

            btnStart.setEnabled(false); 

            btnStop.setEnabled(false); 

            btnPlay.setEnabled(false); 

            btnFinish.setEnabled(true);          

        } 

         

    } 

 

 

對瞭 別忘瞭權限

Java代碼

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> 

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

    <uses-permission android:name="android.permission.RECORD_AUDIO" />   

發佈留言