Audio samochodowe

Android Automotive OS (AAOS) opiera się na podstawowym stosie audio Androida, aby obsługiwać przypadki użycia jako system informacyjno-rozrywkowy w pojeździe. AAOS jest odpowiedzialny za dźwięki informacyjno-rozrywkowe (tj. multimedia, nawigację i komunikację), ale nie jest bezpośrednio odpowiedzialny za dzwonki i ostrzeżenia, które mają ścisłe wymagania dotyczące dostępności i czasu. Chociaż system AAOS zapewnia sygnały i mechanizmy pomagające pojazdowi zarządzać dźwiękiem, ostatecznie to od pojazdu zależy, jakie dźwięki powinny być odtwarzane kierowcy i pasażerom, zapewniając prawidłowe słyszenie dźwięków krytycznych dla bezpieczeństwa i dźwięków regulacyjnych, bez przerwanie.

Ponieważ system Android zarządza multimediami w pojeździe, zewnętrzne źródła multimediów, takie jak tuner radiowy, powinny być reprezentowane przez aplikacje, które mogą obsługiwać fokus audio i kluczowe zdarzenia multimedialne dla źródła.

Android 11 zawiera następujące zmiany w obsłudze dźwięku związanego z motoryzacją:

Dźwięki i strumienie na Androida

Samochodowe systemy audio obsługują następujące dźwięki i strumienie:

Diagram architektury skoncentrowanej na strumieniu

Rysunek 1. Schemat architektury skoncentrowanej na strumieniu

Android zarządza dźwiękami pochodzącymi z aplikacji na Androida, kontrolując te aplikacje i kierując ich dźwięki do urządzeń wyjściowych w HAL w oparciu o typ dźwięku:

  • Strumienie logiczne , znane jako źródła w podstawowej nomenklaturze audio, są oznaczone atrybutami audio .
  • Strumienie fizyczne , zwane urządzeniami w podstawowej nomenklaturze audio, po zmiksowaniu nie mają informacji kontekstowych.

Aby zapewnić niezawodność, dźwiękami zewnętrznymi (pochodzącymi z niezależnych źródeł, takimi jak sygnały ostrzegawcze o zapięciu pasów bezpieczeństwa) zarządza się poza systemem Android, poniżej warstwy HAL lub nawet na oddzielnym sprzęcie. Twórcy systemu muszą zapewnić mikser, który akceptuje jeden lub więcej strumieni dźwięku z systemu Android, a następnie łączy te strumienie w odpowiedni sposób z zewnętrznymi źródłami dźwięku wymaganymi przez pojazd.

Implementacja HAL i zewnętrzny mikser odpowiadają za zapewnienie, że krytyczne dla bezpieczeństwa dźwięki zewnętrzne będą słyszalne oraz za miksowanie strumieni dostarczanych przez Androida i kierowanie ich do odpowiednich głośników.

Dźwięki Androida

Aplikacje mogą mieć jeden lub więcej odtwarzaczy, które wchodzą w interakcję za pośrednictwem standardowych interfejsów API systemu Android (na przykład AudioManager do kontroli ostrości lub MediaPlayer do przesyłania strumieniowego), aby emitować jeden lub więcej logicznych strumieni danych audio. Dane te mogą być jednokanałowe, monofoniczne lub przestrzenne 7.1, ale są kierowane i traktowane jako pojedyncze źródło. Strumień aplikacji jest powiązany z atrybutami AudioAttributes , które dają systemowi wskazówki dotyczące sposobu wyrażania dźwięku.

Strumienie logiczne są wysyłane za pośrednictwem usługi AudioService i kierowane do jednego (i tylko jednego) dostępnych fizycznych strumieni wyjściowych, z których każdy jest wyjściem miksera w AudioFlinger. Po zmiksowaniu atrybutów audio do strumienia fizycznego nie są one już dostępne.

Każdy strumień fizyczny jest następnie dostarczany do warstwy audio HAL w celu renderowania na sprzęcie. W aplikacjach motoryzacyjnych sprzętem renderującym mogą być lokalne kodeki (podobnie jak w urządzeniach mobilnych) lub zdalny procesor w fizycznej sieci pojazdu. Tak czy inaczej, zadaniem implementacji Audio HAL jest dostarczenie rzeczywistych przykładowych danych i sprawienie, aby stały się one słyszalne.

