fmod使用fader dsp控制音量——不影响频谱采样nice

问题参考:
https://qa.fmod.com/t/fmod-lipsync-question-fmod-volume-affect-spectrum-extracting/18274/21

主要是为了解决实时口型的问题,如果使用vca的方式,改变音量,那么口型会被影响。
当音量小的时候,采样不出来了。

于是,我们使用添加fader dsp的方式改变音量。
这里有几个注意点:
1.fader dsp如何加在指定的ChannelGroup上去
2.fader dsp的取值范围是多少,会以线性的方式影响音量吗?
3.master group的音量控制也要相应的修改为fader dsp的方式

问题1:fader dsp如何加在指定的ChannelGroup上去
首先创建一个dsp的方式是:
RuntimeManager.CoreSystem.createDSPByType(FMOD.DSP_TYPE.FFT, out m_fftDsp);
master group的添加的方式很简单:

RuntimeManager.CoreSystem.getMasterChannelGroup(out m_masterGroup);
var result = m_masterGroup.addDSP(-1, m_faderAllDsp);

而一般的channelgroup使用的方式,则要先播放一个event,然后再添加进去,这个在上面的帖子中,大佬已经给出了示例代码,也没有什么难度。
难点在于,到底往前找几次parent group呢?
经过和音频师的讨论,发现还是有规律的,这个跟文件夹的层级有关系。
比如:
在这里插入图片描述
比如,这里想在Tone的group下,加一个dsp,那么播放一个ToneEmpty,然后向上找一次即可。
这个ToneEmpty,你可以让音频师,做一个空的声音,然后放在Tone下就可以了。

m_toneEmpty = RuntimeManager.CreateInstance("event:/Tone/ToneEmpty");
var res = m_toneEmpty.start();

然后同一帧,还不能添加成功,奶奶的

    private void Update()
    {
        if (!m_initedDSP)
        {
            FMOD.Studio.PLAYBACK_STATE state;
            m_toneEmpty.getPlaybackState(out state);
            if (state != FMOD.Studio.PLAYBACK_STATE.STARTING)
            {
                AddDSP();
                m_initedDSP = true;
            }
        }
    }

问题2:fader dsp其实值在[-80,10]之间
这个[-80,10]是fmod studio中的最小值和最大值,这个我还专门去音频师那里看了下,果然对应了起来。

然后这里有个坑就是,使用fader dsp进行音量的控制不是线性的,你会发现在[-20,10]的时候,衰减的特别明显,以至于滑动条在[-80,-20]直接,拖动没有任何的效果,所以,我们要做一个remap的操作。
这里给出一个绘图工具:
https://www.geogebra.org/graphing
在这里插入图片描述
我们实际项目中,使用[-70,0]这个范围。
因为不能改变之前的音量,所以上限取0
下限如果是-80,结果频谱还是一样没有,所以取到-70基本上就没有声音了。

我们可以将(m,n)~(0,0)这个取消,衰减的慢,而(-70,-70)到(m,n)之间衰减的快一点,这样就近似模拟线性衰减的效果了。

具体代码:

 public static FMOD.DSP m_fftDsp;
    public static FMOD.DSP m_faderDsp;
    public static FMOD.DSP m_faderAllDsp;
    private FMOD.Studio.EventInstance m_toneEmpty;
    private FMOD.ChannelGroup m_masterGroup;
    private FMOD.ChannelGroup m_toneGroup;
    private bool m_initedDSP = false;

    private void Start()
    {
        InitDSP();
        m_toneEmpty = RuntimeManager.CreateInstance("event:/Tone/ToneEmpty");
        var res = m_toneEmpty.start();
    }

    private void InitDSP()
    {
        var res = RuntimeManager.CoreSystem.createDSPByType(FMOD.DSP_TYPE.FFT, out m_fftDsp);
        res = RuntimeManager.CoreSystem.createDSPByType(FMOD.DSP_TYPE.FADER, out m_faderDsp);
        res = RuntimeManager.CoreSystem.createDSPByType(FMOD.DSP_TYPE.FADER, out m_faderAllDsp);
    }

    private void AddDSP()
    {
        RuntimeManager.CoreSystem.getMasterChannelGroup(out m_masterGroup);
        var result = m_masterGroup.addDSP(-1, m_faderAllDsp);

        result = m_toneEmpty.getChannelGroup(out FMOD.ChannelGroup g1);
        result = g1.getParentGroup(out FMOD.ChannelGroup parentGroup);
        result = parentGroup.getParentGroup(out FMOD.ChannelGroup parentGroup2);
        m_toneGroup = parentGroup2;
        result = m_toneGroup.addDSP(-1, m_faderDsp);
        result = m_toneGroup.addDSP(-2, m_fftDsp);
    }

    private void Update()
    {
        if (!m_initedDSP)
        {
            FMOD.Studio.PLAYBACK_STATE state;
            m_toneEmpty.getPlaybackState(out state);
            if (state != FMOD.Studio.PLAYBACK_STATE.STARTING)
            {
                AddDSP();
                m_initedDSP = true;
            }
        }
    }

    private float x = -40;
    private float y = -10;
    /// <summary>
    /// x=-40, y=-10
    /// </summary>
    /// <param name="value"></param>
    private float GetFaderValue(float value)
    {
        if (value >= x)
        {
            return y * 1.0f * value / x;
        }
        else
        {
            return (y + 70) * 1.0f * value / (x + 70) + y - (y + 70) * 1.0f * x / (x + 70);
        }
    }
 	public void SetMainVolume(float volume)
    {
        if (FMODUnity.RuntimeManager.Instance != null)
        {
            float faderValue = GetFaderValue(volume);
            var res = m_faderAllDsp.setParameterFloat((int)FMOD.DSP_FADER.GAIN, faderValue);
            // Debug.LogError(res + "   faderValue=" + faderValue);
        }
    }

这样就不会影响频谱采样喽!!!

问题3:master group的音量控制也要相应的修改为fader dsp的方式
master group的音量控制方式,也要有原来的vca的方式控制,改为fader dsp的方式控制。
其他的group,我们还是可以使用vca的方式进行控制的。
其形式大致如下:
在这里插入图片描述

补充于:
2022/3/3
dsp在游戏关闭的时候要记得销毁,否则会有一个"connectionsremaining==0" failed.报错。

    /// <summary>
    /// 关闭游戏的时候要销毁,否则会有一个报错信息"connectionsremaining==0" failed.
    /// </summary>
    public void OnDestroy()
    {
        var result = m_toneGroup.removeDSP(m_faderDsp);
        result = m_toneGroup.removeDSP(m_fftDsp);
        result = m_masterGroup.removeDSP(m_faderAllDsp);

        result = m_fftDsp.release();
        result = m_faderDsp.release();
        result = m_faderAllDsp.release();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值