Changed: #1031 Music is "stopped" when client is loading with OpenAL driver

This commit is contained in:
kervala 2010-07-28 21:13:39 +02:00
parent 39e25f218e
commit 2a1441858f
5 changed files with 116 additions and 74 deletions

View file

@ -33,13 +33,8 @@ CMusicChannelAL::CMusicChannelAL(CSoundDriverAL *soundDriver)
{ {
// create a default source for music streaming // create a default source for music streaming
_Source = static_cast<CSourceAL*>(_SoundDriver->createSource()); _Source = static_cast<CSourceAL*>(_SoundDriver->createSource());
_Source->setPos(CVector(0, 0, 0)); _Source->setType(SourceMusic);
_Source->setVelocity(CVector(0, 0, 0));
_Source->setDirection(CVector(0, 0, 0));
_Source->setSourceRelativeMode(true);
_Source->setStreamingBuffersMax(4);
_Source->setStreamingBufferSize(32768); _Source->setStreamingBufferSize(32768);
// _Source->setStreaming(true);
} }
CMusicChannelAL::~CMusicChannelAL() CMusicChannelAL::~CMusicChannelAL()
@ -110,72 +105,47 @@ void CMusicChannelAL::setBufferFormat(IBuffer *buffer)
void CMusicChannelAL::run() void CMusicChannelAL::run()
{ {
bool first = true;
if (_Async) // use queued buffers
do
{ {
bool first = true; // buffers to update
std::vector<CBufferAL*> buffers;
// use queued buffers if (first)
do
{ {
// buffers to update // get all buffers to queue
std::vector<CBufferAL*> buffers; _Source->getStreamingBuffers(buffers);
if (first) // set format for each buffer
{
// get all buffers to queue
_Source->getStreamingBuffers(buffers);
// set format for each buffer
for(uint i = 0; i < buffers.size(); ++i)
setBufferFormat(buffers[i]);
}
else
{
// get unqueued buffers
_Source->getProcessedStreamingBuffers(buffers);
}
// fill buffers
for(uint i = 0; i < buffers.size(); ++i) for(uint i = 0; i < buffers.size(); ++i)
fillBuffer(buffers[i], _Source->getStreamingBufferSize()); setBufferFormat(buffers[i]);
// play the source
if (first)
{
_Source->play();
first = false;
}
// wait 100ms before rechecking buffers
nlSleep(100);
} }
while(!_MusicBuffer->isMusicEnded() && _Playing); else
}
else
{
// use an unique buffer managed by CMusicChannelAL
_Buffer = _SoundDriver->createBuffer();
// set format
setBufferFormat(_Buffer);
// fill data
fillBuffer(_Buffer, _MusicBuffer->getUncompressedSize());
// we don't need _MusicBuffer anymore because all is loaded into memory
if (_MusicBuffer)
{ {
delete _MusicBuffer; // get unqueued buffers
_MusicBuffer = NULL; _Source->getProcessedStreamingBuffers(buffers);
} }
// use this buffer as source // fill buffers
_Source->setStaticBuffer(_Buffer); for(uint i = 0; i < buffers.size(); ++i)
fillBuffer(buffers[i], _Source->getStreamingBufferSize());
// _Source->updateManualRolloff();
// play the source // play the source
_Source->play(); if (first)
{
_Source->play();
first = false;
}
// wait 100ms before rechecking buffers
nlSleep(100);
} }
while(!_MusicBuffer->isMusicEnded() && _Playing);
// music finished without interruption // music finished without interruption
if (_Playing) if (_Playing)
@ -189,6 +159,35 @@ void CMusicChannelAL::run()
} }
} }
/// Play sync music
bool CMusicChannelAL::playSync()
{
// use an unique buffer managed by CMusicChannelAL
_Buffer = _SoundDriver->createBuffer();
// set format
setBufferFormat(_Buffer);
// fill data
fillBuffer(_Buffer, _MusicBuffer->getUncompressedSize());
// we don't need _MusicBuffer anymore because all is loaded into memory
if (_MusicBuffer)
{
delete _MusicBuffer;
_MusicBuffer = NULL;
}
// delete previous queued buffers
_Source->setStreamingBuffersMax(0);
// use this buffer as source
_Source->setStaticBuffer(_Buffer);
// play the source
return _Source->play();
}
/** Play some music (.ogg etc...) /** Play some music (.ogg etc...)
* NB: if an old music was played, it is first stop with stopMusic() * NB: if an old music was played, it is first stop with stopMusic()
* \param filepath file path, CPath::lookup is done here * \param filepath file path, CPath::lookup is done here
@ -205,23 +204,38 @@ bool CMusicChannelAL::play(const std::string &filepath, bool async, bool loop)
if (_MusicBuffer) if (_MusicBuffer)
{ {
// create the thread if it's not yet created
if (!_Thread) _Thread = IThread::create(this);
if (!_Thread)
{
nlwarning("AL: Can't create a new thread");
return false;
}
_Async = async; _Async = async;
_Playing = true; _Playing = true;
// we need to loop the source only if not async _Source->setSourceRelativeMode(true);
_Source->setLooping(async ? false:loop);
// start the thread if (_Async)
_Thread->start(); {
// create the thread if it's not yet created
if (!_Thread) _Thread = IThread::create(this);
if (!_Thread)
{
nlwarning("AL: Can't create a new thread");
return false;
}
// use 4 queued buffers
_Source->setStreamingBuffersMax(4);
// we need to loop the source only if not async
_Source->setLooping(false);
// start the thread
_Thread->start();
}
else
{
// we need to loop the source only if not async
_Source->setLooping(loop);
return playSync();
}
} }
else else
{ {
@ -298,6 +312,16 @@ void CMusicChannelAL::setVolume(float gain)
_Source->setGain(gain); _Source->setGain(gain);
} }
/// Update music
void CMusicChannelAL::update()
{
// stop sync music once finished playing
if (_Playing && !_Async && !_Source->isPlaying())
{
stop();
}
}
} /* namespace NLSOUND */ } /* namespace NLSOUND */
/* end of file */ /* end of file */

