Android 14 支援音訊架構和 Audio HAL 中的音量,可持續監控音量測量結果,並在音量達到可能損害聽力的程度時,向使用者發出警告。
音量劑量是指一段時間內的音壓級別測量值。 監控音量有助於保護使用者,避免因長時間暴露於過大音量而造成聽力損傷,進而提升使用 Android 可攜式裝置時的聽力保護效果,並盡量降低聽力受損的風險。
安全聆聽裝置的新標準符合 IEC62368-1 第 3 版 (需要登入) 和 EN50332-3 (僅限訂閱者存取) 的聽力保護法規要求,並導入音量劑量概念。
音量劑量功能可讓原始設備製造商遵守新的聽力安全法規。如要支援音量劑量功能,原始設備製造商必須遵守所有自訂項目和認證的介面規格和法規。自訂的 OEM 實作項目可以略過或修改 AOSP 預設的音量劑量實作項目。不過,我們強烈建議使用 AOSP 實作方式。
音量劑量計算
IEC62368-1 第 3 版和 EN50332-3 標準會計算音量暴露量 (CSD),以提高音量暴露量測量的準確度。CSD 是透過整合一段時間內的瞬間暴露量 (MEL) 計算而得。系統會維護七天的累積 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 的影格。
音量劑量會導入兩個元件:SoundDoseHelper
和 SoundDoseManager,
,如圖 1 所示:
圖 1. 音量劑量功能的架構元件。
SoundDoseHelper
SoundDoseHelper
類別位於 systemserver
程序中,是所有相關音量劑量資料的主要收集點。AudioService
類別會管理 SoundDoseHelper
類別。
SoundDoseHelper
類別負責下列事項:
- 處理新的劑量資訊
- 保留音量劑量值
- 在
audioserver
當機時復原狀態 - 觸發系統 UI 通知
- 調低音量
SoundDoseManager
SoundDoseManager
類別位於 audioserver
程序中,屬於 AudioFlinger
類別的一部分,負責從 HAL 收集音量劑量資料,或從傳送至 HAL 的影格計算音量劑量資料 (做為備援)。SoundDoseManager
類別會將音量劑量資料傳送至 SoundDoseHelper
類別。
MelProcessor 和 MelAggregator
如果 HAL 無法提供 MEL 值,系統會使用 libaudioutils
中的 MelProcessor
和 MelAggregator
公用程式,計算內部音量劑量。
在 MelProcessor
類別中,主要運算是在含有音訊樣本的緩衝區上執行,方法是呼叫 MelProcessor::process(const void* buffer, size_t bytes)
。如有需要,原始設備製造商 (OEM) 可以在 HAL 實作中使用 MelProcessor
。
MelAggregator
類別會從不同音訊連接埠接收 MEL 值,並以七天的滾動視窗計算 CSD 值。MelAggregator::aggregateAndAddNewMelRecord_l(MelRecord mel)
方法會執行邏輯。結果會傳送至 SoundDoseManager
類別,以便與 AudioService
通訊。
實作
Android 14 以上版本已淘汰 HIDL 介面擴充功能,因此系統會將名為 ISoundDose
的新 HAL 介面定義為 AIDL Audio HAL 的一部分,用於擷取計算出的 MEL 值及發布曝光警告。不過,如果實作者需要更多時間整合 AIDL Audio 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 的音量劑量
在 OEM 廠商將音量劑量整合至 AIDL 音訊 HAL 前,他們可以暫時使用獨立的 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 支援
音量劑量介面長期支援 AIDL Audio HAL,方法是擴充 IModule
介面,如下列程式碼範例所示:
@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。
原始設備製造商可以實作新的 HAL 介面,並為 CSD 提供準確的 MEL 資料給音訊架構 (建議做法),或是提供自訂音量劑量實作方式,藉此認證裝置。
啟用音量劑量計算功能
根據預設,Android 開放原始碼計畫支援聽力安全邏輯,確保符合現有 EN50332-2 和 IEC62368-1 10.6.5 標準的認證。
在 Android 14 中,系統預設會停用音量劑量計算功能。
請按照下列指南操作,從 Android 14-QPR1 開始啟用音量劑量計算功能。
如果你的國家/地區強制執行音量劑量法規,請檢查
config.xml
中的config_safe_media_volume_enabled
是否設為true
。為符合 EN50332-3 和 IEC62368-1 10.6.3 規定,供應商必須在
config.xml
中疊加config_safe_sound_dosage_enabled
標記,以顯示true
。如果裝置支援卸載解碼,但未實作音量劑量 HAL 介面,則不得將config_safe_sound_dosage_enabled
設為true
。在這種情況下,將config_safe_sound_dosage_enabled
設為true
可能會導致 CSD 值不準確,並造成安全聽力標準的認證問題。
下方的決策圖表說明相關邏輯,可根據國家/地區限制和旗標值,判斷要計算 CSD 還是舊版聽力安全等級 (Android 14 之前實作)。
圖 2. 啟用音量劑量計算功能 (Android 14-QPR1 中新增了這項邏輯)。
驗證
實作音量劑量 HAL 介面時,原始設備製造商必須根據 VtsHalAudioCoreTargetTest
定義的 VTS 測試案例,驗證 IModule AIDL Audio HAL 實作項目,或根據 VtsHalSoundDoseFactoryTargetTest
定義的 VTS 測試案例,驗證獨立音量劑量 AIDL HAL 實作項目。