I have multiple channels, with a chain of effects per channel. I manage to turn them on and off, but setActive(true) on a given effect for a particular channel, activates all effects. All ‘read’ functions get called and processed. Am I missing something?
Other related questions. I have to channel->addDSP(mydsp, 0) every time I system->playSound and setDelay(FMOD_DELAYTYPE_DSPCLOCK_END on that channel. Is that normal / OK?
- TeeJay asked 8 years ago
[quote:1lbgarn6]It looks like that setDelay(FMOD_DELAYTYPE_DSPCLOCK_START…) on a channel turns on active DSP units on that channel by default even though the FMOD_DELAYTYPE_DSPCLOCK_START time wasn’t reached yet. Is that right?[/quote:1lbgarn6]
Using setDelay requires that the DSPs are active, if they are inactive they are not processed which means they will not start. Setting something to inactive is pretty much completely cutting it off, it (and all of it’s children) will no longer be processed at all for anything.
[quote:1lbgarn6]In that case the number of "playing" channels matters computationally. Is that expected behavior? [/quote:1lbgarn6]
Yes that is expected, every channel needs to be processed. Even if it is just waiting on a setDelay start, it still needs to check when it’s ready to start. Channels are inexpensive, you can have hudreds of active channels.
[quote:1lbgarn6]And FMOD_DELAYTYPE_DSPCLOCK_START is more like a mute at the output of the DSP chain?[/quote:1lbgarn6]
Not really, it will delay the start of a channel. If there are other sounds going through the DSP chain they will still be audible.
It looks like that setDelay(FMOD_DELAYTYPE_DSPCLOCK_START…) on a channel turns on active DSP units on that channel by default even though the FMOD_DELAYTYPE_DSPCLOCK_START time wasn’t reached yet. Is that right? In that case the number of "playing" channels matters computationally. Is that expected behavior? And FMOD_DELAYTYPE_DSPCLOCK_START is more like a mute at the output of the DSP chain?
Thanks Peter. I finally got it to work. Having to use DSP::setBypass is a bit confusing because DSP::setBypass doc says that "If a unit is bypassed, it will still process its inputs." which is why I used DSP::setActive, that says "If a unit is disabled, and has inputs, they will also cease to be processed." which seems to be the right thing to use. I’m using both somehow in order to turn on and off the right dsp units of the chain.
There is no way for FMOD to know if data has been written to the outbuffer. The onus is on the developer to make sure the data in outbuffer is valid. We could memset it internally prior to firing the callback, but that would slow down the mixer. If you are doing no processing inside your DSP the you should just memcpy inbuffer to outbuffer. If you are making an oscillator DSP then just memset outbuffer to zero.
Edit: I have looked into this and has been designed so that the delay mechanism is processed inside the mixer; this is what allows the delay to be sample accurate. A channel which is delayed will generate silence prior to starting the sound. That silence is a signal which still has to be processed DSP chain, including your custom DSP.
I did some testing and found something slightly disturbing. When I skip writing samples into the outbuffer of the read function, the mixer doesn’t seem to set its volumes properly (I am forced to divide my signal amplitude manually by the number of channels). If I write zeros in the outbuffer instead, volumes are correct. How do you know that I wrote something in the outbuffer?
I understand the active/bypass roles, but what is confusing to me is what happens "before" the FMOD_DELAYTYPE_DSPCLOCK_START time kicks in. When channels are active, and delays are set to a later start, I expect virtually no process time until then, as you mentioned yourself. However, the read functions of my DSP units (custom effects) get called on every channel no matter what time it is (specifically because the channel is active). If I want to avoid the computing, am I supposed to check the time in the DSP unit read function and have my delay time in the userdata, and do the bypass manually until the time is up? Or am I not using custom effects properly? Thanks again.
Please login first to submit.