Changed: #1030 Implement music streaming in OpenAL driver

This commit is contained in:
kervala 2010-07-27 18:56:34 +02:00
parent e16ae0c3e5
commit 97e7509803
2 changed files with 99 additions and 24 deletions

View file

@ -16,6 +16,7 @@
#include "stdopenal.h"
#include "sound_driver_al.h"
#include "music_channel_al.h"
#include "buffer_al.h"
#include "listener_al.h"
#include "source_al.h"
@ -49,6 +50,7 @@ void alTestError()
case AL_INVALID_VALUE: nlerror("OpenAL: Invalid value");
case AL_INVALID_OPERATION: nlerror("OpenAL: Invalid operation");
case AL_OUT_OF_MEMORY: nlerror("OpenAL: Out of memory");
default: nlerror("OpenAL: Unknown error %x", errcode);
}
}
#endif
@ -181,13 +183,21 @@ _NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f)
*/
CSoundDriverAL::~CSoundDriverAL()
{
// Release internal resources of all remaining IMusicChannel instances
if (_MusicChannels.size())
{
nlwarning("AL: _MusicChannels.size(): '%u'", (uint32)_MusicChannels.size());
set<CMusicChannelAL *>::iterator it(_MusicChannels.begin()), end(_MusicChannels.end());
for (; it != end; ++it) delete *it;
_MusicChannels.clear();
}
// Remove the allocated (but not exported) source and buffer names-
// Release internal resources of all remaining ISource instances
if (_Sources.size())
{
nlwarning("AL: _Sources.size(): '%u'", (uint32)_Sources.size());
set<CSourceAL *>::iterator it(_Sources.begin()), end(_Sources.end());
for (; it != end; ++it) (*it)->release();
for (; it != end; ++it) delete *it;
_Sources.clear();
}
if (!_Buffers.empty()) alDeleteBuffers(compactAliveNames(_Buffers, alIsBuffer), &*_Buffers.begin());
@ -196,7 +206,7 @@ CSoundDriverAL::~CSoundDriverAL()
{
nlwarning("AL: _Effects.size(): '%u'", (uint32)_Effects.size());
set<CEffectAL *>::iterator it(_Effects.begin()), end(_Effects.end());
for (; it != end; ++it) (*it)->release();
for (; it != end; ++it) delete *it;
_Effects.clear();
}
@ -615,6 +625,42 @@ void CSoundDriverAL::commit3DChanges()
}
}
/// Write information about the driver to the output stream.
void CSoundDriverAL::writeProfile(std::string& out)
{
// TODO
}
// Does not create a sound loader .. what does it do then?
void CSoundDriverAL::startBench()
{
NLMISC::CHTimer::startBench();
}
void CSoundDriverAL::endBench()
{
NLMISC::CHTimer::endBench();
}
void CSoundDriverAL::displayBench(NLMISC::CLog *log)
{
NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(log, CHTimer::TotalTime, true, 48, 2);
NLMISC::CHTimer::displayHierarchical(log, true, 48, 2);
NLMISC::CHTimer::displayByExecutionPath(log, CHTimer::TotalTime);
NLMISC::CHTimer::display(log, CHTimer::TotalTime);
}
/** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver
* \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available)
*/
bool CSoundDriverAL::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title)
{
// add support for additional non-standard music file types info here
return IMusicBuffer::getInfo(filepath, artist, title);
}
/// Remove a buffer
void CSoundDriverAL::removeBuffer(CBufferAL *buffer)
{
@ -637,6 +683,21 @@ void CSoundDriverAL::removeEffect(CEffectAL *effect)
else nlwarning("AL: removeEffect already called");
}
/// Create a music channel
IMusicChannel *CSoundDriverAL::createMusicChannel()
{
CMusicChannelAL *music_channel = new CMusicChannelAL(this);
_MusicChannels.insert(music_channel);
return static_cast<IMusicChannel *>(music_channel);
}
/// (Internal) Remove a music channel (should be called by the destructor of the music channel class).
void CSoundDriverAL::removeMusicChannel(CMusicChannelAL *musicChannel)
{
if (_MusicChannels.find(musicChannel) != _MusicChannels.end()) _MusicChannels.erase(musicChannel);
else nlwarning("AL: removeMusicChannel already called");
}
/// Delete a buffer or a source
bool CSoundDriverAL::deleteItem( ALuint name, TDeleteFunctionAL aldeletefunc, vector<ALuint>& names )
{

View file

@ -24,6 +24,7 @@ namespace NLSOUND {
class CListenerAL;
class CSourceAL;
class CEffectAL;
class CMusicChannelAL;
// alGenBuffers, alGenSources
//typedef ALAPI ALvoid ALAPIENTRY (*TGenFunctionAL) ( ALsizei, ALuint* );
@ -80,6 +81,8 @@ private:
std::set<CSourceAL *> _Sources;
// Allocated effects
std::set<CEffectAL *> _Effects;
/// Array with the allocated music channels created by client code.
std::set<CMusicChannelAL *> _MusicChannels;
// Number of exported buffers (including any deleted buffers)
uint _NbExpBuffers;
// Number of exported sources (including any deleted sources)
@ -97,10 +100,6 @@ public:
/// Destructor
virtual ~CSoundDriverAL();
inline ALCdevice *getAlDevice() { return _AlDevice; }
inline ALCcontext *getAlContext() { return _AlContext; }
inline float getRolloffFactor() { return _RolloffFactor; }
/// Return a list of available devices for the user. The value at index 0 is empty, and is used for automatic device selection.
virtual void getDevices(std::vector<std::string> &devices);
/// Initialize the driver with a user selected device. If device.empty(), the default or most appropriate device is used.
@ -111,44 +110,59 @@ public:
/// Return if an option is enabled (including those that cannot be disabled on this driver).
virtual bool getOption(TSoundOptions option);
/// Create a sound buffer
virtual IBuffer *createBuffer();
/// Commit all the changes made to 3D settings of listener and sources
virtual void commit3DChanges();
/// Create the listener instance
virtual IListener *createListener();
/// Create a source
/// Create a source, destroy with delete
virtual ISource *createSource();
/// Create a sound buffer, destroy with delete
virtual IBuffer *createBuffer();
/// Create a reverb effect
virtual IReverbEffect *createReverbEffect();
/// Return the maximum number of sources that can created
virtual uint countMaxSources();
/// Return the maximum number of effects that can be created
virtual uint countMaxEffects();
virtual void startBench() { /* todo */ }
virtual void endBench() { /* todo */ }
virtual void displayBench(NLMISC::CLog * /* log */) { /* TODO */ }
/// Write information about the driver to the output stream.
virtual void writeProfile(std::string& /* out */);
virtual void startBench();
virtual void endBench();
virtual void displayBench(NLMISC::CLog * /* log */);
/// Create a music channel, destroy with destroyMusicChannel.
virtual IMusicChannel *createMusicChannel();
/** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver
* \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available)
*/
virtual bool getMusicInfo(const std::string &filepath, std::string &artist, std::string &title);
/// Get audio/container extensions that are supported natively by the driver implementation.
virtual void getMusicExtensions(std::vector<std::string> & /* extensions */) const { }
/// Return if a music extension is supported by the driver's music channel.
virtual bool isMusicExtensionSupported(const std::string & /* extension */) const { return false; }
ALCdevice *getAlDevice() { return _AlDevice; }
ALCcontext *getAlContext() { return _AlContext; }
float getRolloffFactor() { return _RolloffFactor; }
/// Change the rolloff factor and apply to all sources
void applyRolloffFactor(float f);
/// Commit all the changes made to 3D settings of listener and sources
virtual void commit3DChanges();
/// Write information about the driver to the output stream.
virtual void writeProfile(std::string& /* out */) { }
/// Remove a buffer
void removeBuffer(CBufferAL *buffer);
/// Remove a source
void removeSource(CSourceAL *source);
/// Remove an effect
void removeEffect(CEffectAL *effect);
/// Get audio/container extensions that are supported natively by the driver implementation.
virtual void getMusicExtensions(std::vector<std::string> & /* extensions */) const { }
/// Return if a music extension is supported by the driver's music channel.
virtual bool isMusicExtensionSupported(const std::string & /* extension */) const { return false; }
/// (Internal) Remove music channel (should be called by the destructor of the music channel class).
void removeMusicChannel(CMusicChannelAL *musicChannel);
protected: