Zarządzanie głośnością

AAOS ma własne zarządzanie głośnością w ramach CarAudioService . Wykorzystuje stałe poziomy głośności, zakładając, że poziomy głośności powinny być stosowane poniżej HAL za pomocą wzmacniacza sprzętowego, a nie oprogramowania. Organizuje także urządzenia wyjściowe w grupy woluminów, aby zastosować te same wzmocnienia do wszystkich urządzeń powiązanych z grupą woluminów.

Używanie stałych woluminów

Implementacje AAOS powinny kontrolować głośność za pomocą wzmacniacza sprzętowego zamiast miksera programowego. Aby uniknąć skutków ubocznych, ustaw flagę config_useFixedVolume na true (w razie potrzeby nałóż):

<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ść false), aplikacje mogą wywołać funkcję AudioManager.setStreamVolume() i zmienić 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 zastosowania oraz fakt, że tłumienie głośności w mikserze programowym skutkuje mniejszą liczbą znaczących bitów dostępnych w sygnale odbieranym przez wzmacniacz sprzętowy.

Grupy woluminów

Grupy woluminów zarządzają głośnością zbioru urządzeń w strefie audio. Dla każdej grupy głośności można niezależnie regulować głośność, a uzyskane wzmocnienia konfigurować na powiązanych urządzeniach, aby zastosować je we wzmacniaczu pojazdu. Ustawienia głośności są zachowywane dla użytkownika i ładowane, gdy użytkownik się zaloguje.

Definiowanie grup woluminów

CarAudioService korzysta z grup woluminów 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 car_audio_configuration.xml .

Każda grupa woluminów powinna zawierać jedno lub więcej urządzeń wyjściowych z powiązanymi adresami. Adresy te powinny odpowiadać urządzeniom wyjściowym zdefiniowanym w audio_policy_configuration.xml .

Konfigurowanie wzmocnień grup woluminów

Każda grupa woluminów ma 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 dla urządzeń powiązanych z grupą woluminów.

<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 woluminów sprawdzi wartości wzmocnienia powiązanych urządzeń i skonfiguruje grupę w następujący sposób:

  • Rozmiar kroku. Musi być taki sam dla wszystkich urządzeń kontrolowanych przez grupę woluminów
  • Minimalny zysk. Najmniejsze minimalne wzmocnienie wśród urządzeń w grupie
  • Maksymalny zysk. Największe maksymalne wzmocnienie wśród urządzeń w grupie
  • Domyślne wzmocnienie. Największe domyślne wzmocnienie wśród urządzeń w grupie

Ze względu na sposób skonfigurowania tych wartości możliwe jest ustawienie wzmocnienia grupy woluminów poza zakresem obsługiwanym przez urządzenie powiązane z tą grupą woluminów. W takim przypadku dla tego urządzenia wzmocnienie zostanie ustawione na minimalną lub maksymalną wartość wzmocnienia urządzenia w zależności od tego, czy wartość grupy głośności znajduje się poniżej, czy powyżej zakresu.

Identyfikatory grup woluminów

Grupy woluminów są identyfikowane w czasie wykonywania na podstawie kolejności ich definicji w pliku XML. Identyfikatory mieszczą się w zakresie od 0 do N-1 w strefie audio, gdzie N to liczba grup głośności w tej strefie. Dzięki temu identyfikatory grup woluminów nie są unikalne w poszczególnych strefach. Identyfikatory te są używane w interfejsach API CarAudioManager powiązanych z grupami woluminów. Każdy interfejs API, który przyjmuje groupId bez zoneId , domyślnie będzie wskazywał główną strefę audio.

Zarządzanie głośnością w wielu strefach

Oczekuje się, że każda strefa audio będzie mieć jedną lub więcej grup głośności, a każda grupa głośności będzie powiązana tylko z jedną strefą audio. Ta relacja jest zdefiniowana jako część pliku car_audio_configuration.xml . Zobacz przykład podany w sekcji Definiowanie grup woluminów powyżej.

Bieżące poziomy głośności dla każdej strefy są zachowywane dla użytkownika powiązanego z tą strefą. Ustawienia te są specyficzne dla strefy, co oznacza, że ​​jeśli użytkownik zaloguje się na wyświetlaczu powiązanym ze strefą podstawową, a następnie zaloguje się do strefy powiązanej z dodatkową strefą audio, poziomy głośności załadowane i zachowane dla pierwszej strefy będą inne niż te dla strefy wtórnej.

Obsługa zdarzeń związanych z kluczem głośności

