Always getting a nullptr from Bus::getChannelGroup long after everything's loaded

I’m using the C++ API to attach a custom DSP to the Master Bus’s Channel Group (eventually in an attempt to record the output).

Everything seems to work up until using Bus::getChannelGroup because, despite receiving an FMOD_RESULT of FMOD_OK from the function, it’s clearly a nullptr when logged and using any function on it results in FMOD_ERR_INVALID_HANDLE.

I’ve tried several things to make sure the Banks and Master Bus have loaded before trying to get the Channel Group, even calling the logic after 100 updates have passed, but no luck.


My code to initialize FMOD Studio and load my banks is very basic:

FMOD::Studio::System* studio;
FMOD_CALL(FMOD::Studio::System::create(&studio));
FMOD_CALL(studio->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, nullptr));

FMOD::Studio::Bank* bank = nullptr;
FMOD_CALL(studio->loadBankFile((content_dir + "sounds/Desktop/Master.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &bank));
FMOD_CALL(studio->loadBankFile((content_dir + "sounds/Desktop/Master.strings.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &bank));

After that is when I’ve experimented with calling studio->update() with no luck.

Next I create the DSP, which I’ll abbreviate, and the get the master bus. Both are definitely working as far as I can tell and are not null:

FMOD_DSP_DESCRIPTION dsp_description = {};
// ... creating DSP settings here
FMOD::DSP* dsp = nullptr;
FMOD::System* core_system = nullptr;
FMOD_CALL(studio->getCoreSystem(&core_system));
FMOD_CALL(core_system->createDSP(&dsp_description, &dsp));

FMOD::Studio::Bus* master_bus = nullptr;
FMOD_RESULT result = FMOD_ERR_INVALID_HANDLE;

while (result == FMOD_ERR_INVALID_HANDLE)
{
    result = FMOD_CALL(studio->getBus("bus:/", &master_bus));
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

Finally, the ChannelGroup, which usually fails just ONCE with FMOD_ERR_STUDIO_NOT_LOADED before finally getting FMOD_OK:

FMOD::ChannelGroup* channel_group = nullptr;
result = FMOD_ERR_INVALID_HANDLE;

while (result == FMOD_ERR_INVALID_HANDLE)
{
    result = FMOD_CALL(master_bus->getChannelGroup(&channel_group));
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

It then fails here due to being null:

FMOD_CALL(master_bus->lockChannelGroup());
FMOD_CALL(channel_group->addDSP(FMOD_CHANNELCONTROL_DSP_HEAD, dsp));
FMOD_CALL(master_bus->unlockChannelGroup());

Hi,

I would recommend adding flushCommands() and flushSampleData() after lockChannelGroup() which will make sure the channel is loaded in memory before we try and access it to add the DSP.

FMOD_CALL(master_bus->lockChannelGroup());
FMOD_CALL(studio->flushCommands());
FMOD_CALL(studio->flushSampleData());
FMOD_CALL(channel_group->addDSP(FMOD_CHANNELCONTROL_DSP_HEAD, dsp));
FMOD_CALL(master_bus->unlockChannelGroup());

You can read more about these functions under FMOD API | Studio API Reference - Studio::System.

Hope this helps!

Hi Connor, I’m not seeing any function named flushSampleData in the docs you linked, and I don’t see it as a method on FMOD::Studio::System either.

Hi,

Apologies, it was meant to be FMOD_CALL(studio->flushSampleLoading());. Which can be found here FMOD API | Studio API Reference - Studio::System.