【Android AudioFrameWork】 device的選擇

手機上的音頻模塊是一個很複雜的系統,爲了區分和管理,
android中引入了streamType, routing_strategy和device的概念
應用在播放音樂時,只需要將streamType設置下來,底層根據streamType選擇routing_strategy, 再根據routing_strategy選擇device,從而決定聲音從那裏發生,是揚聲器,是聽筒,還是耳機。

1 streamType簡介

針對不同的音頻流,有不同的類型
如:
通話中的voice音, 類型爲 AUDIO_STREAM_VOICE_CALL
來電的響鈴音, 類型爲 AUDIO_STREAM_RING
播放視頻的媒體音, 類型爲 AUDIO_STREAM_MUSIC
鬧鐘的提示音,類型爲 AUDIO_STREAM_ALARM
系統的通知音, 類型爲 AUDIO_STREAM_NOTIFICATION 

streamType的枚舉值可參考 system/media/audio/include/system/audio-base.h 文件

2 routing_strategy 簡介

	通路策略與 streamType一一對應,不同的streamType的音,會採取不同的通路,
	比如,
	通話時,選擇的streamType爲 AUDIO_STREAM_VOICE_CALL,
		那麼根據voice_call,獲取的 strategy是 STRATEGY_PHONE。

	鬧鐘響鈴時,選擇的streamType爲 AUDIO_STREAM_ALARM
		那麼根據alarm,獲取的 strategy 是 STRATEGY_SONIFICATION

	具體策略可以參考 audiopolicy中的 engine.cpp中的 Engine::getStrategyForStream 函數
	routing_strategy的枚舉值可參考frameworks/av/services/audiopolicy/common/include/RoutingStrategy.h文件

3 device簡介

audio中針對音頻的播放通路,有device這個概念。
比如說打電話時聲音從聽筒出來,聽筒就是一個device:AUDIO_DEVICE_OUT_EARPIECE

如果打開免提的話,會從揚聲器出聲,揚聲器也是一個device:AUDIO_DEVICE_OUT_SPEAKER
如果連接上藍牙耳機或者有線耳機或者usb耳機,
聲音便從耳機出,這又是三個不同的設備:
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET
AUDIO_DEVICE_OUT_WIRED_HEADSET
AUDIO_DEVICE_OUT_USB_HEADSET

當然,也有采集聲音的麥克
打電話時,我們的聲音會被手機底部的mic採集,底部mic是一個輸入 device:		AUDIO_DEVICE_IN_BUILTIN_MIC
如果打開免提,我們的聲音會被背部的mic採集,背部mic也是一個輸入device:		AUDIO_DEVICE_IN_BACK_MIC

device的枚舉值可參考	system/media/audio/include/system/audio-base.h 文件

4 device的選擇策略

首先,一塊手機上有固定的device,比如mic, 聽筒和揚聲器
其次,插上手機後,會有新增的device,比如耳機,音響等。
故,device的來源有兩個,一個是固有的,一個的可增刪的。

4.1 固有device來源於xml:

audioserver啓動時,創建 AudioPolicyManager時,會分別從手機的如下目錄
"/odm/etc", "/vendor/etc/audio", "/vendor/etc", "/system/etc"
查找 audio_policy_configuration.xml 文件並解析。
xml中首先有 <attachedDevices> item,列出了所有可能的固有device
其次有 <devicePorts> item,列出了所有的device的特性,
二者求交集,便產生了手機的固有device

4.2 可增刪設備來源於手機插拔上報事件

比如,插入一個usb耳機後,usb驅動會上報插拔事件,usbAlasManager解析設備,
如果是音頻設備,會間接調用 setDeviceConnectionState,
將新增的device傳給底層,底層將新增的設備add到 mAvailableOutputDevices vector中,
選擇輸出設備時,便從這些可利用的device中,根據一定的策略來獲取device,
策略見engine.cpp中的 Engine::getDeviceForStrategy函數。


至此,我們根據應用傳遞的streamType,選擇了deivce.

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章