View file

@ -91,6 +91,12 @@ public:
* NB: in OpenAL driver, the volume of music IS affected by IListener::setGain() * NB: in OpenAL driver, the volume of music IS affected by IListener::setGain()
*/ */
virtual void setVolume(float gain); virtual void setVolume(float gain);
/// Play sync music
bool playSync();
/// Update music
void update();
}; /* class CMusicChannelAL */ }; /* class CMusicChannelAL */
} /* namespace NLSOUND */ } /* namespace NLSOUND */

View file

@ -618,11 +618,16 @@ void CSoundDriverAL::commit3DChanges()
// Sync up sources & listener 3d position. // Sync up sources & listener 3d position.
if (getOption(OptionManualRolloff)) if (getOption(OptionManualRolloff))
{ {
for (std::set<CSourceAL *>::iterator it(_Sources.begin()), end(_Sources.end()); it != end; ++it) set<CSourceAL*>::iterator it = _Sources.begin(), iend = _Sources.end();
while(it != iend)
{ {
(*it)->updateManualRolloff(); (*it)->updateManualRolloff();
++it;
} }
} }
// update the music (XFade etc...)
updateMusic();
} }
/// Write information about the driver to the output stream. /// Write information about the driver to the output stream.
@ -661,6 +666,12 @@ bool CSoundDriverAL::getMusicInfo(const std::string &filepath, std::string &arti
return IMusicBuffer::getInfo(filepath, artist, title); return IMusicBuffer::getInfo(filepath, artist, title);
} }
void CSoundDriverAL::updateMusic()
{
set<CMusicChannelAL *>::iterator it(_MusicChannels.begin()), end(_MusicChannels.end());
for (; it != end; ++it) (*it)->update();
}
/// Remove a buffer /// Remove a buffer
void CSoundDriverAL::removeBuffer(CBufferAL *buffer) void CSoundDriverAL::removeBuffer(CBufferAL *buffer)
{ {

View file

@ -176,6 +176,7 @@ public:
float getGain(); float getGain();
protected: protected:
void updateMusic();
/// Allocate nb new buffers or sources /// Allocate nb new buffers or sources
void allocateNewItems( TGenFunctionAL algenfunc, TTestFunctionAL altestfunc, void allocateNewItems( TGenFunctionAL algenfunc, TTestFunctionAL altestfunc,

View file

@ -533,7 +533,7 @@ void initMainLoop()
// During load of the game, fade completely out SFX, and leave outgame music // During load of the game, fade completely out SFX, and leave outgame music
// When the game will begin, it will fade in slowly // When the game will begin, it will fade in slowly
if(SoundMngr) if(SoundMngr)
SoundMngr->setupFadeSound(1.f, 1.f); SoundMngr->setupFadeSound(0.f, 1.f);
initLast = initCurrent; initLast = initCurrent;
initCurrent = ryzomGetLocalTime(); initCurrent = ryzomGetLocalTime();