About WebGL project load bank and memory useage

We are developing a multi-platform project for Android, iOS, and WebGL.

However, I noticed a detail about loading the Bank under the WebGL platform, the final loading method used in the C# code is: Studio::System::loadBankMemory().
Does this cause the entire Bank file to be loaded into memory, while streaming loading of Streaming data has no effect?

In my local testing, it appears that after loading the Bank file, FMOD’s memory footprint increases by a value close to the size of the Bank file.
Do we have a better way to handle this situation?

Runtime memory concerns using FMOD for WebGL / HTML5 project - FMOD Studio - FMOD Forums
I saw this thread in the forum where he mentioned optimizing the memory footprint by loading and unloading the Bank itself.
But there are Bank interdependencies between Event and Event, is there an easier way for us to get the dependencies between them other than building them into the same Bank file?

Currently I’m working in FMOD Studio to analyze dependencies between Events via JavaScript scripts and export a file for reading these relationships.
However, as the complexity of Events increases, so does the painstaking difficulty of this analysis.

Is there a way in FMOD’s native API to detect dependencies between Events, and to detect dependencies between Events and Banks?

Studio::System::loadBankMemory with the default mode FMOD_STUDIO_LOAD_MEMORY causes FMOD to copy bank data from an external buffer provided by you to an internal buffers - this includes streaming sample data. In this case, since your data has already been loaded into memory, compressed sample playback is generally preferable to streaming.

Only loading a bank shouldn’t incur significant memory usage increase until the bank’s sample data is loaded into memory. If you’re also loading sample data, or are using loadBankMemory, then what you’re describing is expected behavior.

Can you elaborate on your events’ interdependencies? All sample data needed by an event will be assigned to its bank - unless specified, this includes the sample data used referenced events that are assigned to other banks.

1 Like

I guess maybe I should have gone into more detail about what’s going on.

In FMOD for Unity, the LoadBank(string bankName, bool loadSamples, string bankId) method in the RuntimeManager class has two ways of loading.
The first is loading from local, which ends up using the Studio::System::loadBankFile() API.
The second is loading from a network request, which calls the loadFromWeb(string bankPath, string bankName, bool loadSamples) method in the RuntimeManager, which ultimately uses the Studio::System::: loadBankMemory API. loadBankMemory` API.

Obviously, on Android and iOS platforms, files will be loaded locally, and FMOD will use Streaming data to keep memory at a reasonable level.
But when it comes to WebGL platforms, due to various limitations, we can’t store files locally, only in memory. The Studio::System::loadBankMemory API also downloads the entire Bank file into memory, which obviously has a huge impact on memory usage.

Therefore, we need to maintain a system that allows loading Banks into memory only when they are needed, and unloading them when they are not - similar to jeff_fmod’s idea.

However, the problem arises at this point, under the WebGL platform, each Bank file has to be downloaded from the server, so we need to control the size of the Bank file within a certain limit, otherwise it will take too long to load the Banks.

Therefore we split the Event into multiple Banks, which also leads to the possibility that the Events may have references to each other.

As an example, Event A is assigned in Bank A, and Event B is assigned in Bank B.
In Event A, Event B is used as Event Instrument.
If I want to play Event A, I need to load both Bank A and Bank B at the same time.
Based on the previous reasons, I need to load and unload the Bank files manually. Then I need to know in some way that this reference relationship exists between Event A and Event B. And make sure that both Bank A and Bank B have been loaded before playing Event A.

The way I’m currently using is to export to a json file via a script in FMOD Studio to record these relationships.

But there is a tricky problem at this point:
If there is an Event C that uses a Parameter Sheet, it is assigned in Bank C.
Also referenced in Event C are Events C1, C2, C3, …, and C10, each of which uses a very large audio file (e.g. background music).
And these Events are in turn assigned in Banks C1, C2, C3, …, and C10 (in order to ensure that the size of each Bank file does not exceed the limit).
The result of my JavaScript script execution is that when playing Event C, Bank C, C1, C2, …, and C10 need to be loaded at the same time because of the dependencies between them. But again, this results in a huge memory footprint.

Is there a better and more direct way for us to get out the relationship between Event and Bank? Or is there a better solution for this situation?
It seems that enabling “Include referenced events in banks (recommended)” when building banks doesn’t solve the problem.

Thanks for the detailed explanation.

While it would solve your organizational problem of handling the dependencies of event C and loading banks C1 through C10 yourself, ultimately it wouldn’t help with your memory constraints.

Unfortunately, while there are ways to tailor it to your needs, the relationship between bank and event and the expectation that the developer will know ahead of time which banks to load are a something of a pillar of FMOD Studio’s intended, higher level workflow. As a result, there may not be an easy solution to your problem.

That said, besides standard optimizations like more heavily compressing your assets, you may have to tailor/limit your event structure even further to match your needs - for example, some combination of the three:

  • Further separating your events where possible to ensure that only the required banks are loaded instead of all banks C1 through C10
  • Restructuring or limiting the scope of event C to not require ten referenced events
  • Adding even more granularity to your bank/bank dependency Script, so that you know which specific banks from C1 to C10 you need to load at any given time, instead of knowing that you need to load all of them

That last point may be the most workable for you - if the “Include referenced events in banks” option in Studio is disabled, and you load the bank of a parent event but not its referenced event, during playbank the event instrument containing the referenced event that isn’t loaded will instead be silent. So, if you know that you only need events C1, C3, and C7, you can then only load banks C1, C3, and C7, and the rest of the events that are referenced by event C will be silent.

1 Like

That said, my best solution for this situation would be:

  1. from FMOD Studio, get all the relationships between Events, and between Events and Banks by way of scripting, and store them in your own way.
  2. when playing Events in the game, dynamically control which Banks need to be loaded in memory based on the stored dependencies to keep the memory footprint within a reasonable range.

And as for how to get these relationships, there’s no better way than using a script to get them myself?

Besides just simplifying your event structure/dependencies so that you require less assets in memory, and compressing your assets further, yes, that is likely the best solution to your problem.

Yes, the best way to track relationships between banks, events, etc. for you purposes is to use a custom Studio script.

1 Like