10.AudioRecord实现“助听器”

来源:互联网 发布:剑网三天策捏脸数据 编辑:程序博客网 时间:2024/04/28 19:10

Android可以利用MediaRecorder和AudioRecord这两个工具来实现录音,MediaRecorder直接把麦克风的数据存到文件,并且能够直接进行编码(如AMR、MP3等),而AudioRecord则是读取麦克风的音频流。本文使用AudioRecord读取音频流,使用AudioTrack播放音频流,通过“边读边播放”以及增大音量的方式来实现一个简单的助听器程序。

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

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

PS:程序音量调节只是程序内部调节音量而已,要调到最大音量还需要手动设置系统音量。

程序音量调节

使用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
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?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:id="@+id/btnRecord"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="开始边录边放"
        />
    <Button
        android:id="@+id/btnStop"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="停止"
        />
    <Button
        android:id="@+id/btnExit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="退出"
        >
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="程序音量调节"
        />
    <SeekBar
        android:id="@+id/skbVolume"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        />
</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
115
116
117
118
119
120
121
122
123
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(newSeekBar.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);
            }
        }
    };
}
原创粉丝点击