Questions about DSP

I have several DSP related questions.

  1. If I apply FMOD_DSP_SetBypass(TRUE) to a certain DSP instance, does FMOD still consume some CPU power for the DSP effect in the background or do nothing?

When I add a global echo / reverb instance to a channel group using FMOD_ChannelGroup_AddDSP() or FMOD_System_SetReverbProperties(),
calling FMOD_Channel_Stop() / FMOD_ChannelGroup_Stop() only stops the original source sound but not the remaining echo / reverb effect of the sound.
On the other hand, I could stop the whole sound using FMOD_Channel_Stop() / FMOD_ChannelGroup_Stop() when I added an echo / reverb instance to a specific channel using FMOD_Channel_AddDSP().

  1. Is there a way to stop a sound including its remaining DSP effects immediately when the DSP instances are added to a channel group?

Calling FMOD_ChannelGroup_SetMute() or FMOD_ChannelGroup_SetVolume() on DSP instances added using FMOD_Channel_AddDSP() or FMOD_System_SetReverbProperties() works fine,
(whereas FMOD_Channel_SetMute() and FMOD_Channel_SetVolume() don’t.)
but FMOD_Channel_SetMute(), FMOD_ChannelGroup_SetVolume(), FMOD_ChannelGroup_SetMute() and FMOD_ChannelGroup_SetVolume() don’t work at all with DSP instances
added using FMOD_ChannelGroup_AddDSP().

  1. How can I adjust the volume of a channel group’s DSPs?

The final question is not actually related to DSP, but let me ask.
I read about FMOD_System_SetStreamBufferSize() from the Core API Reference and found this statement.

“Does not affect latency of playback.”

  1. Is there really nothing to worry about with large values other than consuming more memory unlike FMOD_System_SetDSPBufferSize() which causes high latency?

It should not use any CPU while it is bypassed, if it does it will so minimal that it is not noticeable.

You can cut off any signal from a DSP using DSP::reset.

You can control the level of DSP::Connections between DSPs to achieve that, using DSPConnection::setMix.

You would be limited by the disk access speed.

1 Like

Thank you very much!

May I ask one more question?

What are advantages and disadvantages of FMOD_DSP_SetActive() over FMOD_DSP_SetBypass(), when I just want to disable a DSP for a few seconds to a few minutes?

SetActive stops the signal flow at the DSP, bypass passes the signal around the DSP.

Reading your comments, I guess, from a user’s perspective, it may seem the same as calling FMOD_DSP_SetBypass() and then FMOD_DSP_Reset() since CPU is not used either when bypassing.
Thanks!

I wanted to try FMOD_DSPConnection_SetMix() but failed because I couldn’t get a FMOD_DSPCONNECTION*.
I guess, a FMOD_DSPCONNECTION* can be obtained using FMOD_ChannelGroup_AddGroup(), but isn’t there any other way for a DSP directly added to the Master Channel Group using FMOD_ChannelGroup_AddDSP() and a Standard Reverb object created by FMOD_System_SetReverbProperties() ?

You can use DSP::getInput & DSP::getOutput to access the DSPConnections.

1 Like

In fact, I already had a look at them, but didn’t really think it would help because it required an index, which I have no idea at all.
But anyway I tried again because you said it would work.

First I compared the dsp pointers resulted from FMOD_DSP_GetOutput() with the original dsp pointer, iterating from 0 to FMOD_DSP_GetNumOutputs().
And I found two things.

  1. There’s only one connection for my reverb DSP.
  2. My reverb DSP pointer and the pointer from the function are not the same.

So now I simply tried calling FMOD_DSP_GetOutput(g_DSP_reverb, 0, &ouputDSP, &outputDSPConnection); and this worked for me.

My final question is,

  1. If there’s any connection, will index-0 be always valid? Or do I have to iterate through the whole range and find a valid one myself?

  2. If I added a dsp using FMOD_ChannelGroup_AddGroup() to the Master Channel Group just once, will that dsp ever have more than one input/output connections? Or can I just assume there’s always only one?

  3. Can’t I call FMOD_DSP_GetOutput() right after FMOD_ChannelGroup_AddGroup()?
    In my test, I had to put some delay before calling FMOD_DSP_GetOutput().

Thanks.

This depends where and to what you are adding the DSP.

  • All leaf Channels will have at least one output but may not have an input.
  • The Master Channel Group will have inputs but no output.
  • DSP’s on the tail of a ChannelGroup can have multiple outputs.

If you wanted, for example, the output of a DSP you know won’t be at the tail of a ChannelGroup you can be confident that it will only have one output.

It depends, see above.

