W wersji Androida 10 wprowadzono znaczącą refaktoryzację menedżera zasad dotyczących dźwięku, aby zapewnić większą elastyczność w obsłudze złożonych zastosowań samochodowych:
- Strategie routingu właściwe dla OEM.
- Grupy głośności, które można dostosowywać, dla grup starszych typów strumieni za pomocą tych samych krzywych głośności.
- strategie routingu deklarowane przez mechanizm zasad audio zamiast być zakodowane na stałe.
- Krzywe głośności i grupy zarządzane przez silnik zasad dotyczących dźwięku.
- Wewnętrzne refaktoryzowanie przygotowujące do przyszłego podziału na kod wspólny i konfigurowalny oraz oferujący zaawansowane funkcje zarządzania urządzeniami audio. Na przykład w regułach zasad można używać wszystkich właściwości urządzenia, a nie tylko jego typu.
W Androidzie 7.0 wprowadzono format pliku konfiguracji zasad audio (XML) do opisywania topologii audio.
Poprzednie wersje Androida wymagały użycia device/<company>/<device>/audio/audio_policy.conf
do zadeklarowania urządzeń audio dostępnych w produkcie (przykład tego pliku dotyczy sprzętu audio Galaxy Nexus w device/samsung/tuna/audio/audio_policy.conf
). CONF to prosty, zastrzeżony format, którego nie można opisać zbyt złożonym topologią dla branż takich jak telewizory czy samochody.
wycofano obsługę Androida 7.0 audio_policy.conf
i dodano obsługę definiowania topologii audio za pomocą formatu pliku XML, który jest bardziej czytelny dla człowieka, zawiera szeroki zakres narzędzi do edycji i analizy oraz jest na tyle elastyczny, że umożliwia opisywanie złożonych topologii audio. Android 7.0 używa flagi kompilacji USE_XML_AUDIO_POLICY_CONF
do wyboru formatu XML plików konfiguracji.
Zalety formatu XML
Podobnie jak w przypadku pliku CONF, plik XML pozwala określić liczbę i typy profili strumieni wyjściowych, urządzeń używanych do odtwarzania i przechwytywania oraz atrybuty audio. Format XML zapewnia też te ulepszenia:
- W Androidzie 10 można jednocześnie używać więcej niż 1 aktywnej aplikacji do nagrywania.
- Rozpoczęcie nagrywania nigdy nie jest odrzucane z powodu sytuacji równoległej.
- Funkcja
registerAudioRecordingCallback(AudioManager.AudioRecordingCallback cb)
powiadamia klientów o zmianach ścieżki przechwytywania.
- W tych sytuacjach klient otrzymuje cichsze próbki dźwiękowe:
- Aktywny jest przypadek użycia, który wymaga ochrony prywatności (np.
VOICE_COMMUNICATION
). - Klient nie ma usługi na pierwszym planie ani interfejsu użytkownika na pierwszym planie.
- Role specjalne są rozpoznawane przez zasady:
- Usługa ułatwień dostępu: może nagrywać nawet wtedy, gdy aktywne jest zastosowanie wymagające ochrony prywatności.
- Asystent: uznawany za poważną ochronę prywatności, jeśli interfejs jest umieszczony na samej górze.
- Aktywny jest przypadek użycia, który wymaga ochrony prywatności (np.
- Profile audio mają strukturę podobną do prostych deskryptorów audio HDMI, co umożliwia stosowanie różnych zestawów częstotliwości próbkowania i masek kanałów w przypadku każdego formatu audio.
- Istnieją konkretne definicje wszystkich możliwych połączeń między urządzeniami i strumieniami. Wcześniej reguła domyślna umożliwiała połączenie wszystkich urządzeń podłączonych do tego samego modułu HAL, uniemożliwiając zasadom dotyczącym dźwięku kontrolowanie połączeń żądanych za pomocą interfejsów API łatki audio. W formacie XML opis topologii definiuje ograniczenia połączeń.
- Obsługa includes pozwala uniknąć powtarzania standardowych definicji A2DP, USB lub reroute submit.
- Krzywe głośności można dostosowywać. Wcześniej tabele woluminów były zakodowane na stałe. W formacie XML tabele objętości są opisane i można je dostosować.
Szablon dostępny pod adresemframeworks/av/services/audiopolicy/config/audio_policy_configuration.xml
pokazuje wiele z tych funkcji w akcji.
Format i lokalizacja pliku
Nowy plik konfiguracji zasad audio to audio_policy_configuration.xml
i znajduje się w lokalizacji /system/etc
. Poniższe przykłady przedstawiają prostą konfigurację zasad audio w formacie pliku XML dla Androida 12 i wersji Androida 12 starszych.
Przykład zasad dotyczących dźwięku w Androidzie 12
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <globalConfiguration speaker_drc_enabled="true"/> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>Speaker</item> <item>Earpiece</item> <item>Built-In Mic</item> </attachedDevices> <defaultOutputDevice>Speaker</defaultOutputDevice> <mixPorts> <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="primary input" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address=""> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> </devicePorts> <routes> <route type="mix" sink="Earpiece" sources="primary output"/> <route type="mix" sink="Speaker" sources="primary output"/> <route type="mix" sink="Wired Headset" sources="primary output"/> <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/> </routes> </module> <xi:include href="a2dp_audio_policy_configuration.xml"/> </modules> <xi:include href="audio_policy_volumes.xml"/> <xi:include href="default_volume_tables.xml"/> </audioPolicyConfiguration>
Przykład zasad dotyczących dźwięku w przypadku wersji starszych niż Android 12
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <globalConfiguration speaker_drc_enabled="true"/> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>Speaker</item> <item>Earpiece</item> <item>Built-In Mic</item> </attachedDevices> <defaultOutputDevice>Speaker</defaultOutputDevice> <mixPorts> <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="primary input" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address=""> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> </devicePorts> <routes> <route type="mix" sink="Earpiece" sources="primary output"/> <route type="mix" sink="Speaker" sources="primary output"/> <route type="mix" sink="Wired Headset" sources="primary output"/> <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/> </routes> </module> <xi:include href="a2dp_audio_policy_configuration.xml"/> </modules> <xi:include href="audio_policy_volumes.xml"/> <xi:include href="default_volume_tables.xml"/> </audioPolicyConfiguration>
Struktura najwyższego poziomu zawiera moduły odpowiadające poszczególnym modułom sprzętowym HAL audio. Każdy moduł ma listę portów miksowania, portów urządzenia i tras:
- Porty miksowania opisują możliwe profile konfiguracji strumieni, które można otworzyć w HAL dźwięku na potrzeby odtwarzania i przechwytywania.
- Porty urządzeń opisują urządzenia, które można podłączyć za pomocą ich typu (i opcjonalnie adres i właściwości audio, jeśli są potrzebne).
- Trasy są oddzielone od deskryptora portów, co umożliwia opis tras między urządzeniami lub przesyłanie strumieniowe na urządzenie.
Tabele głośności to proste listy punktów definiujących krzywą używaną do przekształcania indeksu interfejsu w głośność w dB. Oddzielny plik include zawiera domyślne krzywe, ale każdą krzywą dla danego zastosowania i kategorii urządzenia można zastąpić.
Przykład tabeli objętości
<?xml version="1.0" encoding="UTF-8"?> <volumes> <reference name="FULL_SCALE_VOLUME_CURVE"> <point>0,0</point> <point>100,0</point> </reference> <reference name="SILENT_VOLUME_CURVE"> <point>0,-9600</point> <point>100,-9600</point> </reference> <reference name="DEFAULT_VOLUME_CURVE"> <point>1,-4950</point> <point>33,-3350</point> <point>66,-1700</point> <point>100,0</point> </reference> </volumes>
Przykład pokazywania tomów
<?xml version="1.0" encoding="UTF-8"?> <volumes> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"> <point>1,-5500</point> <point>20,-4300</point> <point>86,-1200</point> <point>100,0</point> </volume> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/> </volumes>
Uwzględnianie plików
Metody uwzględniania XML (XInclude) można używać do uwzględniania informacji o konfiguracji zasad dotyczących dźwięku znajdujących się w innych plikach XML. Wszystkie uwzględnione pliki muszą mieć strukturę opisaną powyżej z tymi ograniczeniami:
- Pliki mogą zawierać tylko elementy najwyższego poziomu.
- Pliki nie mogą zawierać elementów XInclude.
Używaj go, aby uniknąć kopiowania informacji o standardowych konfiguracjach modułu HAL dźwięku z projektu Android Open Source (AOSP) do wszystkich plików konfiguracji zasad dźwięku (co może powodować błędy). Standardowy plik XML konfiguracji zasad audio jest dostępny dla tych interfejsów HAL dźwięku:
- A2DP:
a2dp_audio_policy_configuration.xml
- Przekieruj submiksję:
rsubmix_audio_policy_configuration.xml
- USB:
usb_audio_policy_configuration.xml
Organizacja kodu zasad dotyczących dźwięku
AudioPolicyManager.cpp
jest podzielony na kilka modułów, aby ułatwić jego utrzymanie i konfigurowanie. Organizacja frameworks/av/services/audiopolicy
zawiera te moduły:
Moduł | Opis |
---|---|
/managerdefault |
Zawiera ogólne interfejsy i implementację działania typowe dla wszystkich aplikacji. Podobnie jak w przypadku AudioPolicyManager.cpp , funkcje silnika i pojęcia ogólne są abstrakcyjne. |
/common |
Definiuje klasy podstawowe (np. struktury danych dla profili wejściowych profili strumienia audio, deskryptorów urządzeń audio, poprawek audio i portów audio). Wcześniej była ona zdefiniowana w AudioPolicyManager.cpp . |
/engine |
implementuje reguły określające, których urządzeń i głośników należy używać w danym przypadku użycia. Implementuje standardowy interfejs z częścią ogólną, na przykład aby uzyskać odpowiednie urządzenie do danego przypadku użycia odtwarzania lub rejestrowania, albo aby ustawić połączone urządzenia lub stan zewnętrzny (czyli stan wywołania w przypadku wymuszonego użycia), który może zmienić decyzję dotyczącą routingu. Dostępne w 2 wersjach: konfigurowalnej i domyślnej. Informacje o wyborze wersji znajdziesz w artykule na temat konfigurowania za pomocą platformy parametrów. |
/engineconfigurable |
Implementacja mechanizmu zasad, która opiera się na ramach parametrów (patrz poniżej). Konfiguracja opiera się na ramach parametrów i zasadach zdefiniowanych w plikach XML. |
/enginedefault |
Implementacja Policy Engine na podstawie poprzednich implementacji Menedżera zasad dotyczących dźwięku na urządzeniach z Androidem. Jest to domyślna opcja, która zawiera zakodowane na stałe reguły odpowiadające implementacjom w Nexusie i AOSP. |
/service |
Obejmuje interfejsy bindera, implementację wątków i blokowania z interfejsem do reszty frameworka. |
Konfiguracja za pomocą ramki parametrów
Kod zasad dotyczących dźwięku jest uporządkowany w sposób ułatwiający jego zrozumienie i utrzymanie, a jednocześnie obsługuje zasady dźwięku zdefiniowane wyłącznie przez pliki konfiguracji. Organizacja i projekt zasad dotyczących dźwięku są oparte na platformie Intel Parameter Framework, która jest platformą opartą na wtyczkach i regułach do obsługi parametrów.
Dzięki konfigurowalnej polityce dotyczącej dźwięku producenci OEM mogą:
- Opisz strukturę systemu i jego parametry w formacie XML.
- Aby uzyskać dostęp do opisanych parametrów, napisz (w C++) lub ponownie użyj backendu (wtyczki).
- Zdefiniuj (w XML-u lub w języku domeny) warunki lub reguły, według których dany parametr musi przyjmować określoną wartość.
AOSP zawiera przykładowy plik konfiguracji zasad audio, który korzysta z ramy parametrycznej (Frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
). Szczegółowe informacje znajdziesz w dokumentacji firmy Intel na temat ramy danych.
W Androidzie 10 i starszych wersjach zasada dotycząca dźwięku z możliwością konfigurowania jest wybierana za pomocą opcji kompilacji USE_CONFIGURABLE_AUDIO_POLICY
.
W Androidzie 11 lub nowszym wersja silnika zasad dotyczących dźwięku jest wybierana w pliku audio_policy_configuration.xml
.
Aby wybrać konfigurowalny mechanizm zasad dotyczących dźwięku, ustaw wartość atrybutu engine_library
elementu globalConfiguration
na configurable
, jak w tym przykładzie:
<audioPolicyConfiguration> <globalConfiguration engine_library="configurable" /> ... </audioPolicyConfiguration>
Interfejsy API routingu zasad audio
Android 6.0 wprowadził publiczny interfejs API Enumeration and Selection, który działa na podstawie infrastruktury łatki audio lub portu audio i umożliwia deweloperom aplikacji wskazanie preferowanego wyjścia lub wejścia na urządzeniu dla połączonych nagrań lub ścieżek audio.
W Androidzie 7.0 interfejs API do zliczania i wyboru jest weryfikowany przez testy CTS oraz rozszerzony o przekierowywanie natywnych strumieni audio C/C++ (OpenSL ES).
Przekierowywanie strumieni natywnych nadal odbywa się w języku Java, ale z dodatkiem interfejsu AudioRouting
, który zastępuje, łączy i wycofa jawne metody kierowania, które były specyficzne dla klas AudioTrack
i AudioRecord
.
Szczegółowe informacje o interfejsie Enumeration and Selection API znajdziesz w artykułach na temat interfejsów konfiguracji Androida oraz OpenSLES_AndroidConfiguration.h
.
Szczegółowe informacje o przesyłaniu dźwięku znajdziesz w artykule AudioRouting.
Pomoc dostępna w wielu kanałach
Jeśli sprzęt i sterownik obsługują dźwięk wielokanałowy przez HDMI, możesz przesyłać strumień audio bezpośrednio do sprzętu audio (omijając mikser AudioFlinger, dzięki czemu nie zostanie on zmiksowany do 2 kanałów). HAL dźwięku musi udostępniać informacje o tym, czy profil strumienia wyjściowego obsługuje funkcje dźwięku wielokanałowego. Jeśli HAL ujawnia swoje możliwości, domyślny menedżer zasad zezwala na odtwarzanie wielokanałowe przez HDMI. Szczegóły wdrażania znajdziesz w dokumentacji device/samsung/tuna/audio/audio_hw.c
.
Aby określić, że Twój produkt zawiera wyjście audio wielokanałowe, zmodyfikuj plik konfiguracji zasad dotyczących dźwięku, aby opisać wyjście wielokanałowe dla produktu. Ten przykład z frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml
pokazuje dynamiczną maskę kanału, co oznacza, że menedżer zasad dotyczących dźwięku wysyła zapytanie o maski kanałów obsługiwane przez odbiornik HDMI po połączeniu.
Przykład konfiguracji urządzenia HDMI
<module name="primary" halVersion="2.0"> <attachedDevices> <item>Speaker</item> </attachedDevices> <defaultOutputDevice>Speaker</defaultOutputDevice> <mixPorts> <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="direct" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT" /> <mixPort name="tunnel" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC" /> </mixPorts> <devicePorts> <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink" /> <devicePort tagName="Out Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink" encodedFormats="AUDIO_FORMAT_AC3 AUDIO_FORMAT_IEC61937" /> </devicePorts> <routes> <route type="mix" sink="Speaker" sources="primary output"/> <route type="mix" sink="Out Aux Digital" sources="primary output,direct,tunnel"/> </routes> </module>
Możesz też podać stałą maskę kanału, np. AUDIO_CHANNEL_OUT_5POINT1
. Mikser w AudioFlinger automatycznie konwertuje treści na dźwięk stereo, gdy zostaną wysłane na urządzenie audio, które nie obsługuje dźwięku wielokanałowego.
Kodeki multimediów
Upewnij się, że kodeki audio obsługiwane przez sprzęt i sterowniki są prawidłowo zadeklarowane w Twoim produkcie. Szczegółowe informacje znajdziesz w artykule Wyświetlanie kodeków w ramach frameworku.