Strumienie zewnętrzne

Strumienie dźwięku, które nie powinny być kierowane przez Androida (ze względów certyfikacyjnych lub czasowych), mogą być przesyłane bezpośrednio do zewnętrznego miksera. Począwszy od Androida 11, warstwa HAL może teraz zażądać skupienia się na dźwiękach zewnętrznych, aby poinformować system Android o konieczności podjęcia odpowiednich działań, takich jak wstrzymywanie multimediów lub uniemożliwianie innym uzyskania fokusu.

Jeśli zewnętrzne strumienie są źródłami multimediów, które powinny wchodzić w interakcję ze środowiskiem dźwiękowym generowanym przez Androida (na przykład zatrzymać odtwarzanie MP3 po włączeniu zewnętrznego tunera), te zewnętrzne strumienie powinny być reprezentowane przez aplikację na Androida. Taka aplikacja żądałaby fokusu audio w imieniu źródła multimediów zamiast HAL i reagowałaby na powiadomienia o fokusie, uruchamiając/zatrzymując źródło zewnętrzne, jeśli jest to konieczne, aby dopasować się do zasad fokusu Androida. Aplikacja jest również odpowiedzialna za obsługę kluczowych zdarzeń multimedialnych, takich jak odtwarzanie/pauza. Jednym z sugerowanych mechanizmów kontroli takich urządzeń zewnętrznych jest HwAudioSource .

Urządzenia zewnętrzne

Na poziomie Audio HAL urządzenie typu AUDIO_DEVICE_OUT_BUS zapewnia ogólne urządzenie wyjściowe do stosowania w systemach audio pojazdów. Urządzenie magistrali obsługuje porty adresowalne (gdzie każdy port jest punktem końcowym strumienia fizycznego) i oczekuje się, że będzie jedynym obsługiwanym typem urządzenia wyjściowego w pojeździe.

Implementacja systemu może wykorzystywać jeden port magistrali dla wszystkich dźwięków Androida, w takim przypadku Android miksuje wszystko razem i dostarcza jako jeden strumień. Alternatywnie, warstwa HAL może zapewnić jeden port magistrali dla każdego CarAudioContext , aby umożliwić jednoczesne dostarczanie dowolnego typu dźwięku. Umożliwia to implementacji HAL miksowanie i wyciszanie różnych dźwięków według potrzeb.

Przypisanie kontekstów audio do urządzeń wyjściowych odbywa się poprzez car_audio_configuration.xml .

Wejście mikrofonowe

Podczas przechwytywania dźwięku warstwa Audio HAL odbiera wywołanie openInputStream zawierające argument AudioSource wskazujący, w jaki sposób powinien być przetwarzany sygnał wejściowy z mikrofonu.

Źródło VOICE_RECOGNITION (w szczególności Asystent Google) oczekuje strumienia z mikrofonu stereofonicznego z efektem eliminacji echa (jeśli jest dostępny), ale nie zastosowano do niego żadnego innego przetwarzania. Oczekuje się, że kształtowanie wiązki będzie wykonywane przez Asystenta.

Wielokanałowe wejście mikrofonowe

