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

转自:http://blog.csdn.net/hellogv/article/details/6026455


      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. 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的源码如下:


  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.     };  



你可能感兴趣的:(Android,android,layout,button,buffer,encoding,float)