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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章