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 c7146ea3a..a6905d356 100644
--- a/code/nel/src/sound/driver/openal/music_channel_al.cpp
+++ b/code/nel/src/sound/driver/openal/music_channel_al.cpp
@@ -279,13 +279,13 @@ bool CMusicChannelAL::isEnded()
/// 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 _Async && _Playing && !_Source->isPlaying();
}
/// Return the total length (in second) of the music currently played
float CMusicChannelAL::getLength()
{
- if (_MusicBuffer) return _MusicBuffer->getLength();
+ if (_MusicBuffer) return _MusicBuffer->getLength();
else return .0f;
}
diff --git a/code/nel/src/sound/driver/openal/source_al.cpp b/code/nel/src/sound/driver/openal/source_al.cpp
index 84b2d7f39..d565e0438 100644
--- a/code/nel/src/sound/driver/openal/source_al.cpp
+++ b/code/nel/src/sound/driver/openal/source_al.cpp
@@ -15,34 +15,52 @@
// along with this program. If not, see .
#include "stdopenal.h"
+#include "source_al.h"
#include "sound_driver_al.h"
#include "listener_al.h"
#include "effect_al.h"
#include "buffer_al.h"
-#include "source_al.h"
#include "ext_al.h"
using namespace std;
using namespace NLMISC;
-namespace NLSOUND {
-
-CSourceAL::CSourceAL(CSoundDriverAL *soundDriver) :
-_SoundDriver(NULL), _Buffer(NULL), _BuffersMax(0), _BufferSize(32768), _Source(AL_NONE),
-_DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL),
-_IsPlaying(false), _IsPaused(false),
-_Pos(0.0f, 0.0f, 0.0f), _Gain(NLSOUND_DEFAULT_GAIN), _Alpha(1.0),
-_MinDistance(1.0f), _MaxDistance(numeric_limits::max()),
-_Effect(NULL), _Direct(true),
-_DirectGain(NLSOUND_DEFAULT_DIRECT_GAIN), _EffectGain(NLSOUND_DEFAULT_EFFECT_GAIN),
-_DirectFilterType(ISource::FilterLowPass), _EffectFilterType(ISource::FilterLowPass),
-_DirectFilterEnabled(false), _EffectFilterEnabled(false),
-_DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN)
+namespace NLSOUND
{
+
+CSourceAL::CSourceAL(CSoundDriverAL *soundDriver):ISource(), _SoundDriver(NULL), _Source(AL_NONE),
+ _DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL)
+{
+ _IsPlaying = false;
+ _IsPaused = false;
+
+ _Type = SourceSound;
+ _Buffer = NULL;
+ _BuffersMax = 0;
+ _BufferSize = 32768;
+
+ _PosRelative = false;
+ _Gain = NLSOUND_DEFAULT_GAIN;
+ _Alpha = 0.0;
+ _Pos = CVector::Null;
+ _MinDistance = 1.0f;
+ _MaxDistance = numeric_limits::max();
+
+ _Effect = NULL;
+ _Direct = true;
+ _DirectGain = NLSOUND_DEFAULT_DIRECT_GAIN;
+ _EffectGain = NLSOUND_DEFAULT_EFFECT_GAIN;
+ _DirectFilterType = ISource::FilterLowPass;
+ _EffectFilterType = ISource::FilterLowPass;
+ _DirectFilterEnabled = false;
+ _EffectFilterEnabled = false;
+ _DirectFilterPassGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN;
+ _EffectFilterPassGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN;
+
// create the al source
alGenSources(1, &_Source);
alTestError();
-
+
// configure rolloff
if (!soundDriver || soundDriver->getOption(ISoundDriver::OptionManualRolloff))
{
@@ -54,7 +72,7 @@ _DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(N
alSourcef(_Source, AL_ROLLOFF_FACTOR, soundDriver->getRolloffFactor());
alTestError();
}
-
+
// create filters
if (soundDriver && soundDriver->getOption(ISoundDriver::OptionEnvironmentEffects))
{
@@ -63,6 +81,7 @@ _DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(N
alFilterf(_DirectFilter, AL_LOWPASS_GAIN, NLSOUND_DEFAULT_DIRECT_GAIN);
alFilterf(_DirectFilter, AL_LOWPASS_GAINHF, NLSOUND_DEFAULT_FILTER_PASS_GAIN);
alTestError();
+
alGenFilters(1, &_EffectFilter);
alFilteri(_EffectFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
alFilterf(_EffectFilter, AL_LOWPASS_GAIN, NLSOUND_DEFAULT_EFFECT_GAIN);
@@ -94,13 +113,37 @@ void CSourceAL::release()
/// (Internal) Update the 3d changes.
void CSourceAL::updateManualRolloff()
{
- CVector distanceVector = _Pos - CListenerAL::getInstance()->getPos();
- float distanceSquare = distanceVector.sqrnorm();
- float rolloff = ISource::computeManualRolloff(_Alpha, distanceSquare, _MinDistance, _MaxDistance);
- alSourcef(_Source, AL_GAIN, _Gain * rolloff);
+ CVector pos = getPos();
+
+ // make relative to listener (if not already!)
+ if (!_PosRelative)
+ pos -= CListenerAL::getInstance()->getPos();
+
+ float sqrdist = pos.sqrnorm();
+ float rolloff = ISource::computeManualRolloff(_Alpha, sqrdist, _MinDistance, _MaxDistance);
+ float volume = _Gain * rolloff;
+
+ // apply SFX volume
+ if (_SoundDriver && _Type == SourceSound)
+ volume *= _SoundDriver->getGain();
+
+ // set the attenuated volume
+ alSourcef(_Source, AL_GAIN, volume);
alTestError();
}
+/// Set type of the source
+void CSourceAL::setType(TSourceType type)
+{
+ _Type = type;
+}
+
+/// Get type of the source
+TSourceType CSourceAL::getType() const
+{
+ return _Type;
+}
+
/// Enable or disable streaming mode. Source must be stopped to call this.
void CSourceAL::setStreaming(bool /* streaming */)
{
@@ -392,9 +435,16 @@ void CSourceAL::getDirection( NLMISC::CVector& dir ) const
void CSourceAL::setGain(float gain)
{
_Gain = std::min(std::max(gain, NLSOUND_MIN_GAIN), NLSOUND_MAX_GAIN);
+
if ((_SoundDriver == NULL) || !_SoundDriver->getOption(ISoundDriver::OptionManualRolloff))
{
- alSourcef(_Source, AL_GAIN, _Gain);
+ float gain = _Gain;
+
+ // apply SFX volume
+ if (_SoundDriver && _Type == SourceSound)
+ gain *= _SoundDriver->getGain();
+
+ alSourcef(_Source, AL_GAIN, gain);
alTestError();
}
}
@@ -428,6 +478,7 @@ float CSourceAL::getPitch() const
/// Set the source relative mode. If true, positions are interpreted relative to the listener position.
void CSourceAL::setSourceRelativeMode( bool mode )
{
+ _PosRelative = mode;
alSourcei(_Source, AL_SOURCE_RELATIVE, mode?AL_TRUE:AL_FALSE );
alTestError();
}
@@ -435,10 +486,11 @@ void CSourceAL::setSourceRelativeMode( bool mode )
/// Get the source relative mode (3D mode only)
bool CSourceAL::getSourceRelativeMode() const
{
- ALint b;
- alGetSourcei(_Source, AL_SOURCE_RELATIVE, &b );
- alTestError();
- return (b==AL_TRUE);
+ return _PosRelative;
+// ALint b;
+// alGetSourcei(_Source, AL_SOURCE_RELATIVE, &b );
+// alTestError();
+// return (b==AL_TRUE);
}
/// Set the min and max distances (3D mode only)
@@ -447,12 +499,12 @@ void CSourceAL::setMinMaxDistances( float mindist, float maxdist, bool /* deferr
nlassert( (mindist >= 0.0f) && (maxdist >= 0.0f) );
_MinDistance = mindist;
_MaxDistance = maxdist;
- if ((_SoundDriver == NULL) || !_SoundDriver->getOption(ISoundDriver::OptionManualRolloff))
- {
+// if ((_SoundDriver == NULL) || !_SoundDriver->getOption(ISoundDriver::OptionManualRolloff))
+// {
alSourcef(_Source, AL_REFERENCE_DISTANCE, mindist);
alSourcef(_Source, AL_MAX_DISTANCE, maxdist);
alTestError();
- }
+// }
}
/// Get the min and max distances
diff --git a/code/nel/src/sound/driver/openal/source_al.h b/code/nel/src/sound/driver/openal/source_al.h
index 25193952b..6fcfa288d 100644
--- a/code/nel/src/sound/driver/openal/source_al.h
+++ b/code/nel/src/sound/driver/openal/source_al.h
@@ -17,14 +17,17 @@
#ifndef NL_SOURCE_AL_H
#define NL_SOURCE_AL_H
-#include
+#include "nel/sound/driver/source.h"
-namespace NLSOUND {
+namespace NLSOUND
+{
class IBuffer;
class CBufferAL;
class CSoundDriverAL;
class CEffectAL;
+ enum TSourceType { SourceSound, SourceMusic };
+
/**
* OpenAL sound source
*
@@ -47,6 +50,10 @@ private:
/// Sound driver
CSoundDriverAL *_SoundDriver;
+ /// AL Handles
+ ALuint _Source;
+ ALuint _DirectFilter, _EffectFilter;
+
/// Assigned buffer object
CBufferAL *_Buffer;
/// Queued buffers map (uint is buffer name)
@@ -58,11 +65,10 @@ private:
uint _BuffersMax;
/// Default size of a buffer
uint _BufferSize;
-
- /// AL Handles
- ALuint _Source;
- ALuint _DirectFilter, _EffectFilter;
-
+
+ /// Position is relative to listener
+ bool _PosRelative;
+
/// Playing status
bool _IsPlaying;
bool _IsPaused;
@@ -83,6 +89,9 @@ private:
TFilter _DirectFilterType, _EffectFilterType;
bool _DirectFilterEnabled, _EffectFilterEnabled;
float _DirectFilterPassGain, _EffectFilterPassGain;
+
+ /// Source type can be SourceSound or SourceMusic
+ TSourceType _Type;
public:
/// Constructor
@@ -95,7 +104,12 @@ public:
/// Return the OpenAL source name
inline ALuint getSource() const { return _Source; }
-
+
+ /// Set type of the source
+ void setType(TSourceType type);
+ /// Get type of the source
+ TSourceType getType() const;
+
/// (Internal) Set the effect send for this source, NULL to disable.
void setEffect(CEffectAL *effect);
/// (Internal) Setup the direct send filter.