频道栏目
首页 > 程序开发 > 移动开发 > Android > 正文
android AudioTrack不能播放awr
2011-08-15 11:45:21           
收藏   我要投稿

我用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" />   

点击复制链接 与好友分享!回本站首页
上一篇:Android中的Application类
下一篇:基于Android NDK的学习之旅-----JNI数据类型
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站