SFML community forums

Help => Audio => Topic started by: dassie on March 30, 2020, 01:24:00 am

Title: Proper usage of SoundStream class
Post by: dassie on March 30, 2020, 01:24:00 am
I am using the SoundStream class to output computed audio and I'm unsure if I'm using it correctly because I notice that the onGetData() function gets called kind of "irregularly".

My implementation is pretty simple. In my class constructor I call initialize(2,44100). From the SFML docs I gathered that the audio format is signed 16 bit integers but there's no mention of how to encode channels, I assumed they need to be output back-to-back (e.g. the stream of Int16s looks like: L0,R0,L1,R1,L2,R2,...). I'm also using version 2.5.1.

onGetData() looks like this:
bool MySoundStream::onGetData(Chunk& chunk)
{
   // buffer is a vector<Int16>

   buffer.clear();
  ReadAudioStream(buffer); // <- This function waits for a lock to access the compute thread's data

   chunk.samples = buffer.data();
   chunk.sampleCount = buffer.size();

   LOG_INFO("Sample count = %d", chunk.sampleCount);

   return chunk.sampleCount > 0;
}


When I notice that onGetData() gets called very rapidly about ~1ms apart, and the second one ends up fetching nothing:

[23:06:58.472] [WARN] MySoundStream::onGetDataSample count = 41300
[23:06:58.472] [WARN] MySoundStream::onGetDataSample count = 0
The thread 0x63ac has exited with code 0 (0x0).
[23:06:58.958] [WARN] MySoundStream::onGetDataSample count = 41300
[23:06:58.958] [WARN] MySoundStream::onGetDataSample count = 0
The thread 0x3eb4 has exited with code 0 (0x0).
[23:06:59.445] [WARN] MySoundStream::onGetDataSample count = 42776
[23:06:59.446] [WARN] MySoundStream::onGetDataSample count = 0
The thread 0x1184 has exited with code 0 (0x0).
[23:06:59.946] [WARN] MySoundStream::onGetDataSample count = 42774
[23:06:59.946] [WARN] MySoundStream::onGetDataSample count = 0
The thread 0x954 has exited with code 0 (0x0).
[23:07:00.445] [WARN] MySoundStream::onGetDataSample count = 41300
[23:07:00.445] [WARN] MySoundStream::onGetDataSample count = 0


Another issue I noticed is _sometimes_ the audio playback stalls a lot. So the logs end up showing large chunks of samples being fetched as it catches up (the problem of reading 0 samples doesn't show up, each consecutive call as it tries to catch up will have data in it). The playback doesn't corrects itself unless I call stop() then play() again.

Sorry for the incomplete code example I'm giving (I can clarify more if needed), I'm moreso asking to confirm that my assumptions about the usage is correct and to find out why onGetData() is being called 1ms apart like that and sometimes not being called for long gaps.

Edit: after checking the source code a bit it looks like this is because the base class is assuming my audio stream is finished when I return false (from looking at SoundStream::fillAndPushBuffer()). I will change up my code to make sure it always returns some data.