Android Audio系统

1 简述

Audio 是Android 一个重要组成部分, 它主要包括三个方面:

1 Audio Recorder和Audio Track: 提供对外的API,完成Android 平台audio 数据采集和输出任务。

2 AudioFlinger: 承担音频数据的混音,以及读写audio 硬件等工作以实现数据的输入输出

3 AudioPolicyService:它是Audio 系统的策略控制中心,具体掌管系统中声音设备的选择和切换,音量控制等功能。

2 AudioTrack 使用

关于AudioTrack 有两种数据加载模式:1 MODE_STREAM:将数据一步一步的通过write() 写入,长的音频都是这种模式;2 MODE_STATIC:将数据一次写入,适合于短的铃声。

//相关函数在audioTrack.java 中
//step 1:根据音频数据特定, 确定所需分配的最小buffer
int bufsize = AudioTrack.getMinBufferSize(sampleRate,AudioFormat.CHANNEL_CONFIGURATIO_STEREO,AudioFormat.ENODING_PCM_16BIT);
...
//step 2: 创建audioTrack,需要传入audio type,采样率,声道,采样位数,buffsize,数据加载模式
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT,buffsize,AudioTrack.MODE_STREAM);
...
track.play(); //step 3:播放
track.write(); //step 4:写数据
track.stop(); //step 5: 停止播放
track.release(); //step 6: 释放资源

 3 AudioTrack(java空间)

AudioTrack构造函数的实现在AudioTrack.java 中,往下call 到JNI , 到Android_media_AudioTrack.cpp。 audioTrack java 到JNI 这段,函数逻辑很简单,大部分逻辑都是在native 层实现的。

4 AudioTrack(Native 空间)

1 new AudioTrack 和set() 分析

AudioTrack::AudioTrack() //无参构造函数
{
    //比较简单,把状态初始化成NO_INIT,Andriod 的很多类都采用这种状态控制。
}
status AudioTrack::set(int streamType, uint32_t sampleRate, int format...)
{
    .....
    audio_io_handle_t output = AudioSystem::getOutput();//这个output 值非常重要,用来表示工作线程索引号,audioFlinger会根据这个值创建几个工作线程。
    ....
    status_t status = createTrack();//这函数往下call 到audioFlinger ,详情往下看
    ...
    if(cbf != 0) //如果设置了回调函数,则启动一个线程,主动从用户那个pull 数据,不然主动write push 数据
    {
        mAudioTrackTread = new AudioTrackTread()
    }

}

status AudioTrack::creatTrack(int streamType ...)
{
    ...
    const sp<IAudioFlinger> &audioFlinger = AudioSystem::get_audio_flinger();//得到AudioFlinger 的binder 代理端bpAudioFlinger
/*IAudioTrack 是联系AT 和 AF 的关键纽带,在IAudioTrack 中有一块共享内存,其头部是audio_track_cblk_t, 通过它协调和管理AT 和 AF 间数据生产和消费
    sp<IAudioTrack> track = AuidoFlinger->createTrack();
}

2 pull 与 push mode

在pull mode 下
bool AudioTrack::processAudioBuffer()
{
    ...
    status_t err = obtainBuffer();//从CB那里得到一块可写的缓冲
    mCbf(EVENT_MORE_DATA,mUserData,&audioBuffer);//从用户那里pull 数据
    releaseBuffer();//更新写位置,同时会触发消费者
    ...
}

在push mode 下:
size_t AudioTrack::write()
{
	...
	status err = obtainBuffer(&audioBuffer,-1);
	memcpy(aoudioBuffer.i8,src,toWrite);
	releaseBuffer(&audioBuffer);
	...
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值