cerberspace 发表于 2012-12-19 23:10:53

Audio的系统结构

<div id="cnblogs_post_body">  摘要:Audio系统负责Android中的PCM数据的录制输入流和播放输出流的传输和控制,以及音频设备的管理和设置。这里主要介绍播放和录制环节在各个层次的内容,整个结构层次分明,包括了java接口层,JNI层,本地框架层,audio服务层,硬件抽象层等5层。它的结构图如下
http://images.cnblogs.com/cnblogs_com/cerberspace/416181/r_%e5%9b%be1-1.png                                                       图1-1 Audio系统结构
  一、java接口层
    AudioManager:音频管理对外的接口,提供了音量和ringtone模式的管理,由getSystemService(Context.AUDIO_SERVICE)返回。
    Audioservice:是一个非常重要的java层的系统服务,所有的用户发起的调用都是由它往底层转发的。
    AudioSystem:提供管理native接口,只时提供在media包的AudioService内部使用,不对用户直接提供接口。
    AudioTrack:提供用户从java层直接输出pcm数据的接口write函数,以及部分播放控制函数。
    AudioRecord:提供用户在java层直接从外部获取pcm数据的接口read函数。
    下面贴一段边录边播放的例子代码说明这些函数的使用
<div class="cnblogs_code" >http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gifhttp://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gifView Code <div id="cnblogs_code_open_5d50daaa-a516-4a74-9095-b5a3a6859ac7" class="cnblogs_code_hide">1 package test.Record;2   3 import java.io.BufferedInputStream;4 import java.io.File;5 import java.io.FileInputStream;6 import java.io.FileOutputStream;7 import java.io.InputStream;8 import java.io.OutputStream;9 10 import android.app.Activity; 11 import android.content.Intent; 12 import android.media.AudioFormat; 13 import android.media.AudioManager; 14 import android.media.AudioRecord; 15 import android.media.AudioTrack; 16 import android.media.MediaRecorder; 17 import android.os.Bundle; 18 import android.util.Log; 19 import android.view.View; 20 import android.widget.Button; 21 import android.widget.SeekBar; 22 import android.widget.Toast; 23    24 public class testRecord extends Activity { 25   /** Called when the activity is first created. */ 26     Button btnRecord, btnStop, btnExit; 27   SeekBar skbVolume;//调节音量 28   boolean isRecording = false;//是否录放的标记 29   static final int frequency = 44100; 30   static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; 31   static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 32   int recBufSize,playBufSize; 33     AudioRecord audioRecord; 34     AudioTrack audioTrack; 35    36     @Override 37   public void onCreate(Bundle savedInstanceState) { 38         super.onCreate(savedInstanceState); 39       setContentView(R.layout.main); 40         setTitle("助听器"); 41       42         //------------------------------------------ 43         btnRecord = (Button) this.findViewById(R.id.btnRecord); 44         btnRecord.setOnClickListener(new ClickEvent()); 45         btnStop = (Button) this.findViewById(R.id.btnStop); 46         btnStop.setOnClickListener(new ClickEvent()); 47         btnExit = (Button) this.findViewById(R.id.btnExit); 48         btnExit.setOnClickListener(new ClickEvent()); 49         skbVolume=(SeekBar)this.findViewById(R.id.skbVolume); 50         skbVolume.setMax(100);//音量调节的极限 51         skbVolume.setProgress(100);//设置seekbar的位置值 52         //audioTrack.setStereoVolume(1.0f, 1.0f);//设置当前音量大小 53         skbVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 54                55                56             public void onStopTrackingTouch(SeekBar seekBar) { 57               float vol=(float)(seekBar.getProgress())/(float)(seekBar.getMax()); 58               //audioTrack.setStereoVolume(vol, vol);//设置音量 59             } 60                61                62             public void onStartTrackingTouch(SeekBar seekBar) { 63               // TODO Auto-generated method stub 64             } 65                66                67             public void onProgressChanged(SeekBar seekBar, int progress, 68                     boolean fromUser) { 69               // TODO Auto-generated method stub 70             } 71       }); 72     } 73    74     @Override 75   protected void onDestroy() { 76         super.onDestroy(); 77       android.os.Process.killProcess(android.os.Process.myPid()); 78     } 79    80   class ClickEvent implements View.OnClickListener { 81    82          83         public void onClick(View v) { 84             if (v == btnRecord) {                85               if(!isRecording) { 86                     isRecording = true; 87                     AudioManager audioManager = (AudioManager) getSystemService(getApplicationContext().AUDIO_SERVICE); 88                   audioManager.setMode(AudioManager.MODE_NORMAL); 89               recBufSize = AudioRecord.getMinBufferSize(frequency, 90                             channelConfiguration, audioEncoding); 91                     playBufSize=AudioTrack.getMinBufferSize(frequency, 92                             channelConfiguration, audioEncoding); 93 94                     audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, 95                             channelConfiguration, audioEncoding, recBufSize); 96                97                     audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency, 98                             channelConfiguration, audioEncoding, 99                             playBufSize, AudioTrack.MODE_STREAM);100                     101                     new RecordPlayThread().start();// 开一条线程边录边放 102                 }                103             } else if (v == btnStop) {                104               if(isRecording) {105                     isRecording = false;106                     AudioManager audioManager = (AudioManager) getSystemService(getApplicationContext().AUDIO_SERVICE);107                   audioManager.setMode(AudioManager.MODE_NORMAL);108                 }                109             } else if (v == btnExit) {110               isRecording = false; 111               AudioManager audioManager = (AudioManager) getSystemService(getApplicationContext().AUDIO_SERVICE);112                 audioManager.setMode(AudioManager.MODE_NORMAL);113               testRecord.this.finish();114             }115       }116     }117   118   class RecordPlayThread extends Thread {119         public void run() {120             try {121                  byte[] buffer = new byte;122               audioRecord.startRecording();//开始录制123               audioTrack.play();//开始播放 124               while (isRecording) {125                     //从MIC保存数据到缓冲区126                     int bufferReadResult = audioRecord.read(buffer, 0,127                             recBufSize);128                     byte[] tmpBuf = new byte;129                     System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);130                     //写入数据即播放131                     audioTrack.write(tmpBuf, 0, tmpBuf.length);132                 }133                 audioTrack.stop();134                 audioTrack.release(); 135                 audioRecord.stop();136                 audioRecord.release();137             } catch (Throwable t) {138               Toast.makeText(testRecord.this, t.getMessage(), 1000);139             }140       }141     }142 }
页: [1]
查看完整版本: Audio的系统结构