最新传奇游戏,新开sf网站.欧比奥传奇发布网
当前位置:网站首页 > sf发布网 > 正文

高通audiohal分析

作者:admin发布时间:2021-10-23分类:sf发布网浏览:21评论:5


导读:函数这个函数首先是有一些out-的判断然后会判断是否是如果是会调用去打开输出设备。然后如果pcm状态正常的情况下会调用函数向adsp中写入数据。是的函数我们这里只分析hal层所以接...

高通audiohal分析

函数

这个函数首先是有一些out-的判断然后会判断是否是如果是会调用去打开输出设备。然后如果pcm状态正常的情况下会调用函数向adsp中写入数据。是的函数我们这里只分析hal层所以接下来我们去看一下函数打开设备的流程。

函数

这个函数首先调用platform_get_pcm_device_id函数去获取deviceid这个id的定义是取决于kernel的也就是说hal层把这个id传给kernelkernel根据对应的id去打开相应的通路。platform_get_pcm_device_id函数在platform.c中主要是从pcm_device_table中根据相应的usecase去获取对应的通路id。定义如下

staticintpcm_device_table[AUDIO_USECASE_MAX][2]{[USECASE_AUDIO_PLAYBACK_DEEP_BUFFER]{DEEP_BUFFER_PCM_DEVICE,DEEP_BUFFER_PCM_DEVICE},[USECASE_AUDIO_PLAYBACK_WITH_HAPTICS]{AUDIO_HAPTICS_PCM_DEVICE,AUDIO_HAPTICS_PCM_DEVICE},[USECASE_AUDIO_PLAYBACK_LOW_LATENCY]{LOWLATENCY_PCM_DEVICE,LOWLATENCY_PCM_DEVICE},[USECASE_AUDIO_PLAYBACK_ULL]{MULTIMEDIA3_PCM_DEVICE,MULTIMEDIA3_PCM_DEVICE},[USECASE_AUDIO_PLAYBACK_MULTI_CH]{MULTIMEDIA2_PCM_DEVICE,MULTIMEDIA2_PCM_DEVICE},[USECASE_AUDIO_PLAYBACK_HIFI]{MULTIMEDIA2_PCM_DEVICE,MULTIMEDIA2_PCM_DEVICE},[USECASE_AUDIO_PLAYBACK_TTS]{MULTIMEDIA2_PCM_DEVICE,MULTIMEDIA2_PCM_DEVICE},[USECASE_AUDIO_PLAYBACK_OFFLOAD]{PLAYBACK_OFFLOAD_DEVICE,PLAYBACK_OFFLOAD_DEVICE},[USECASE_AUDIO_PLAYBACK_OFFLOAD2]{PLAYBACK_OFFLOAD_DEVICE2,PLAYBACK_OFFLOAD_DEVICE2},[USECASE_AUDIO_PLAYBACK_OFFLOAD3]{PLAYBACK_OFFLOAD_DEVICE3,PLAYBACK_OFFLOAD_DEVICE3},[USECASE_AUDIO_PLAYBACK_OFFLOAD4]{PLAYBACK_OFFLOAD_DEVICE4,PLAYBACK_OFFLOAD_DEVICE4},[USECASE_AUDIO_PLAYBACK_OFFLOAD5]{PLAYBACK_OFFLOAD_DEVICE5,PLAYBACK_OFFLOAD_DEVICE5},[USECASE_AUDIO_PLAYBACK_OFFLOAD6]{PLAYBACK_OFFLOAD_DEVICE6,PLAYBACK_OFFLOAD_DEVICE6},[USECASE_AUDIO_PLAYBACK_OFFLOAD7]{PLAYBACK_OFFLOAD_DEVICE7,PLAYBACK_OFFLOAD_DEVICE7},[USECASE_AUDIO_PLAYBACK_OFFLOAD8]{PLAYBACK_OFFLOAD_DEVICE8,PLAYBACK_OFFLOAD_DEVICE8},[USECASE_AUDIO_PLAYBACK_OFFLOAD9]{PLAYBACK_OFFLOAD_DEVICE9,PLAYBACK_OFFLOAD_DEVICE9},。。。};

然后DEEP_BUFFER_PCM_DEVICE等分别对应定义好的一个int值。

然后会调用到select_devices函数中。

3.select_devices函数

