diff --git a/code/nel/src/sound/driver/openal/music_channel_al.cpp b/code/nel/src/sound/driver/openal/music_channel_al.cpp index a6905d356..efff2465b 100644 --- a/code/nel/src/sound/driver/openal/music_channel_al.cpp +++ b/code/nel/src/sound/driver/openal/music_channel_al.cpp @@ -33,13 +33,8 @@ CMusicChannelAL::CMusicChannelAL(CSoundDriverAL *soundDriver) { // create a default source for music streaming _Source = static_cast(_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 buffers; - // use queued buffers - do + if (first) { - // buffers to update - std::vector 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 */ diff --git a/code/nel/src/sound/driver/openal/music_channel_al.h b/code/nel/src/sound/driver/openal/music_channel_al.h index dddb5a052..157c18810 100644 --- a/code/nel/src/sound/driver/openal/music_channel_al.h +++ b/code/nel/src/sound/driver/openal/music_channel_al.h @@ -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 */ diff --git a/code/nel/src/sound/driver/openal/sound_driver_al.cpp b/code/nel/src/sound/driver/openal/sound_driver_al.cpp index 270117c4f..f6ec2e537 100644 --- a/code/nel/src/sound/driver/openal/sound_driver_al.cpp +++ b/code/nel/src/sound/driver/openal/sound_driver_al.cpp @@ -618,11 +618,16 @@ void CSoundDriverAL::commit3DChanges() // Sync up sources & listener 3d position. if (getOption(OptionManualRolloff)) { - for (std::set::iterator it(_Sources.begin()), end(_Sources.end()); it != end; ++it) + set::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::iterator it(_MusicChannels.begin()), end(_MusicChannels.end()); + for (; it != end; ++it) (*it)->update(); +} + /// Remove a buffer void CSoundDriverAL::removeBuffer(CBufferAL *buffer) { diff --git a/code/nel/src/sound/driver/openal/sound_driver_al.h b/code/nel/src/sound/driver/openal/sound_driver_al.h index 848637f6c..a781d3216 100644 --- a/code/nel/src/sound/driver/openal/sound_driver_al.h +++ b/code/nel/src/sound/driver/openal/sound_driver_al.h @@ -176,6 +176,7 @@ public: float getGain(); protected: + void updateMusic(); /// Allocate nb new buffers or sources void allocateNewItems( TGenFunctionAL algenfunc, TTestFunctionAL altestfunc, diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index 5256722bc..88bf1ac5a 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -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();