Android提高之AudioRecord实现助听器的方法
程序员文章站
2022-05-16 12:28:49
通常来说,在进行android项目开发的时候可以通过mediarecorder和audiorecord这两个工具来实现录音的功能,mediarecorder直接把麦克风的数...
通常来说,在进行android项目开发的时候可以通过mediarecorder和audiorecord这两个工具来实现录音的功能,mediarecorder直接把麦克风的数据存到文件,并且能够直接进行编码(如amr,mp3等),而audiorecord则是读取麦克风的音频流。本文使用audiorecord读取音频流,使用audiotrack播放音频流,通过“边读边播放”以及增大音量的方式来实现一个简单的助听器程序。
此处需要注意:由于目前的android模拟器还不支持audiorecord,因此本程序需要编译之后放到真机运行。
先贴出本文程序运行截图:
另外还要注意:在本程序音量调节只是程序内部调节音量而已,要调到最大音量还需要手动设置系统音量。
使用audiorecord必须要申请许可,在androidmanifest.xml里面添加这句:
<uses-permission android:name="android.permission.record_audio"></uses-permission>
main.xml的源码如下:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <button android:layout_height="wrap_content" android:id="@+id/btnrecord" android:layout_width="fill_parent" android:text="开始边录边放"></button> <button android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="停止" android:id="@+id/btnstop"></button> <button android:layout_height="wrap_content" android:id="@+id/btnexit" android:layout_width="fill_parent" android:text="退出"></button> <textview android:id="@+id/textview01" android:layout_height="wrap_content" android:text="程序音量调节" android:layout_width="fill_parent"></textview> <seekbar android:layout_height="wrap_content" android:id="@+id/skbvolume" android:layout_width="fill_parent"></seekbar> </linearlayout>
testrecord.java的源码如下:
package com.testrecord; 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.bundle; import android.view.view; import android.widget.button; import android.widget.seekbar; import android.widget.toast; public class testrecord extends activity { /** called when the activity is first created. */ button btnrecord, btnstop, btnexit; seekbar skbvolume;//调节音量 boolean isrecording = false;//是否录放的标记 static final int frequency = 44100; static final int channelconfiguration = audioformat.channel_configuration_mono; static final int audioencoding = audioformat.encoding_pcm_16bit; int recbufsize,playbufsize; audiorecord audiorecord; audiotrack audiotrack; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); settitle("助听器"); recbufsize = audiorecord.getminbuffersize(frequency, channelconfiguration, audioencoding); playbufsize=audiotrack.getminbuffersize(frequency, channelconfiguration, audioencoding); // ----------------------------------------- audiorecord = new audiorecord(mediarecorder.audiosource.mic, frequency, channelconfiguration, audioencoding, recbufsize); audiotrack = new audiotrack(audiomanager.stream_music, frequency, channelconfiguration, audioencoding, playbufsize, audiotrack.mode_stream); //------------------------------------------ btnrecord = (button) this.findviewbyid(r.id.btnrecord); btnrecord.setonclicklistener(new clickevent()); btnstop = (button) this.findviewbyid(r.id.btnstop); btnstop.setonclicklistener(new clickevent()); btnexit = (button) this.findviewbyid(r.id.btnexit); btnexit.setonclicklistener(new clickevent()); skbvolume=(seekbar)this.findviewbyid(r.id.skbvolume); skbvolume.setmax(100);//音量调节的极限 skbvolume.setprogress(70);//设置seekbar的位置值 audiotrack.setstereovolume(0.7f, 0.7f);//设置当前音量大小 skbvolume.setonseekbarchangelistener(new seekbar.onseekbarchangelistener() { @override public void onstoptrackingtouch(seekbar seekbar) { float vol=(float)(seekbar.getprogress())/(float)(seekbar.getmax()); audiotrack.setstereovolume(vol, vol);//设置音量 } @override public void onstarttrackingtouch(seekbar seekbar) { // todo auto-generated method stub } @override public void onprogresschanged(seekbar seekbar, int progress, boolean fromuser) { // todo auto-generated method stub } }); } @override protected void ondestroy() { super.ondestroy(); android.os.process.killprocess(android.os.process.mypid()); } class clickevent implements view.onclicklistener { @override public void onclick(view v) { if (v == btnrecord) { isrecording = true; new recordplaythread().start();// 开一条线程边录边放 } else if (v == btnstop) { isrecording = false; } else if (v == btnexit) { isrecording = false; testrecord.this.finish(); } } } class recordplaythread extends thread { public void run() { try { byte[] buffer = new byte[recbufsize]; audiorecord.startrecording();//开始录制 audiotrack.play();//开始播放 while (isrecording) { //从mic保存数据到缓冲区 int bufferreadresult = audiorecord.read(buffer, 0, recbufsize); byte[] tmpbuf = new byte[bufferreadresult]; system.arraycopy(buffer, 0, tmpbuf, 0, bufferreadresult); //写入数据即播放 audiotrack.write(tmpbuf, 0, tmpbuf.length); } audiotrack.stop(); audiorecord.stop(); } catch (throwable t) { toast.maketext(testrecord.this, t.getmessage(), 1000); } } }; }
希望本文所述实例对大家的android项目开发有一定的借鉴价值。