基于Agora SDK实现Android端的声动互娱(四)——美声、变声和人声

时间:2023-03-26 17:00:48

近几年诈骗罪成为了我国刑事犯罪的第一大罪名,在网络上勾引你裸聊的“小姐姐”很可能是抠脚大汉利用美声软件假扮的。美声和人声在社交娱乐场景中可以为增添场景的趣味性并提升互动体验。Agora提供封装在枚举中的预设的美声(VoiceBeautifier)和变声(VoiceConversion)效果参数,可以帮助你在项目中快速集成美声、变声和人声效果。


设置音频编码属性

注意本文中提到的setVoiceBeautifierPreset()、setVoiceBeautifierParameters()、setVoiceConversionPreset()、setAudioEffectPreset()、setAudioEffectParameters()方法两两互斥,后调用的会完全覆盖先调用的,然后setLocalVoicePitch()、setLocalVoiceEqualization()、setLocalVoiceReverb()方法也会影响先调用的方法的结果,所以方法调用顺序不能乱。

回到上文初始化RtcEngine的initializeAndJoinChannel()方法里,进行如下修改:

try {
    // 配置参数
    RtcEngineConfig config = new RtcEngineConfig();
    config.mContext = getBaseContext();
    config.mAppId = appId;
    config.mEventHandler = mRtcEventHandler;
    // 将 RtcEngineConfig 中的 mAudioScenario 设置为 AUDIO_SCENARIO_GAME_STREAMING。
    config.mAudioScenario = Constants.AudioScenario.getValue(Constants.AudioScenario.GAME_STREAMING);
    // 初始化核心类RtcEngine
    mRtcEngine = RtcEngine.create(config);
    // 调用 setAudioProfile,将场景设置为 AUDIO_PROFILE_MUSIC_HIGH_QUALITY 或 AUDIO_PROFILE_MUSIC_HIGH_QUALITY_STEREO。
    mRtcEngine.setAudioProfile(Constants.AudioProfile.getValue(Constants.AudioProfile.MUSIC_HIGH_QUALITY_STEREO));
} catch (Exception e) {
    throw new RuntimeException("Check the error.");
}

美声

美声是指在不改变原声辨识度的前提下,根据男女声各自的特点美化说话声。只需写很简单的一行代码便可以使用Agora傻瓜式的美声功能:

// 设置预设的美声效果
mRtcEngine.setVoiceBeautifierPreset(Constants.SINGING_BEAUTIFIER);

可以填写的参数的值都在io.agora.rtc2. Constants文件中:

/**
 * 代码来自 {@link io.agora.rtc2.Constants}
 */
// 原声,即关闭美声效果
public static final int VOICE_BEAUTIFIER_OFF = 0;
// 磁性(限男)
public static final int CHAT_BEAUTIFIER_MAGNETIC = 16843008;
// 清新(限女)
public static final int CHAT_BEAUTIFIER_FRESH = 16843264;
// 活力(限女)
public static final int CHAT_BEAUTIFIER_VITALITY = 16843520;
// 歌唱美声
public static final int SINGING_BEAUTIFIER = 16908544;
// 浑厚
public static final int TIMBRE_TRANSFORMATION_VIGOROUS = 16974080;
// 低沉
public static final int TIMBRE_TRANSFORMATION_DEEP = 16974336;
// 圆润
public static final int TIMBRE_TRANSFORMATION_MELLOW = 16974592;
// 假音
public static final int TIMBRE_TRANSFORMATION_FALSETTO = 16974848;
// 饱满
public static final int TIMBRE_TRANSFORMATION_FULL = 16975104;
// 清澈
public static final int TIMBRE_TRANSFORMATION_CLEAR = 16975360;
// 高亢
public static final int TIMBRE_TRANSFORMATION_RESOUNDING = 16975616;
// 嘹亮
public static final int TIMBRE_TRANSFORMATION_RINGING = 16975872;

擅长整活的读者,现在已经开始用高昂的Constants. TIMBRE_TRANSFORMATION_RESOUNDING结合上文讲过的击筑配音来实现“渐离击悲筑,宋意唱高声”了。


