0
0

I have a common fsb file with many soubsounds. I would like to be able to stream 4 sounds from this fsb file at a time. I call createStream 4 times with the fsb filename. If I look at the memory allocated it ends up at 360k per stream. I set the buffer size to be 64k using

Result = sm_System->setStreamBufferSize( 64*1024, FMOD_TIMEUNIT_RAWBYTES );

So double bufferred I would expect 128k plus a bit more for the header(232k?). Now the fact that I’m using the same fsb it would be nice if I could share whatever is in the extra 230k per stream. Is this possible in any way? So instead of using 230k*4 = 960k, I would only have 1 copy(230K) thus saving me 690K.

Is there some completely different way to do this? Can I use another bank format other than fsb. If I create my own wad file with all the individual wav files in it, can I use FMOD_OPENUSER and have FMOD do the file streaming or will I need to do all of the file access myself using the callbacks?

Cheers
Stephen

  • You must to post comments
0
0

You’re missing the fact that that is just the file buffer. There is a circular buffer that the data is read from and decoded into, the pcm ring buffer. This decode buffer size can be reduced in FMOD_CREATESOUNDEXINFO and is default at 400ms or something to be safe. You could probably bring it down to 100ms and save a fair bit of memory without stuttering.

FSB is not the issue here, the format itself has very minimal overhead and is less intensive than wav and other formats.

Edit: there is also the FMOD_LOWMEM flag to reduce memory allocs and along with it a few features like the ability to call getName etc.

  • You must to post comments
0
0

I will start by saying that I am using the Wii version reduced lib and not using any software mixing. Here are the result of some test.

[u:3prh3u22]TEST1[/u:3prh3u22]
[code:3prh3u22]Result = sm_System->setStreamBufferSize( 48*1024, FMOD_TIMEUNIT_RAWBYTES );
Result = m_pSystem->createStream( strFilename.GetBufferConst(), FMOD_LOWMEM | FMOD_HARDWARE, NULL, &m_pStream );[/code:3prh3u22]

AUDIO/WII/SPEECH/A01_Escape_Asylum.fsb
before createStream FMOD Memory (5692212) Peek(5692212) Max(12582912)
after createStream FMOD Memory (6022144) Peek(6022144) Max(12582912)
total memory 329932
Number of sub sounds = 1934

[u:3prh3u22]TEST2[/u:3prh3u22]
[code:3prh3u22]Result = sm_System->setStreamBufferSize( 48*1024, FMOD_TIMEUNIT_RAWBYTES );
Result = m_pSystem->createStream( strFilename.GetBufferConst(), FMOD_HARDWARE, NULL, &m_pStream );[/code:3prh3u22]

AUDIO/WII/SPEECH/A01_Escape_Asylum.fsb
before createStream FMOD Memory (5704888) Peek(5704888) Max(12582912)
after createStream FMOD Memory (6043068) Peek(6043068) Max(12582912)
total memory 338180
Number of sub sounds = 1934

LOWMEM memory savings 8248 bytes. The low mem flag is very missleading and should really be called, FMOD_REMOVE_FILENAMES, because low mem it is not(Sorry).

[u:3prh3u22]TEST3[/u:3prh3u22]
All of the samples in the fsb file are @ 24000 Htz. So thats 48000 bytes per second * .4 seconds = 19200 decode buffer.
So I added

[code:3prh3u22]FMOD_CREATESOUNDEXINFO SoundExInfo;
memset( &SoundExInfo, 0, sizeof(FMOD_CREATESOUNDEXINFO) );
SoundExInfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
SoundExInfo.decodebuffersize = 4800; // 48000 bytes per second * .1 seconds = 4800 for a wopping 14k savings(but not really)

Result = sm_System->setStreamBufferSize( 48*1024, FMOD_TIMEUNIT_RAWBYTES );
Result = m_pSystem->createStream( strFilename.GetBufferConst(), FMOD_HARDWARE, NULL, &m_pStream );
[/code:3prh3u22]
AUDIO/WII/SPEECH/A01_Escape_Asylum.fsb
before createStream FMOD Memory (5687448) Peek(5687448) Max(12582912)
after createStream FMOD Memory (6022908) Peek(6022908) Max(12582912)
total memory 335460
Number of sub sounds = 1934