intselect_devices(structaudio_device*adev,audio_usecase_tuc_id){ALOGD(%sforusecase(%s),__func__,use_case_table[uc_id]);usecaseget_usecase_from_list(adev,uc_id);if(usecaseNULL){ALOGE(%s:Couldnotfindtheusecase(%d),__func__,uc_id);return-EINVAL;}if(usecase-typePCM_PLAYBACK){if(usecase-stream.outNULL){ALOGE(%s:stream.outisNULL,__func__);return-EINVAL;}usecase-devicesusecase-stream.out-devices;in_snd_deviceSND_DEVICE_NONE;if(out_snd_deviceSND_DEVICE_NONE){structstream_out*voip_outadev-primary_output;structstream_in*voip_inget_voice_communication_input(adev);if(usecase-devicesAUDIO_DEVICE_OUT_BUS)out_snd_deviceaudio_extn_auto_hal_get_output_snd_device(adev,uc_id);elseout_snd_deviceplatform_get_output_snd_device(adev-platform,usecase-stream.out);voip_usecaseget_usecase_from_list(adev,USECASE_AUDIO_PLAYBACK_VOIP);if(voip_usecase)voip_outvoip_usecase-stream.out;if(usecase-stream.outvoip_outvoip_in!NULL)select_devices(adev,voip_in-usecase);}}/*Enablenewsounddevices*/if(out_snd_device!SND_DEVICE_NONE){check_usecases_codec_backend(adev,usecase,out_snd_device);if(platform_check_codec_asrc_support(adev-platform))check_and_set_asrc_mode(adev,usecase,out_snd_device);enable_snd_device(adev,out_snd_device);}enable_audio_route(adev,usecase);audio_extn_qdsp_set_device(usecase);}

这个函数会调用get_usecase_from_list函数把device和usecase等信息封装到audio_usecase结构体中如果usecase-type是播放的话会去判断输出设备是否是AUDIO_DEVICE_OUT_BUS这个是车机的device因为我们是车机所以就看一下这个if调用的函数然后调用audio_extn_auto_hal_get_output_snd_device函数再到auto_hal_get_output_snd_device函数这个函数会根据device和usecase去选择hal层对应的snd_device。这个snd_device和上面传过来的device不同传过来的device是framework上定义的一个名称这个snd_device才是真正的hal层的device比如framework传过来的是通过offload模式媒体播放设备是AUDIO_DEVICE_OUT_BUS去播放设备在这里会根据这个usecase和device把snd_device转换成SND_DEVICE_OUT_BUS_MEDIA如果framework传过来的是NAV导航模式AUDIO_DEVICE_OUT_BUS设备那么snd_device对应的就是SND_DEVICE_OUT_BUS_NAV。同样的如果设备不是AUDIO_DEVICE_OUT_BUS会调用platform_get_output_snd_device但是这个函数也是做上面的一些操作只不过这个函数相对会复杂一些除了AUDIO_DEVICE_OUT_BUS之外所有的device转换都是从这里做的比如headset手机上的听筒等。最后调用enable_snd_device去打开输出设备通路以及调用enable_audio_route去使能audioroute。

4.enable_snd_device函数

这个函数首先调用platform_get_snd_device_name_extn函数使用上一步得到的snd_device去获取device_name这个device_name就是mixer_path中所定义的名字还是以SND_DEVICE_OUT_BUS_MEDIA为例进行分析这里从device_table数组中得到的device_name是bus-speaker。然后继续往下走会走到audio_route_apply_and_update_path函数再到audio_route_update_path函数这里首先根据上面获取到的device_name去解析mixer_path然后拿到mixer_path中定义的bus-speaker所对应的通路然后调用tinyalsa的mixer.c中的mixer_ctl_set_value函数去打开设备通路。

5.enable_audio_route函数

这个函数会调用platform_add_backend_name函数在通路的设备上添加设备名用于不同的usecase定义也就是把headphones-44.1,speaker-and-headphones等添加到usecase的设备名称中主要是为了应对同样的usecase不同的设备配置不同的问题。比如同样的offload模式有如下两种不同的定义

pathnamecompress-offload-playbackctlnameTERT_TDM_RX_0ChannelsvalueSix/ctlnameTERT_TDM_RX_0AudioMixerMultiMedia4value1//pathpathnamecompress-offload-playbackbt-scoctlnameSLIMBUS_7_RXAudioMixerMultiMedia4value1//path

通过上面的例子我们可以看到同样的offload模式蓝牙的和默认的定义是完全不同的。最后这个函数和enable_snd_device函数一样也是调用audio_route_apply_and_update_path函数通过tinyalsa去打开对应的usecase。到这里hal层的打开usecase通路以及打开device输出设备的流程就大体分析完成了


已有5位网友发表了看法:

欢迎 发表评论: