사운드 양

Android 14는 연속적으로 음량 측정항목을 모니터링하고 사용자에게 유해한 노출 수준을 경고하여 오디오 프레임워크와 오디오 HAL에서 음량에 관한 지원을 제공합니다.

음량은 일정 기간에 걸쳐 음압 수준을 측정한 것입니다. 음량을 모니터링하여 과도하거나 장기간의 음 노출로 인한 해로운 영향에서 사용자를 보호할 수 있으므로 휴대용 Android 기기에서 헤드폰 사용 시 청력을 더 잘 보호할 수 있고 청력 손상 가능성을 최소화할 수 있습니다.

안전한 청취 기기의 새 표준은 음량 개념을 도입한 IEC62368-1 3판(로그인 필요) 및 EN50332-3(구독자로 액세스 제한됨)의 청력 보호 규정 요구사항을 준수합니다.

음량 기능을 사용하면 OEM이 새로운 청력 안전 규정을 따를 수 있습니다. 음량을 지원하려면 OEM은 모든 맞춤설정과 인증에 관한 인터페이스 사양과 규정을 따라야 합니다. 맞춤설정된 OEM 구현은 음량의 AOSP 기본 구현을 우회하거나 수정할 수 있지만 AOSP 구현을 사용하는 것이 좋습니다.

음량 계산

IEC62368-1 3판 및 EN50332-3의 표준은 계산된 음량(CSD)을 계산하여 음 노출 측정의 정확성을 개선합니다. CSD는 시간 경과에 따른 순간적인 노출 수준(MEL)을 통합하여 계산됩니다. 누적 CSD 값의 7일 연속 롤링 기간은 음량 계산을 위해 유지됩니다.

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 계산에서 사용자가 노출되는 실제 음압 수준에 가까운 값을 사용하는 것이 중요합니다.

아키텍처

프레임이 캡처되는 위치에 따라 트랜스듀서의 하드웨어 특성과 효과는 렌더링된 프레임의 전력 수준에 영향을 미칠 수 있습니다. 정확한 출력 음압 수준을 측정하기 위해 디지털 신호 프로세서(DSP) 또는 스피커 속성(예: 임피던스, 감도, 주파수 응답)으로 적용되는 가능한 효과를 위해 MEL 값을 기본 하드웨어 및 계정에서 직접 가져오도록 HAL을 확장했습니다.

HAL에서 MEL 값을 제공할 수 없는 경우 대체 메커니즘으로 오디오 프레임워크는 CSD를 분석하고 계산합니다. 오디오 프레임워크의 이 계산은 HAL에서 보고된 렌더링된 출력에 관한 정보와 오디오 DSP에 전송된 프레임에 기반합니다.

음량은 그림 1과 같이 SoundDoseHelperSoundDoseManager,라는 두 가지 구성요소를 도입합니다.

sound_dose_arch

그림 1. 음량 기능의 아키텍처 구성요소

SoundDoseHelper

systemserver 프로세스에 있는 SoundDoseHelper 클래스는 모든 관련 음량 데이터의 기본 수집 지점입니다. AudioService 클래스가 SoundDoseHelper 클래스를 관리합니다.

SoundDoseHelper 클래스는 다음 작업을 담당합니다.

  • 새로운 양 정보 처리
  • 음량 값 유지
  • audioserver 비정상 종료 시 상태 복구
  • 시스템 UI 알림 트리거
  • 볼륨 낮추기

SoundDoseManager

audioserver 프로세스에 있고 AudioFlinger 클래스의 일부인 SoundDoseManager 클래스는 HAL에서 음량 데이터를 수집하거나 HAL로 전송된 프레임에서 내부적으로 대체로 이를 계산합니다. SoundDoseManager 클래스는 음량 데이터를 SoundDoseHelper 클래스로 전송합니다.

MelProcessor 및 MelAggregator

HAL이 MEL 값을 제공할 수 없는 경우 libaudioutilsMelProcessorMelAggregator 유틸리티는 내부 음량 계산에 사용됩니다.

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 인터페이스 ISoundDoseAIDL 오디오 HAL의 일부로 정의됩니다. 그러나 AIDL 오디오 HAL을 통합하는 데 시간이 더 필요한 구현자를 위해 ISoundDoseFactory 인터페이스를 제공하는 독립형 음량 AIDL HAL이 있습니다. 이는 향후 지원 중단됩니다.

음량 지원을 위한 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를 사용할 수 있습니다. 다음 코드 샘플과 같이 ISoundDoseFactoryISoundDose 인터페이스를 사용합니다.

@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 테스트 사례를 대상으로 유효성을 검사해야 합니다.