音響暴露

Android 14 はオーディオ フレームワークとオーディオ HAL の音響暴露をサポートしています。音響暴露の測定結果を継続的にモニタリングし、ユーザーに有害な暴露レベルの警告を通知します。

音響暴露は一定期間の音圧レベルを測定したものです。音響暴露をモニタリングすることによって、過度な音響暴露または長期におよぶ音響暴露による有害な影響からユーザーを保護し、ポータブル Android デバイスでのヘッドフォン使用時の聴覚の保護を高め、聴覚障がいの発生を最小限に抑えます。

安全なリスニング デバイスの新基準は、音響暴露の概念を導入した IEC62368-1 第 3 版(ログインが必要)と EN50332-3(登録者のみアクセス可能)の聴覚保護の規制要件に準拠しています。

音響暴露機能により、OEM は新たな聴覚の安全性に関する規制に準拠できます。音響暴露をサポートするためには、OEM はすべてのカスタマイズと認証において、インターフェース要件と規制に従う必要があります。カスタマイズした OEM 実装で、AOSP の音響暴露のデフォルト実装を回避したり、修正したりできます。ただし、AOSP 実装の使用を強くおすすめします。

音響暴露の算出

IEC62368-1 第 3 版および EN50332-3 の基準は算出音響暴露(CSD)を計算することにより、音響暴露の精度を高めています。CSD は長期間の一時的な暴露レベル(MEL)を統合して計算されます。7 日間連続ローリング時間枠の累積 CSD 値が音響暴露計算のために保持されます。

IEC62368-1 第 3 版の 10.6.3.2 項によると、CSD 値の上限 100% に達すると、システムは 100% に達するたびにユーザーに音響レベルの警告を通知します。ユーザーが警告を確認しない場合、IEC62368-1 の表 39 で事前定義されている放射エネルギー源クラス 1(RS1)の値に音量が下げられます。

IEC62368-1 第 3 版の 10.6.3.3 項に記載のとおり、音響暴露の警告に加えて、システムは MEL 値が IEC62368-1 の表 39 の放射エネルギー源クラス 2(RS2)の値を超過するたびに、暴露に基づき警告を発する必要があります。

これらの規制の認証を受けるため、また CSD 値をよりわかりやすくするために、システムはユーザーが認識できる正確な出力値(メディアの再生出力など)を使用する必要があります。CSD の計算ではユーザーがさらされている実際の音圧レベルに近い値を使用することが重要です。

アーキテクチャ

フレームがどこでキャプチャされるかによって、トランスデューサのハードウェアの特性とエフェクトはレンダリングされたフレームの出力に影響を及ぼす可能性があります。正確に出力音圧レベルを計測するために、HAL を拡張して、MEL 値を基盤となるハードウェアから直接取得し、インピーダンス、感度、周波数応答などのデジタル シグナル プロセッサ(DSP)またはスピーカー プロパティによって適用される可能性があるエフェクトに対応しています。

HAL から MEL 値を取得できない場合、フォールバック メカニズムとして、オーディオ フレームワークが CSD を分析し、計算します。オーディオ フレームワークでの計算は、HAL から報告されたレンダリング出力とオーディオ DSP に送信されたフレームに関する情報に基づいています。

図 1 のとおり、音響暴露には SoundDoseHelperSoundDoseManager, という 2 つのコンポーネントがあります。

sound_dose_arch

図 1. 音響暴露機能のアーキテクチャ コンポーネント

SoundDoseHelper

SoundDoseHelper クラスは systemserver プロセスに存在し、関連するすべての音響暴露データの主要な収集ポイントです。AudioService クラスは SoundDoseHelper クラスを管理します。

SoundDoseHelper クラスは次のことを担います。

  • 新たな暴露情報の処理
  • 音響暴露値の保持
  • audioserver 障害の場合のステータスの復元
  • システム UI 通知のトリガー
  • 音量の低下

SoundDoseManager

SoundDoseManager クラスは audioserver プロセス内に存在し、AudioFlinger クラスの一部として、HAL から音響暴露データを収集したり、HAL に送信されたフレームからフォールバックとして内部で計算したりします。SoundDoseManager クラスは音響暴露データを SoundDoseHelper クラスに送信します。

MelProcessor と MelAggregator

HAL から MEL 値を取得できない場合、libaudioutils 内の MelProcessorMelAggregator ユーティリティが内部音響暴露計算に使用されます。

