Hello !
J'ai récemment créé une bibliothèque dynamique (sous Visual C++ 2012) utilisant SFML seulement j'ai un problème avec l'audio. L'erreur survient toujours avec sf::Music, rien d'autre. J'ai pas mal cherché mais je n'ai pas trouvé la source de l'erreur, peut être une mauvaise manipulation de ma part...
Je suis parvenu à écrire un code minimal qui reproduit l'erreur : il s'agit d'un simple lecteur de musique.
Premier cas : m_currentMusic est un sf::Music.Côté DLL :CMusicPlayer.hpp#ifndef CMUSICPLAYER_HPP
#define CMUSICPLAYER_HPP
class DLL_API CMusicPlayer
{
public:
void Register(const char* pName, const char* pPath);
void Play(const char* pName);
static CMusicPlayer& GetInstance();
private:
CMusicPlayer();
~CMusicPlayer();
private:
static CMusicPlayer ms_instance;
sf::Music m_currentMusic;
std::map<const char*, const char*> m_musics;
};
#define MusicPlayer CMusicPlayer::GetInstance()
#endif
CMusicPlayer.cpp#include "DLL.hpp"
CMusicPlayer CMusicPlayer::ms_instance;
CMusicPlayer::CMusicPlayer()
{
}
CMusicPlayer::~CMusicPlayer()
{
}
void CMusicPlayer::Register(const char* pName, const char* pPath)
{
assert(pName && pPath && m_musics.count(pName) <= 0);
m_musics[pName] = pPath;
}
void CMusicPlayer::Play(const char* pName)
{
assert(pName && m_musics.count(pName) > 0);
m_currentMusic.openFromFile(m_musics.find(pName)->second);
m_currentMusic.play();
}
CMusicPlayer& CMusicPlayer::GetInstance()
{
return ms_instance;
}
Côté client :main.cppint main()
{
MusicPlayer.Register("super_musique", "ambiance.ogg");
MusicPlayer.Play("super_musique");
return EXIT_SUCCESS;
}
Dans ce premier cas, le problème se situe au démarrage de l'application. Il n'y a pas d'erreur mais le thread est bloqué dans le constructeur de CMusicPlayer. Je n'ai pas beaucoup d'information là dessus si ce n'est que l’exécution est coincée dans dsound.dll d'après le débogueur.
Deuxième cas : m_currentMusic devient un pointeur sur sf::MusicCôté DLL :CMusicPlayer.hpp#ifndef CMUSICPLAYER_HPP
#define CMUSICPLAYER_HPP
class DLL_API CMusicPlayer
{
public:
void Register(const char* pName, const char* pPath);
void Play(const char* pName);
static CMusicPlayer& GetInstance();
private:
CMusicPlayer();
~CMusicPlayer();
private:
static CMusicPlayer ms_instance;
sf::Music* m_currentMusic;
std::map<const char*, const char*> m_musics;
};
#define MusicPlayer CMusicPlayer::GetInstance()
#endif
CMusicPlayer.cpp#include "DLL.hpp"
CMusicPlayer CMusicPlayer::ms_instance;
CMusicPlayer::CMusicPlayer()
: m_currentMusic(nullptr)
{
}
CMusicPlayer::~CMusicPlayer()
{
if (m_currentMusic)
{
delete m_currentMusic;
m_currentMusic = nullptr;
}
}
void CMusicPlayer::Register(const char* pName, const char* pPath)
{
assert(pName && pPath && m_musics.count(pName) <= 0);
m_musics[pName] = pPath;
}
void CMusicPlayer::Play(const char* pName)
{
assert(pName && m_musics.count(pName) > 0);
if (m_currentMusic)
{
delete m_currentMusic;
m_currentMusic = nullptr;
}
m_currentMusic = new sf::Music;
m_currentMusic->openFromFile(m_musics.find(pName)->second);
m_currentMusic->play();
}
CMusicPlayer& CMusicPlayer::GetInstance()
{
return ms_instance;
}
Côté client le main.cpp reste inchangé.Dans ce deuxième cas, le problème survient à la fermeture de l'application (la musique fonctionne parfaitement). Je reçois le message d'erreur suivant lors du delete de m_currentMusic dans le destructeur de CMusicPlayer :
"an internal OpenAL call failed in SoundSource.cpp <64> : AN_INVALID_OPERATION the specified operation is not allowed in the current state."Voilà, désolé de la grosse tartine, j'ai essayé d'être le plus clair et précis possible.
Merci d'avance,
Oliveira