Aby przechwycić dźwięk z urządzenia z więcej niż dwoma kanałami (stereo), użyj maski indeksu kanału zamiast maski indeksu pozycyjnego (takiej jak 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 ustawione są zarówno setChannelMask , jak i setChannelIndexMask , AudioRecord używa tylko wartości ustawionej przez setChannelMask (maksymalnie dwa kanały).

Równoczesne przechwytywanie

Począwszy od Androida 10, środowisko Androida obsługuje jednoczesne przechwytywanie danych wejściowych, ale z ograniczeniami mającymi na celu ochronę prywatności użytkownika. W ramach tych ograniczeń źródła wirtualne, takie jak AUDIO_SOURCE_FM_TUNER , są ignorowane i jako takie mogą być przechwytywane jednocześnie ze zwykłym sygnałem wejściowym (takim jak mikrofon). HwAudioSources również nie są uwzględniane w ramach ograniczeń jednoczesnego przechwytywania.

Aplikacje zaprojektowane do współpracy z urządzeniami AUDIO_DEVICE_IN_BUS lub dodatkowymi urządzeniami AUDIO_DEVICE_IN_FM_TUNER muszą polegać na jawnej identyfikacji tych urządzeń i użyciu AudioRecord.setPreferredDevice() w celu ominięcia domyślnej logiki wyboru źródła Androida.

Zastosowania audio

AAOS wykorzystuje przede wszystkim AudioAttributes.AttributeUsages do routingu, regulacji głośności i zarządzania fokusem. Zwyczaje reprezentują „dlaczego” odtwarzany jest strumień. Dlatego wszystkie strumienie i żądania fokusu audio powinny określać sposób ich odtwarzania. Jeśli nie zostanie to specjalnie ustawione podczas budowania obiektu AudioAttributes, użycie zostanie domyślnie ustawione na USAGE_UNKNOWN . Chociaż jest to obecnie traktowane tak samo jak USAGE_MEDIA , nie należy polegać na tym zachowaniu w przypadku odtwarzania multimediów.

Zastosowania systemu

W Androidzie 11 wprowadzono zastosowania systemowe. Te zastosowania zachowują się podobnie do wcześniej ustalonych zastosowań, z tą różnicą, że wymagają użycia systemowych interfejsów API oraz android.permission.MODIFY_AUDIO_ROUTING . Nowe zastosowania systemu to:

  • USAGE_EMERGENCY
  • USAGE_SAFETY
  • USAGE_VEHICLE_STATUS
  • USAGE_ANNOUNCEMENT

Aby skonstruować AudioAttributes przy użyciu systemu, użyj AudioAttributes.Builder#setSystemUsage zamiast setUsage . Wywołanie tej metody w przypadku użycia innego niż systemowe spowoduje zgłoszenie wyjątku IllegalArgumentException . Ponadto, jeśli w kreatorze ustawiono zarówno użycie systemu, jak i użycie, podczas budowania zostanie zgłoszony IllegalArgumentException .

Aby sprawdzić, jakie użycie jest powiązane z instancją AudioAttributes , wywołaj AudioAttributes#getSystemUsage . Zwraca to użycie lub użycie systemu, które jest powiązane.

Konteksty dźwiękowe

Aby uprościć konfigurację dźwięku AAOS, podobne zastosowania zostały pogrupowane w CarAudioContext . Te konteksty audio są używane w CarAudioService do definiowania routingu, grup głośności i zarządzania fokusem audio.

Konteksty audio w systemie Android 11 to:

Kontekst audio samochodu Powiązane atrybutyUżycia
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 audio i zastosowań. Podświetlone wiersze dotyczą nowych zastosowań systemu .

Dźwięk wielostrefowy

W branży motoryzacyjnej pojawia się nowy zestaw przypadków użycia obejmujących równoczesnych użytkowników wchodzących w interakcję z platformą i chcących korzystać z oddzielnych multimediów. Na przykład kierowca może odtwarzać muzykę w kabinie, podczas gdy pasażerowie na tylnym siedzeniu oglądają film z YouTube'a na tylnym wyświetlaczu. Umożliwia to wielostrefowy dźwięk, umożliwiając jednoczesne odtwarzanie różnych źródeł dźwięku w różnych obszarach pojazdu.

Dźwięk wielostrefowy, począwszy od systemu Android 10, umożliwia producentom OEM konfigurowanie dźwięku w oddzielnych strefach. Każda strefa to zbiór urządzeń w pojeździe z własnymi grupami woluminów, konfiguracją routingu dla kontekstów i zarządzaniem fokusem. W ten sposób główną kabinę można skonfigurować jako jedną strefę audio, a gniazda słuchawkowe tylnego wyświetlacza jako drugą strefę.

Strefy są zdefiniowane w pliku car_audio_configuration.xml . Następnie CarAudioService odczytuje konfigurację i pomaga AudioService kierować strumienie audio w oparciu o powiązaną z nimi strefę. Każda strefa nadal definiuje reguły routingu w oparciu o konteksty i identyfikator UID aplikacji. Po utworzeniu odtwarzacza CarAudioService określa, do której strefy jest on powiązany, a następnie w oparciu o wykorzystanie, do jakiego urządzenia AudioFlinger powinien skierować dźwięk.

Ostrość jest także utrzymywana niezależnie dla każdej strefy audio. Dzięki temu aplikacje znajdujące się w różnych strefach mogą niezależnie generować dźwięk bez wzajemnego zakłócania się, a aplikacje nadal uwzględniają zmiany ostrości w obrębie swojej strefy. CarZonesAudioFocus w ramach CarAudioService odpowiada za zarządzanie fokusem dla każdej strefy.

Skonfiguruj dźwięk wielostrefowy

Rysunek 2. Skonfiguruj dźwięk wielostrefowy

Dźwięk HAL

Implementacje audio w samochodach opierają się na standardowym systemie Android Audio HAL, który obejmuje:

  • IDevice.hal . Tworzy strumienie wejściowe i wyjściowe, obsługuje główną głośność i wyciszanie oraz wykorzystuje:
    • createAudioPatch . Aby utworzyć łatki zewnętrzne-zewnętrzne między urządzeniami.
    • IDevice.setAudioPortConfig() w celu zapewnienia głośności dla każdego strumienia fizycznego.
  • IStream.hal . Wraz z wariantami wejściowymi i wyjściowymi zarządza przesyłaniem strumieniowym próbek audio do i ze sprzętu.

Typy urządzeń motoryzacyjnych

Poniższe typy urządzeń dotyczą platform samochodowych.

Rodzaj urządzenia Opis
AUDIO_DEVICE_OUT_BUS Podstawowe wyjście z systemu Android (w ten sposób cały dźwięk z systemu Android jest dostarczany do pojazdu). Używany jako adres do ujednoznaczniania strumieni dla każdego kontekstu.
AUDIO_DEVICE_OUT_TELEPHONY_TX Używany do przesyłania sygnału audio kierowanego do radia komórkowego.
AUDIO_DEVICE_IN_BUS Używane do wejść niesklasyfikowanych inaczej.
AUDIO_DEVICE_IN_FM_TUNER Używane tylko do wejścia radiowego.
AUDIO_DEVICE_IN_TV_TUNER Używane do urządzenia telewizyjnego, jeśli jest obecne.
AUDIO_DEVICE_IN_LINE Używany do gniazda wejściowego AUX.
AUDIO_DEVICE_IN_BLUETOOTH_A2DP Muzyka odbierana przez Bluetooth.
AUDIO_DEVICE_IN_TELEPHONY_RX Używany do dźwięku odbieranego z radia komórkowego powiązanego z połączeniem telefonicznym.

Konfiguracja urządzeń audio

Urządzenia audio widoczne dla systemu Android muszą być zdefiniowane w /audio_policy_configuration.xml , który zawiera następujące komponenty:

  • Nazwa modułu. Obsługuje „podstawowy” (używany w zastosowaniach motoryzacyjnych), „A2DP”, „remote_submix” i „USB”. Nazwę modułu i odpowiadający mu sterownik audio należy skompilować do audio.primary.$(variant).so .
  • Porty urządzeń. Zawiera listę deskryptorów urządzeń dla wszystkich urządzeń wejściowych i wyjściowych (w tym urządzeń podłączonych na stałe i urządzeń wymiennych), do których można uzyskać dostęp z tego modułu.
    • Dla każdego urządzenia wyjściowego można zdefiniować kontrolę wzmocnienia, która składa się z wartości min./maks./domyślnej/kroku w milibelach (1 milibel = 1/100 dB = 1/1000 bela).
    • Atrybut adresu instancji DevicePort może zostać użyty do znalezienia urządzenia, nawet jeśli istnieje wiele urządzeń tego samego typu co AUDIO_DEVICE_OUT_BUS .
  • mixPorty. Zawiera listę wszystkich strumieni wyjściowych i wejściowych udostępnianych przez warstwę audio HAL. Każdą instancję mixPort można uznać za fizyczny strumień do Android AudioService.
  • trasy. Definiuje listę możliwych połączeń pomiędzy urządzeniami wejściowymi i wyjściowymi lub pomiędzy strumieniem a urządzeniem.

Poniższy przykład definiuje urządzenie wyjściowe bus0_phone_out, w którym wszystkie strumienie audio Androida są miksowane przez mikser_bus0_phone_out. Trasa przenosi strumień wyjściowy mixer_bus0_phone_out do urządzenia 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>