Android definiuje kilka kodów klawiszy do regulacji głośności, w tym KEYCODE_VOLUME_UP , KEYCODE_VOLUME_DOWN i KEYCODE_VOLUME_MUTE . Domyślnie system Android kieruje zdarzenia związane z klawiszami głośności do aplikacji. Implementacje motoryzacyjne powinny wymuszać te kluczowe zdarzenia na CarAudioService , która może następnie wywołać odpowiednio setGroupVolume lub setMasterMute .

Aby wymusić to zachowanie, ustaw flagę config_handleVolumeKeysInWindowManager na true :

<resources>
    <bool name="config_handleVolumeKeysInWindowManager">true</bool>
</resources>

Zdarzenia związane z klawiszami głośności nie pozwalają obecnie na rozróżnienie, do której strefy są przeznaczone, dlatego zakłada się, że wszystkie są powiązane z główną strefą audio. Po odebraniu zdarzenia związanego z kluczem głośności CarAudioService określa, którą grupę głośności należy dostosować, pobierając konteksty audio dla aktywnych odtwarzaczy, a następnie dostosowując grupę głośności zawierającą urządzenie wyjściowe powiązane z kontekstem audio o najwyższym priorytecie. Priorytety ustalane są na podstawie ustalonej kolejności określonej w CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY .

Zanik i równowaga

Obie wersje AudioControl HAL zawierają interfejsy API do ustawiania zanikania i balansu w pojeździe. Istnieją odpowiednie interfejsy API systemu dla CarAudioManager, które przekazują wartości do warstwy HAL AudioControl. Te interfejsy API wymagają android.car.permission.CAR_CONTROL_AUDIO_VOLUME .

Interfejsy API AudioControl to:

  • setBalanceTowardRight(float value) . Przesuwa głośność głośnika w prawą (+) lub lewą (-) stronę samochodu. 0,0 jest wyśrodkowane, +1,0 jest całkowicie prawe, -1,0 jest całkowicie lewe, a wartość spoza zakresu -1 do 1 jest błędem.
  • setFadeTowardFront(float value) - Przesuwa głośność głośnika w stronę przodu (+) lub tyłu (-) samochodu. 0,0 oznacza wyśrodkowanie, +1,0 oznacza całkowite przesunięcie do przodu, -1,0 oznacza całkowite przesunięcie do tyłu, a wartość spoza zakresu od -1 do 1 oznacza błąd.

To producenci OEM decydują, w jaki sposób te wartości powinny być stosowane i w jaki sposób będą udostępniane użytkownikom. Można je zastosować wyłącznie do multimediów lub ogólnie do wszystkich dźwięków Androida.

W Androidzie 11 wprowadzono także obsługę stosowania efektów dźwiękowych do urządzeń wyjściowych. Dzięki temu możliwe jest alternatywne zarządzanie zanikaniem i balansem za pomocą efektów dźwiękowych na odpowiednich urządzeniach wyjściowych, a nie za pośrednictwem tych interfejsów API.

Wyciszanie dźwięku

Wyciszanie dźwięku ma miejsce, gdy pojazd zmniejsza wzmocnienie jednego strumienia, dzięki czemu inny strumień odtwarzany w tym samym czasie jest wyraźniej słyszalny. W AAOS wyciszanie dźwięku zależy od warstwy HAL, ponieważ istnieje potencjalnie wiele dźwięków poza systemem Android, nad którymi system operacyjny nie ma kontroli. W systemie Android 11 główną informacją dostępną dla warstwy HAL przy podejmowaniu decyzji o wycięciu jest to, czy oba urządzenia wyjściowe mają aktywne strumienie.

Kiedy się schować

Chociaż to od konkretnego producenta OEM zależy, w jaki sposób jego HAL będzie obsługiwać tłumienie, istnieje kilka ogólnych wskazówek, które zalecamy. Odtwarzanie wielu strumieni w systemie Android najczęściej ma miejsce, gdy dwie aplikacje/usługi jednocześnie obsługują dźwięk. Mając to na uwadze, zobacz Matryca interakcji , aby dowiedzieć się, kiedy system Android może przyznać równoczesny fokus i w związku z tym, kiedy możliwe jest jednoczesne odtwarzanie dwóch różnych strumieni.

Pamiętaj, że wszelkie strumienie zmieszane razem przez Androida zostaną wykonane przed zastosowaniem jakichkolwiek korzyści. W związku z tym każdy strumień, który powinien zostać wyciszony podczas odtwarzania jednocześnie z innym, powinien zostać skierowany do oddzielnych urządzeń wyjściowych, aby warstwa HAL mogła zastosować wyciszenie przed ich zmieszaniem.

Zalecane zachowanie przy uniku

