System operacyjny Android Automotive (AAOS) opiera się na podstawowym pakiecie audio Androida, aby obsługiwać przypadki użycia systemu multimedialnego w samochodzie. AAOS odpowiada za dźwięki systemów informacyjno-rozrywkowych (czyli dźwięki związane z multimediami, nawigacją i komunikacją), ale nie odpowiada bezpośrednio za sygnały dźwiękowe i ostrzeżenia, które mają ścisłe wymagania dotyczące dostępności i czasu. Chociaż AAOS udostępnia sygnały i mechanizmy, które pomagają pojazdowi zarządzać dźwiękiem, to ostatecznie to pojazd decyduje, jakie dźwięki powinny być odtwarzane dla kierowcy i pasażerów, aby zapewnić prawidłowe odtwarzanie dźwięków związanych z bezpieczeństwem i dźwięków regulowanych bez zakłóceń.
Ponieważ Android zarządza multimediami w samochodzie, zewnętrzne źródła multimediów, takie jak tuner radiowy, powinny być reprezentowane przez aplikacje, które mogą obsługiwać zdarzenia dotyczące skupienia na dźwięku i kluczy multimedialnych dla źródła.
Android 11 wprowadza następujące zmiany w obsługiwaniu dźwięku w samochodach:
- Automatyczny wybór strefy dźwięku na podstawie powiązanego identyfikatora User ID
- Nowe zastosowania systemu do obsługi dźwięków związanych z samochodem
- Obsługa ostrości dźwięku HAL
- Opóźnione skupienie na dźwięku w przypadku strumieni nieprzelotnych
- Ustawienie użytkownika umożliwiające kontrolowanie interakcji między nawigacją a wywołaniami
Dźwięki i strumienie z Androida
Systemy audio w pojazdach obsługują te dźwięki i strumienie:
Rysunek 1. Schemat architektury skoncentrowanej na strumieniu
Android zarządza dźwiękami pochodzącymi z aplikacji, kontrolując te aplikacje i przekierowując ich dźwięki do urządzeń wyjściowych w HAL na podstawie typu dźwięku:
- Strumienie logiczne, czyli źródła w podstawowej nomenklaturze audio, są oznaczane za pomocą atrybutów audio.
- Stremy fizyczne, czyli urządzenia w podstawowej nomenklaturze audio, nie zawierają informacji kontekstowych po zmiksowaniu.
Ze względu na niezawodność dźwięki zewnętrzne (pochodzące z niezależnych źródeł, takich jak sygnały ostrzegawcze dotyczące pasów bezpieczeństwa) są zarządzane poza Androidem, poniżej HAL lub nawet na osobnym sprzęcie. Implementatorzy systemu muszą zapewnić mikser, który przyjmuje co najmniej 1 strumień wejściowy dźwięku z Androida, a następnie łączy te strumienie w odpowiednim sposób z zewnętrznych źródeł dźwięku wymaganych przez pojazd.
Implementacja HAL i zewnętrzny mikser odpowiadają za to, aby dźwięki zewnętrzne istotne z punktu widzenia bezpieczeństwa były słyszalne, a także za miksowanie strumieni danych udostępnianych przez Androida i przekierowywanie ich do odpowiednich głośników.
Dźwięki w Androidzie
Aplikacje mogą mieć co najmniej 1 odtwarzacz, który współpracuje ze standardowymi interfejsami API Androida (np. AudioManager do kontrolowania ostrości lub MediaPlayer do strumieniowego przesyłania danych), aby emitować co najmniej 1 logiczny strumień danych audio. Te dane mogą być mono mono lub dźwiękiem przestrzennym 7.1, ale są kierowane i traktowane jako pojedyncze źródło. Strumień aplikacji jest powiązany z atrybutami audio, które podpowiadają systemowi, jak powinien brzmieć dźwięk.
Strumienie logiczne są wysyłane przez AudioService i przekierowywane do jednego (i tylko jednego) z dostępnych fizycznych strumieni wyjściowych, z których każdy jest wyjściem miksera w AudioFlinger. Gdy atrybuty dźwiękowe zostaną zmiksowane do fizycznego strumienia, nie są już dostępne.
Następnie każdy fizyczny strumień jest dostarczany do Audio HAL w celu renderowania na sprzęcie. W przypadku aplikacji samochodowych sprzęt do renderowania może być lokalnym kodekiem (podobnie jak w przypadku urządzeń mobilnych) lub zdalnym procesorem w ramach fizycznej sieci pojazdu. W obu przypadkach zadaniem implementacji interfejsu Audio HAL jest dostarczenie rzeczywistych danych próbkowania i ustawienie ich tak, aby były słyszalne.
strumieniowanie zewnętrzne,
Strumienie dźwięku, które nie powinny być kierowane przez Androida (ze względów certyfikacyjnych lub ze względów związanych z synchronizacją), mogą być wysyłane bezpośrednio do zewnętrznego miksera. Od Androida 11 interfejs HAL może żądać skupienia na tych zewnętrznych dźwiękach, aby poinformować Androida, aby mógł podjąć odpowiednie działania, takie jak wstrzymanie multimediów lub uniemożliwienie innym aplikacji przejęcia kontroli.
Jeśli strumienie zewnętrzne to źródła multimediów, które powinny wchodzić w interakcje ze środowiskiem dźwiękowym generowanym przez Androida (np. zatrzymywać odtwarzanie MP3, gdy włączony jest tuner zewnętrzny), powinny być reprezentowane przez aplikację na Androida. Taka aplikacja będzie prosić o skupienie dźwięku w imieniu źródła multimediów zamiast HAL i będzie odpowiadać na powiadomienia o skupieniu, uruchamiając lub zatrzymując źródło zewnętrzne w sposób zgodny z zasadami Androida dotyczącymi skupienia. Aplikacja jest też odpowiedzialna za obsługę kluczowych zdarzeń związanych z multimediami, takich jak odtwarzanie/wstrzymanie. Jednym z zalecanych mechanizmów sterowania takimi urządzeniami zewnętrznymi jest HwAudioSource.
Urządzenia wyjściowe
Na poziomie Audio HAL typ urządzenia AUDIO_DEVICE_OUT_BUS
stanowi ogólne urządzenie wyjściowe do użytku w systemach audio pojazdu. Urządzenie z interfejsem magistrali obsługuje adresowalne porty (gdzie każdy port jest punktem końcowym fizycznego strumienia) i ma być jedynym obsługiwanym typem urządzenia wyjściowego w pojazdzie.
Implementacja systemu może używać jednego portu magistrali do wszystkich dźwięków Androida. W takim przypadku Android miksuje wszystkie dźwięki i przesyła je jako jeden strumień.
Alternatywnie HAL może udostępnić jeden port magistrali dla każdego CarAudioContext
, aby umożliwić jednoczesną dostawę dowolnego typu dźwięku. Dzięki temu implementacja HAL może miksować i zmieniać głośność różnych dźwięków zgodnie z potrzebami.
Przypisywanie kontekstów audio do urządzeń wyjściowych odbywa się za pomocą car_audio_configuration.xml
.
Dane wejściowe z mikrofonu
Podczas rejestrowania dźwięku interfejs Audio HAL otrzymuje wywołanie openInputStream
, które zawiera argument AudioSource
wskazujący, jak przetwarzać dane wejściowe z mikrofonu.
Źródło VOICE_RECOGNITION
(w szczególności Asystent Google) oczekuje strumienia mikrofonu stereo, który zawiera efekt redukcji echa (jeśli jest dostępny), ale nie ma żadnego innego przetwarzania.
Beamforming powinien być wykonywany przez Asystenta.
Wielokanałowy mikrofon
Aby rejestrować dźwięk z urządzenia z więcej niż 2 kanałami (stereo), użyj maski indeksu kanału zamiast maski indeksu pozycyjnego (np. CHANNEL_IN_LEFT
). Przykład:
final AudioFormat audioFormat = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(44100) .setChannelIndexMask(0xf /* 4 channels, 0..3 */) .build(); final AudioRecord audioRecord = new AudioRecord.Builder() .setAudioFormat(audioFormat) .build(); audioRecord.setPreferredDevice(someAudioDeviceInfo);
Gdy ustawisz zarówno setChannelMask
, jak i setChannelIndexMask
, AudioRecord
będzie używać tylko wartości ustawionej przez setChannelMask
(maksymalnie 2 kanały).
Równoczesne przechwytywanie
Od Androida 10 platforma Android obsługuje jednoczesne rejestrowanie danych wejściowych, ale z ograniczeniami, które chronią prywatność użytkownika. W ramach tych ograniczeń źródła wirtualne, takie jak AUDIO_SOURCE_FM_TUNER
, są ignorowane, dzięki czemu można je rejestrować jednocześnie z normalnym wejściem (np. mikrofonem).
HwAudioSources
nie są też uwzględniane w ramach ograniczeń dotyczących jednoczesnego przechwytywania.
Aplikacje zaprojektowane do działania na urządzeniach AUDIO_DEVICE_IN_BUS
lub na urządzeniach pomocniczych AUDIO_DEVICE_IN_FM_TUNER
muszą wyraźnie identyfikować te urządzenia i korzystać z funkcji AudioRecord.setPreferredDevice()
, aby ominąć domyślną logikę wyboru źródła w Androidzie.
Zastosowania dźwięku
AAOS wykorzystuje głównie
AudioAttributes.AttributeUsages
do routingu, regulacji głośności i zarządzania ostrością. Użycia to reprezentacja „dlaczego” strumień jest odtwarzany. Dlatego wszystkie żądania dotyczące strumieni i żądania dotyczące dźwięku powinny określać sposób odtwarzania dźwięku. Jeśli podczas tworzenia obiektu AudioAttributes nie zostanie określony, domyślnie zostanie ustawiona wartość USAGE_UNKNOWN
. Obecnie jest ono traktowane tak samo jak USAGE_MEDIA
, ale nie należy polegać na tym podczas odtwarzania multimediów.
Wykorzystanie przez system
W Androidzie 11 wprowadzono użycie systemu. Te zastosowania działają podobnie do wcześniej ustalonych zastosowań, z tym wyjątkiem, że wymagają interfejsów API systemu i interfejsu android.permission.MODIFY_AUDIO_ROUTING
. Nowe zastosowania systemu:
USAGE_EMERGENCY
USAGE_SAFETY
USAGE_VEHICLE_STATUS
USAGE_ANNOUNCEMENT
Aby utworzyć AudioAttributes
z użyciem systemu, użyj AudioAttributes.Builder#setSystemUsage
zamiast setUsage
. Wywołanie tej metody w celu niesystematycznym spowoduje wyjątek IllegalArgumentException
. Jeśli w kreatorze ustawisz zarówno użycie systemu, jak i użycie, podczas kompilowania wystąpi błąd IllegalArgumentException
.
Aby sprawdzić, jakie użycie jest powiązane z instancją AudioAttributes
, wywołaj funkcję AudioAttributes#getSystemUsage
.
Zwraca powiązane dane o korzystaniu z aplikacji lub systemu.
Konteksty audio
Aby uprościć konfigurację dźwięku w AAOS, podobne zastosowania zostały pogrupowane w grupę CarAudioContext
. Te konteksty audio są używane w całym CarAudioService
do definiowania routingu, grup głośności i zarządzania skupieniem dźwięku.
Konteksty dźwięku w Androidzie 11:
CarAudioContext | Powiązane atrybutyUsages |
---|---|
MUSIC |
UNKNOWN, GAME, MEDIA |
NAVIGATION |
ASSISTANCE_NAVIGATION_GUIDANCE |
VOICE_COMMAND |
ASSISTANT, ASSISTANCE_ACCESSIBILITY |
CALL_RING |
NOTIFICATION_RINGTONE |
CALL |
VOICE_COMMUNICATION, VOICE_COMMUNICATION_SIGNALING |
ALARM |
ALARM |
NOTIFICATION |
NOTIFICATION, NOTIFICATION_* |
SYSTEM_SOUND |
ASSISTANCE_SONIFICATION |
EMERGENCY |
EMERGENCY |
SAFETY |
SAFETY |
VEHICLE_STATUS |
VEHICLE_STATUS |
ANNOUNCEMENT |
ANNOUNCEMENT |
mapowanie kontekstów i zastosowanie dźwięku; Wyróżnione wiersze dotyczą nowych użytków systemu.
Dźwięk wielostrefowy
W przypadku branży motoryzacyjnej pojawia się nowy zestaw przypadków użycia dotyczących jednoczesnych użytkowników, którzy korzystają z platformy i chcą korzystać z różnych mediów. Na przykład kierowca może odtwarzać muzykę w kabinie, podczas gdy pasażerowie na tylnym siedzeniu oglądają film w YouTube na wyświetlaczu z tyłu. Umożliwia to dźwięk wielostrefowy, który pozwala na odtwarzanie różnych źródeł dźwięku w różnych obszarach pojazdu jednocześnie.
Tryb dźwięku wielostrefowego, który pojawił się w Androidzie 10, umożliwia producentom urządzeń z systemem Android konfigurowanie dźwięku w oddzielnych strefach. Każda strefa to zbiór urządzeń w pojazdzie z własnymi grupami głośności, konfiguracją routingu dla kontekstów i zarządzaniem skupieniem. W ten sposób kabina główna może być skonfigurowana jako jedna strefa audio, a gniazda słuchawek na tylnym ekranie jako druga strefa.
Strefy są definiowane w ramach car_audio_configuration.xml
.
CarAudioService
odczytuje konfigurację i pomoże usłudze AudioService przekierowywać strumienie audio na podstawie powiązanej strefy. Każda strefa nadal definiuje reguły routingu na podstawie kontekstów i identyfikatorów aplikacji. Gdy tworzony jest odtwarzacz, CarAudioService
określa, z jaką strefą jest powiązany, a następnie na podstawie sposobu użycia określa, na które urządzenie AudioFlinger powinien przekierować dźwięk.
Ustawienie to jest również utrzymywane niezależnie w przypadku każdej strefy dźwięku. Dzięki temu aplikacje w różnych strefach mogą niezależnie od siebie generować dźwięk bez zakłócania się nawzajem, a jednocześnie uwzględniać zmiany w fokusie w swojej strefie. CarZonesAudioFocus
w CarAudioService
odpowiada za zarządzanie fokusem w poszczególnych strefach.
Rysunek 2. Konfigurowanie dźwięku wielostrefowego
Interfejs HAL dźwięku
Implementacje audio w samochodach korzystają ze standardowego interfejsu HAL Androida Audio, który obejmuje:
IDevice.hal
. Tworzy strumienie wejściowe i wyjściowe, obsługuje główną głośność i wyciszanie oraz używa:createAudioPatch
. Aby tworzyć poprawki zewnętrzne między urządzeniami.IDevice.setAudioPortConfig()
, aby określić głośność dla każdego fizycznego strumienia.
IStream.hal
. Wraz z wariantami wejścia i wyjścia zarządza strumieniowaniem próbek audio do i z urządzenia.
Typy urządzeń samochodowych
W przypadku platform samochodowych istotne są te typy urządzeń:
Typ urządzenia | Opis |
---|---|
AUDIO_DEVICE_OUT_BUS |
Podstawowe wyjście z Androida (w ten sposób wszystkie dźwięki z Androida są dostarczane do pojazdu). Służy jako adres do rozróżniania strumieni w ramach każdego kontekstu. |
AUDIO_DEVICE_OUT_TELEPHONY_TX |
Używany do dźwięku kierowanego do radia komórkowego w celu transmisji. |
AUDIO_DEVICE_IN_BUS |
Używany w przypadku danych wejściowych, które nie zostały zaklasyfikowane w inny sposób. |
AUDIO_DEVICE_IN_FM_TUNER |
Służy tylko do wprowadzania danych z radia nadawczego. |
AUDIO_DEVICE_IN_TV_TUNER |
Używany w przypadku telewizora, jeśli jest dostępny. |
AUDIO_DEVICE_IN_LINE |
Służy do gniazda wejściowego AUX. |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
Muzyka odbierana przez Bluetooth. |
AUDIO_DEVICE_IN_TELEPHONY_RX |
Służy do odtwarzania dźwięku z radia komórkowego powiązanego z połączeniem telefonicznym. |
Konfigurowanie urządzeń audio
Urządzenia audio widoczne dla Androida muszą być zdefiniowane w pliku /audio_policy_configuration.xml
, który zawiera te komponenty:
- nazwa modułu. Obsługuje „primary” (używane w przypadku zastosowań motoryzacyjnych), „A2DP”, „remote_submix” i „USB”. Nazwa modułu i odpowiadający mu sterownik audio powinny zostać skompilowane do
audio.primary.$(variant).so
. - devicePorts. Zawiera listę deskryptorów urządzeń dla wszystkich urządzeń wejściowych i wyjściowych (w tym urządzeń trwale podłączonych i wymiennych), do których można uzyskać dostęp z tego modułu.
- W przypadku każdego urządzenia wyjściowego możesz zdefiniować kontrolę wzmocnienia, która składa się z wartości min/max/domyślna/krok w miliblach (1 milibel = 1/100 dB = 1/1000 bel).
- Atrybutu adresu w przypadku instancji devicePort można użyć do znalezienia urządzenia, nawet jeśli jest kilka urządzeń tego samego typu co
AUDIO_DEVICE_OUT_BUS
. - mixPorts. Zawiera listę wszystkich strumieni wyjściowych i wejściowych udostępnionych przez HAL audio. Każda instancja mixPort może być traktowana jako fizyczny strumień do usługi Android AudioService.
- tras. Określa listę możliwych połączeń między urządzeniami wejściowymi i wyjściowymi lub między strumieniem a urządzeniem.
W tym przykładzie definiujemy wyjściowe urządzenie bus0_phone_out, w którym wszystkie strumienie audio z Androida są miksowane przez mixer_bus0_phone_out. Trasa przenosi strumień wyjściowy z mixer_bus0_phone_out
na urządzenie bus0_phone_out
.
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>bus0_phone_out</item> <defaultOutputDevice>bus0_phone_out</defaultOutputDevice> <mixPorts> <mixPort name="mixport_bus0_phone_out" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="bus0_phone_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="BUS00_PHONE"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> <gains> <gain name="" mode="AUDIO_GAIN_MODE_JOINT" minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort> </devicePorts> <routes> <route type="mix" sink="bus0_phone_out" sources="mixport_bus0_phone_out"/> </routes> </module> </modules> </audioPolicyConfiguration>