欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android AudioManager控制系统声音的流程

程序员文章站 2022-04-29 14:10:52
首先上层java调用 xxxplayer audiomanager audiomanage = (audiomanager) context.getsystemservice(context.aud...

首先上层java调用

xxxplayer

audiomanager audiomanage = (audiomanager) context.getsystemservice(context.audio_service);

audiomanager就是我们定义的控制声音的对象,(如果context报错,可将其改成xxxplayer.this)

audiomanager.setstreamvolume(aa,bb,cc),是我们可以直接使用的audiomanager的成员函数,3个参数表示的意思:aa:有内置的常量,可以在audiomanager里面查到相关的定义,我们在此用 audiomanager.stream_music, bb:自己设置音量的值,cc:也是一些标示量,我在此设置为0;

1.audiomanager.java

public void setstreamvolume(int streamtype, int index, int flags);上层接口

?????? 1)调用iaudioservice service = getservice(); 当程序开启时会获得service,调用此来获得

2.执行servicemanager.java?
public static ibinder getservice(string name)获取audio服务

3.audioservice.java?
public void setstreamvolume(int streamtype, int index, int flags)//服务接口
?? 1) private void setstreamvolumeint(int streamtype, int index, boolean force, boolean lastaudible)//服务函数
?? 2)调用以下函数??
sendmsg(maudiohandler, msg_set_system_volume, streamtype, sendmsg_noop, 0, 0,streamstate, 0)?
?????? //post message to set system volume (it in turn will post a message
??????????? ????? // to persist)
3)audiohandler::setsystemvolume(volumestreamstate streamstate);//sendmsg(...)后执行函数
?? 4)调用audiohandler::setstreamvolumeindex(int stream, int index)
??? 5)audiosystem.setstreamvolumeindex(stream,index);//audiosystem接口

static int android_media_audiosystem_setstreamvolumeindex(jnienv *env, jobject thiz, jint stream, jint index)
1)调用audiosystem::setstreamvolumeindex

6.status_t audiosystem::setstreamvolumeindex(stream_type stream, int index)(处理到这时,也可以直接走audioflinger路线,不经过策略)?
1)获得服务 const sp& aps = audiosystem::get_audio_policy_service();
2)调用aps->setstreamvolumeindex(stream, index)

7.status_t audiopolicyservice::setstreamvolumeindex(audiosystem::stream_type stream, int index)
1)调用mppolicymanager->setstreamvolumeindex(stream, index)
status_t audiopolicymanager::setstreamvolumeindex(audiosystem::stream_type stream, int index)
1)记录音量index: mstreams[stream].mindexcur = index
2)compute and apply stream volume on all outputs:
checkandsetvolume(stream, index, moutputs.keyat(i), moutputs.valueat(i)->device())

8.status_t audiopolicymanager::checkandsetvolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayms, bool force)
1)计算音量:float volume = computevolume(stream, index, output, device);
2)调用:mpclientinterface->setstreamvolume((audiosystem::stream_type)stream, volume, output, delayms);

9.status_t audiopolicyservice::setstreamvolume(audiosystem::stream_type stream, float volume, audio_io_handle_t output, int delayms)
调用maudiocommandthread->volumecommand((int)stream, volume, (int)output, delayms);

10.status_t audiopolicyservice::audiocommandthread::volumecommand(int stream, float volume, int output, int delayms)
调用insertcommand_l(command, delayms);

补充1)在条用getservice();获取服务的时候 ,实际调用的是servicemanager.getservice(context);

系统服务都是由servicemanager来管理的,要添加服务,可以调用servicemanager.addservice(context,service);

每添加一个service,都会有对应的唯一context, 当getservice的时候就会根据context获得相应的服务,

可查看servicemanager.java, servicemanager.h/cpp

补充2) audioservice 的接口在 iaudioservice.aidl中定义。添加自定义功能时( 我们创建控制接口比如创建个音效处理的接口seteffectvolume(xxx),可以参照setstreamvolume(a,b,c))别忘了修改此处,否则,audiomanager 会出现cannot find symbol..错误!!!

补充3)编译的时候可能会在audiomanager.java中调用自己写的接口时出错,此时先将该文件中的调用注释掉,执行 make update-api

执行完成后,将注释去掉,然后从新编译。。。