Poniżej przedstawiono potencjalne równoczesne interakcje, w przypadku których zalecamy zastosowanie wyciszenia:

  • EMERGENCY . Przycisz lub wycisz wszystko oprócz SAFETY , aby mieć pewność, że kierowca usłyszy dźwięk
  • SAFETY . Schowaj wszystko oprócz EMERGENCY , aby kierowca usłyszał dźwięk
  • NAVIGATION . Unikaj wszystkiego oprócz SAFETY i EMERGENCY
  • CALL . Unikaj wszystkiego z wyjątkiem SAFETY , EMERGENCY i NAVIGATION
  • VOICE . Kacz CALL_RING
  • Do producentów OEM należy określenie znaczenia aktywnych VEHICLE_SOUNDS i określenie, czy powinni wyciszać inne dźwięki, aby mieć pewność, że kierowca je usłyszy.
  • MUSIC i ANNOUNCEMENT należy unikać wszystkiego. Głównym wyjątkiem są dźwięki interakcji dotykowej, które obecnie są odtwarzane jako SYSTEM_SOUND

Inne kwestie do rozważenia podczas wykonywania uników

Niektóre aplikacje/usługi, takie jak nawigacja lub asystent, mogą wykorzystywać wielu graczy do wykonywania swoich działań. Producenci OEM powinni unikać zbyt agresywnego wyciszania w zależności od tego, kiedy dane strumieniowe przestają przechodzić przez te urządzenia wyjściowe, aby mieć pewność, że użytkownik nie spowoduje chwilowego powrotu multimediów do pełnej głośności, zanim nie zostanie ponownie ściszony po rozpoczęciu następnego odtwarzania z aplikacji nawigacyjnej lub aplikacji asystenta.

W przypadku pojazdów z wieloma scenami dźwiękowymi i wystarczająco dobrą izolacją istnieje również możliwość skierowania dźwięku do różnych obszarów samochodu zamiast wyciszania. Na przykład instrukcje nawigacyjne mogą być kierowane do głośników w zagłówku kierowcy, podczas gdy w całej kabinie gra muzyka z normalną głośnością.

Dźwięki krytyczne dla bezpieczeństwa

Chociaż w systemie Android 11 wprowadzono interfejsy API skupiające dźwięk HAL , w dalszym ciągu zadaniem HAL jest zapewnienie, że dźwięki krytyczne dla bezpieczeństwa będą traktowane priorytetowo przed innymi. Nawet jeśli HAL utrzymuje fokus audio dla USAGE_EMERGENCY , nie gwarantuje to, że aplikacje i usługi w systemie Android nie będą odtwarzać dźwięków. Do warstwy HAL należy określenie, które strumienie z systemu Android powinny zostać zmiksowane lub wyciszone podczas odtwarzania dźwięków krytycznych dla bezpieczeństwa.

Konfigurowanie interfejsu użytkownika ustawień głośności

AAOS oddziela interfejs użytkownika ustawień woluminów od konfiguracji grupy woluminów (którą można nałożyć zgodnie z opisem w sekcji Konfigurowanie grup woluminów). Dzięki takiemu oddzieleniu nie będą wymagane żadne zmiany, jeśli konfiguracja grup woluminów ulegnie zmianie w przyszłości.

W interfejsie użytkownika ustawień samochodu plik packages/apps/Car/Settings/res/xml/car_volume_items.xml zawiera elementy interfejsu użytkownika (zasoby tytułów i ikon) powiązane z każdym zdefiniowanym AudioAttributes.USAGE . Ten plik zapewnia rozsądne renderowanie zdefiniowanych VolumeGroups przy użyciu zasobów powiązanych z pierwszym rozpoznanym użyciem zawartym w każdej grupie woluminów.

Na przykład poniższy przykład definiuje grupę woluminów jako obejmującą zarówno voice_communication , jak i voice_communication_signalling . Domyślna implementacja interfejsu użytkownika ustawień samochodu renderuje grupę woluminów przy użyciu zasobów skojarzonych z voice_communication , ponieważ są one pierwsze 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żyte w powyższej konfiguracji są zadeklarowane w packages/apps/Car/Settings/res/values/attrs.xml . Interfejs ustawień głośności korzysta z następujących interfejsów API CarAudioManager opartych na grupie woluminów:

  • getVolumeGroupCount() , aby dowiedzieć się, ile kontrolek należy narysować.
  • getGroupMinVolume() i getGroupMaxVolume() , aby uzyskać dolną i górną granicę.
  • getGroupVolume() , aby uzyskać bieżący wolumin.
  • registerVolumeChangeObserver() aby otrzymywać powiadomienia o zmianach woluminu.