Android AudioEffect 音效方案(基于 Android 2.3 - Android 8.1)

787 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

Android2.3 增加了对音频混响的支持,通过 AudioEffect 可以方便地对 AudioTrack 和 MediaPlayer 播放的音乐进行音效控制。AudioEffect 是 Android 音频框架提供的用于控制音频效果的基类,开发者不应直接使用此类,应该使用它的派生类:

  • Equalizer 均衡器:增加或降低某一频率的声音响度来达到想要的效果。
  • Virtualizer 环绕音:让声音可以产生一种空间感,数值越大声音就距离耳机越远。
  • BassBoost 重低音控制器:增加低音的强度。
  • PresetReverb 预设混响(推荐用于音乐):使音乐通过声音在不同路径传播下造成的反射叠加产生的声音特效,比如流行,古典,爵士等。
  • EnvironmentalReverb 环境混响(推荐用于游戏):比如马路,走廊,室内,大厅等。 以上音效包含在 android.media.audiofx 包中,可以参考官方文档。 为了使用音效处理需要在AndroidManifest.xml 添加相应的权限:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

1 Equalizer

Equalizer 的使用方法如下:

MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.test_cbr/*音频路径*/);
Equalizer equalizer = new Equalizer(0, mediaPlayer.getAudioSessionId());
equalizer.setEnabled(true);

//获取均衡器引擎支持的频段数
short bands = equalizer.getNumberOfBands();
        
//获取最大和最小增益
final short minEQLevel = equalizer.getBandLevelRange()[0];
final short maxEQLevel = equalizer.getBandLevelRange()[1];
for (short i = 0; i < bands; i++) {
    final short band = i;
    //获取当前频段的中心频率,分别为:60Hz,230Hz,910Hz,3600Hz,14000Hz
    int currentFreq = equalizer.getCenterFreq(band);
    //获取给定均衡器频段的增益
    short level = equalizer.getBandLevel(band);
    Log.d("Equalizer","currentFreq is: " + currentFreq + ", band level is: " + level);
    //为给定的均衡器频带设置增益值
    equalizer.setBandLevel(band,xx);
}

在构造函数 Equalizer(int priority, int audioSession) 中:

  • int priority:优先级,多个应用可以共享同一 Equalizer 引擎,该参数指出控制优先权,默认为0。
  • int audioSession:音频会话 ID,系统范围内唯一,Equalizer 将被附加在拥有相同音频会话 ID 的 MediaPlayer 或 AudioTrack 上生效。 Android 系统预置了一些增益参数,可通过下面代码获取:
short presets= equalizer.getNumberOfPresets();
//获取系统预设的增益
for (short i = 0; i < presets; i++) {
  Log.d("presets",equalizer.getPresetName(i));
}

结果为:Normal、Classical、Dance、Flat、Folk、Heavy Metal、Hip hop、Jazz、Pop、Rock。 然后通过 equalizer.usePreset(); 使用系统预置参数。 销毁时:

if (equalizer != null) {
    equalizer.setEnabled(false);
    equalizer.release();
    equalizer = null;
}

2 Virtualizer

Virtualizer 的使用方法如下:

Virtualizer mVirtualizer= new Virtualizer (0, mMediaPlayer.getAudioSessionId()); //优先级为0
mVirtualizer.setEnabled(true);
if (mVirtualizer.getStrengthSupported())
{
    short strength = mVirtualizer.getRoundedStrength();
    mVirtualizer.setStrength((short)strength);
}
  • getRoundedStrength() :获取特效力度,特效力度值在0~1000间变化。
  • setStrength() :设置特效力度。 如果指定的会话 ID 为0,则 Virtualizer 作用于主要的音频输出混音器(mix)。

3 BassBoost

低音增强,用于增强或放大声音的低频。 它与简单的均衡器相当,但仅限于低频范围内的一个频段放大。 主要使用方法为:

BassBoost bassBoost = new BassBoost(0,mediaPlayer.getAudioSessionId());
bassBoost.setEnabled(true);
if (bassBoost.getStrengthSupported()){
    bassBoost.setStrength((short) 100);
}

其中,getStrengthSupported()指示是否支持设置强度。如果此方法返回 false,则仅支持一种强度,并且 setStrength() 方法始终舍入到该值。 setStrength() 设置效果的当前强度,强度的有效范围是[0, 1000],0 表示最温和的效果,1000 表示最强的效果。

4 PresetReverb

PresetReverb 使用预设混响来配置全局混响,适合于音乐。预置的常见混响场景有:

  • PresetReverb.PRESET_LARGEHALL(适合整个管弦乐队的大型大厅);
  • PresetReverb.PRESET_LARGEROOM(适合现场表演的大型房间的混响预设)。 使用方法为:
PresetReverb presetReverb = new PresetReverb(0,mediaPlayer.getAudioSessionId());
presetReverb.setEnabled(true);
presetReverb.setPreset(PresetReverb.PRESET_LARGEROOM);

5 EnvironmentalReverb

允许应用程序控制全局混响环境中的每个混响引擎属性,更适合游戏。下面介绍下该类常用方法:

  • setDecayHFRatio:设置高频到中频衰减比率。范围是[100, 2000] ,如果设为1000,则全部衰减相同。
  • setDecayTime:中频混响衰减时间。[100, 20000]
  • setDensity:在后期混响衰减,控制模态密度的值。[0, 1000]
  • setDiffusion:在后期混响衰减,控制回声密度的值。 [0, 1000]
  • setReflectionsDelay:初始反射延迟时间。[0, 300]
  • setReflectionsLevel:对于环境效果的早期反射等级。[-9000, 1000]
  • setReverbDelay:先对于初始反射的后期混响延迟时间。 [0, 100]
  • setReverbLevel:相对于环境效果的后期混响等级。[-9000, 2000]
  • setRoomHFLevel:相对于高频环境效果等级。 [-9000, 0]
  • setRoomLevel:相对于低频环境效果等级。[-9000, 0]