Android提高之AudioRecord实现助听器的方法

时间:2022-09-20 15:04:19

通常来说,在进行android项目开发的时候可以通过mediarecorder和audiorecord这两个工具来实现录音的功能,mediarecorder直接把麦克风的数据存到文件,并且能够直接进行编码(如amr,mp3等),而audiorecord则是读取麦克风的音频流。本文使用audiorecord读取音频流,使用audiotrack播放音频流,通过“边读边播放”以及增大音量的方式来实现一个简单的助听器程序。

此处需要注意:由于目前的android模拟器还不支持audiorecord,因此本程序需要编译之后放到真机运行。

先贴出本文程序运行截图:

另外还要注意:在本程序音量调节只是程序内部调节音量而已,要调到最大音量还需要手动设置系统音量。

Android提高之AudioRecord实现助听器的方法

使用audiorecord必须要申请许可,在androidmanifest.xml里面添加这句:

?
1
<uses-permission android:name="android.permission.record_audio"></uses-permission>

main.xml的源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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的源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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项目开发有一定的借鉴价值。