AudioTrack Native的简介
AudioTrack(Native)是Audio模块Native层对外提供的用来播放一段PCM数据(一般情况下只用来播放PCM,offload模式下可以播放MP3或者是AAC,需要底层硬件的支持)的接口。
AudioTrack与MediaPlayer的区别:
我们知道APP如果需要播放类似MP3、AAC的音乐,通常情况下就直接会调用MediaPlayer去播放音乐。MediaPlayer内部首先会通过Stagefright对音乐文件进行解析解码,获取到PCM数据;然后调用AudioTrack播放处理后的PCM数据。
AudioTrack创建的流程
对于Audio模块,AudioTrack可以看做是C/S模型中的Client,而对应的Server则是AudioFlinger。对于一般的C/S模型大致会有下面的过程,我们接下来的代码分析会涉及到这些过程,这样可以方便对代码的理解:
- 服务器端首先监听客户端的请求;(AudioFlinger会通过Binder驱动监听AudioTrack的请求)
- 客户端获取服务器端的IP地址;(对应AudioTack调用get_audio_flinger)
- 客户端获取服务器可以通信的端口号;(对应AudioTack调用getOutputForAttr)
- 客户端请求连接服务器的指定端口;(对应AudioTack调用createTrack)
- 服务器收到客户端的连接请求后与客户端建立连接;(AudioFlinger处理createTrack)
- 连接成功后,客户端与服务器通过连接进行通信了。(对应AudioTrack传输数据)
- 通信完毕后,客户端与服务器端两边各自断开连接。
使用AudioTrack播放
1.获取Buffer的大小
获取一次需要传输的数据的多少(framecount),这个决定了Buffer的大小。
AudioTrack::getMinFrameCount(&framecount, AUDIO_STREAM_MUSIC, sampleRate)
2.构造并初始化AudioTrac
这个过程包括了上面C/S模型过程的第2—5步
sp<AudioTrack> track = new AudioTrack();
track->set(AUDIO_STREAM_MUSIC,
sampleRate,
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_OUT_STEREO,
0,
AUDIO_OUTPUT_FLAG_DEEP_BUFFER,
NULL ,
NULL /*user*/,
0 /*notificationFrames*/,
0 /*sharedBuffer*/,
false /*threadCanCallJava*/,
(audio_session_t)0 /*sessionId*/,
AudioTrack::TRANSFER_OBTAIN)
3.数据传输
向AudioFlinger传输PCM数据,对应上面过程的第6步。
track->start();
status_t status = track->obtainBuffer(&abuffer, 1);
memcpy(abuffer.i8, (char *)buffer + offset, abuffer.size);
4. 结束播放
调用stop函数结束播放,并且对应上面过程的第7步
track->stop();
track->~AudioTrack();
一个AudioTrack(cpp)的实例
https://github.com/xuechongwen/AudioTrackTest
AudioTrack参数的解析
这里是指用于初始化AudioTrack的参数,参数通话set方法传入
audio_stream_type_t streamType,audio_attributes_t* pAttributes
streamType: AudioTrack对应的流的类型,与声音的应用场景有关(e.g. AUDIO_STREAM_MUSIC,AUDIO_STREAM_VOICE_CALL,AUDIO_STREAM_RING…)
Android 比较新的版本更倾向于使用audio_attributes_t代替stream。attibute可以描述更多的应用场景。
uint32_t sampleRate,
音频数据的采样率,以Hz为单位
audio_format_t format
数据的格式,一个32位组成(4字节),前8位表示主格式,后24位表示子格式。例如对于PCM格式,主格式为AUDIO_FORMAT_PCM(0x00),子格式一般表示数据的采样精度如,AUDIO_FORMAT_PCM_SUB_16_BIT(0x1).
audio_channel_mask_t channelMask,
数据包含声道的掩码,AUDIO_CHANNEL_OUT_MONO(0x1),AUDIO_CHANNEL_OUT_STEREO(0x3), AUDIO_CHANNEL_OUT_2POINT1(0x7)
size_t frameCount
以帧计数,Buffer的大小(一个Buffer含有多少帧)。这个参数会影响到数据 播放的延时(Buffer引起的延时),如果与HAL层的参数不符,AudioTrack会内部做增大的调整。0表示采用默认值。
audio_output_flags_t flags,
输出标志,表示希望track使用标志所对应的输出流,AUDIO_OUTPUT_FLAG_FAST,AUDIO_OUTPUT_FLAG_DEEP_BUFFER
callback_t cbf
回调函数,只有应用使用TRANSFER_CALLBACK模式向AudioTrack传数据的时候使用。
bool threadCanCallJava
callback是否可以调用JN
int sessionId
会话的ID,由AudioFlinger提供的唯一ID,可以提前调用AudioSystem生成,也可以传入0作为默认值
transfer_type transferType
应用向AudioTrack传输数据的方式
*audio_offload_info_t offloadInfo
Offload模式下offload参数
int uid, int pid
应用的UID, 应用的PID
bool doNotReconnect
如果出现错误,是否重新创建一个AudioTrack