SFML community forums
Help => Audio => Topic started by: drmoth on November 18, 2009, 01:46:59 am
-
Hi,
I've recently been using the Audio subsystem of SFML in a separate project. It's been really easy to integrate and the code is super clean, highly appreciated :)
However I have a couple of questions...
First of all when I quit my app (not an SFML app by the way) the OpenAL context is destroyed before the streaming music I'm playing is stopped, so I get a number of OpenAL errors from the thread that's still running (until it aborts).
If I stop the stream manually before exiting, this is fine, but I was wondering is there was an automatic way to do this? (i.e. making sure any music streams are stopped before stopping openal)
Second of all, I see that the music streams are threaded, but in my code the sample playback isn't. However I read in another post in this forum that the entire audio system is threaded. Is that correct? I am I missing some SFML code that does this?
thanks!
Pierre
-
First of all when I quit my app (not an SFML app by the way) the OpenAL context is destroyed before the streaming music I'm playing is stopped, so I get a number of OpenAL errors from the thread that's still running (until it aborts).
Which version of SFML do you use? How can you tell that the context is destroyed before your music? Is the music in global scope?
Second of all, I see that the music streams are threaded, but in my code the sample playback isn't. However I read in another post in this forum that the entire audio system is threaded. Is that correct? I am I missing some SFML code that does this?
Sounds are threaded by the driver/hardware, this is not handled by SFML. Just like graphics.
-
Hi,
I'm usng version 1.5 from source (not svn).
The music is kept as a public pointer in my application class, and in my setup code I do this:
myMusic = new Music();
// Load an ogg music file
if (!myMusic->OpenFromFile("data/bells.ogg"))
return;
myMusic->SetLoop(true);
myMusic->Play();
Then, once I exit the application, if I haven't manually stopped the music by calling
myMusic->Stop();
just before the class holding the music pointer gets destroyed then I get a number of openal errors from the thread:
An internal OpenAL call failed in Sound.cpp (332) : AL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (221) : AL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (227) : AL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (239) : AL_INVALID_OPERATION, the specified operation is not allowed in the current state
AL lib: ALc.c:1650: alcCloseDevice(): deleting 4 Buffer(s)
ofxSoundPlayerExample_debug: /home/blah/code/audio/openal-soft-1.10.622/OpenAL32/Include/alMain.h:54: EnterCriticalSection: Assertion `ret == 0' failed.
Aborted
Does that make sense?
-
Can you provide a complete and minimal example that reproduces this problem? So that I can copy-paste it to a single file and test it directly.
-
Well, unfortunately it's a little difficult to give you a working example because of the framework I'm using, but basically I found a workaround, sort of.
I don't get this error if I declare
Music myMusic;
and don't create the object in setup using new().
Also if I use the pointer version, I don't get the problem if I explicitly delete the pointer on exit, i.e.
delete myMusic
However I thought that explicitly deleting an object was necessary only if it was created on the stack, and not as a member of a class...but maybe I'm confused about this, or maybe the problem is elsewhere and this is just a symptom.
I was able to recreate this error I think in the Sound.cpp sample from SFML by creating a global variable called sf::Music* Music and then not deleting it. Is this just a gap in my C++ knowledge? Somehow I thought that a class member object variable would call it's own destructor on exit.
-
Hmm, take care when using global variables.
//global_music.h
#include <sfml/audio...>
sf::Music* global_music;
That piece of code doesn't work as you may think: you will have different pointers called global_music at different scopes.
You must define it as extern, and declare it somewhere else.
Also, if you don't make use of new, no sf::Music object is created.
On the other hand, if you store pointers in a class (or somewhere else, like STL containers), you must delete'em explicitely.
-
Yeah I don't normally use global variables, just trying to find an equivalent example (which I guess isn't that equivalent).
I suppose my confusion comes from somehow in the past receiving a "double delete" error on exit when trying to delete member objects created using new()...but maybe I'm just confused :)
anyway problem solved.