LaurentGomila/SFML — Issue #180: Audio streaming hangs when OnGetData() is slow
Author: bastienleonard
Created: 2012-02-24 20:51:51+00:00
State: open

Example:

#include

#include
#include

class CustomStream : public sf::SoundStream
{
public:
CustomStream(const std::string& path)
{
sound_buffer.LoadFromFile(path);
unsigned int channel_count = sound_buffer.GetChannelCount();
unsigned int sample_rate = sound_buffer.GetSampleRate();
buffer = sound_buffer.GetSamples();
Initialize(channel_count, sample_rate);
}

virtual bool OnGetData(Chunk& chunk)
{
const int BUFFER_SIZE = 4096;
chunk.Samples = buffer;
chunk.SampleCount = BUFFER_SIZE;
buffer += BUFFER_SIZE;
sf::Sleep(sf::Seconds(5));

if (buffer > sound_buffer.GetSamples() + sound_buffer.GetSampleCount())
{
chunk.SampleCount = sound_buffer.GetSampleCount() % BUFFER_SIZE;
return false;
}

return true;
}

virtual void OnSeek(sf::Time time_offset)
{
std::cout << "Time offset: " << time_offset.AsMilliseconds() << '\n';
}

private:
sf::SoundBuffer sound_buffer;
const sf::Int16 *buffer;
};

int main()
{
sf::RenderWindow app(sf::VideoMode(800, 600, 32), "Title");
app.SetFramerateLimit(60);
sf::Event event;
CustomStream stream("music.ogg");
stream.Play();
stream.SetPlayingOffset(sf::Milliseconds(0));

while (app.IsOpen())
{
while (app.PollEvent(event))
{
switch (event.Type)
{
case sf::Event::Closed:
app.Close();
break;
default:
break;
}
}

app.Clear(sf::Color::White);
app.Display();
}

return 0;
}

Note that the program doesn't hang if `stream.SetPlayingOffset(sf::Milliseconds(0))` is removed.
My guess is that when `SetPlayingOffset()` stops the stream, the call to `Thread.Wait()` never returns.
However it should return at some point; it's just slow in this case because of `sf::Sleep(sf::Seconds(5))`.

Platform: GNU/Linux, SFML commit #e7256e3324a196bb1432786c678f195c9ffb982b.

For the record, I encountered this bug while adding streaming to my Python binding.
Currently the API is very slow, and I was wondering why my program hangs when testing seeking with `SetPlayingOffset()`.