I have been ordered to make sure that it is possible to load all FMOD resources from memory instead of files and looking at the API it doesn’t really look like something the API was designed for. There is ofcourse the register/unregisterMemoryFSB but that only solves one part of the problem. I do have some ideas of how to solve the rest but they do involve some "hacking" and I need to make sure that what I am about to do won’t cause any weird errors.
The idea I have is to use the filesystem callbacks and design them to access a "memoryimage" instead of a file. The memoryimage(s) are created before the init/load/get functions are called, that is the functions that trigger filesystem calls. I don’t see any reason why this shouldn’t work apart from fsb’s that contain streamed content. To solve this I use the registerFSB functions for fsb-files and skip the callbacks. Since I want to, at least for now, let FMOD handle the streaming I need to make sure that I disable the callbacks when I’m not loading content. Is this at all possible without wrecking FMOD? I’m totally aware of the risk of turning callbacks on/off if I were to be streming a sound at the same time as I was doing a non-blocking read but I won’t be making any non-blocking reads only access data from memory and let our resourcestreamer fetch the actual data from disc. So to conclude, is it safe to:
a) Re-direct the filesystem callbacks to access memoryimages instead of files for .fevs.
b) Use registerFSB for all fsb:s.
c) Switch the filesystem callbacks on/off provided that this isn’t done when a non-blocking fileaccess is taking place.
- Frohagen asked 10 years ago
What registerMemoryFSB does is to tell FMOD to assume the bank it’s going to use is already available at the pointer you specified instead of loading it through the file callbacks.
To preload a bank just reserve memory with whichever memory manager you have (the default operator ‘new’, an overloaded one or something similar), load it from disk to your reserved buffer and call registerMemoryFSB passing the pointer to, again, the reserved buffer. What you end up with is: (1) One memory pool which is ONLY used by FMOD to load the project, event instances, any unregistered bank subsound, etc.; (2) One buffer for each bank you preloaded and registered as mentioned above.
Although using the file callbacks to read from memory instead of actually reading from disc sounds like a good idea, it is not because you would end up having each bank twice in memory (one loaded by yourself and then FMOD would copy it to its own memory pool). So you do need to register the bank.
Hope this helps,
- acolorado answered 10 years ago
We would prefer avoiding two memorypools and it is possible to do this. By skipping the registerMemoryFSB function and fooling the filesystem callbacks to access memory all content will end up in FMOD’s memorypool. The memorybuffer from which we do the reads in the callbacks will ofcourse be deleted at closefile so no, we will not end up with two copies of the memory. Unfortunatelly, even though the filesystem callback-trick sounds pretty easy in theory it’s really, really messy to implement and it produces some rather "hack:ish" code which can be painfull to look at At least that is the case right now.
One more thing. It’s a bit unclear about memorymanagement when it comes to the registerMemoryFSB. Will the memory be copied or do I need to store it somewhere. If I am to maintain it externally then is there someway that I could do this and still use the same memorypool as the rest of the sounddata? Or do I need a seperate memorypool for external sounddata? If I register my fsbs and the do a loadEventData with these referenced I get the following error: "Tried to use a feature that requires the software engine. Software engine has either been turned off, or command was executed on a hardware channel which does not support this feature. " Do I really need to force software to be able to register from memory and why?
Yet another thing. Since it seems to work really good to do the callback-hack to enable loading any FMOD resource from memory I’m thinking of using it for samplebanks as well instead of the registerMemoryFSB function. Actually, what I want to do is a way of doing loadEventdData from memory. The problem though is that in order to make it work I need to pre-buffer all referenced samplebanks. This is a problem since:
a) It’s very messy to get all samplebanks used by an eventgroup. I need to traverse all events and in cases where thre are lots of events in a group it’s not really a nice solution. Would it be possible to have included in the eventgroup-info all referenced samplebanks?
b) There is no way to figure out if a samplebank is loaded. Only if it is registered. Or can I use the EventSystem::getInMemoryFSB for samplebanks loaded by loadEventdata?
[quote="Frohagen":1jeasol5]One more thing. It’s a bit unclear about memorymanagement when it comes to the registerMemoryFSB. Will the memory be copied or do I need to store it somewhere. [/quote:1jeasol5]
It is not copied, it is pointed to.
If I am to maintain it externally then is there someway that I could do this and still use the same memorypool as the rest of the sounddata?
Or do I need a seperate memorypool for external sounddata? If I register my fsbs and the do a loadEventData with these referenced I get the following error: "Tried to use a feature that requires the software engine. Software engine has either been turned off, or command was executed on a hardware channel which does not support this feature. " Do I really need to force software to be able to register from memory and why?[/quote:1jeasol5]
Yes , hardware doesnt always know how to just ‘point’ to data. It depends on what platform you’re on.
I don’t know if I have misunderstood the very point of register/unregisterMemoryFSB but as I see it would have been nice with an extension that makes FMOD maintain the memory. Why is this a good feature? Well, what we want to achieve in our game by using registerMemoryFSB is to cut down on loading times, that is instead of doing one disc access for every samplebank we load them all as one big chunk. I know that we won’t save minutes by doing so but rather seconds but it’s the later that counts in the end when you spend weeks hunting places to optimize to make the loading times stay within the allowed timeframe. Unfortunatelly, the registerMemoryFSB functionallity as it is right now messes up the memory management a bit since we would need two memorypool. Not rocket-science to implement but something we rather avoid having. What do you say?
Please login first to submit.