2011.08.12(4)——— android audiotrack 不能播放awr
[url=http://blog.sina.com.cn/s/blog_7cb539590100qkcr.html]http://blog.sina.com.cn/s/blog_7cb539590100qkcr.html[/url]
[url=http://blog.youkuaiyun.com/chenjie19891104/article/details/6333553]http://blog.youkuaiyun.com/chenjie19891104/article/details/6333553[/url]
[url=http://blog.youkuaiyun.com/hellogv/article/details/6026455]http://blog.youkuaiyun.com/hellogv/article/details/6026455[/url]
我用audiotrack播放mp3 awr都是不成功的 只会传出一堆的噪声,但是播放wav是没有问题的,因为wav就相当于原生态的pcm
这时候 我有两个选择
1、从3gp网站上下载awr解码算法 用jni调用 把awr解码成pcm
2、可以用audiorecord来录制pcm 并用audiotrack来播放
我用的时后者
对了 别忘了权限
[url=http://blog.sina.com.cn/s/blog_7cb539590100qkcr.html]http://blog.sina.com.cn/s/blog_7cb539590100qkcr.html[/url]
[url=http://blog.youkuaiyun.com/chenjie19891104/article/details/6333553]http://blog.youkuaiyun.com/chenjie19891104/article/details/6333553[/url]
[url=http://blog.youkuaiyun.com/hellogv/article/details/6026455]http://blog.youkuaiyun.com/hellogv/article/details/6026455[/url]
我用audiotrack播放mp3 awr都是不成功的 只会传出一堆的噪声,但是播放wav是没有问题的,因为wav就相当于原生态的pcm
这时候 我有两个选择
1、从3gp网站上下载awr解码算法 用jni调用 把awr解码成pcm
2、可以用audiorecord来录制pcm 并用audiotrack来播放
我用的时后者
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); } }}
对了 别忘了权限
<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" />