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

Author Topic: Playing audio  (Read 4580 times)

0 Members and 1 Guest are viewing this topic.

DojoMike

  • Newbie
  • *
  • Posts: 9
    • View Profile
Playing audio
« on: June 21, 2017, 04:19:53 am »
Hey guys, what's up,

So I've been following the tutorials on playing sounds, and I've run into a kind of weird issue that doesn't seem to be mentioned anywhere: The sound doesn't play, and when the program ends I get this error: "AL lib: (EE) alc_cleanup: 1 device not closed".  So after a bit of Googlefishing, I found a few sites where people have asked about it, and even one guy who filed a bug about it - but since I'm new to SFML I'm assuming it's something I've done wrong. :D

So here's my code:


#ifndef SOUND_PLAYER_H
#define SOUND_PLAYER_H
#include <map>
#include <SFML/Audio.hpp>

class SoundPlayer
{
public:
    static SoundPlayer * Get();
    void PlayerLaser();
private:
    static SoundPlayer * Instance;
    SoundPlayer();
    sf::SoundBuffer player_laser;
};

SoundPlayer * SoundPlayer::Instance = NULL;

SoundPlayer * SoundPlayer::Get()
{
    if (Instance == NULL)
        Instance = new SoundPlayer();
    return Instance;
}
SoundPlayer::SoundPlayer()
{
    if (!player_laser.loadFromFile("bin\\debug\\sounds\\player_laser.wav"))
        throw "Error loading the player laser sound";
}
void SoundPlayer::PlayerLaser()
{
    sf::Sound sound;
    sound.setBuffer(player_laser);
    sound.play();
}

#endif

// And here is how it's used:
SoundPlayer * sp = SoundPlayer::Get();
sp->PlayerLaser();
The SoundPlayer class is mostly an attempt to keep the sound-related objects in scope (since stuff seems to go out of scope and get destroyed super-easy/almost instantly with SFML), but originally it was the constructor and PlayerLaser methods as one function.  I figured that was not efficient (cuz it would have to re-load-from-file every time the sound is played), but I figured I'd share it anyway.

But this error seems to suggest that something needs closing?  I didn't see anything in the tutorial about that (apart from if you have too many sounds, but I can't get it to play just one).  I haven't managed to find any clear answer on Google or in the API docs, but then again I only spent like half an hour fighting with it.  Has anyone here dealt with this cryptic error before?  No big deal (I can always use IrrKlang for sounds if I can't get past it) but I'm guessing it's another newbie mistake on my part and a common pitfall everybody fights with at some point.

Also, if there is a better way to make references to SFML objects permanent, or at least exist a little longer, I'm all ears.  I recently had a similar struggle with textures, and learned the hard way that storing them in a vector was a dumb idea.  I know others have found or built workarounds, but if it's basic C++ stuff it really is something I should learn.  I know what a pointer is, but I've never had as many issues with pointers being destroyed as I have with SFML; but I'm sure SFML isn't the only framework to auto-destroy pointers, so I "better figger it out fast" tyvm
« Last Edit: June 21, 2017, 07:55:04 am by Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Playing audio
« Reply #1 on: June 21, 2017, 08:06:16 am »
SoundPlayer::PlayerLaser() creates a sf::Sound instance, plays it, and then immediately destroys it since it is local to the function. If you want to hear that sound, it has to be alive as long as it is playing.

Quote
stuff seems to go out of scope and get destroyed super-easy/almost instantly with SFML
[...]
I've never had as many issues with pointers being destroyed as I have with SFML
SFML has nothing special in this regard, objects lifetime follows the standard rules of C++. It's your responsibility to manage your objects and their lifetime correctly.
Laurent Gomila - SFML developer

DojoMike

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Playing audio
« Reply #2 on: June 21, 2017, 09:36:30 am »
Code: [Select]
Okay, so how do I "keep it alive"?  I know it plays sounds in its own thread - is that what needs to be "kept alive" or "closed" afterward?

And as for the pointer thing, I only said that because so far that has been my experience - I've never had this kind of trouble managing objects or pointers before, but as soon as I dove into SFML, it seems nothing sticks around long enough to be used.  But I also said I was sure SFML isn't the only framework that does this, and it was probably a mistake on my end.  Sorry if I wasn't clear about that.

So now that I've stomped everyone's toes to oblivion (lol sorry, totally didn't mean it) how do you guys handle the "keeping sounds alive" problem?  I just tried getting rid of the SoundPlayer class altogether and just calling it like this:

[code lang="cpp"}sf::SoundBuffer b;
    if (!b.loadFromFile("bin\\debug\\sounds\\player_laser.wav"))
        throw "Error loading the player laser sound";
    sf::Sound sound;
    sound.setBuffer(b);
    sound.play();

This of course got the same result.  And every reference I've been able to find to playing sounds with SFML says to do pretty much exactly what I've got here (the only differences being variable names and the sound file path).  There is no mention of closing anything or "keeping it alive" anywhere... sf::sleep maybe?  If that's the case I guess I'll stick with IrrKlang, since sf::sleep stops the game while the sounds play.
« Last Edit: June 21, 2017, 10:39:09 am by DojoMike »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Playing audio
« Reply #3 on: June 21, 2017, 11:44:17 am »
Scopes are what makes C++ to some degree. If you create an object in a function it exists until you reach the end of the function. To keep it alive you need to define it in a larger scope, like as member variable.

C++ scopes: http://en.cppreference.com/w/cpp/language/scope

I highly recommend you pick up a good C++ book and work through it. There's a lot to learn before one should dive into SFML. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

DojoMike

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Playing audio
« Reply #4 on: June 21, 2017, 01:10:48 pm »
And I agree I have a lot to learn; I've done plenty of work in C++, but the more I learn, the more I realize I still need to discover.  I understand the concept of scope, but had no idea it played such a critical role (apparently more than any of the other languages I know) in tools like SFML.

But anyway, your idea of making the sf::sound a class property did the trick.  Thanks!  Now one last dumb question: How do I mark this topic as solved?  :)