A generated sample stream, unknown length - how to have channel stop after samples are all played?


#1

Hi,

I’m hoping someone can help me out with a method to achieve these goals:

  1. I have a stream of PCM samples generated procedurally at runtime.
  2. I don’t know how many samples there are or length of stream at fmod “createSound/playSound” time
  3. I would like to play the stream back, and then have the channel stop once all the samples are played (ie, once the generator tells me that no more samples will be coming).

So far, I have tried:
A looping streaming sound with a pcmread callback to pull samples from the input buffer - once no more samples are coming, I tried various ways of stopping the looping/stopping the sound etc… but nothing stops “cleanly” at the end of the samples - either the stream is cut off (if fmod channel is stopped after the last sample is supplied to fmod), or loops over the last samples a couple of times (depending on decode buffer size etc).

A custom codec: mostly works. Return an error code (eg FMOD_ERR_FILE_ENDOFDATA ) from the codec read callback, but again has issues at the end of the stream - some of the samples at the end of the stream don’t playback correctly once the error is returned from the read function.

A custom DSP - I haven’t tried this yet, but I can’t see anything in the documentation about how to tell fmod the DSP is “finished” (so that the channel stops) from within the DSP callback functions. It seems I would also have to deal with resampling and mixing differing number of input channels to output channels etc if I went down this route.

I did find another piece of info today that I could apparently set the sound length to -1 in createSound, which means I wouldn’t have to use looping for the stream to continuously play, but I’m still not sure how to get the channel to stop after all the samples have played.

None of the samples I have seen deal with this situation - they all seem to stop the channel “manually” at an arbitrary point (eg, on a button press), rather than stopping automatically when “all samples have played”

Does anyone have any advice please?

Thanks,
Damian.


#2

I’ve played around with everything I could think of after reading the documentation, looking at samples and looking at anything I could find that sounded related on the net. I couldn’t find any system that used FMOD to stream audio of unknown length, then stopped when the source data was finished.

I’ve ended up implementing a work around - I store how many PCM bytes I’ve written to FMOD from the stream, and then in an update function, I check how many PCM bytes the channel has played. If the number played is greater than/equal to the number written, I stop the channel “manually”.

This is doing the job for now, assuming all my streams smaller than the max uint value… =D


#3

Using a custom codec and returning FMOD_ERR_FILE_EOF should do the trick, ENDOFDATA does sound more appropriate but doesn’t appear to be hooked up to anything internally.


#4

Thanks. Returning EOF is what I first tried with the custom codec, following an untested suggestion from another thread. It didn’t work correctly, samples at the end of the stream didn’t play back correctly, or the stream didn’t end or something…

I don’t have the custom codec code I was testing any more, so I can’t verify what the exact issue was any longer, sorry.

I’ll try it again, should the current method end up with any issues down the track.