Android的Audio系统

本文介绍了Android的Audio系统,包括其层次结构:media库接口、AudioFlinger、硬件抽象层及Java框架接口。重点讨论了AudioTrack和AudioRecorder的功能,以及如何通过AudioFactory创建和控制它们。此外,还展示了AudioPalyer和AudioRecorder的示例代码,用于播放和录制音频。

Audio系统综述

    Audio系统在Android中负责音频方面的数据流传输和控制功能,也负责音频设备的管理。
    Audio系统主要的分成几个层次:
1. media中库提供的Audio系统的上层接口
2. AudioFlinger作为Audio系统的中枢
3. Audio库的硬件抽象层提供底层的支持
4. Audio接口通过JNI和Java框架提供给上层
   Audio系统的上层接口主要提供了两方面的功能:放音(Track)和录音(Recorder)。

 

    Media库(libmedia.so)的Audio部分的目录中:
        frameworks/base/include/media/
        frameworks/base/media/libmedia/
这部分的内容被编译成库libmedia.so,提供Audio部分的接口。
    Audio Flinger (libaudioflinger.so):
        frameworks/base/libs/audioflinger
这部分内容被编译成库libaudioflinger.so。

    Audio的JNI部分:

        frameworks/base/core/jni
    Audio的JAVA部分:
        frameworks/base/media/java/android/media
主要包含AudioManager和Audio系统的几个类。
    Audio硬件抽象层的接口:
        hardware/libhardware_legacy/include/hardware/

Audio系统和上层接口

    Audio系统的结构:
libmedia.so提供Audio接口,这些Audio接口既像上层开放,也向本地代码开发。
libaudiofilnger.so提供Audio接口实现。
Audio硬件抽象层提供到硬件的接口,供AudioFlinger 调用。
Audio使用JNI和JAVA对上层提供接口。

 

    Android 的Audio的核心框架在media库中提供,其中对上面主要实现AudioSystem、AudioTrack和AudioRecorder三个类。提供了IAudioFlinger类接口,在这个类中,可以获得IAudioTrack和IAudioRecorder两个接口,分别用于声音的播放和录制。AudioTrack和AudioRecorder分别通过调用IAudioTrack和IAudioRecorder来实现。

 

    AudioTrack和AudioRecorder 都具有start,stop和pause等接口。前者具有write接口,用于声音的播放,后者具有read接口,用于声音的录制。
    AudioSystem用于Audio系统的控制工作,主要包含一些set和get接口,是一个对上层的类。

运用实例

1.AudioFactory.java(用于获取AudioRecord和AudioTrack)

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;

public class AudioFactory {
 private AudioRecord audioRecord = null;
 private AudioTrack audioTrack = null;

 private int audioSource;
 private int sampleRateInHz;
 private int channelConfig;
 private int audioFormat;
 private int bufferSizeInBytes;

 private int streamType;
 private int mode;

 public AudioFactory() {
  init();
 }

 public AudioTrack getAudioTrack() {
  if (audioTrack == null) {
   audioTrack = new AudioTrack(streamType, sampleRateInHz,
     channelConfig, audioFormat, bufferSizeInBytes, mode);
  }
  return audioTrack;
 }

 public AudioRecord getAudioRecord() {
  if (audioRecord == null) {
   audioRecord = new AudioRecord(audioSource, sampleRateInHz,
     channelConfig, audioFormat, bufferSizeInBytes);
  }
  return audioRecord;
 }

 public int getAudioSource() {
  return audioSource;
 }

 public void setAudioSource(int audioSource) {
  this.audioSource = audioSource;
 }

 public int getSampleRateInHz() {
  return sampleRateInHz;
 }

 public void setSampleRateInHz(int sampleRateInHz) {
  this.sampleRateInHz = sampleRateInHz;
 }

 public int getChannelConfig() {
  return channelConfig;
 }

 public void setChannelConfig(int channelConfig) {
  this.channelConfig = channelConfig;
 }

 public int getAudioFormat() {
  return audioFormat;
 }

 public void setAudioFormat(int audioFormat) {
  this.audioFormat = audioFormat;
 }

