Changed: #1030 Implement music streaming in OpenAL driver
This commit is contained in:
parent
982136e0d2
commit
409b34a3d8
7 changed files with 436 additions and 10 deletions
|
@ -94,19 +94,22 @@ public:
|
||||||
virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) =0;
|
virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) =0;
|
||||||
|
|
||||||
/// Get the amount of channels (2 is stereo) in output.
|
/// Get the amount of channels (2 is stereo) in output.
|
||||||
virtual uint16 getChannels() =0;
|
virtual uint8 getChannels() =0;
|
||||||
|
|
||||||
/// Get the samples per second (often 44100) in output.
|
/// Get the samples per second (often 44100) in output.
|
||||||
virtual uint32 getSamplesPerSec() =0;
|
virtual uint32 getSamplesPerSec() =0;
|
||||||
|
|
||||||
/// Get the bits per sample (often 16) in output.
|
/// Get the bits per sample (often 16) in output.
|
||||||
virtual uint16 getBitsPerSample() =0;
|
virtual uint8 getBitsPerSample() =0;
|
||||||
|
|
||||||
/// Get if the music has ended playing (never true if loop).
|
/// Get if the music has ended playing (never true if loop).
|
||||||
virtual bool isMusicEnded() =0;
|
virtual bool isMusicEnded() =0;
|
||||||
|
|
||||||
/// Get the total time in seconds.
|
/// Get the total time in seconds.
|
||||||
virtual float getLength() =0;
|
virtual float getLength() =0;
|
||||||
|
|
||||||
|
/// Get the size of uncompressed data in bytes.
|
||||||
|
virtual uint getUncompressedSize() =0;
|
||||||
}; /* class IMusicBuffer */
|
}; /* class IMusicBuffer */
|
||||||
|
|
||||||
} /* namespace NLSOUND */
|
} /* namespace NLSOUND */
|
||||||
|
|
|
@ -75,19 +75,22 @@ public:
|
||||||
virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum);
|
virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum);
|
||||||
|
|
||||||
/// Get the amount of channels (2 is stereo) in output.
|
/// Get the amount of channels (2 is stereo) in output.
|
||||||
virtual uint16 getChannels();
|
virtual uint8 getChannels();
|
||||||
|
|
||||||
/// Get the samples per second (often 44100) in output.
|
/// Get the samples per second (often 44100) in output.
|
||||||
virtual uint32 getSamplesPerSec();
|
virtual uint32 getSamplesPerSec();
|
||||||
|
|
||||||
/// Get the bits per sample (often 16) in output.
|
/// Get the bits per sample (often 16) in output.
|
||||||
virtual uint16 getBitsPerSample();
|
virtual uint8 getBitsPerSample();
|
||||||
|
|
||||||
/// Get if the music has ended playing (never true if loop).
|
/// Get if the music has ended playing (never true if loop).
|
||||||
virtual bool isMusicEnded();
|
virtual bool isMusicEnded();
|
||||||
|
|
||||||
/// Get the total time in seconds.
|
/// Get the total time in seconds.
|
||||||
virtual float getLength();
|
virtual float getLength();
|
||||||
|
|
||||||
|
/// Get the size of uncompressed data in bytes.
|
||||||
|
virtual uint getUncompressedSize();
|
||||||
}; /* class CMusicBufferVorbis */
|
}; /* class CMusicBufferVorbis */
|
||||||
|
|
||||||
} /* namespace NLSOUND */
|
} /* namespace NLSOUND */
|
||||||
|
|
|
@ -158,7 +158,7 @@ uint32 CMusicBufferVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 ma
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 CMusicBufferVorbis::getChannels()
|
uint8 CMusicBufferVorbis::getChannels()
|
||||||
{
|
{
|
||||||
vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
|
vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
|
||||||
return (uint16)vi->channels;
|
return (uint16)vi->channels;
|
||||||
|
@ -170,7 +170,7 @@ uint32 CMusicBufferVorbis::getSamplesPerSec()
|
||||||
return vi->rate;
|
return vi->rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 CMusicBufferVorbis::getBitsPerSample()
|
uint8 CMusicBufferVorbis::getBitsPerSample()
|
||||||
{
|
{
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,11 @@ float CMusicBufferVorbis::getLength()
|
||||||
return (float)ov_time_total(&_OggVorbisFile, -1);
|
return (float)ov_time_total(&_OggVorbisFile, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint CMusicBufferVorbis::getUncompressedSize()
|
||||||
|
{
|
||||||
|
return (uint)ov_pcm_total(&_OggVorbisFile, -1) * (getBitsPerSample() / 2) * getChannels();
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace NLSOUND */
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
/* end of file */
|
/* end of file */
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
||||||
OutputFile="..\..\..\..\lib\nel_drv_openal_win_d.dll"
|
OutputFile="..\..\..\..\lib\nel_drv_openal_win_d.dll"
|
||||||
IgnoreDefaultLibraryNames="msvcrt.lib;libcmt.lib"
|
IgnoreDefaultLibraryNames="msvcrt.lib"
|
||||||
ModuleDefinitionFile="$(ProjectName).def"
|
ModuleDefinitionFile="$(ProjectName).def"
|
||||||
GenerateDebugInformation="true"
|
GenerateDebugInformation="true"
|
||||||
SubSystem="2"
|
SubSystem="2"
|
||||||
|
@ -159,7 +159,7 @@
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
||||||
OutputFile="..\..\..\..\lib64\nel_drv_openal_win_d.dll"
|
OutputFile="..\..\..\..\lib64\nel_drv_openal_win_d.dll"
|
||||||
IgnoreDefaultLibraryNames="msvcrt.lib;libcmt.lib"
|
IgnoreDefaultLibraryNames="msvcrt.lib"
|
||||||
ModuleDefinitionFile="$(ProjectName).def"
|
ModuleDefinitionFile="$(ProjectName).def"
|
||||||
GenerateDebugInformation="true"
|
GenerateDebugInformation="true"
|
||||||
SubSystem="2"
|
SubSystem="2"
|
||||||
|
@ -247,7 +247,7 @@
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
||||||
OutputFile="..\..\..\..\lib\nel_drv_openal_win_r.dll"
|
OutputFile="..\..\..\..\lib\nel_drv_openal_win_r.dll"
|
||||||
IgnoreDefaultLibraryNames="libcmt.lib"
|
IgnoreDefaultLibraryNames=""
|
||||||
ModuleDefinitionFile="$(ProjectName).def"
|
ModuleDefinitionFile="$(ProjectName).def"
|
||||||
GenerateDebugInformation="true"
|
GenerateDebugInformation="true"
|
||||||
SubSystem="2"
|
SubSystem="2"
|
||||||
|
@ -336,7 +336,7 @@
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
AdditionalDependencies="OpenAL32.lib EFX-Util.lib"
|
||||||
OutputFile="..\..\..\..\lib64\nel_drv_openal_win_r.dll"
|
OutputFile="..\..\..\..\lib64\nel_drv_openal_win_r.dll"
|
||||||
IgnoreDefaultLibraryNames="libcmt.lib"
|
IgnoreDefaultLibraryNames=""
|
||||||
ModuleDefinitionFile="$(ProjectName).def"
|
ModuleDefinitionFile="$(ProjectName).def"
|
||||||
GenerateDebugInformation="true"
|
GenerateDebugInformation="true"
|
||||||
SubSystem="2"
|
SubSystem="2"
|
||||||
|
@ -401,6 +401,14 @@
|
||||||
RelativePath=".\listener_al.h"
|
RelativePath=".\listener_al.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\music_channel_al.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\music_channel_al.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source_al.cpp"
|
RelativePath=".\source_al.cpp"
|
||||||
>
|
>
|
||||||
|
|
303
code/nel/src/sound/driver/openal/music_channel_al.cpp
Normal file
303
code/nel/src/sound/driver/openal/music_channel_al.cpp
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "stdopenal.h"
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "sound_driver_al.h"
|
||||||
|
#include "source_al.h"
|
||||||
|
#include "buffer_al.h"
|
||||||
|
#include "music_channel_al.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace NLMISC;
|
||||||
|
|
||||||
|
namespace NLSOUND
|
||||||
|
{
|
||||||
|
|
||||||
|
CMusicChannelAL::CMusicChannelAL(CSoundDriverAL *soundDriver)
|
||||||
|
: _MusicBuffer(NULL), _SoundDriver(soundDriver), _Gain(1.0), _Source(NULL), _Thread(NULL), _Async(false), _Playing(false), _Buffer(NULL)
|
||||||
|
{
|
||||||
|
// 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->setStreamingBufferSize(32768);
|
||||||
|
// _Source->setStreaming(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMusicChannelAL::~CMusicChannelAL()
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
if (_SoundDriver) { _SoundDriver->removeMusicChannel(this); _SoundDriver = NULL; }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMusicChannelAL::release()
|
||||||
|
{
|
||||||
|
// stop thread before deleting it
|
||||||
|
stop();
|
||||||
|
|
||||||
|
// delete thread
|
||||||
|
if (_Thread)
|
||||||
|
{
|
||||||
|
delete _Thread;
|
||||||
|
_Thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete source
|
||||||
|
if (_Source)
|
||||||
|
{
|
||||||
|
delete _Source;
|
||||||
|
_Source = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fill IBuffer with data from IMusicBuffer
|
||||||
|
bool CMusicChannelAL::fillBuffer(IBuffer *buffer, uint length)
|
||||||
|
{
|
||||||
|
if (!buffer || !length)
|
||||||
|
{
|
||||||
|
nlwarning("AL: No data to stream");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill buffer with music data
|
||||||
|
uint8 *tmp = buffer->lock(length);
|
||||||
|
if (tmp == NULL)
|
||||||
|
{
|
||||||
|
nlwarning("AL: Can't allocate %u bytes for buffer", length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 size = _MusicBuffer->getNextBytes(tmp, length, length);
|
||||||
|
buffer->unlock(size);
|
||||||
|
|
||||||
|
// add buffer to streaming buffers queue
|
||||||
|
_Source->submitStreamingBuffer(buffer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use buffer format from IMusicBuffer
|
||||||
|
void CMusicChannelAL::setBufferFormat(IBuffer *buffer)
|
||||||
|
{
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
nlwarning("AL: No buffer specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use the same format as music for buffers
|
||||||
|
buffer->setFormat(IBuffer::FormatPcm, _MusicBuffer->getChannels(),
|
||||||
|
_MusicBuffer->getBitsPerSample(), _MusicBuffer->getSamplesPerSec());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMusicChannelAL::run()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_Async)
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
// use queued buffers
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// buffers to update
|
||||||
|
std::vector<CBufferAL*> 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
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
delete _MusicBuffer;
|
||||||
|
_MusicBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use this buffer as source
|
||||||
|
_Source->setStaticBuffer(_Buffer);
|
||||||
|
|
||||||
|
// play the source
|
||||||
|
_Source->play();
|
||||||
|
}
|
||||||
|
|
||||||
|
// music finished without interruption
|
||||||
|
if (_Playing)
|
||||||
|
{
|
||||||
|
// wait until source is not playing
|
||||||
|
while(_Source->isPlaying() && _Playing) nlSleep(1000);
|
||||||
|
|
||||||
|
_Source->stop();
|
||||||
|
|
||||||
|
_Playing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
* \param async stream music from hard disk, preload in memory if false
|
||||||
|
* \param loop must be true to play the music in loop.
|
||||||
|
*/
|
||||||
|
bool CMusicChannelAL::play(const std::string &filepath, bool async, bool loop)
|
||||||
|
{
|
||||||
|
// stop a previous music
|
||||||
|
stop();
|
||||||
|
|
||||||
|
// when not using async, we must load the whole file once
|
||||||
|
_MusicBuffer = IMusicBuffer::createMusicBuffer(filepath, async, async ? loop:false);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// start the thread
|
||||||
|
_Thread->start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nlwarning("AL: Can't stream file %s", filepath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop the music previously loaded and played (the Memory is also freed)
|
||||||
|
void CMusicChannelAL::stop()
|
||||||
|
{
|
||||||
|
_Playing = false;
|
||||||
|
|
||||||
|
_Source->stop();
|
||||||
|
|
||||||
|
// if not using async streaming, we manage static buffer ourself
|
||||||
|
if (!_Async && _Buffer)
|
||||||
|
{
|
||||||
|
_Source->setStaticBuffer(NULL);
|
||||||
|
delete _Buffer;
|
||||||
|
_Buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until thread is finished
|
||||||
|
if (_Thread)
|
||||||
|
_Thread->wait();
|
||||||
|
|
||||||
|
if (_MusicBuffer)
|
||||||
|
{
|
||||||
|
delete _MusicBuffer;
|
||||||
|
_MusicBuffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pause the music previously loaded and played (the Memory is not freed)
|
||||||
|
void CMusicChannelAL::pause()
|
||||||
|
{
|
||||||
|
_Source->pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resume the music previously paused
|
||||||
|
void CMusicChannelAL::resume()
|
||||||
|
{
|
||||||
|
_Source->play();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if a song is finished.
|
||||||
|
bool CMusicChannelAL::isEnded()
|
||||||
|
{
|
||||||
|
return !_Playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading
|
||||||
|
bool CMusicChannelAL::isLoadingAsync()
|
||||||
|
{
|
||||||
|
return _Async && _Playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the total length (in second) of the music currently played
|
||||||
|
float CMusicChannelAL::getLength()
|
||||||
|
{
|
||||||
|
if (_MusicBuffer) return _MusicBuffer->getLength();
|
||||||
|
else return .0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1)
|
||||||
|
* NB: in OpenAL driver, the volume of music IS affected by IListener::setGain()
|
||||||
|
*/
|
||||||
|
void CMusicChannelAL::setVolume(float gain)
|
||||||
|
{
|
||||||
|
_Gain = gain;
|
||||||
|
_Source->setGain(gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
|
/* end of file */
|
100
code/nel/src/sound/driver/openal/music_channel_al.h
Normal file
100
code/nel/src/sound/driver/openal/music_channel_al.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef NLSOUND_MUSIC_CHANNEL_AL_H
|
||||||
|
#define NLSOUND_MUSIC_CHANNEL_AL_H
|
||||||
|
|
||||||
|
#include "nel/sound/driver/music_channel.h"
|
||||||
|
|
||||||
|
namespace NLSOUND
|
||||||
|
{
|
||||||
|
class CSoundDriverAL;
|
||||||
|
class IMusicBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief CMusicChannelAL
|
||||||
|
* \date 2010-07-27 16:56GMT
|
||||||
|
* \author Kervala
|
||||||
|
* CMusicChannelAL is an implementation of the IMusicChannel interface to run on OpenAL.
|
||||||
|
*/
|
||||||
|
class CMusicChannelAL : public IMusicChannel, public NLMISC::IRunnable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// outside pointers
|
||||||
|
CSoundDriverAL* _SoundDriver;
|
||||||
|
|
||||||
|
// pointers
|
||||||
|
IMusicBuffer* _MusicBuffer;
|
||||||
|
NLMISC::IThread* _Thread;
|
||||||
|
|
||||||
|
IBuffer* _Buffer;
|
||||||
|
CSourceAL* _Source;
|
||||||
|
bool _Playing;
|
||||||
|
bool _Async;
|
||||||
|
|
||||||
|
float _Gain;
|
||||||
|
|
||||||
|
/// Fill IBuffer with data from IMusicBuffer
|
||||||
|
bool fillBuffer(IBuffer *buffer, uint length);
|
||||||
|
|
||||||
|
/// Use buffer format from IMusicBuffer
|
||||||
|
void setBufferFormat(IBuffer *buffer);
|
||||||
|
|
||||||
|
/// Declared in NLMISC::IRunnable interface
|
||||||
|
virtual void run();
|
||||||
|
|
||||||
|
public:
|
||||||
|
CMusicChannelAL(CSoundDriverAL *soundDriver);
|
||||||
|
virtual ~CMusicChannelAL();
|
||||||
|
void release();
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
* \param async stream music from hard disk, preload in memory if false
|
||||||
|
* \param loop must be true to play the music in loop.
|
||||||
|
*/
|
||||||
|
virtual bool play(const std::string &filepath, bool async, bool loop);
|
||||||
|
|
||||||
|
/// Stop the music previously loaded and played (the Memory is also freed)
|
||||||
|
virtual void stop();
|
||||||
|
|
||||||
|
/// Pause the music previously loaded and played (the Memory is not freed)
|
||||||
|
virtual void pause();
|
||||||
|
|
||||||
|
/// Resume the music previously paused
|
||||||
|
virtual void resume();
|
||||||
|
|
||||||
|
/// Return true if a song is finished.
|
||||||
|
virtual bool isEnded();
|
||||||
|
|
||||||
|
/// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading
|
||||||
|
virtual bool isLoadingAsync();
|
||||||
|
|
||||||
|
/// Return the total length (in second) of the music currently played
|
||||||
|
virtual float getLength();
|
||||||
|
|
||||||
|
/** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1)
|
||||||
|
* NB: in OpenAL driver, the volume of music IS affected by IListener::setGain()
|
||||||
|
*/
|
||||||
|
virtual void setVolume(float gain);
|
||||||
|
}; /* class CMusicChannelAL */
|
||||||
|
|
||||||
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
|
#endif /* #ifndef NLSOUND_MUSIC_CHANNEL_AL_H */
|
||||||
|
|
||||||
|
/* end of file */
|
|
@ -50,10 +50,14 @@
|
||||||
#include "nel/misc/fast_mem.h"
|
#include "nel/misc/fast_mem.h"
|
||||||
#include "nel/misc/path.h"
|
#include "nel/misc/path.h"
|
||||||
#include "nel/misc/dynloadlib.h"
|
#include "nel/misc/dynloadlib.h"
|
||||||
|
#include "nel/misc/hierarchical_timer.h"
|
||||||
|
#include "nel/misc/thread.h"
|
||||||
|
|
||||||
#include "nel/sound/driver/sound_driver.h"
|
#include "nel/sound/driver/sound_driver.h"
|
||||||
#include "nel/sound/driver/buffer.h"
|
#include "nel/sound/driver/buffer.h"
|
||||||
#include "nel/sound/driver/source.h"
|
#include "nel/sound/driver/source.h"
|
||||||
#include "nel/sound/driver/listener.h"
|
#include "nel/sound/driver/listener.h"
|
||||||
#include "nel/sound/driver/effect.h"
|
#include "nel/sound/driver/effect.h"
|
||||||
|
#include "nel/sound/driver/music_buffer.h"
|
||||||
|
|
||||||
/* end of file */
|
/* end of file */
|
||||||
|
|
Loading…
Reference in a new issue