一、AudioTrack介绍
播放声音可以使用 MediaPlayer 和 AudioTrack,两者都提供 Java API 给应用开发者使用。两者的差别在于:MediaPlayer 可以播放多种格式的音源,如 mp3、flac、wma、ogg、wav 等,而 AudioTrack 只能播放解码后的 PCM 数据流。从上面 Android 音频系统架构图来看:MediaPlayer 在 Native 层会创建对应的音频解码器和一个 AudioTrack,解码后的数据交由 AudioTrack 输出。所以 MediaPlayer 的应用场景更广,一般情况下使用它也更方便;只有一些对声音时延要求非常苛刻的应用场景才需要用到 AudioTrack。
AudioTrack由JAVA代码、JNI代码、C++代码组成:
AudioTrack代码位于:
frameworks/base/media/java/android/media/AudioTrack.java
frameworks/base/core/jni/android_media_AudioTrack.cpp
frameworks/base/core/jni/android_media_AudioTrack.h
frameworks/av/media/libaudioclient/AudioTrack.cpp
frameworks/av/media/libaudioclient/AudioTrack.h
AudioTrack的定义:
public class AudioTrack extends PlayerBase implements AudioRouting, VolumeAutomation {}
class AudioTrack : public AudioSystem::AudioDeviceCallback {}
二、AudioTrack API
AudioTrack分为JAVA API和Native API,下面分别介绍它们。
1、AudioTrack Java API
AudioTrack Java API如下:
-
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode) :构造函数
-
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId) :构造函数
-
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat) :构造函数
-
static int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat):计算最小缓冲区大小,参数同构造函数中三个参数。
-
void play():开始播放
-
int write(byte[] audioData, int offsetInBytes, int sizeInBytes) :写入音频数据到硬件有两个方法,返回成功写入的数据个数
-
int write(short[] audioData, int offsetInShorts, int sizeInShorts) :写入音频数据到硬件有两个方法,返回成功写入的数据个数
-
void stop():停止播放
-
void pause():暂停播放
-
void release():释放资源
-
int getState():获取状态
-
int getPlayState():获取播放状态
-
int setVolume(float gain):设置音量(0~1.0)
其中AudioTrack Java API 两种数据传输模式:
mode | Description |
---|---|
MODE_STATIC |
应用进程将回放数据一次性付给 AudioTrack,适用于数据量小、时延要求高的场景 |
MODE_STREAM |
用进程需要持续调用 write() 写数据到 FIFO,写数据时有可能遭遇阻塞(等待 AudioFlinger::PlaybackThread 消费之前的数据),基本适用所有的音频场景 |
其中AudioTrack Java API 音频流类型:
Stream Type | Description |
---|---|
STREAM_VOICE_CALL |
电话语音 |
STREAM_SYSTEM |
系统声音 |
STREAM_RING |
铃声声音,如来电铃声、闹钟铃声等 |
STREAM_MUSIC |
音乐声音 |
STREAM_ALARM |
警告音 |
STREAM_NOTIFICATION |
通知音 |
STREAM_DTMF |
DTMF 音(拨号盘按键音) |
Android 为什么要定义这么多的流类型?这与 Android 的音频管理策略有关,例如:
-
音频流的音量管理,调节一个类型的音频流音量,不会影响到其他类型的音频流
-
根据流类型选择合适的输出设备;比如插着有线耳机期间,音乐声(STREAM_MUSIC)只会输出到有线耳机&