Logarithmic channel volume control. How to do it?

Hello everyone,
So I want to control my channel volume logarithmicly rather than linear. I need logarithmic volume controls because the linear curve is too steep. Is there a way to achieve my goal? I’ve searched around for formulas, but none were exactly suitable. Also there is nothing about logarithmic volume control in the fmod engine api.
Thanks in advance.

Generally this would be a little out of scope for the FMOD forums, but I will try to get you pointed in the right direction.
I am not sure what your range of desired values is, but let’s say for now you want a minimum value of 0 and a maximum value of 1. In code such a transformation would look like:

float linear(float x)
{
    if (x < 0)
        return 0;
    else if (x < 1)
        return x;
    else
        return 1;
}

So anything less than 0 we want to map to 0, anything greater than 1 we want to map to 1, and everything between that we want to map directly to x. Here is what that would look like graphing all possible x input values to their corresponding y output values:
image

So you are saying you want a logarithmic function specifically. To do that, we can swap out the x < 1 case for something that uses a log function:

float logarithmic(float x)
{
    if (x < 0)
        return 0;
    else if (x < 1)
        return log2f(x + 1); // +1 for desired max value
    else
        return 1;
}

With this function, any values closer to 0 will change rapidly, and values closer to 1 will change slowly. Then you just need to pass that into setVolume instead of your raw 0 → 1 value.

channel->setVolume(logarithmic(sliderValue));

Hopefully that makes sense. You can experiment with different calculations in the x < 1 case. For a steeper curve you can raise x to the power of a fractional value until you find a curve that suits your needs.

1 Like

Thankyou for the solution. However, I have another problem now. It’s now with the Pan dsp. So I need to pan the channel and I do the following: create the sound, play it with Start paused set to true, then I add a pan dsp to index 0. However, when I unpause the said channel, I hear a click in the center and after a fraction of a second it actually panns right. Fmod updates on my main thread every frame, I’ve tried a lot of thought up solutions and googled, but I found nothing that could solve my problem. Everything is ok but the small click in the center at the start of a sound is there. Any hints on where to go from here please? I’ve tried disabling MixFromUpdate and StreamFromUpdate flags, but it didn’t help.

I have also noticed that the problem is only when using the 2d stereo panning mode. Other panning methods seem to work without clicking in the start.

I found a very unexpected solution:
Setting the software format to 192khz, speaker mode to raw and number of channels 2 solved the click problem and now the panner does fine. I think it’s a bug or something, I’m not sure.

I have not been able to reproduce this, what version of FMOD are you using?
Could you please share a code snippet of how you are creating the sound, adding the Pan DSP, and any additional calls you are making to Channel::set3DAttributes or DSP::setParameterFloat?

fmod v 2.2.20.
code:
FMOD.Factory.System_Create (out FMOD.System FmodSystem);
FmodSystem.init (4095, INITFLAGS.MIX_FROM_UPDATE|INITFLAGS.STREAM_FROM_UPDATE, 0);
byte LoadedBytes = File.ReadAllBytes(“test.ogg”);
FmodSystem.createSound(“test.ogg”, MODE.DEFAULT, out Sound SoundHandle);
FmodSystem.playSound (SoundHandle, default(ChannelGroup), true, out Channel ChannelHandle);
FmodSystem.createDSPByType (DSP_TYPE.PAN, out DSP Panner);
Panner.setParameterInt ((int)DSP_PAN.MODE, (int)DSP_PAN_MODE_TYPE.STEREO);|
ChannelHandle.addDSP (0, Panner);
Panner.setParameterFloat((int)DSP_PAN._2D_STEREO_POSITION, 100);
ChannelHandle.setPaused (false);