If I want to play a sound that uses data that I provide from an external resourcestreamer I assume one way is to use FMOD_OPENMEMORY when I create the stream. What puzzles me though is the text written in bold saying that can’t release the buffers until the sound is finished. In practice this means that my stream buffer will grow to the full size of the sample which kinda contradicts the idea of using streaming. So is this a bad idea of implementing streaming from an externally provided buffer or have I just missed something?
- Frohagen asked 10 years ago
Its pretty simple – the FMOD_OPENMEMORY flag simply points to a file that has been loaded into memory. So of course this means you can’t release that memory if fmod is still streaming from it.
If you’re trying to feed data in a block at a time, you should be using a custom stream with a read callback.
If what you are suggesting is what is implemented in the example "usercreatedsound" then I have some further questions. How do I implement this in the eventsystem? I mean as I see it the only way to do such a thing would be to create a programmersound and somehow pass this user created sound to the sound I get thru the create-callback. But will this work? Can I attach a sound that is starving at start which would be the case here? The first time I get to know which sound to use is when I get the callback since that’s where I get the identifier for the sound bundled in the sound-def name. Ofcourse I could let the sound designer type the name of the resource as an user property but I see lots of good reasons not to do that. Actually I can’t even create the sound in the callback wihout doing a blocking read since I need the header for filling out the FMOD_CREATESOUNDEXINFO struct. So, as I see it this is far from trivial in combination with the eventsystem and any additional information would be more than welcome.
Two more things:
If I’m streaming compressed data (mp3/xma) from a soundbank then how do I solve that? What I can see there is only a callback for doing pcmreads or am I missing something?
The readcallback, will it be called when the playing buffer is finished or is there some kind of internal doublebuffering that one can rely on? If I fail to provide data in the callback since it’s not finished what will happen with the sound? Will it be turn silent or just fail?
So to avoid confusion. If my aim is to handle streamed playback thru our own resourcestreamer (compressed or not) then I should use the filecallbacks, right? Should I use the global filecallbacks or the ones that can be assigned to a single sound thru the FMOD_CREATESOUNDEXINFO. If I am to use the global filecallbacks then I’m still wondering how I should be able to figure out that a read request comes from a streaming sound and not a file that is being loaded.
I’m pretty sure that the support is there to do whatever I want to with FMOD but it’s really, really hard to figure out how to use since a) the examples are a bit to "ideal" b) doesn’t illustrate how to do it all when using FMOD designer. Also, the feedback on this forum can be a bit elite if you know what I mean. I really appreciate the fact that there is a forum and that you get fast feedback and I know that you are very busy people at firelight but I totally understand "identitycrisisuk" who get the n00b feeling, I feel just the same when it comes to this streaming thingie. Maybee there should be some section in the docs about this? No matter if you want to do the streaming yourself or not streaming is a big issue in most games and it’s vital that you get it right.
The issue is that you never really explained yourself from the beginning, so I simply answer your direct questions, and we have limited time.
Your original statement said " play a sound that uses data that I provide from an external resourcestreamer " which didnt specify if it was compressed data etc so i assumed you wanted something like usercreatedstream.
You can use per stream file callbacks, or the global one, I dont know what you’re doing. If you want it just for music streams, then just use it on a per stream file callback basis. That is of course for low level FMOD::Sound streams. For the event system you’ll have to use the global system because we dont give you access to FMOD::Sound pointers.
…and that’s where the tricky part begins, that is using global callbacks and user-managed streaming. I just can’t see how that is to be solved since the callbacks are transpartent to what the reads are for. But, I have managed to customize one of the examples (programmersound) so it uses per stream callbacks for doing streaming and it seems to work as good as it does without these. The problems I am facing now is of a different nature. First of all pre-buffering. If I don’t feed FMOD data when it asks for it it simply hangs, so I need to pre-buffer the data. Since I don’t know what to pre-buffer (headers or data, or both) and how the data is offseted in the fsb-file this gets quite tricky. Doing guesswork based in memorydumps of the fsp isn’t really the ideal way to go. If there is some kind of spec then please tell me where I can find it. The second problem is to figure out which fsb to use when I get the "sound-def created" callback. I could ofcourse let the sound-designer store this name in a user-property or use some kind of naming-convention for the sound-def names but if there is a better way I would be glad to hear about it. If these issues could be solved then I dare say the main problem is solved as well.
Another problem that I found is how to fetch the loop-mode and use when I create my user-streamed FMOD::Sound. I’m guessing I can’t check the event’s channel-group in this case, right? Also, what’s the correct way of telling FMOD that a sounddef creation (thru callback) failed? It seems like I need to return something if my buffers aren’t there when the event wants to kick off or else fmod will hang. The same goes for the read callback. What’s the correct return value when I can’t fetch daat since it’s not yet there? I’m guessing that setting an incorrect value might produce undefined behaviours.
[quote="Frohagen":1kxua37z]What’s the correct return value when I can’t fetch daat since it’s not yet there? I’m guessing that setting an incorrect value might produce undefined behaviours.[/quote:1kxua37z]
I have been filling the buffer with zeros (silence) in this case. I have also been experimenting with returning FMOD_ERR_FILE_EOF, which seems to be working also, but don’t quote me on that.
My streaming method was working fairly solidly in 4.07.09, but I have been having lots of problems in versions after that.
- dave7L answered 10 years ago
Please login first to submit.