AAOS ma własne zarządzanie głośnością w ramach CarAudioService
. Używa stałych poziomów głośności z założeniem, że poziomy te powinny być stosowane poniżej HAL przez wzmacniacz sprzętowy, a nie w oprogramowaniu. Urządzenia wyjściowe są też grupowane w grupy głośności, aby stosować te same wzmocnienia do wszystkich urządzeń powiązanych z grupą głośności.
Korzystanie z płyt o stałej objętości
W przypadku implementacji AAOS głośność powinna być kontrolowana za pomocą wzmacniacza sprzętowego, a nie miksera programowego. Aby uniknąć efektów ubocznych, ustaw flagę config_useFixedVolume
na wartość prawda (w razie potrzeby włóż nakładkę):
<resources> <!-- Car uses hardware amplifier for volume. --> <bool name="config_useFixedVolume">true</bool> </resources>
Jeśli flaga config_useFixedVolume
nie jest ustawiona (lub ma wartość Fałsz), aplikacje mogą wywoływać funkcję AudioManager.setStreamVolume()
i zmieniać głośność według typu strumienia w mikserze programowym. Może to być niepożądane ze względu na potencjalny wpływ na inne aplikacje oraz fakt, że tłumienie głośności w mikserze programowym powoduje, że w sygnale odbieranym przez wzmacniacz sprzętowy jest mniej znaczących bitów.
Grupy objętości
Grupy głośności zarządzają głośnością kolekcji urządzeń w strefie audio. Głośność każdej grupy można regulować niezależnie, a otrzymane wzmocnienia są konfigurowane na powiązanych urządzeniach, aby były stosowane przez wzmacniacz pojazdu. Ustawienia głośności są zapisywane dla użytkownika i wczytywane, gdy się zaloguje.
Definiowanie grup rabatowych
Usługa CarAudioService używa grup głośności zdefiniowanych w car_audio_configuration.xml
:
<audioZoneConfiguration version="2.0"> <zones> <zone name="primary zone" isPrimary="true"> <volumeGroups> <group> <device address="bus0_media_out"> <context context="music"/> </device> </group> <group> <device address="bus1_navigation_out"> <context context="navigation"/> </device> <device address="bus2_voice_command_out"> <context context="voice_command"/> </device> </group> ... </volumeGroups> </zone> </zones> </audioZoneConfiguration>
Przykładowa implementacja usługi car_audio_configuration.xml
.
Każda grupa głośności powinna zawierać co najmniej 1 urządzenie wyjściowe z powiązanymi adresami.
Te adresy powinny odpowiadać urządzeniom wyjściowym zdefiniowanym w pliku audio_policy_configuration.xml
.
Konfigurowanie zysków grupy objętości
Każda grupa głośności ma wartości minimalne, maksymalne i domyślne wartości wzmocnienia, a także wielkość kroku. Są one określane na podstawie wartości skonfigurowanych w audio_policy_configuration.xml
na urządzeniach powiązanych z grupą objętości.
<devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus0_media_out"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> <gains> <gain name="" mode="AUDIO_GAIN_MODE_JOINT" minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort>
Podczas inicjalizacji grupa głośności sprawdza wartości wzmocnienia powiązanych urządzeń i konfiguruje grupę w następujący sposób:
- Wielkość kroku. Musi być taka sama na wszystkich urządzeniach kontrolowanych przez grupę głośności.
- Minimalny przyrost. najmniejszy minimalny przyrost wśród urządzeń w grupie,
- Maksymalny przyrost. Największy maksymalny zysk wśród urządzeń w grupie
- Domyślny wzmocnienie. najwyższy domyślny zysk wśród urządzeń w grupie;
Ze względu na sposób konfiguracji tych wartości można ustawić wzmocnienie grupy głośności poza obsługiwanym zakresem dla urządzenia powiązanego z grupą głośności. W takim przypadku wzmocnienie zostanie ustawione na minimalną lub maksymalną wartość wzmocnienia urządzenia w zależności od tego, czy wartość grupy objętej objętością jest poniżej czy powyżej zakresu.
Identyfikatory grup wolumenów
Grupy wolumenów są identyfikowane w czasie wykonywania kodu według kolejności ich definicji w pliku XML.
Identyfikatory w strefie audio mają zakres od 0 do N-1, gdzie N to liczba grup głośności w tej strefie. W ten sposób identyfikatory grup woluminów nie są unikalne w różnych strefach. Te identyfikatory są używane w przypadku interfejsów API CarAudioManager
powiązanych z grupami objętości. Każdy interfejs API, który przyjmuje parametr groupId
bez parametru zoneId
, domyślnie przyjmie strefę audio głównego.
Zarządzanie głośnością w wielu strefach
Każda strefa dźwięku powinna mieć co najmniej 1 grupę głośności, a każda grupa głośności jest powiązana tylko z 1 strefą dźwięku. Ta relacja jest zdefiniowana w ramach car_audio_configuration.xml
. Zobacz przykład podany w sekcji Definiowanie grup woluminów powyżej.
Obecne poziomy głośności dla każdej strefy są zapisywane dla użytkownika powiązanego ze strefą. Te ustawienia są specyficzne dla strefy, co oznacza, że jeśli użytkownik zaloguje się na wyświetlaczu powiązanym ze strefą główną, a następnie zaloguje się w strefie powiązanej z dodatkową strefą audio, poziomy głośności załadowane i utrzymane w pierwszej strefie będą inne niż w strefie dodatkowej.
Obsługa zdarzeń związanych z klawiszem głośności
Android definiuje kilka kodów klawiszy do sterowania głośnością, m.in. KEYCODE_VOLUME_UP
, KEYCODE_VOLUME_DOWN
i KEYCODE_VOLUME_MUTE
. Domyślnie Android kieruje zdarzenia związane z klawiszem głośności do aplikacji. W przypadku wdrożeń w samochodach te kluczowe zdarzenia powinny być wymuszane w komponencie CarAudioService
, który może następnie wywołać komponent setGroupVolume
lub setMasterMute
w odpowiednich przypadkach.
Aby wymusić to zachowanie, ustaw flagę config_handleVolumeKeysInWindowManager
na true
:
<resources> <bool name="config_handleVolumeKeysInWindowManager">true</bool> </resources>
Zdarzenia związane z kluczem głośności nie pozwalają obecnie na rozróżnienie, do której strefy są przeznaczone. Zakłada się więc, że wszystkie są powiązane z główną strefą dźwiękową.
Gdy otrzymane zostanie zdarzenie związane z klawiszem głośności, CarAudioService
określa, którą grupę głośności ma dostosować, pobierając konteksty audio dla aktywnych odtwarzaczy, a następnie dostosowując grupę głośności, która zawiera urządzenie wyjściowe powiązane z kontekstem audio o najwyższym priorytecie. Priorytety są określane na podstawie ustalonej kolejności zdefiniowanej w CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY
.
Zanikanie i balans
Obie wersje interfejsu AudioControl HAL zawierają interfejsy API do ustawiania ścieżki dźwiękowej i balansu w samochodzie. Istnieją odpowiednie interfejsy API systemu dla CarAudioManager, które przekazują wartości do interfejsu AudioControl HAL. Te interfejsy API wymagają:
android.car.permission.CAR_CONTROL_AUDIO_VOLUME
.
Interfejsy API AudioControl:
setBalanceTowardRight(float value)
. Zmienia głośność głośnika w stronę prawej (+) lub lewej (-) strony samochodu. Wartość 0,0 jest wyśrodkowana, +1,0 – całkowicie po prawej stronie, -1,0 – całkowicie po lewej stronie, a wartość spoza zakresu -1–1 jest błędna.setFadeTowardFront(float value)
– przesuwa głośność głośnika w stronę przodu (+) lub tyłu (-) samochodu. Wartość 0,0 oznacza środek, +1,0 – całkowicie do przodu, -1,0 – całkowicie do tyłu, a wartość spoza zakresu -1–1 – błąd.
Producenci OEM muszą sami zdecydować, jak te wartości mają być stosowane i jak mają być wyświetlane użytkownikom. Mogą one dotyczyć tylko multimediów lub wszystkich dźwięków na Androidzie.
Android 11 wprowadził też obsługę efektów dźwiękowych na urządzeniach wyjściowych. Dzięki temu możesz zamiast tego zarządzać ściemnianiem i balansem za pomocą efektów dźwiękowych na odpowiednich urządzeniach wyjściowych, a nie za pomocą tych interfejsów API.
Wyciszanie tła
Wyciszanie dźwięku występuje, gdy pojazd zmniejsza wzmocnienie jednego strumienia, aby inny strumień odtwarzany w tym samym czasie był lepiej słyszalny. W AAOS funkcja wyciszania dźwięku jest implementowana przez HAL, ponieważ poza Androidem może być wiele dźwięków, nad którymi system nie ma kontroli. W Androidzie 11 główną informacją dostępną dla HAL w celu podejmowania decyzji o wyciszeniu jest to, czy oba urządzenia wyjściowe mają aktywne strumienie.
Kiedy się kłaść
Chociaż to poszczególni producenci OEM decydują, jak funkcja wyciszania będzie obsługiwana przez ich HAL, zalecamy przestrzeganie ogólnych wytycznych. Wiele strumieni odtwarzanych na Androidzie będzie najczęściej występować, gdy 2 aplikacje lub usługi będą jednocześnie mieć fokus audio. Pamiętaj o tym, gdy korzystasz z matrycy interakcji, aby dowiedzieć się, kiedy Android może przyznać równoczesny fokus, a co za tym idzie, kiedy możliwe jest odtwarzanie 2 różnych strumieni jednocześnie.
Pamiętaj, że wszystkie strumienie zmiksowane przez Androida zostaną zmiksowane przed zastosowaniem wzmocnienia. Dlatego każdy strumień, który powinien być wyciszony podczas odtwarzania równocześnie z innym, powinien być kierowany na osobne urządzenia wyjściowe, aby HAL mógł zastosować wyciszenie przed zmiksowaniem ich ze sobą.
Zalecane zachowanie podczas opuszczania
Poniżej przedstawiamy potencjalne jednoczesne interakcje, w których przypadku zalecamy zastosowanie tłumienia dźwięku:
EMERGENCY
. Wycisz wszystko opróczSAFETY
, aby kierowca słyszał dźwiękSAFETY
. Wycisz wszystko opróczEMERGENCY
, aby kierowca słyszał dźwiękNAVIGATION
. Omijaj wszystko opróczSAFETY
iEMERGENCY
CALL
. Unikaj wszystkiego opróczSAFETY
,EMERGENCY
iNAVIGATION
VOICE
. DuckCALL_RING
- Producenci OEM muszą określić znaczenie aktywnego
VEHICLE_SOUNDS
i to, czy inne dźwięki powinny być wyciszone, aby kierowca mógł je usłyszeć. MUSIC
iANNOUNCEMENT
powinny być ignorowane przez wszystko. Głównym wyjątkiem są dźwięki interakcji dotykowych, które są obecnie odtwarzane jako:SYSTEM_SOUND
Inne kwestie dotyczące wyciszania
Niektóre aplikacje lub usługi, takie jak nawigacja czy asystent, mogą używać wielu odtwarzaczy do wykonywania swoich działań. Producenci OEM powinni unikać zbyt agresywnego odtwarzania dźwięku na podstawie tego, kiedy dane strumienia przestają być przesyłane przez te urządzenia wyjściowe. Dzięki temu użytkownik nie będzie miał chwilowego powrotu do pełnej głośności dźwięku, zanim dźwięk zostanie ponownie wyciszony, gdy rozpocznie się następne odtwarzanie z aplikacji do nawigacji lub asystenta.
W przypadku pojazdów z wieloma etapami dźwiękowymi o wystarczającej izolacji istnieje też opcja przesyłania dźwięku do różnych obszarów samochodu zamiast wyciszania. Na przykład instrukcje nawigacji mogą być kierowane do głośników w zagłówku kierowcy, podczas gdy muzyka nadal będzie odtwarzana w całej kabinie z normalną głośnością.
Dźwięki związane z bezpieczeństwem
Chociaż w Androidzie 11 wprowadzono interfejsy API HAL dotyczące priorytetu dźwięku, to nadal to HAL odpowiada za zapewnienie, że dźwięki związane z bezpieczeństwem mają wyższy priorytet niż inne dźwięki. Nawet jeśli HAL ma fokus dźwiękowy dla USAGE_EMERGENCY
, nie oznacza to, że aplikacje i usługi w Androidzie nie będą odtwarzać dźwięków. To HAL decyduje, które strumienie z Androida powinny być zmiksowane lub wyciszone, gdy odtwarzane są dźwięki krytyczne dla bezpieczeństwa.
Konfigurowanie interfejsu ustawień głośności
AAOS oddziela interfejs ustawień głośności od konfiguracji grupy głośności (którą można nałożyć zgodnie z opisem w sekcji Konfigurowanie grup głośności). Dzięki temu nie trzeba wprowadzać żadnych zmian, jeśli w przyszłości zmieni się konfiguracja grup woluminów.
W interfejsie Ustawienia samochodu plik packages/apps/Car/Settings/res/xml/car_volume_items.xml
zawiera elementy interfejsu użytkownika (zasoby tytułu i ikony) powiązane z każdym zdefiniowanym plikiem AudioAttributes.USAGE
. Ten plik umożliwia prawidłowe renderowanie zdefiniowanego VolumeGroups
za pomocą zasobów powiązanych z pierwszym rozpoznanym użyciem zawartym w każdej grupie woluminów.
Na przykład w tym przykładzie grupa VolumeGroup obejmuje zarówno voice_communication
, jak i voice_communication_signalling
. Domyślna implementacja interfejsu ustawień samochodu renderuje grupę VolumeGroup za pomocą zasobów powiązanych z voice_communication
, ponieważ jest to pierwszy zasób w pliku.
<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto"> <item car:usage="voice_communication" car:title="@*android:string/volume_call" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="voice_communication_signalling" car:title="@*android:string/volume_call" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="media" car:title="@*android:string/volume_music" car:icon="@*android:drawable/ic_audio_media"/> <item car:usage="game" car:title="@*android:string/volume_music" car:icon="@*android:drawable/ic_audio_media"/> <item car:usage="alarm" car:title="@*android:string/volume_alarm" car:icon="@*android:drawable/ic_audio_alarm"/> <item car:usage="assistance_navigation_guidance" car:title="@string/navi_volume_title" car:icon="@drawable/ic_audio_navi"/> <item car:usage="notification_ringtone" car:title="@*android:string/volume_ringtone" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistant" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> <item car:usage="notification" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_request" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_instant" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_delayed" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_event" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistance_accessibility" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistance_sonification" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> <item car:usage="unknown" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> </carVolumeItems>
Atrybuty i wartości używane w powyżej opisanej konfiguracji są zadeklarowane w elementach packages/apps/Car/Settings/res/values/attrs.xml
. Ustawienia głośności
UI używa następujących interfejsów CarAudioManager opartych na VolumeGroup:
getVolumeGroupCount()
, aby dowiedzieć się, ile elementów sterujących należy narysować.getGroupMinVolume()
igetGroupMaxVolume()
, aby uzyskać dolną i górną granicę.getGroupVolume()
, aby uzyskać bieżącą głośność.registerVolumeChangeObserver()
, aby otrzymywać powiadomienia o zmianach głośności.