I’m about 2hrs new to FMOD, so forgive my ignorance…

  1. Can Streams Be Put On Channels? It seems that channels are the only way to get 3d applied to a sound.

  2. When a sound is loaded from memory as RAW and the mode is UNMANAGED, is the data copied? I want to update the memory myself and replay the sound with a, well, different sound…

My whole goal is to add in-game voice to a game that uses FMOD. I can live with just a team-only ‘radio’ comms, but would also like to add in the ability for people to ‘hear’ each other when they are close.


  • You must to post comments

Thanks for the info Brett.

I have a couple more questsions regarding custom streams.

I really want to know how I can ‘feed’ a stream. As packets come in on the network, I want to get the stream to play them.

So, it looks like I would follow the ‘userstream’ example.

In theory then, I would:
1. FSOUND_Stream_Create to create a stream of a fixed size (lets say 1k or so)
2. implement a stream callback that puts network data into the buffer supplied by the FSOUND_STREAMCALLBACK

My main question is with when and how that callback is called?

I’ve put some additional printouts into the callback and it seems to be called at a regular interval (10’s of times a second), but the calls to GetLength, GetPos, GetTime using the stream from the callback all return 0.

So, when the callback comes in does it start at the beggining of the buffer you supply every time? Thereby only being able to play a fraction of a second worth of sound?

  1. When is the callback made? Fixed time interval? Fixed byte interval?
  2. Does it start at the beginning of the buffer you supply? So, if the callback function was playing a large clip, it must keep track of where it is in the clip and copy the next section of the clip into the buffer?
  3. How would I take an MP3, from a file, decompress it (I have to feed the user stream RAW data?) and feed it to the stream using the stream callback?

I’m really sorry if these questions are really noobish.


  • You must to post comments

[quote="brett":2l2r3dk9]The callback is called every time it needs the amount of data that you specified (1k i guess).[/quote:2l2r3dk9]

Ah… So, let me see if I understand the sequence for user streams…

  1. FSOUND_Stream_Create: creates a buffer, internal to FMOD, of the size I specified and calls my callback when the buffer needs to be filled?
  2. FSOUND_Stream_Play: immediately calls my callback to fill the buffer, then calls it again when it reaches the end?

[quote="brett":2l2r3dk9]If you told the stream to be size of 44100 and thats the rate it was playing at, it would call it once per second. Does that make sense?[/quote:2l2r3dk9]

Yes. That makes alot of sense.

[quote="brett":2l2r3dk9]You have to buffer any incoming data yourself. It is not fmod’s job to do that, it just requests chunks of data at regular intervals, as you have found.[/quote:2l2r3dk9]

Right, when the callback comes, I just copy what I have in my buffer to the buffer supplied in the callback?

Quick question… does FMOD use the same buffer every time? I mean, can I save the pointer in the first call to my callback and use it to start back-filling the buffer, making sure to stay behind current play position? So that when the callback is finally called, the FMOD buffer is almost full again?

[quote="brett":2l2r3dk9]you can’t decompress your own mp3 data without writing your own mp3 decompressor.[/quote:2l2r3dk9]

My current plan is to use FLAC (flac.sourceforge.net) as follows:

  1. Record sample (.5-1 second) using FMOD
  2. feed bytes to FLAC to compress
  3. send bytes over UDP to client
  4. re-assemble FLAC clip
  5. decompress using FLAC
  6. feed to FMOD using a user stream

Does that make sense?

Steps 1-5 look fairly straight forward, but step 6 I’m still a little confused. Thanks to your explanations, I understand what I must do to feed data to FMOD through a user stream, but I’m not sure it would be in the right format…

I’ve been working with the recording example and see that when the data is recorded in a sample, it is saved out as a WAV file. I see how the header is put on and everything. I can then feed that recorded wav file into the stream example for playback.

When the recording is played back using FSOUND_Stream_Open, it looks like FMOD examines the data for information (header) on what type of data it is and then does what it needs to do to play it back.

Now, the documentation says that FSOUND_Stream_Create only supports SIGNED RAW, 8/16 bit, Mono/Stereo. If I understand the API correctly, I will use the same settings (to create the stream) that I used when I allocated the sample for recording?

So to record:
FSOUND_Sample_Alloc(FSOUND_UNMANAGED, 22050 /.5s/, FSOUND_STEREO | FSOUND_16BITS , 44100, 255, 128, 255);

And create stream:
FSOUND_Stream_Create(streamcallback, 4410 * 4 /.1s/, FSOUND_NORMAL | FSOUND_16BITS | FSOUND_STEREO, 44100, (void *) “player_1”);

I will be trying to solve this today, but want to put my question to you as well to make sure I understand everything.

[quote="brett":2l2r3dk9]for your question 2, im a bit hazy on what you mean, but the first buffer that is presented to you via the callback is the first audible buffer, of course. From then on yes, you have to keep track of the position in your own source buffer, but thats outside of fmod. You’re doing the copying.[/quote:2l2r3dk9]

So, FMOD doesn’t store anything like how many bytes played or where it is in the current buffer? That would imply that I can’t use things like FSOUND_Stream_AddSynchPoint?

Thanks a million for all the help Brett, but yes, I have a few more questions 😆

Would it be simpler to do the following:

  1. create a stream using FSOUND_Stream_Open
  2. set up the stream to loop
  3. back-fill the buffer while it is playing
    • set synch points so I can know when the stream is past a certain point

The only reason why I ask if I can do this is because the streaming sample says that the memory I give to FSOUND_Stream_Open must remain valid while playing…

But, maybe that doesn’t apply to looping? I mean, does FMOD only use the memory you pass it once? Essentially copying it to an internal buffer, and then if the LOOP flag is set it loops over the internal buffer? Cause that would eliminate this second option right away.

Sorry about having so many questions.


  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.