Android提高第十篇之AudioRecord实现"助听器"[转]

来源:互联网 发布:淘宝达人发帖挣钱 编辑:程序博客网 时间:2024/04/28 23:56

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

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

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

 

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

 

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

 

Xml代码  收藏代码
  1. <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>   

 

 

main.xml的源码如下:

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>    
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     android:orientation="vertical" android:layout_width="fill_parent"    
  4.     android:layout_height="fill_parent">    
  5.     
  6.     <Button android:layout_height="wrap_content" android:id="@+id/btnRecord"    
  7.         android:layout_width="fill_parent" android:text="开始边录边放"></Button>    
  8.     <Button android:layout_height="wrap_content"    
  9.         android:layout_width="fill_parent" android:text="停止" android:id="@+id/btnStop"></Button>    
  10.     <Button android:layout_height="wrap_content" android:id="@+id/btnExit"    
  11.         android:layout_width="fill_parent" android:text="退出"></Button>    
  12.     <TextView android:id="@+id/TextView01" android:layout_height="wrap_content"    
  13.         android:text="程序音量调节" android:layout_width="fill_parent"></TextView>    
  14.     <SeekBar android:layout_height="wrap_content" android:id="@+id/skbVolume"    
  15.         android:layout_width="fill_parent"></SeekBar>    
  16.     
  17. </LinearLayout>   

 

testRecord.java的源码如下:

 

Java代码  收藏代码
  1. package com.testRecord;    
  2.     
  3. import android.app.Activity;    
  4. import android.media.AudioFormat;    
  5. import android.media.AudioManager;    
  6. import android.media.AudioRecord;    
  7. import android.media.AudioTrack;    
  8. import android.media.MediaRecorder;    
  9. import android.os.Bundle;    
  10. import android.view.View;    
  11. import android.widget.Button;    
  12. import android.widget.SeekBar;    
  13. import android.widget.Toast;    
  14.     
  15. public class testRecord extends Activity {    
  16.     /** Called when the activity is first created. */    
  17.     Button btnRecord, btnStop, btnExit;    
  18.     SeekBar skbVolume;//调节音量    
  19.     boolean isRecording = false;//是否录放的标记    
  20.     static final int frequency = 44100;    
  21.     static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;    
  22.     static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;    
  23.     int recBufSize,playBufSize;    
  24.     AudioRecord audioRecord;    
  25.     AudioTrack audioTrack;    
  26.     
  27.     @Override    
  28.     public void onCreate(Bundle savedInstanceState) {    
  29.         super.onCreate(savedInstanceState);    
  30.         setContentView(R.layout.main);    
  31.         setTitle("助听器");    
  32.         recBufSize = AudioRecord.getMinBufferSize(frequency,    
  33.                 channelConfiguration, audioEncoding);    
  34.     
  35.         playBufSize=AudioTrack.getMinBufferSize(frequency,    
  36.                 channelConfiguration, audioEncoding);    
  37.         // -----------------------------------------    
  38.         audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,    
  39.                 channelConfiguration, audioEncoding, recBufSize);    
  40.     
  41.         audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,    
  42.                 channelConfiguration, audioEncoding,    
  43.                 playBufSize, AudioTrack.MODE_STREAM);    
  44.         //------------------------------------------    
  45.         btnRecord = (Button) this.findViewById(R.id.btnRecord);    
  46.         btnRecord.setOnClickListener(new ClickEvent());    
  47.         btnStop = (Button) this.findViewById(R.id.btnStop);    
  48.         btnStop.setOnClickListener(new ClickEvent());    
  49.         btnExit = (Button) this.findViewById(R.id.btnExit);    
  50.         btnExit.setOnClickListener(new ClickEvent());    
  51.         skbVolume=(SeekBar)this.findViewById(R.id.skbVolume);    
  52.         skbVolume.setMax(100);//音量调节的极限    
  53.         skbVolume.setProgress(70);//设置seekbar的位置值    
  54.         audioTrack.setStereoVolume(0.7f, 0.7f);//设置当前音量大小    
  55.         skbVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {    
  56.                 
  57.             @Override    
  58.             public void onStopTrackingTouch(SeekBar seekBar) {    
  59.                 float vol=(float)(seekBar.getProgress())/(float)(seekBar.getMax());    
  60.                 audioTrack.setStereoVolume(vol, vol);//设置音量    
  61.             }    
  62.                 
  63.             @Override    
  64.             public void onStartTrackingTouch(SeekBar seekBar) {    
  65.                 // TODO Auto-generated method stub    
  66.             }    
  67.                 
  68.             @Override    
  69.             public void onProgressChanged(SeekBar seekBar, int progress,    
  70.                     boolean fromUser) {    
  71.                 // TODO Auto-generated method stub    
  72.             }    
  73.         });    
  74.     }    
  75.     
  76.     @Override    
  77.     protected void onDestroy() {    
  78.         super.onDestroy();    
  79.         android.os.Process.killProcess(android.os.Process.myPid());    
  80.     }    
  81.     
  82.     class ClickEvent implements View.OnClickListener {    
  83.     
  84.         @Override    
  85.         public void onClick(View v) {    
  86.             if (v == btnRecord) {    
  87.                 isRecording = true;    
  88.                 new RecordPlayThread().start();// 开一条线程边录边放    
  89.             } else if (v == btnStop) {    
  90.                 isRecording = false;    
  91.             } else if (v == btnExit) {    
  92.                 isRecording = false;    
  93.                 testRecord.this.finish();    
  94.             }    
  95.         }    
  96.     }    
  97.     
  98.     class RecordPlayThread extends Thread {    
  99.         public void run() {    
  100.             try {    
  101.                 byte[] buffer = new byte[recBufSize];    
  102.                 audioRecord.startRecording();//开始录制    
  103.                 audioTrack.play();//开始播放    
  104.                     
  105.                 while (isRecording) {    
  106.                     //从MIC保存数据到缓冲区    
  107.                     int bufferReadResult = audioRecord.read(buffer, 0,    
  108.                             recBufSize);    
  109.     
  110.                     byte[] tmpBuf = new byte[bufferReadResult];    
  111.                     System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);    
  112.                     //写入数据即播放    
  113.                     audioTrack.write(tmpBuf, 0, tmpBuf.length);    
  114.                 }    
  115.                 audioTrack.stop();    
  116.                 audioRecord.stop();    
  117.             } catch (Throwable t) {    
  118.                 Toast.makeText(testRecord.this, t.getMessage(), 1000);    
  119.             }    
  120.         }    
  121.     };    
  122. }  
原创粉丝点击