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

Author Topic: Threading questions for audio  (Read 7517 times)

0 Members and 1 Guest are viewing this topic.

drmoth

  • Newbie
  • *
  • Posts: 9
    • View Profile
Threading questions for audio
« 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

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Threading questions for audio
« Reply #1 on: November 18, 2009, 08:13:19 am »
Quote
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?

Quote
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.
Laurent Gomila - SFML developer

drmoth

  • Newbie
  • *
  • Posts: 9
    • View Profile
Threading questions for audio
« Reply #2 on: November 18, 2009, 10:21:21 am »
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:

Code: [Select]
   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
Code: [Select]
myMusic->Stop();
just before the class holding the music pointer gets destroyed then I get a number of openal errors from the thread:

Quote
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?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Threading questions for audio
« Reply #3 on: November 18, 2009, 12:04:57 pm »
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.
Laurent Gomila - SFML developer

drmoth

  • Newbie
  • *
  • Posts: 9
    • View Profile
Threading questions for audio
« Reply #4 on: November 18, 2009, 01:29:29 pm »
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

Code: [Select]
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.
Code: [Select]
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.

panithadrum

  • Sr. Member
  • ****
  • Posts: 304
    • View Profile
    • Skyrpex@Github
    • Email
Threading questions for audio
« Reply #5 on: November 18, 2009, 01:47:37 pm »
Hmm, take care when using global variables.
Code: [Select]
//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.

drmoth

  • Newbie
  • *
  • Posts: 9
    • View Profile
Threading questions for audio
« Reply #6 on: November 18, 2009, 02:12:53 pm »
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.