before setting the decodebuffer size to 4800 total memory was 338180 and after 335460 for a difference of 2720 bytes.

I can live with the fact that the fsb file uses 48K * 2 for the stream buffer and that it even uses another 230k for other data. I am making the assuption that most of this memory is static infomation about the sounds in the fsb, like file offsets, sizes, and names etc. The issue I have is that if I want to stream 4 sounds from the same file then this data is duplicated 4 times in memory instead of shared. This is a bit wasteful. The real killer is that the largest single sound that I am trying to stream is only 244k, so even if I want to play 4 of them I could load them completely into memory using a full 244k and still be better off than streaming them. Which by the way is what I am now doing. I’m not trying to bash, I just want to make sure that I’m doing things in the most efficient way.

Please tell me if my math is wrong or am I at least close.
accounting for 330k

fsb file header stuff
80 bytes fsb header * 1934 = 154720
8 bytes basic header * 1934 = 15472
4 bytes offsets * 1934 = 7736

48k * 2 = 96k for stream double buffer
14k for 400 ms decode buffer, though I am using FMOD_HARDWARE exclusively and would think that this should not be needed

173k for file header stuff

283k is close enough to 330k

Cheers
Stephen Orr

  • You must to post comments
0
0

Just because it is hardware doesnt mean you don’t need a ‘decode’ buffer. I never even mentioned software mixing.
Maybe the name throws you off, it is the sound buffer that is actually playing. This could even be located in ARAM for example on GC. You definitely need a sound buffer to play on regardless.

Now you’re probably thinking next why doesnt the file just read into that buffer. This is because that just doesnt work and is inneficient in 2 ways.
1.
A sound buffer doesnt want to be as big as a file buffer. The reason is that it is a waste of sound ram. A sound buffer can be very small. For disk reads you need a large buffer to cope with cd access times (ie thats what you set with setStreamBufferSize). If it is 200k on ps2 for example thats a huge chunk to take out of sound ram from 2mb. On ps2 sound buffer size is more like 4k.
2.
Not as relevant here, but if it was decompressing into pcm (ie mp3) and the sound/file buffer were the same size, you would be doing a big file read, then a big decode, causing a huge cpu spike every few seconds. Having a small decode buffer means it can first read a large file chunk, then decode from that buffer in little chunks into a little sound buffer. Thats what it does now and means the streamer is spread out and very efficient with no cpu spikes.


I think the reason you see extra memory used is purely the fact that you have 2000 sounds in one fsb. You never mentioned that before.
That is what basicheaders is meant for, if you use that flag, you will get a big saving – you just can’t mix sample rates or channel counts in that file, they all have to be the same.

Next use FMOD_LOWMEM flag to stop it allocating memory for name fields etc.

  • You must to post comments
0
0

I understand the decode buffer concept and the need for it. But dude your talking about saving me 14K out of 465K. 2000 sounds in a single fsb is not a lot of sounds for an average game, or even level. Our last game The Warriors had almost 16000 sounds in a single bank. I am using basic headers and with wasted space each stream consumes 465K. I would like to play 4 of these so 4*465K = 1862K WOW!

If I don’t use the basic headers each stream consumes 617K! 4*617 = 2468K

I’m using FMOD_LOWMEM.

Each stream uses 363k of memory with 102K in alignment and blocksize padding(I reduced it in our version to 32byte padding and 32byte blocks or this would be worse). 2*64K for the file buffer 363-128 = 235k. All of the files are 24000Htz so thats 48000 samples per second * 400ms = 19K for the decode buffer. 235-19 = 216k …. Lets say the fsb file has a really big header of 2K for stuff. So we have 214k for 1934 sounds. Thats over 100 bytes extra per sound without a name filed.

[code:179sdw2s] typedef struct
{
unsigned int lengthsamples;
unsigned int lengthcompressedbytes;

} FMOD_FSB_SAMPLE_HEADER_BASIC;[/code:179sdw2s]

This looks great to me, but I’m just not seeing it. That would be 16k for all 2000 sound. Awsome. But I’m seeing over 200k used.

Cheers
Stephen

  • You must to post comments
Showing 4 results
Your Answer

Please first to submit.