I’m confused about how the memory usage is reported from getMemoryInfo(). When I add the memory used by the info only events I’ll get 37mb, after unloading unused events, using freeEventData(), it will go down to 8mb, as expected. The WAVEBANKINFO will still show high memory usage, and the system getMemoryInfo() will still be 40-50mb. When calling getInfo(), and getMemoryInfo() on an info only event is that the aggregate values for all event instances of that event?
Also is there a way to enumerate all event instances? Specifically loaded events. SYSTEMINFO says there are 122 events, and 556 instances but the numinstances in EVENT_INFO on a info only event is always 0.
- capybara asked 3 years ago
With low level opening of FSB, With default settings for streamBufferSize and decodeBufferSize, the memory usage for an mp3 FSB with 5 subsounds in it is 128kb, and when I loaded it again, 126kb.
With event API using getEvent, getting a streamed event was 144kb for the first time, and 133kb for the 2nd getEvent.
You could reproduce these figures using simple_event and changing the fmod designer example project’s ‘tutorial_bank’ to streaming instead of load into memory, i also changed it from mp2 to mp3. I also used ‘basic event’ and changed it max playbacks property to 2.
Our programmer was able to reproduce what you are seeing with the examples project. However, we just recently updated the engine and Designer to 4.44.14 and saw that the RAM usage for streaming is now in line with what you said it should be. So this higher RAM usage for streams appears to have been an API/Designer bug that since got fixed (aside from the issue of having 5.1 files in a stereo bank).
As a side note, our motivation to update to 4.44.14 was due to another oddity where, after playing the game for a while, our ambiances (generally streaming sounds) would become virtual. This issue disappeared when we moved up to 4.44.14.
I’m able to see some instances now from info only Events. That seems to work but it’s not as useful as I thought; I’m still having issues:
freeEventData() does not seem to be working. I’m calling Memory_GetStats() before and after and there is no change, I have waituntilready set true, and there is no error returned.
I’m sort of understanding how sample memory is used: Every sample Event is returning the same memory usage from getMemoryInfo() for example 22841kb, then if I go though the System Sound objects and add the sample memory usage together I get approximately the same value, so I assume sample Events return the memory used by Sounds used by all sample events, is this right?
Streams aren’t making sense though. After preloading Events the sample Sounds will add up to 22841kb like I mentioned, but the streams add up to 36481kb (the fsb itself is 49576kb). Does preloading streams completely load them into memory? If so, is there way to prevent that? Otherwise why is so much memory being used for streams?
Related to 3, going through the Sound objects, I’m seeing a lot of streams that are 453kb and the same amount that are 0kb, what are these?
1. freeEventData works fine, but it depends on your data, you might be freeing a reference count and not the data maybe, its hard to tell. A bank for an event wont be freed if other events still hold a handle to it for example. event instance memory should be freed though.
2. I think it might be counting the whole bank, though it probably shouldn’t be. getMemoryInfo has to manually count through its structures, and so can count shared memory twice from 2 different events, its inclusively counting objects rather than exclusively.
3. this is data dependent again, but its possible you have max streams set too high, is it set to 32 or something? It should be only set to how many simultaneous plays of any sound in the bank you want to hear at once, ie 1 or 2. streambuffersize and decodebuffersize will determine memory usage here. No, stream banks are not loaded into memory, unless you did so with preloadFSB.
Thanks, Brett. Regarding stream RAM usage, I wanted to clarify that we’re setting things up appropriately for streaming. We’ve used streaming before, but never to this degree. I had always assumed that it used a trivial amount of RAM. What we’re seeing is when an audio file is loaded from a streaming bank it gets allocated:
– a 16kb streaming buffer that contains the audio in its compressed state (e.g. celt, xma, mp3, etc.)
– a 400ms (~437kb) decode buffer (i.e. where the wav audio is stored after being decompressed)
So if you have 10 streaming audio files loaded, you have on the order of 4530kb of RAM usage (10 x 453kb). In other words, if I have a single event, containing a single layer, but the sound def in the layer contains 10 variations (one of which is randomly chosen each time the event is called), that event is going to require 4530kb of RAM (even if the event only uses 1 stream at any given moment). Is that correct? That’s what I’m seeing in the game and in the event player, but I’m hoping we’re doing something wrong, because it makes streaming much less useful from a RAM saving perspective. I would have thought that such an event would only need one decode buffer (provided only 1 playback was permitted)?
If this is all expected, then I assume that reducing the size of the decode buffer is not a good idea (we’re targeting the Xbox360, but we’ve been doing the debugging for this on the PC)? Furthermore, is it safe to conclude that there’s no point in streaming unless the size of the compressed file is larger than 453kb (stream buffer + decode buffer)? Can we bypass the decode buffer by not using compression on the streaming bank?
Just a quick note – 400ms of a 16bit stereo PCM buffer is 70kb. Maybe 140kb if i’m not counting it as a double buffer. Not 437kb. Are your streams 5.1 and not stereo? Even so that would be 350kb at the worst.
16kb sounds about right for compressed mp3 file data (*2 = 32kb probably for double buffer).
It should be about 100kb by default for stream per instance. There’s no indication that streaming banks are a memory hog and not worth it. It sounds project related or there’s a code setting that you’ve changed to increase memory consumption.
The max streams setting is for -potential- simultaneous sounds in events that share the same bank. So number of banks is irrelevant just in case you were thinking that.
It might be best if you send your whole project over, and I can do some profiling myself. If you have tens of thousands of sounds in a bank, that can add up to some memory usage (about 8 bytes per subsound).
Thanks, Brett. I totally botched that size calculation. I must have been thinking 1 meg/sec for some reason. Most of my streams are 16bit stereo PCM.
100kb sounds much more in line with what I had in mind. I’ll send my project and assets over. I should mention that I’m really pushing the stream count in certain gameplay scenarios (Max Streams is currently set to 80), but aside from high RAM usage, the performance has been fine, so I’d like to stick with a high stream count if I can. And at 100kb per stream, 80 streams should only hit 8 megs of RAM usage, which may be okay for this game.
I’m currently using Designer version 4.40.05. However, I did run a test with the latest version of Designer and saw some different RAM usage results in the Event player, but the numbers were still higher than 100kb per stream. Maybe I’ve encountered a bug?
It looks like the 5.1 channel sounds in your bank are the culprit as I expected. Move them into their own bank, as each stream buffer has to cater for the largest channel count. Have just a bank for the 5.1 stuff or if it doesnt need to be 5.1, make them stereo, then the whole bank will drop to stereo buffers.
80 max streams is not necessary. Bring it back to the MINIMUM you think you need to save memory, as it will most likely allocate that many streams if you load the bank. If your voice count isnt that high (ie software voices) then you wont even be hearing those streams anyway (ie is your voice count 32? Thats why you didnt notice a performance hit, because anything above that was virtualized and not using cpu/disk).
Thanks a lot, Brett! Moving those 5.1 sounds into their own bank made a big difference. I’m still not quite at 100kb for a single stereo stream though (see event names Jungle1 and BombedOutCity1). I’m around 185-200kb (as per the Event Player), even when I set Max Streams to 2 on the corresponding FSB. Is the extra 85-100kb most likely coming from event metadata, or maybe there’s something else that I’m overlooking?
I’ll have to get the programmer to print out how many real and virtual streams are active. On one really busy level there are about 35 virtual voices present, but I’m not sure which of those are streams. I originally set the Max Streams to 80 because one level seemed to be using close to that many and, when I set it too low, some critical sounds weren’t getting played because all the streams were in use. Prioritization didn’t help since the FSB doesn’t adhere to event/layer priorities when allocating streams. However, what I’ll do is move all low priority streaming sounds to their own bank and cap the Max Streams much lower. This will help ensure that the higher priority streams get played (by not sharing their streams with low priority sounds) and it will keep the # of streams for the lower priority streams under control.
Please login first to submit.