When I load a
sf::SoundBuffer or
sf::Music through a stream,
read() is passed a size which leads to reading past the end of the stream.
#include <SFML/Audio.hpp>
#include <fstream>
#include <iostream>
class MyStream : public sf::InputStream
{
public:
MyStream(const char* filename)
: stream(filename, std::ios::in | std::ios::binary)
{
}
virtual sf::Int64 read(void* data, sf::Int64 size)
{
std::cout << "Begin " << tell() << "\n";
std::cout << "End " << tell() + size << "\n";
std::cout << "Total size " << getSize() << "\n\n";
stream.read(static_cast<char*>(data), size);
if (!stream)
{
std::cout << "FAIL\n";
std::exit(0);
}
return stream.gcount();
}
virtual sf::Int64 seek(sf::Int64 position)
{
stream.seekg(position);
return tell();
}
virtual sf::Int64 tell()
{
return stream.tellg();
}
virtual sf::Int64 getSize()
{
sf::Int64 backup = tell();
stream.seekg(0, std::ios::end);
sf::Int64 size = tell();
seek(backup);
return size;
}
private:
std::ifstream stream;
};
int main()
{
MyStream stream("Music.ogg");
sf::SoundBuffer buffer;
bool success = buffer.loadFromStream(stream);
sf::Sound sound(buffer);
sound.play();
sf::sleep(buffer.getDuration());
}
success is false in some cases (for wav, it seemed to work), but there is no SFML error output on the console.
Instead of
size, one can write
std::min(size, getSize() - tell()), but I suggest to handle this on SFML side if possible. I don't know however how well you can influence the low-level library callbacks, maybe this is given.
In case you cannot reproduce the problem, I'll upload an OGG file.