Android 14 支援音訊架構和音訊 HAL 中的聲音劑量,透過持續監控聲音量測值,並向使用者發出受損暴露量警告。
音量劑量是指一段時間內的音壓值。透過監控音量,我們可以保護使用者免於因過度或長時間暴露於音量而造成的傷害,在 Android 行動裝置上使用耳機時提供更完善的聽力保護,並盡可能降低聽力受損的機率。
安全聆聽裝置的新標準符合 IEC62368-1 第 3 版 (需要登入) 和 EN50332-3 (僅限訂閱者存取) 中有關聽力保護的法規規定,這兩項標準都引入了音量劑量的概念。
音量劑量功能可讓原始設備製造商遵守新的聽力安全法規。為支援聲音劑量,原始設備製造商 (OEM) 必須遵循所有自訂和認證的介面規格和法規。自訂的原始設備製造商 (OEM) 實作項目可以略過或修改 Android 開放原始碼計畫的預設音效實作方式。不過,我們強烈建議您使用 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 介面擴充功能已淘汰,因此名為 ISoundDose
的新 HAL 介面可用於擷取計算的 MEL 值,並發出暴露警告,這是 AIDL 音訊 HAL 的一部分。然而,如果實作者需要更多時間來整合 AIDL 音訊 HAL,我們提供獨立音效 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);
}
是否支援 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 介面,並為音訊架構提供準確的 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 介面時,原始設備製造商 (OEM) 必須根據 VtsHalAudioCoreTargetTest
針對 IModule AIDL 音訊 HAL 實作或 VtsHalSoundDoseFactoryTargetTest
定義的 VTS 測試案例進行驗證,或驗證獨立音符 AIDL HAL 實作的案例。