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
_Source = static_cast<CSourceAL*>(_SoundDriver->createSource());
_Source->setPos(CVector(0, 0, 0));
_Source->setVelocity(CVector(0, 0, 0));
_Source->setDirection(CVector(0, 0, 0));
_Source->setSourceRelativeMode(true);
_Source->setStreamingBuffersMax(4);
_Source->setType(SourceMusic);
_Source->setStreamingBufferSize(32768);
// _Source->setStreaming(true);
}
CMusicChannelAL::~CMusicChannelAL()
@ -110,72 +105,47 @@ void CMusicChannelAL::setBufferFormat(IBuffer *buffer)
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
do
if (first)
{
// buffers to update
std::vector<CBufferAL*> buffers;
// get all buffers to queue
_Source->getStreamingBuffers(buffers);
if (first)
{
// 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
// set format for each buffer
for(uint i = 0; i < buffers.size(); ++i)
fillBuffer(buffers[i], _Source->getStreamingBufferSize());
// play the source
if (first)
{
_Source->play();
first = false;
}
// wait 100ms before rechecking buffers
nlSleep(100);
setBufferFormat(buffers[i]);
}
while(!_MusicBuffer->isMusicEnded() && _Playing);
}
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)
else
{
delete _MusicBuffer;
_MusicBuffer = NULL;
// get unqueued buffers
_Source->getProcessedStreamingBuffers(buffers);
}
// use this buffer as source
_Source->setStaticBuffer(_Buffer);
// fill buffers
for(uint i = 0; i < buffers.size(); ++i)
fillBuffer(buffers[i], _Source->getStreamingBufferSize());
// _Source->updateManualRolloff();
// 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
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...)
* NB: if an old music was played, it is first stop with stopMusic()
* \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)
{
// 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;
_Playing = true;
// we need to loop the source only if not async
_Source->setLooping(async ? false:loop);
_Source->setSourceRelativeMode(true);
// start the thread
_Thread->start();
if (_Async)
{
// 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
{
@ -298,6 +312,16 @@ void CMusicChannelAL::setVolume(float gain)
_Source->setGain(gain);
}
/// Update music
void CMusicChannelAL::update()
{
// stop sync music once finished playing
if (_Playing && !_Async && !_Source->isPlaying())
{
stop();
}
}
} /* namespace NLSOUND */
/* end of file */

View file

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

View file

@ -618,11 +618,16 @@ void CSoundDriverAL::commit3DChanges()
// Sync up sources & listener 3d position.
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;
}
}
// update the music (XFade etc...)
updateMusic();
}
/// 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);
}
void CSoundDriverAL::updateMusic()
{
set<CMusicChannelAL *>::iterator it(_MusicChannels.begin()), end(_MusicChannels.end());
for (; it != end; ++it) (*it)->update();
}
/// Remove a buffer
void CSoundDriverAL::removeBuffer(CBufferAL *buffer)
{

View file

@ -176,6 +176,7 @@ public:
float getGain();
protected:
void updateMusic();
/// Allocate nb new buffers or sources
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
// When the game will begin, it will fade in slowly
if(SoundMngr)
SoundMngr->setupFadeSound(1.f, 1.f);
SoundMngr->setupFadeSound(0.f, 1.f);
initLast = initCurrent;
initCurrent = ryzomGetLocalTime();