Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Playing sf::Music of unknown total size  (Read 3321 times)

0 Members and 1 Guest are viewing this topic.

ecraven

  • Newbie
  • *
  • Posts: 9
    • View Profile
Playing sf::Music of unknown total size
« on: June 26, 2014, 12:34:23 pm »
Hello!

I'd like to play some legacy music. The file format does not contain a total size of the audio. I just know the number of channels, the sample rate and the bit depth. Is there a way to use an InputStream for this, or do I *always* have to know the exact total size? Decoding the entire file just to get the total size doesn't seem a good idea. Is there any way to decode and play this music "on the fly"?

Thanks for any help!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Playing sf::Music of unknown total size
« Reply #1 on: June 26, 2014, 01:37:52 pm »
Is there really no way of knowing the total size by decoding the header? You really need to read all the samples?

Anyway, use sf::SoundStream (sse tutorials).
Laurent Gomila - SFML developer

ecraven

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Playing sf::Music of unknown total size
« Reply #2 on: June 26, 2014, 04:15:32 pm »
Thank you! This is what I've been looking for.. now I just need to find out why onGetData isn't called after I return 0 samples twice in a row, but that's probably some problem on my side :)

I have a sample rate of 22050, I return about 23000 samples on the first call. that should be enough for 1 second. SFML calls onGetData again twice immediatly (where I return 0 samples both times, but a return value of true, to indicate there is more data coming). Then SFML never again calls onGetData, even though I have new data available every 1/15s, which would be plenty... I can't find a bug in my program, and I can't see anything strange in SoundStream.cpp, any ideas?

EDIT:
The problem seems to be that SFML internally uses 3 sound buffers. If I don't return all available data on the first call, but keep some for later, things work.
Is this considered a bug? Otherwise, some mention of this in the documentation might be helpful :)

Thanks to zagabar for pointing me in that direction!
« Last Edit: June 26, 2014, 04:27:28 pm by ecraven »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Playing sf::Music of unknown total size
« Reply #3 on: June 26, 2014, 05:56:06 pm »
It looks like a bug. I can't find anythying in the implementation that would stop the stream if a chunk is empty. Could you provide a complete and minimal example that reproduces the problem?
Laurent Gomila - SFML developer

ecraven

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Playing sf::Music of unknown total size
« Reply #4 on: June 26, 2014, 08:44:49 pm »
this exhibits the problem:

raw data file: http://www.nexoid.at/tmp/foo.raw
program: http://www.nexoid.at/tmp/sfml-sound-problem.cpp

if you change line 33 (true <-> false) you see that it works correctly when all three buffers are filled, but not when only the first one is filled.

I hope this helps ;)

greetings

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Playing sf::Music of unknown total size
« Reply #5 on: June 26, 2014, 11:14:01 pm »
Thanks, that's perfect.

Except one thing: have you tested this exact code? Because it crashes. You're using vector::reserve + operator[]. Should be resize + operator[] or reserve + push_back.

Anyway, I fixed it and I can reproduce the problem. It seems that OpenAL refuses to release a buffer (so that it can be refilled) if it can't switch to another one. Which implies that the following scenarios won't work:
- the streaming queue contains only one buffer
- only one buffer in the streaming queue contains samples
... which are the only two things that SFML can do when you return an empty chunk.

So I see two options:
- document this behaviour so that users know that they can't return empty chunks
- find an ugly workaround, if possible
Laurent Gomila - SFML developer

ecraven

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Playing sf::Music of unknown total size
« Reply #6 on: June 26, 2014, 11:44:39 pm »
I think documenting it is enough at the moment, that way people can avoid the problem. We could create an issue, and just assign it a low priority, maybe someone can come up with a non-ugly workaround :)

This code runs fine for me, but I only tested gcc 4.9 under 64 bit linux. It's obviously a bug, thanks for enlightening me!

So there have to be at least two buffers? Might it be more transparent for the user if SFML internally just used two instead of three buffers, and the documentation mentioned that you *have* to return samples for every call of onGetData?
« Last Edit: June 26, 2014, 11:48:32 pm by ecraven »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Playing sf::Music of unknown total size
« Reply #7 on: June 26, 2014, 11:55:28 pm »
What difference does it make if SFML uses 2 or more buffers? The user has to return valid data in onGetData. Always. The fact that it could "work" if he returns an empty chunk sometimes and SFML has more than 2 buffers, is an internal side-effect and shouldn't change the requirements of the function.

You can open an issue on the tracker for improving the documentation, so that we don't forget to do it. Explain why and link to this forum thread ;)

Quote
This code runs fine for me, but I only tested gcc 4.9 under 64 bit linux.
I guess you run a release build, with no range checking inside STL containers.
Laurent Gomila - SFML developer

 

anything