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
位於 systemserver
程序中的 SoundDoseHelper
類別,是所有相關音訊劑量資料的主要收集點。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 介面擴充功能已淘汰,因此用於擷取計算的 MEL 值並發出曝光警告的新 HAL 介面 (名為 ISoundDose
) 已納入 AIDL Audio HAL 的一部分。不過,如果實作人員需要更多時間來整合 AIDL Audio HAL,我們也提供獨立的 sound dose 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 值的預估值。
支援 Sound Dose 獨立 AIDL
在原始設備製造商能夠在 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);
}
是否支援 Sound dose AIDL Audio HAL
只要擴充 IModule
介面,即可長期支援音訊劑量介面,做為 AIDL Audio 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 資料給音訊架構 (建議做法),或是提供自訂的音量實作。
啟用音量劑量計算功能
根據預設,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
。如果裝置支援卸載解碼功能,但未實作 sound dose 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 實作。