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

本文来自http://blog.csdn.net/hellogv/,引用必须注明出处!

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

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

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

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

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

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

  1. <uses-permissionandroid:name="android.permission.RECORD_AUDIO"></uses-permission>

main.xml的源码如下:

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

testRecord.java的源码如下:

  1. packagecom.testRecord;
  2. importandroid.app.Activity;
  3. importandroid.media.AudioFormat;
  4. importandroid.media.AudioManager;
  5. importandroid.media.AudioRecord;
  6. importandroid.media.AudioTrack;
  7. importandroid.media.MediaRecorder;
  8. importandroid.os.Bundle;
  9. importandroid.view.View;
  10. importandroid.widget.Button;
  11. importandroid.widget.SeekBar;
  12. importandroid.widget.Toast;
  13. publicclasstestRecordextendsActivity{
  14. /**Calledwhentheactivityisfirstcreated.*/
  15. ButtonbtnRecord,btnStop,btnExit;
  16. SeekBarskbVolume;//调节音量
  17. booleanisRecording=false;//是否录放的标记
  18. staticfinalintfrequency=44100;
  19. staticfinalintchannelConfiguration=AudioFormat.CHANNEL_CONFIGURATION_MONO;
  20. staticfinalintaudioEncoding=AudioFormat.ENCODING_PCM_16BIT;
  21. intrecBufSize,playBufSize;
  22. AudioRecordaudioRecord;
  23. AudioTrackaudioTrack;
  24. @Override
  25. publicvoidonCreate(BundlesavedInstanceState){
  26. super.onCreate(savedInstanceState);
  27. setContentView(R.layout.main);
  28. setTitle("助听器");
  29. recBufSize=AudioRecord.getMinBufferSize(frequency,
  30. channelConfiguration,audioEncoding);
  31. playBufSize=AudioTrack.getMinBufferSize(frequency,
  32. channelConfiguration,audioEncoding);
  33. //-----------------------------------------
  34. audioRecord=newAudioRecord(MediaRecorder.AudioSource.MIC,frequency,
  35. channelConfiguration,audioEncoding,recBufSize);
  36. audioTrack=newAudioTrack(AudioManager.STREAM_MUSIC,frequency,
  37. channelConfiguration,audioEncoding,
  38. playBufSize,AudioTrack.MODE_STREAM);
  39. //------------------------------------------
  40. btnRecord=(Button)this.findViewById(R.id.btnRecord);
  41. btnRecord.setOnClickListener(newClickEvent());
  42. btnStop=(Button)this.findViewById(R.id.btnStop);
  43. btnStop.setOnClickListener(newClickEvent());
  44. btnExit=(Button)this.findViewById(R.id.btnExit);
  45. btnExit.setOnClickListener(newClickEvent());
  46. skbVolume=(SeekBar)this.findViewById(R.id.skbVolume);
  47. skbVolume.setMax(100);//音量调节的极限
  48. skbVolume.setProgress(70);//设置seekbar的位置值
  49. audioTrack.setStereoVolume(0.7f,0.7f);//设置当前音量大小
  50. skbVolume.setOnSeekBarChangeListener(newSeekBar.OnSeekBarChangeListener(){
  51. @Override
  52. publicvoidonStopTrackingTouch(SeekBarseekBar){
  53. floatvol=(float)(seekBar.getProgress())/(float)(seekBar.getMax());
  54. audioTrack.setStereoVolume(vol,vol);//设置音量
  55. }
  56. @Override
  57. publicvoidonStartTrackingTouch(SeekBarseekBar){
  58. //TODOAuto-generatedmethodstub
  59. }
  60. @Override
  61. publicvoidonProgressChanged(SeekBarseekBar,intprogress,
  62. booleanfromUser){
  63. //TODOAuto-generatedmethodstub
  64. }
  65. });
  66. }
  67. @Override
  68. protectedvoidonDestroy(){
  69. super.onDestroy();
  70. android.os.Process.killProcess(android.os.Process.myPid());
  71. }
  72. classClickEventimplementsView.OnClickListener{
  73. @Override
  74. publicvoidonClick(Viewv){
  75. if(v==btnRecord){
  76. isRecording=true;
  77. newRecordPlayThread().start();//开一条线程边录边放
  78. }elseif(v==btnStop){
  79. isRecording=false;
  80. }elseif(v==btnExit){
  81. isRecording=false;
  82. testRecord.this.finish();
  83. }
  84. }
  85. }
  86. classRecordPlayThreadextendsThread{
  87. publicvoidrun(){
  88. try{
  89. byte[]buffer=newbyte[recBufSize];
  90. audioRecord.startRecording();//开始录制
  91. audioTrack.play();//开始播放
  92. while(isRecording){
  93. //从MIC保存数据到缓冲区
  94. intbufferReadResult=audioRecord.read(buffer,0,
  95. recBufSize);
  96. byte[]tmpBuf=newbyte[bufferReadResult];
  97. System.arraycopy(buffer,0,tmpBuf,0,bufferReadResult);
  98. //写入数据即播放
  99. audioTrack.write(tmpBuf,0,tmpBuf.length);
  100. }
  101. audioTrack.stop();
  102. audioRecord.stop();
  103. }catch(Throwablet){
  104. Toast.makeText(testRecord.this,t.getMessage(),1000);
  105. }
  106. }
  107. };
  108. }

你可能感兴趣的:(android)