音效

從 Android 11 開始,裝置製造商可以在選取特定音訊裝置進行音訊擷取或播放時,自動附加及啟用特定音效。其中一項重大改良是,音訊效果架構可控制音訊路徑上插入的音訊效果,這些音訊路徑完全實作於音訊 HAL 以下 (輸入裝置與輸出裝置之間的直接連線)。

這項功能主要適用於汽車原始設備製造商,但也可以用於其他 Android 裝置。舉例來說,應用程式透過音訊 DSP 直接連線至喇叭時,會在 FM 收音機輸出內容中插入語音增強效果。

必要條件

  • 與其他音效相同,音效必須由供應商程式庫實作,並列於 audio_effects.xml 設定檔中。
  • 效果必須是前置處理或後置處理類型 (在 EffectDescriptor.flags 中設定的旗標 TYPE_PRE_PROCTYPE_POST_PROC)。
  • 如果效果實作項目是硬體加速 (在 EffectDescriptor.flags 中設定 HW_ACC_TUNNEL 旗標),則可附加至 HAL 下方完全連線的音訊路徑 (音訊 HAL 中未開啟播放或擷取音訊串流)。

建立及啟用裝置特效

您可以使用下列其中一種方法,例項化裝置專屬的音效。

使用音效設定檔

這種方法可靜態建立音效,並系統性地附加至任何音訊路徑,然後啟用該音效,並選取指定裝置做為接收器或來源。

方法是在 audio_effects.xml 檔案中加入特定區段,如下所示:

<deviceEffects>
<devicePort type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom">
      	<apply effect="agc"/>
      </devicePort>
  </deviceEffects>
  

使用系統 API

android.media.audiofx.AudioEffect 類別已新增 @SystemApi 建構函式,可建立及啟用裝置效果:

AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAttributes device);

指定專屬音訊效果 ID 和音訊裝置描述元來建立效果後,即可使用現有的 AudioEffect API 啟用或停用效果。

您也可以使用 API 查詢實作項目是否支援特定裝置/效果組合。

static boolean isEffectSupportedForDevice(
            @NonNull UUID uuid, @NonNull AudioDeviceAttributes device);

新的 HAL API

音效 HAL

音效 HAL V6.0 的 createEffect() 方法有新的簽章,可建立附加至裝置的效果:

IEffectFactory::createEffect(Uuid uid, AudioSession session,
AudioIoHandle ioHandle, AudioPortHandle device)
  • 指定的 AudioSession 必須是 AudioSessionConsts.DEVICE
  • 如果 sessionAudioSessionConsts.DEVICE,系統會忽略 AudioIoHandle
  • 音訊架構會在透過 IDevice::createAudioPatch() 方法選取音訊 HAL 時,指派專屬 AudioPortHandle device,以識別 device

音訊 HAL

如要支援裝置音效功能,音訊 HAL 必須使用 IDevice::createAudioPatch() API 實作音訊路徑控制項。IDevice::supportsAudioPatches() 方法會回報 true,表示這項作業已完成。

兩個新的 API 方法 (IDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId)IDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId)) 會告知 HAL 實作,裝置效果已在指定裝置上啟用或停用。

裝置的識別方式是透過 AudioPortHandle ID,使用 IDevice::createAudioPatch() 方法建立音訊修補程式時,會用到這個 ID。

如果啟用或停用音效時,音訊和效果 HAL 需要協調,實作項目可以使用 Audio HAL API。