mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-10 09:19:01 +00:00
Changed: #1030 Implement music streaming in OpenAL driver
This commit is contained in:
parent
e16ae0c3e5
commit
97e7509803
2 changed files with 99 additions and 24 deletions
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
Loading…
Reference in a new issue