MelProcessor クラスでの主な計算は MelProcessor::process(const void* buffer, size_t bytes) を呼び出して、音声サンプルを使ってバッファで実行されます。OEM は必要に応じて HAL 実装に MelProcessor を使用できます。

MelAggregator クラスはさまざまなオーディオ ポートから MEL 値を受け取り、7 日間のローリング時間枠で CSD 値を計算します。MelAggregator::aggregateAndAddNewMelRecord_l(MelRecord mel) メソッドがロジックを実行します。結果は AudioService との通信のため SoundDoseManager クラスに送信されます。

実装

HIDL インターフェース拡張機能は Android 14 から非推奨となっています。そのため、計算された MEL 値の取得と暴露警告の通知のための新たな HAL インターフェースが ISoundDose という名前で、AIDL オーディオ HAL の一部として定義されています。ただし、AIDL オーディオ HAL の統合にもう少し時間が必要な場合に備えて、スタンドアロンの音響暴露 AIDL HAL を用意しており、そこから ISoundDoseFactory インターフェースにアクセスできます。これは今後非推奨となる予定です。

音響暴露サポートの HAL メソッドを次のコードサンプルで示しています。

/**
 * This interface provides functions related to sound exposure control required for compliance to
 * EN/IEC 62368-1 3rd edition. Implementing this interface is mandatory for devices for which
 * compliance to this standard is mandated and implementing audio offload decoding or other direct
 * playback paths where volume control happens below the audio HAL.
 */
@VintfStability
interface ISoundDose {
    /**
     * Max value in dBA used for momentary exposure warnings as defined by IEC62368-1
     * 3rd edition. This value represents the default RS2 upper bound.
     */
    const int DEFAULT_MAX_RS2 = 100;
    /** Min value of the RS2 threshold in dBA as defined by IEC62368-1 3rd edition. */
    const int MIN_RS2 = 80;

    /**
     * Sets the RS2 upper bound used for momentary exposure warnings. Default value is
     * DEFAULT_MAX_RS2 as specified in IEC62368-1 3rd edition.
     *
     * @param rs2ValueDbA custom RS2 upper bound to use
     * @throws EX_ILLEGAL_ARGUMENT if rs2ValueDbA is greater than DEFAULT_MAX_RS2 or lower
     *                             than MIN_RS2
     */
    void setOutputRs2UpperBound(float rs2ValueDbA);

    /**
     * Gets the RS2 upper bound used for momentary exposure warnings.
     *
     * @return the RS2 upper bound in dBA
     */
    float getOutputRs2UpperBound();

    /**
     * Registers the HAL callback for sound dose computation. If sound dose is supported
     * the MEL values and exposure notifications will be received through this callback
     * only. The internal framework MEL computation will be disabled.
     * It is not possible to unregister the callback. The HAL is responsible to provide
     * the MEL values throughout its lifecycle.
     *
     * @param callback to use when new updates are available for sound dose
     */
    void registerSoundDoseCallback(in IHalSoundDoseCallback callback);

    @VintfStability
    oneway interface IHalSoundDoseCallback {
        /**
         * Called whenever the current MEL value exceeds the set RS2 upper bound.
         *
         * @param currentDbA the current MEL value which exceeds the RS2 upper bound
         * @param audioDevice the audio device where the MEL exposure warning was recorded
         */
        void onMomentaryExposureWarning(float currentDbA, in AudioDevice audioDevice);

        @VintfStability
        parcelable MelRecord {
            /**
             * Array of continuously recorded MEL values >= MIN_RS2 (1 per second).
             * First value in the array was recorded at 'timestamp'.
             */
            float[] melValues;
            /**
             * Corresponds to the time in seconds, as reported by CLOCK_MONOTONIC, when
             * the first MEL entry in melValues was recorded. The timestamp values have
             * to be consistent throughout all audio ports, equal timestamp values will
             * be aggregated.
             */
            long timestamp;
        }

        /**
         * Provides a MelRecord containing continuous MEL values sorted by timestamp.
         * Note that all the MEL values originate from the audio device specified by audioDevice.
         * In case values from multiple devices need to be reported, the caller should execute
         * this callback once for every device.
         *
         * @param melRecord contains the MEL values used for CSD
         * @param audioDevice the audio device where the MEL values were recorded
         */
        void onNewMelValues(in MelRecord melRecord, in AudioDevice audioDevice);
    }
}