注意Constants. SINGING_BEAUTIFIER比较特殊,在setVoiceBeautifierPreset()方法里只能用于男声,用于女声会失真。不过你的担心是多余的,Agora提供了setVoiceBeautifierParameters()来设置预设美声的具体参数:

/**
 * 第二个参数是歌声的性别特征:1-男 2-女
 * 第三个参数是歌声的混响效果:1-小房间 2-大房间 3-大厅
 */
mRtcEngine.setVoiceBeautifierParameters(Constants.SINGING_BEAUTIFIER,2,3);

变声和人声

除了美声之外,Agora也提供了变声和人声特效:

// 预设变声效果为更中性化的声音。
mRtcEngine.setVoiceConversionPreset(Constants.VOICE_CHANGER_NEUTRAL);
// 预设人声效果为在 KTV 中的效果。
mRtcEngine.setAudioEffectPreset(Constants.ROOM_ACOUSTICS_KTV);
// 这是预设人声的电音效果,我去酒球汇听电音都是听个热闹,实际上不懂这个具体参数
mRtcEngine.setAudioEffectParameters(Constants.ROOM_ACOUSTICS_3D_VOICE,3,1);
// 因为篇幅限制,这三行代码写在一起了,实际上是两两互斥的

因为篇幅有限,Constants类中大段常量的代码就不贴了。


自定义变声参数

除了可以使用预设的美声、变声和人声之外,用户还可以根据自己的实际情况开发属于自己的音效处理方法,我这里放上Constants. VOICE_CHANGER_EFFECT_HULK(无敌浩克)的参数:

private void makeHulkVoice(){
    // 设置本地语音音调。取值范围[0.5,2.0] 越小则音调越低。默认值为 1.0,表示不需要修改音调。
    double pitch = 0.5;
    mRtcEngine.setLocalVoicePitch(pitch);

    // 设置本地人声均衡波段的中心频率。
    // 第 1 个参数为频谱子带索引,取值范围 [0,9],分别代表 10 个频带
    // 第 2 个参数为每个频率区间的增益值,取值范围 [-15,15],单位 dB, 默认值为 0。
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_31, -15);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_62, 3);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_125, -9);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_250, -8);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_500, -6);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_1K, -4);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_2K, -3);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_4K, -2);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_8K, -1);
    mRtcEngine.setLocalVoiceEqualization(Constants.AUDIO_EQUALIZATION_BAND_FREQUENCY.AUDIO_EQUALIZATION_BAND_16K, 1);
    
    // 原始人声强度,即 dry signal,取值范围 [-20,10],单位为 dB。
    mRtcEngine.setLocalVoiceReverb(Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_DRY_LEVEL, 10);
    // 早期反射信号强度,即 wet signal,取值范围 [-20,10],单位为 dB。
    mRtcEngine.setLocalVoiceReverb(Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_WET_LEVEL, 7);
    // 所需混响效果的房间尺寸,一般房间越大,混响效果越强。 取值范围 [0,100]。
    mRtcEngine.setLocalVoiceReverb(Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_ROOM_SIZE, 6);
    // Wet signal 的初始延迟长度,取值范围 [0,200],单位为 ms。
    mRtcEngine.setLocalVoiceReverb(Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_WET_DELAY, 124);
    // 混响效果持续的强度,取值范围为 [0,100],值越大,混响效果越强。
    mRtcEngine.setLocalVoiceReverb(Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_STRENGTH, 78);
}

只要擅长计算以上几个方法的参数,男用户可以把自己的语音修改得像单田芳一样沙哑,然后去讲评书,女用户也可以把自己的语音修改得像蔡明一样阴阳怪气,然后去演小品……因为我能力有限,就不提供更多的语音参数了

最后我们以一个欢乐的视频结束本文,视频里主画面(我的正脸)是对方视角,副画面(我的侧脸)是本人视角,注意听

【视频】

学习过了美声和人声之后,我们关于声动互娱的学习暂时可以告一段落了,但是Agora SDK这座宝库,我们的探索度还是很低的,我会继续更新屏幕共享、音视频观测、噪音衰减等丰富的功能的保姆级教程。