FMOD_DSP_GetOutput will flush the DSP queue (which blocks against the mixer), if you are not seeing this then it may be a bug. Do you get an FMOD_RESULT from GetOutput that would indicate the issue?

Thank you very much!

As for your last question,
I get 0 from FMOD_DSP_GetNumOutputs(), and FMOD_ERR_DSP_NOTFOUND from FMOD_DSP_GetOutput().
But when I call it later AGAIN, then FMOD_DSP_GetNumOutputs() returns 1, and FMOD_DSP_GetOutput() returns FMOD_OK.

My tests are all returning the connection when calling getOutput immediately after adding a channelgroup/dsp.

What version of FMOD are you using?
Are you able to share the code you are using?
You can send it to support@fmod.com if you like.

I tested it again, and found it works always fine with any channels, but it has the issue with the master channel group.

When that happened, I could workaround by either changing the option FMOD_CHANNELCONTROL_DSP_HEAD to FMOD_CHANNELCONTROL_DSP_TAIL,
or adding one more dsp to the master channel group.

a. If only one dsp is added to the head, FMOD_DSP_GetNumOutputs() will return 0.
b. If more than one dsps are added to the head, FMOD_DSP_GetNumOutputs() will return 1.
c. If only one dsp is added to the tail, FMOD_DSP_GetNumInputs() will return 0.
d. If more than one dsps are added to the tail, FMOD_DSP_GetNumInputs() will return 1.
e. Mixing head and tail doesn’t help.
f. When added to a channel, both FMOD_DSP_GetNumOutputs() and FMOD_DSP_GetNumInputs() always return 1.

I’ll attach my test code at the end.

By the way, your Core API Reference says FMOD_DSP_GetOutput() can accept an index which is “Range: [0, DSP::getNumOutputs]”, but it should be “Range: [0, DSP::getNumOutputs - 1]”,
because if FMOD_DSP_GetNumOutputs() returns 1, then there’s only one index I can access, which is 0. The reference can be confusing to some people, I think.


Here’s my test code :

// 09/05/19 2.00.01 - FMOD Studio API minor release (build 102182)

#include <stdio.h>
#include <conio.h>
#include <fmod.h>

FMOD_SYSTEM *g_System;
FMOD_DSP *g_DSP1;
FMOD_DSP g_DSP2;
FMOD_CHANNELGROUP
g_MasterChannelGroup;

void GetOutput() {
static int count;
static FMOD_DSP* ouputDSP;
static FMOD_DSPCONNECTION* outputDSPConnection;

FMOD_DSP_GetNumOutputs(g_DSP1, &count);

FMOD_RESULT result = FMOD_DSP_GetOutput(g_DSP1, 0, &ouputDSP, &outputDSPConnection);

printf("Count:%d, Result:%d\n", count, result);

}

void init() {
FMOD_System_Create(&g_System);

FMOD_System_SetSoftwareChannels(g_System, 128);

FMOD_System_Init(g_System, 1024, FMOD_INIT_NORMAL, NULL);

FMOD_System_GetMasterChannelGroup(g_System, &g_MasterChannelGroup);

// All other DSPs including FMOD_DSP_TYPE_ECHO, FMOD_DSP_TYPE_FLANGE,
// FMOD_DSP_TYPE_PITCHSHIFT, FMOD_DSP_TYPE_LOWPASS and FMOD_DSP_TYPE_HIGHPASS lead to the same result.
FMOD_System_CreateDSPByType(g_System, FMOD_DSP_TYPE_SFXREVERB, &g_DSP1);
FMOD_System_CreateDSPByType(g_System, FMOD_DSP_TYPE_SFXREVERB, &g_DSP2);

// Adding to the tail always works : FMOD_ChannelGroup_AddDSP(g_ChannelGroup, FMOD_CHANNELCONTROL_DSP_TAIL, g_DSP1);
FMOD_ChannelGroup_AddDSP(g_MasterChannelGroup, FMOD_CHANNELCONTROL_DSP_HEAD, g_DSP1);

GetOutput();

FMOD_ChannelGroup_AddDSP(g_MasterChannelGroup, FMOD_CHANNELCONTROL_DSP_HEAD, g_DSP2);
GetOutput();

}

int main(void) {

init();

_getch();

return 0;

}

The Master Chanel Group’s head will never have an output, it is the only channel/group that does not.
If you add a DSP to the head/tail it becomes the new head/tail, if you add another DSP it will become the new head/tail then your first DSP is now 1 DSP away from the head/tail and will have an input/output.

Same as above, but to get input into the Master Channel group there needs to be an active sound playing.

I recommend having a look at the FMOD Profiler, seeing the DSP graph may help.

1 Like

Thank you as always!