本文來自http://blog.csdn.net/hellogv/ ,引用必須註明出處!
Android可以通過MediaRecorder和AudioRecord這兩個工具來實現錄音,MediaRecorder直接把麥克風的資料存到檔案,並且能夠直接進行編碼(如AMR,MP3等),而AudioRecord則是讀取麥克風的音頻流。本文使用AudioRecord讀取音頻流,使用AudioTrack播放音頻流,通過“邊讀邊播放”以及增大音量的方式來實現一個簡單的助聽器程式。
PS:由於目前的Android模擬器還不支援AudioRecord,因此本程式需要編譯之後放到真機運行。
先貼出本文程式運行:
PS:程式音量大小只是程式內部調節音量而已,要調到最大音量還需要手動設定系統音量。
使用AudioRecord必須要申請許可,在AndroidManifest.xml裡面添加這句:
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
main.xml的源碼如下:
<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br />android:orientation="vertical" android:layout_width="fill_parent"<br />android:layout_height="fill_parent"></p><p><Button android:layout_height="wrap_content" android:id="@+id/btnRecord"<br />android:layout_width="fill_parent" android:text="開始邊錄邊放"></Button><br /><Button android:layout_height="wrap_content"<br />android:layout_width="fill_parent" android:text="停止" android:id="@+id/btnStop"></Button><br /><Button android:layout_height="wrap_content" android:id="@+id/btnExit"<br />android:layout_width="fill_parent" android:text="退出"></Button><br /><TextView android:id="@+id/TextView01" android:layout_height="wrap_content"<br />android:text="程式音量大小" android:layout_width="fill_parent"></TextView><br /><SeekBar android:layout_height="wrap_content" android:id="@+id/skbVolume"<br />android:layout_width="fill_parent"></SeekBar></p><p></LinearLayout><br />
testRecord.java的源碼如下:
package com.testRecord;</p><p>import android.app.Activity;<br />import android.media.AudioFormat;<br />import android.media.AudioManager;<br />import android.media.AudioRecord;<br />import android.media.AudioTrack;<br />import android.media.MediaRecorder;<br />import android.os.Bundle;<br />import android.view.View;<br />import android.widget.Button;<br />import android.widget.SeekBar;<br />import android.widget.Toast;</p><p>public class testRecord extends Activity {<br />/** Called when the activity is first created. */<br />Button btnRecord, btnStop, btnExit;<br />SeekBar skbVolume;//調節音量<br />boolean isRecording = false;//是否錄放的標記<br />static final int frequency = 44100;<br />static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;<br />static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;<br />int recBufSize,playBufSize;<br />AudioRecord audioRecord;<br />AudioTrack audioTrack;</p><p>@Override<br />public void onCreate(Bundle savedInstanceState) {<br />super.onCreate(savedInstanceState);<br />setContentView(R.layout.main);<br />setTitle("助聽器");<br />recBufSize = AudioRecord.getMinBufferSize(frequency,<br />channelConfiguration, audioEncoding);</p><p>playBufSize=AudioTrack.getMinBufferSize(frequency,<br />channelConfiguration, audioEncoding);<br />// -----------------------------------------<br />audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,<br />channelConfiguration, audioEncoding, recBufSize);</p><p>audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,<br />channelConfiguration, audioEncoding,<br />playBufSize, AudioTrack.MODE_STREAM);<br />//------------------------------------------<br />btnRecord = (Button) this.findViewById(R.id.btnRecord);<br />btnRecord.setOnClickListener(new ClickEvent());<br />btnStop = (Button) this.findViewById(R.id.btnStop);<br />btnStop.setOnClickListener(new ClickEvent());<br />btnExit = (Button) this.findViewById(R.id.btnExit);<br />btnExit.setOnClickListener(new ClickEvent());<br />skbVolume=(SeekBar)this.findViewById(R.id.skbVolume);<br />skbVolume.setMax(100);//音量大小的極限<br />skbVolume.setProgress(70);//設定seekbar的位置值<br />audioTrack.setStereoVolume(0.7f, 0.7f);//設定當前音量大小<br />skbVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {</p><p>@Override<br />public void onStopTrackingTouch(SeekBar seekBar) {<br />float vol=(float)(seekBar.getProgress())/(float)(seekBar.getMax());<br />audioTrack.setStereoVolume(vol, vol);//設定音量<br />}</p><p>@Override<br />public void onStartTrackingTouch(SeekBar seekBar) {<br />// TODO Auto-generated method stub<br />}</p><p>@Override<br />public void onProgressChanged(SeekBar seekBar, int progress,<br />boolean fromUser) {<br />// TODO Auto-generated method stub<br />}<br />});<br />}</p><p>@Override<br />protected void onDestroy() {<br />super.onDestroy();<br />android.os.Process.killProcess(android.os.Process.myPid());<br />}</p><p>class ClickEvent implements View.OnClickListener {</p><p>@Override<br />public void onClick(View v) {<br />if (v == btnRecord) {<br />isRecording = true;<br />new RecordPlayThread().start();// 開一條線程邊錄邊放<br />} else if (v == btnStop) {<br />isRecording = false;<br />} else if (v == btnExit) {<br />isRecording = false;<br />testRecord.this.finish();<br />}<br />}<br />}</p><p>class RecordPlayThread extends Thread {<br />public void run() {<br />try {<br />byte[] buffer = new byte[recBufSize];<br />audioRecord.startRecording();//開始錄製<br />audioTrack.play();//開始播放</p><p>while (isRecording) {<br />//從MIC儲存資料到緩衝區<br />int bufferReadResult = audioRecord.read(buffer, 0,<br />recBufSize);</p><p>byte[] tmpBuf = new byte[bufferReadResult];<br />System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);<br />//寫入資料即播放<br />audioTrack.write(tmpBuf, 0, tmpBuf.length);<br />}<br />audioTrack.stop();<br />audioRecord.stop();<br />} catch (Throwable t) {<br />Toast.makeText(testRecord.this, t.getMessage(), 1000);<br />}<br />}<br />};<br />}