 public int getBufferSizeInBytes() {
  return bufferSizeInBytes;
 }

 public void setBufferSizeInBytes(int bufferSizeInBytes) {
  this.bufferSizeInBytes = bufferSizeInBytes;
 }

 public int getStreamType() {
  return streamType;
 }

 public void setStreamType(int streamType) {
  this.streamType = streamType;
 }

 public int getMode() {
  return mode;
 }

 public void setMode(int mode) {
  this.mode = mode;
 }

 public void init() {
  this.audioSource = MediaRecorder.AudioSource.MIC;
  this.sampleRateInHz = 8000;
  this.channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
  this.audioFormat = AudioFormat.ENCODING_PCM_16BIT;
  this.bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
    channelConfig, audioFormat);

  this.streamType = AudioManager.STREAM_MUSIC;
  this.mode = AudioTrack.MODE_STREAM;
 }

}

 

2.AudioPalyer(接收socket传递过来的byte数组,用audioTrack播放。)

import android.media.AudioTrack;

public class AudioPalyer {
 private AudioTrack audioTrack;
 // private boolean isTalking;
 private AudioFactory audioFactory;

 // public AudioPalyer() {
 // this.audioFactory = new AudioFactory();
 // this.audioTrack = audioFactory.getAudioTrack();
 // }

 public AudioPalyer(boolean isTalking) {
  this.audioFactory = new AudioFactory();
  this.audioTrack = audioFactory.getAudioTrack();
 }

 public void play() {
  // this.isTalking = false;
  byte[] audioData = null;
  // UdpReceiver udpReceiver = new UdpReceiver();
  byte[] bytes_pkg = null;

  // 开始播放
  audioTrack.play();

  // while (!MyConfig.stopReceive) {
  while (true) {
   int sizeInBytes = audioFactory.getBufferSizeInBytes();
   // 接收语音
   // bytes_pkg = udpReceiver.receive();
   // recording
   audioData = new byte[sizeInBytes];
   audioData = record(bytes_pkg);
   // 播放语音
   audioTrack.write(audioData, 0, sizeInBytes);
  }
 }

 private byte[] record(byte[] audioData) {
  // TODO Auto-generated method stub
  return audioData;
 }

}

 

3.AudioRecorder.java(录音并发送)

import android.media.AudioRecord;
import android.media.AudioTrack;

public class AudioRecorder {
 private AudioRecord audioRecord;
 private boolean isTalking;
 private AudioFactory audioFactory;
 private AudioTrack audioTrack;

 // public AudioRecorder() {
 // this.audioFactory = new AudioFactory();
 // this.audioRecord = audioFactory.getAudioRecord();
 // }

 public AudioRecorder(boolean isTalking) {
  this.audioFactory = new AudioFactory();
  this.audioRecord = audioFactory.getAudioRecord();
  this.audioTrack = audioFactory.getAudioTrack();
 }

 public void record() {
  // 录音开始
  this.isTalking = true;
  audioRecord.startRecording();
  audioTrack.play();
  byte[] audioData = null;
  // UdpSender udpSender = new UdpSender();

  while (this.isTalking) {
   // 获取字节数组
   int bufferSizeInBytes = audioFactory.getBufferSizeInBytes();
   audioData = new byte[bufferSizeInBytes];
   int size = audioRecord.read(audioData, 0, bufferSizeInBytes);
   byte[] tmpBuf = new byte[size];
   System.arraycopy(audioData, 0, tmpBuf, 0, size);
   audioTrack.write(tmpBuf, 0, tmpBuf.length);
   System.out.println("------" + audioData + "------");
   // encording

   // 发送字节数组
   // if (bytes_pkg != null) {
   // udpSender.send(bytes_pkg);
   // }
  }
  audioTrack.stop();
  audioTrack = null;
  audioRecord.stop();
  audioRecord = null;
  audioData = null;
 }

 private byte[] encord(byte[] audioData) {
  // TODO Auto-generated method stub
  return audioData;
 }

 public void stop() {
  this.isTalking = false;
 }

 public boolean isTalking() {
  return isTalking;
 }

 public void setTalking(boolean isTalking) {
  this.isTalking = isTalking;
 }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值