新しい HAL インターフェースはフレームワークに一時的な暴露を伝えるコールバックを実装し、出力レベルが RS1 を超えると常に MEL 値を提供します。このインターフェースが実装されると、フレームワークは CSD のレポートにこのインターフェースを使用します。このコールバック実装がない場合は、AudioFlinger のフォールバック実装を使用して、CSD の推定値が計算されます。

音響暴露スタンドアロン AIDL サポート

AIDL オーディオ HAL に音響暴露を統合できるようになるまで、OEM はスタンドアロンの AIDL API である ISoundDoseFactory を代替として利用できます。ISoundDoseFactory は以下のコードサンプルで示すとおり、ISoundDose インターフェースを使用します。

@VintfStability
interface ISoundDoseFactory {
    /**
     * Retrieve the sound dose interface for a given audio HAL module name.
     *
     * If a device must comply to IEC62368-1 3rd edition audio safety requirements and is
     * implementing audio offload decoding or other direct playback paths where volume control
     * happens below the audio HAL, it must return an instance of the ISoundDose interface.
     * The same instance must be returned during the lifetime of the HAL module.
     * If the HAL module does not support sound dose, null must be returned, without throwing
     * any errors.
     *
     * @param module for which we trigger sound dose updates.
     * @return An instance of the ISoundDose interface implementation.
     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
     */
    @nullable ISoundDose getSoundDose(in @utf8InCpp String module);
}

音響暴露 AIDL オーディオ HAL サポート

以下のコードサンプルで示すとおり、音響暴露インターフェースは IModule インターフェースを拡張することにより、AIDL オーディオ HAL の一部として長期にわたりサポートされます。

@VintfStability
interface IModule {
…
    /**
     * Retrieve the sound dose interface.
     *
     * If a device must comply to IEC62368-1 3rd edition audio safety requirements and is
     * implementing audio offload decoding or other direct playback paths where volume control
     * happens below the audio HAL, it must return an instance of the ISoundDose interface.
     * The same instance must be returned during the lifetime of the HAL module.
     * If the HAL module does not support sound dose, null must be returned, without throwing
     * any errors.
     *
     * @return An instance of the ISoundDose interface implementation.
     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
     */
    @nullable ISoundDose getSoundDose();
}

この機能は IEC62368-1 第 3 版と EN50332-3 に記載されている新たな規則の実装であるため、外部向け API はありません。

OEM がデバイスの認証を受けるには、新しい HAL インターフェースを実装し、CSD の正確な MEL データをオーディオ フレームワークに提供するか(推奨)、カスタムの音響暴露実装を提供します。

音響暴露の計算を有効にする

デフォルトでは、AOSP は聴覚の安全性ロジックをサポートしており、既存の EN50332-2 と IEC62368-1 10.6.5 基準に適合しています。

Android 14 では、音響暴露の計算はデフォルトで無効になっています。

Android 14-QPR1 以降で音響暴露の計算を有効にするには、以下のガイドラインを使用してください。

  • 対象の地域で音響暴露の規制が適用される場合は、config.xmlconfig_safe_media_volume_enabledtrue に設定されているか確認してください。

  • EN50332-3 と IEC62368-1 10.6.3 に準拠するために、ベンダーは config.xmlconfig_safe_sound_dosage_enabled フラグを true にオーバーレイする必要があります。オフロードのデコードをサポートしており、音響暴露 HAL インターフェースを実装していないデバイスの場合、config_safe_sound_dosage_enabledtrue に設定しないでください。このようなケースで、config_safe_sound_dosage_enabledtrue に設定すると、CSD 値が不正確になり、聴覚の安全性基準の認証を受ける際に問題となる可能性があります。

以下の決定グラフは、国別の制限やフラグ値に基づいて計算の対象を CSD にするか以前の聴覚安全性レベル(Android 14 より前のバージョンに実装)にするかを決定するロジックを示しています。

enable_csd

図 2. 音響暴露の計算を有効にする(Android 14-QPR1 で追加されたロジック)

検証

音響暴露の HAL インターフェースを実装した OEM は、IModule AIDL オーディオ HAL 実装の VtsHalAudioCoreTargetTest またはスタンドアロンの音響暴露 AIDL HAL 実装の VtsHalSoundDoseFactoryTargetTest で定義された VTS テストケースと比較して検証する必要があります。