Documentation for module: Audio
Former-commit-id: 4546f9db5579c219d708f87b7062104d24ec6da2
This commit is contained in:
@@ -16,6 +16,21 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup audio
|
||||
* \class Nz::Audio
|
||||
* \brief Audio class that represents the module initializer of Audio
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Gets the format of the audio
|
||||
* \return AudioFormat Enumeration type for the format
|
||||
*
|
||||
* \param channelCount Number of channels
|
||||
*
|
||||
* \remark Produces a NazaraError if the number of channels is erroneous (3 or 5) and AudioFormat_Unknown is returned
|
||||
*/
|
||||
|
||||
AudioFormat Audio::GetAudioFormat(unsigned int channelCount)
|
||||
{
|
||||
switch (channelCount)
|
||||
@@ -34,19 +49,36 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the factor of the doppler effect
|
||||
* \return Global factor of the doppler effect
|
||||
*/
|
||||
|
||||
float Audio::GetDopplerFactor()
|
||||
{
|
||||
return alGetFloat(AL_DOPPLER_FACTOR);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the global volume
|
||||
* \return Float between [0, inf) with 100.f being the default
|
||||
*/
|
||||
|
||||
float Audio::GetGlobalVolume()
|
||||
{
|
||||
ALfloat gain = 0.f;
|
||||
alGetListenerf(AL_GAIN, &gain);
|
||||
|
||||
return gain*100.f;
|
||||
return gain * 100.f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the direction of the listener
|
||||
* \return Direction of the listener, in front of the listener
|
||||
*
|
||||
* \see GetListenerRotation
|
||||
*/
|
||||
|
||||
Vector3f Audio::GetListenerDirection()
|
||||
{
|
||||
ALfloat orientation[6];
|
||||
@@ -55,6 +87,13 @@ namespace Nz
|
||||
return Vector3f(orientation[0], orientation[1], orientation[2]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the listener
|
||||
* \return Position of the listener
|
||||
*
|
||||
* \see GetListenerVelocity
|
||||
*/
|
||||
|
||||
Vector3f Audio::GetListenerPosition()
|
||||
{
|
||||
Vector3f position;
|
||||
@@ -63,6 +102,11 @@ namespace Nz
|
||||
return position;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the rotation of the listener
|
||||
* \return Rotation of the listener
|
||||
*/
|
||||
|
||||
Quaternionf Audio::GetListenerRotation()
|
||||
{
|
||||
ALfloat orientation[6];
|
||||
@@ -73,6 +117,13 @@ namespace Nz
|
||||
return Quaternionf::RotationBetween(Vector3f::Forward(), forward);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the velocity of the listener
|
||||
* \return Velocity of the listener
|
||||
*
|
||||
* \see GetListenerPosition
|
||||
*/
|
||||
|
||||
Vector3f Audio::GetListenerVelocity()
|
||||
{
|
||||
Vector3f velocity;
|
||||
@@ -81,20 +132,33 @@ namespace Nz
|
||||
return velocity;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the speed of sound
|
||||
* \return Speed of sound
|
||||
*/
|
||||
|
||||
float Audio::GetSpeedOfSound()
|
||||
{
|
||||
return alGetFloat(AL_SPEED_OF_SOUND);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes the Audio module
|
||||
* \return true if initialization is successful
|
||||
*
|
||||
* \remark Produces a NazaraError if initialization of modules Core, OpenAL or SoundBuffer failed
|
||||
* \remark Produces a NazaraNotice
|
||||
*/
|
||||
|
||||
bool Audio::Initialize()
|
||||
{
|
||||
if (s_moduleReferenceCounter > 0)
|
||||
if (IsInitialized())
|
||||
{
|
||||
s_moduleReferenceCounter++;
|
||||
return true; // Déjà initialisé
|
||||
return true; // Already initialized
|
||||
}
|
||||
|
||||
// Initialisation des dépendances
|
||||
// Initialisation of dependencies
|
||||
if (!Core::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize core module");
|
||||
@@ -103,10 +167,10 @@ namespace Nz
|
||||
|
||||
s_moduleReferenceCounter++;
|
||||
|
||||
// Initialisation du module
|
||||
// Initialisation of the module
|
||||
CallOnExit onExit(Audio::Uninitialize);
|
||||
|
||||
// Initialisation d'OpenAL
|
||||
// Initialisation of OpenAL
|
||||
if (!OpenAL::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize OpenAL");
|
||||
@@ -119,7 +183,7 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
// Définition de l'orientation par défaut
|
||||
// Definition of the orientation by default
|
||||
SetListenerDirection(Vector3f::Forward());
|
||||
|
||||
// Loaders
|
||||
@@ -131,6 +195,13 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the format is supported by the engine
|
||||
* \return true if it is the case
|
||||
*
|
||||
* \param format Format to check
|
||||
*/
|
||||
|
||||
bool Audio::IsFormatSupported(AudioFormat format)
|
||||
{
|
||||
if (format == AudioFormat_Unknown)
|
||||
@@ -139,21 +210,46 @@ namespace Nz
|
||||
return OpenAL::AudioFormat[format] != 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the module is initialized
|
||||
* \return true if module is initialized
|
||||
*/
|
||||
|
||||
bool Audio::IsInitialized()
|
||||
{
|
||||
return s_moduleReferenceCounter != 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the factor of the doppler effect
|
||||
*
|
||||
* \param dopplerFactor Global factor of the doppler effect
|
||||
*/
|
||||
|
||||
void Audio::SetDopplerFactor(float dopplerFactor)
|
||||
{
|
||||
alDopplerFactor(dopplerFactor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the global volume
|
||||
*
|
||||
* \param volume Float between [0, inf) with 100.f being the default
|
||||
*/
|
||||
|
||||
void Audio::SetGlobalVolume(float volume)
|
||||
{
|
||||
alListenerf(AL_GAIN, volume*0.01f);
|
||||
alListenerf(AL_GAIN, volume * 0.01f);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the direction of the listener
|
||||
*
|
||||
* \param direction Direction of the listener, in front of the listener
|
||||
*
|
||||
* \see SetListenerDirection, SetListenerRotation
|
||||
*/
|
||||
|
||||
void Audio::SetListenerDirection(const Vector3f& direction)
|
||||
{
|
||||
Vector3f up = Vector3f::Up();
|
||||
@@ -167,6 +263,14 @@ namespace Nz
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the direction of the listener
|
||||
*
|
||||
* \param (dirX, dirY, dirZ) Direction of the listener, in front of the listener
|
||||
*
|
||||
* \see SetListenerDirection, SetListenerRotation
|
||||
*/
|
||||
|
||||
void Audio::SetListenerDirection(float dirX, float dirY, float dirZ)
|
||||
{
|
||||
Vector3f up = Vector3f::Up();
|
||||
@@ -180,16 +284,38 @@ namespace Nz
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the listener
|
||||
*
|
||||
* \param position Position of the listener
|
||||
*
|
||||
* \see SetListenerVelocity
|
||||
*/
|
||||
|
||||
void Audio::SetListenerPosition(const Vector3f& position)
|
||||
{
|
||||
alListenerfv(AL_POSITION, position);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the listener
|
||||
*
|
||||
* \param (x, y, z) Position of the listener
|
||||
*
|
||||
* \see SetListenerVelocity
|
||||
*/
|
||||
|
||||
void Audio::SetListenerPosition(float x, float y, float z)
|
||||
{
|
||||
alListener3f(AL_POSITION, x, y, z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the rotation of the listener
|
||||
*
|
||||
* \param rotation Rotation of the listener
|
||||
*/
|
||||
|
||||
void Audio::SetListenerRotation(const Quaternionf& rotation)
|
||||
{
|
||||
Vector3f forward = rotation * Vector3f::Forward();
|
||||
@@ -204,33 +330,61 @@ namespace Nz
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the velocity of the listener
|
||||
*
|
||||
* \param velocity Velocity of the listener
|
||||
*
|
||||
* \see SetListenerPosition
|
||||
*/
|
||||
|
||||
void Audio::SetListenerVelocity(const Vector3f& velocity)
|
||||
{
|
||||
alListenerfv(AL_VELOCITY, velocity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the velocity of the listener
|
||||
*
|
||||
* \param (velX, velY, velZ) Velocity of the listener
|
||||
*
|
||||
* \see SetListenerPosition
|
||||
*/
|
||||
|
||||
void Audio::SetListenerVelocity(float velX, float velY, float velZ)
|
||||
{
|
||||
alListener3f(AL_VELOCITY, velX, velY, velZ);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the speed of sound
|
||||
*
|
||||
* \param speed Speed of sound
|
||||
*/
|
||||
|
||||
void Audio::SetSpeedOfSound(float speed)
|
||||
{
|
||||
alSpeedOfSound(speed);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Uninitializes the Audio module
|
||||
*
|
||||
* \remark Produces a NazaraNotice
|
||||
*/
|
||||
|
||||
void Audio::Uninitialize()
|
||||
{
|
||||
if (s_moduleReferenceCounter != 1)
|
||||
{
|
||||
// Le module est soit encore utilisé, soit pas initialisé
|
||||
// The module is still in use, or can not be uninitialized
|
||||
if (s_moduleReferenceCounter > 1)
|
||||
s_moduleReferenceCounter--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Libération du module
|
||||
// Free of module
|
||||
s_moduleReferenceCounter = 0;
|
||||
|
||||
// Loaders
|
||||
@@ -241,7 +395,7 @@ namespace Nz
|
||||
|
||||
NazaraNotice("Uninitialized: Audio module");
|
||||
|
||||
// Libération des dépendances
|
||||
// Free of dependencies
|
||||
Core::Uninitialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,19 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup audio
|
||||
* \class Nz::Music
|
||||
* \brief Audio class that represents a music
|
||||
*
|
||||
* \remark Module Audio needs to be initialized to use this class
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the parameters for the loading of the music are correct
|
||||
* \return true If parameters are valid
|
||||
*/
|
||||
|
||||
bool MusicParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
@@ -32,11 +45,26 @@ namespace Nz
|
||||
unsigned int sampleRate;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls Destroy
|
||||
*
|
||||
* \see Destroy
|
||||
*/
|
||||
|
||||
Music::~Music()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates a music with a sound stream
|
||||
* \return true if creation was succesful
|
||||
*
|
||||
* \param soundStream Sound stream which is the source for the music
|
||||
*
|
||||
* \remark Produces a NazaraError if soundStream is invalid with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
bool Music::Create(SoundStream* soundStream)
|
||||
{
|
||||
NazaraAssert(soundStream, "Invalid stream");
|
||||
@@ -48,7 +76,7 @@ namespace Nz
|
||||
m_impl = new MusicImpl;
|
||||
m_impl->sampleRate = soundStream->GetSampleRate();
|
||||
m_impl->audioFormat = OpenAL::AudioFormat[format];
|
||||
m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples
|
||||
m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples
|
||||
m_impl->stream.reset(soundStream);
|
||||
|
||||
SetPlayingOffset(0);
|
||||
@@ -56,6 +84,10 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destroys the current music and frees resources
|
||||
*/
|
||||
|
||||
void Music::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
@@ -67,6 +99,14 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enables the looping of the music
|
||||
*
|
||||
* \param loop Should music loop
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
void Music::EnableLooping(bool loop)
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -80,6 +120,13 @@ namespace Nz
|
||||
m_impl->loop = loop;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the duration of the music
|
||||
* \return Duration of the music in milliseconds
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
UInt32 Music::GetDuration() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -93,6 +140,13 @@ namespace Nz
|
||||
return m_impl->stream->GetDuration();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the format of the music
|
||||
* \return Enumeration of type AudioFormat (mono, stereo, ...)
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
AudioFormat Music::GetFormat() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -106,6 +160,13 @@ namespace Nz
|
||||
return m_impl->stream->GetFormat();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the current offset in the music
|
||||
* \return Offset in milliseconds (works with entire seconds)
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
UInt32 Music::GetPlayingOffset() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -125,6 +186,13 @@ namespace Nz
|
||||
return static_cast<UInt32>((1000ULL * (samples + (m_impl->processedSamples / m_impl->stream->GetFormat()))) / m_impl->sampleRate);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of samples in the music
|
||||
* \return Count of samples (number of seconds * sample rate * channel count)
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
UInt32 Music::GetSampleCount() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -138,6 +206,13 @@ namespace Nz
|
||||
return m_impl->stream->GetSampleCount();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the rates of sample in the music
|
||||
* \return Rate of sample in Hertz (Hz)
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
UInt32 Music::GetSampleRate() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -151,6 +226,14 @@ namespace Nz
|
||||
return m_impl->sampleRate;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the status of the music
|
||||
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
|
||||
*
|
||||
* \remark If the music is not playing, Stopped is returned
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
SoundStatus Music::GetStatus() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -163,13 +246,20 @@ namespace Nz
|
||||
|
||||
SoundStatus status = GetInternalStatus();
|
||||
|
||||
// Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread)
|
||||
// To compensate any delays (or the timelaps between Play() and the thread startup)
|
||||
if (m_impl->streaming && status == SoundStatus_Stopped)
|
||||
status = SoundStatus_Playing;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the music is looping
|
||||
* \return true if it is the case
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
bool Music::IsLooping() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -183,26 +273,61 @@ namespace Nz
|
||||
return m_impl->loop;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the music from file
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param filePath Path to the file
|
||||
* \param params Parameters for the music
|
||||
*/
|
||||
|
||||
bool Music::OpenFromFile(const String& filePath, const MusicParams& params)
|
||||
{
|
||||
return MusicLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the music from memory
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param data Raw memory
|
||||
* \param size Size of the memory
|
||||
* \param params Parameters for the music
|
||||
*/
|
||||
|
||||
bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params)
|
||||
{
|
||||
return MusicLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the music from stream
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param stream Stream to the music
|
||||
* \param params Parameters for the music
|
||||
*/
|
||||
|
||||
bool Music::OpenFromStream(Stream& stream, const MusicParams& params)
|
||||
{
|
||||
return MusicLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pauses the music
|
||||
*/
|
||||
|
||||
void Music::Pause()
|
||||
{
|
||||
alSourcePause(m_source);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Plays the music
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
void Music::Play()
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -238,6 +363,14 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the playing offset for the music
|
||||
*
|
||||
* \param offset Offset in the music in milliseconds
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
void Music::SetPlayingOffset(UInt32 offset)
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -260,6 +393,12 @@ namespace Nz
|
||||
Play();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Stops the music
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
void Music::Stop()
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -277,6 +416,13 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Fills the buffer and queues it up
|
||||
* \return true if operation was successful
|
||||
*
|
||||
* \param buffer Index of the buffer
|
||||
*/
|
||||
|
||||
bool Music::FillAndQueueBuffer(unsigned int buffer)
|
||||
{
|
||||
unsigned int sampleCount = m_impl->chunkSamples.size();
|
||||
@@ -304,27 +450,31 @@ namespace Nz
|
||||
alSourceQueueBuffers(m_source, 1, &buffer);
|
||||
}
|
||||
|
||||
return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop)
|
||||
return sampleRead != sampleCount; // End of stream (Does not happen when looping)
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Thread function for the music
|
||||
*/
|
||||
|
||||
void Music::MusicThread()
|
||||
{
|
||||
// Allocation des buffers de streaming
|
||||
// Allocation of streaming buffers
|
||||
ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT];
|
||||
alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);
|
||||
|
||||
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i)
|
||||
{
|
||||
if (FillAndQueueBuffer(buffers[i]))
|
||||
break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers
|
||||
break; // We have reached the end of the stream, there is no use to add new buffers
|
||||
}
|
||||
|
||||
alSourcePlay(m_source);
|
||||
|
||||
// Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure)
|
||||
// Reading loop (Filling new buffers as playing)
|
||||
while (m_impl->streaming)
|
||||
{
|
||||
// La lecture s'est arrêtée, nous avons atteint la fin du stream
|
||||
// The reading has stopped, we have reached the end of the stream
|
||||
SoundStatus status = GetInternalStatus();
|
||||
if (status == SoundStatus_Stopped)
|
||||
{
|
||||
@@ -334,7 +484,7 @@ namespace Nz
|
||||
|
||||
Nz::LockGuard lock(m_impl->bufferLock);
|
||||
|
||||
// On traite les buffers lus
|
||||
// We treat read buffers
|
||||
ALint processedCount = 0;
|
||||
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount);
|
||||
while (processedCount--)
|
||||
@@ -355,14 +505,14 @@ namespace Nz
|
||||
|
||||
lock.Unlock();
|
||||
|
||||
// On retourne dormir un peu
|
||||
// We go back to sleep
|
||||
Thread::Sleep(50);
|
||||
}
|
||||
|
||||
// Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait)
|
||||
// Stop playing of the sound (in the case where it has not been already done)
|
||||
alSourceStop(m_source);
|
||||
|
||||
// On supprime les buffers du stream
|
||||
// We delete buffers from the stream
|
||||
ALint queuedBufferCount;
|
||||
alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount);
|
||||
|
||||
|
||||
@@ -23,6 +23,14 @@ namespace Nz
|
||||
ALCcontext* s_context = nullptr;
|
||||
unsigned int s_version;
|
||||
|
||||
/*!
|
||||
* \brief Parses the devices
|
||||
* \return Number of devices
|
||||
*
|
||||
* \param deviceString String for the device (input / output)
|
||||
* \param devices List of names of the devices
|
||||
*/
|
||||
|
||||
std::size_t ParseDevices(const char* deviceString, std::vector<String>& devices)
|
||||
{
|
||||
if (!deviceString)
|
||||
@@ -41,35 +49,77 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup audio
|
||||
* \class Nz::OpenAL
|
||||
* \brief Audio class that represents the link with OpenAL
|
||||
*
|
||||
* \remark This class is meant to be used by Module Audio
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Gets the entry for the function name
|
||||
* \return Pointer to the function
|
||||
*
|
||||
* \param entryPoint Name of the entry
|
||||
*
|
||||
* \remark This does not produces a NazaraError if entry does not exist
|
||||
*/
|
||||
|
||||
OpenALFunc OpenAL::GetEntry(const String& entryPoint)
|
||||
{
|
||||
return LoadEntry(entryPoint.GetConstBuffer(), false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the name of the renderer
|
||||
* \return Name of the renderer
|
||||
*/
|
||||
|
||||
String OpenAL::GetRendererName()
|
||||
{
|
||||
return s_rendererName;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the name of the vendor
|
||||
* \return Name of the vendor
|
||||
*/
|
||||
|
||||
String OpenAL::GetVendorName()
|
||||
{
|
||||
return s_vendorName;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the version of OpenAL
|
||||
* \return Version of OpenAL
|
||||
*/
|
||||
|
||||
unsigned int OpenAL::GetVersion()
|
||||
{
|
||||
return s_version;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes the module OpenAL
|
||||
* \return true if initialization is successful
|
||||
*
|
||||
* \param openDevice True to get information from the device
|
||||
*
|
||||
* \remark Produces a NazaraError if one of the entry failed
|
||||
* \remark Produces a NazaraError if opening device failed with openDevice parameter set to true
|
||||
*/
|
||||
|
||||
bool OpenAL::Initialize(bool openDevice)
|
||||
{
|
||||
if (s_library.IsLoaded())
|
||||
if (IsInitialized())
|
||||
return true;
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
///FIXME: Est-ce qu'OpenAL Soft est une meilleure implémentation que Creative ?
|
||||
/// Si on pouvait se résigner à utiliser OpenAL Soft tout le temps, cela nous permettrait d'utiliser les extensions sonores
|
||||
/// et de donner plus de possibilités techniques au niveau de l'audio.
|
||||
///FIXME: Is OpenAL Soft a better implementation than Creative ?
|
||||
/// If we could use OpenAL Soft everytime, this would allow us to use sonorous extensions
|
||||
/// and give us more technical possibilities with audio
|
||||
const char* libs[] = {
|
||||
"soft_oal.dll",
|
||||
"wrap_oal.dll",
|
||||
@@ -217,11 +267,23 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the module is initialized
|
||||
* \return true if it is the case
|
||||
*/
|
||||
|
||||
bool OpenAL::IsInitialized()
|
||||
{
|
||||
return s_library.IsLoaded();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Queries the input devices
|
||||
* \return Number of devices
|
||||
*
|
||||
* \param devices List of names of the input devices
|
||||
*/
|
||||
|
||||
std::size_t OpenAL::QueryInputDevices(std::vector<String>& devices)
|
||||
{
|
||||
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER));
|
||||
@@ -231,6 +293,13 @@ namespace Nz
|
||||
return ParseDevices(deviceString, devices);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Queries the output devices
|
||||
* \return Number of devices
|
||||
*
|
||||
* \param devices List of names of the output devices
|
||||
*/
|
||||
|
||||
std::size_t OpenAL::QueryOutputDevices(std::vector<String>& devices)
|
||||
{
|
||||
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER));
|
||||
@@ -240,6 +309,13 @@ namespace Nz
|
||||
return ParseDevices(deviceString, devices);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the active device
|
||||
* \return true if device is successfully opened
|
||||
*
|
||||
* \param deviceName Name of the device
|
||||
*/
|
||||
|
||||
bool OpenAL::SetDevice(const String& deviceName)
|
||||
{
|
||||
s_deviceName = deviceName;
|
||||
@@ -253,6 +329,10 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Uninitializes the module
|
||||
*/
|
||||
|
||||
void OpenAL::Uninitialize()
|
||||
{
|
||||
CloseDevice();
|
||||
@@ -262,8 +342,14 @@ namespace Nz
|
||||
s_library.Unload();
|
||||
}
|
||||
|
||||
///ATTENTION: La valeur entière est le nombre de canaux possédés par ce format
|
||||
ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Valeur ajoutées au chargement d'OpenAL
|
||||
///WARNING: The integer value is the number of canals owned by the format
|
||||
ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Added values with loading of OpenAL
|
||||
|
||||
/*!
|
||||
* \brief Closes the device
|
||||
*
|
||||
* \remark Produces a NazaraWarning if you try to close an active device
|
||||
*/
|
||||
|
||||
void OpenAL::CloseDevice()
|
||||
{
|
||||
@@ -277,24 +363,31 @@ namespace Nz
|
||||
}
|
||||
|
||||
if (!alcCloseDevice(s_device))
|
||||
// Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation
|
||||
// We could not close the close, this means that it's still in use
|
||||
NazaraWarning("Failed to close device");
|
||||
|
||||
s_device = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Opens the device
|
||||
* \return true if open is successful
|
||||
*
|
||||
* \remark Produces a NazaraError if it could not create the context
|
||||
*/
|
||||
|
||||
bool OpenAL::OpenDevice()
|
||||
{
|
||||
// Initialisation du module
|
||||
s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // On choisit le device par défaut
|
||||
// Initialisation of the module
|
||||
s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // We choose the default device
|
||||
if (!s_device)
|
||||
{
|
||||
NazaraError("Failed to open default device");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Un seul contexte nous suffira
|
||||
// One context is enough
|
||||
s_context = alcCreateContext(s_device, nullptr);
|
||||
if (!s_context)
|
||||
{
|
||||
@@ -341,7 +434,7 @@ namespace Nz
|
||||
s_version = 0;
|
||||
}
|
||||
|
||||
// On complète le tableau de formats
|
||||
// We complete the formats table
|
||||
AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16;
|
||||
AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16;
|
||||
|
||||
@@ -359,6 +452,16 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the entry for the function name
|
||||
* \return Pointer to the function
|
||||
*
|
||||
* \param name Name of the entry
|
||||
* \param throwException Should throw exception if failed ?
|
||||
*
|
||||
* \remark Produces a std::runtime_error if entry does not exist and throwException is set to true
|
||||
*/
|
||||
|
||||
OpenALFunc OpenAL::LoadEntry(const char* name, bool throwException)
|
||||
{
|
||||
OpenALFunc entry = reinterpret_cast<OpenALFunc>(s_library.GetSymbol(name));
|
||||
|
||||
@@ -14,32 +14,76 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup audio
|
||||
* \class Nz::Sound
|
||||
* \brief Audio class that represents a sound
|
||||
*
|
||||
* \remark Module Audio needs to be initialized to use this class
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sound object
|
||||
*
|
||||
* \param soundBuffer Buffer to read sound from
|
||||
*/
|
||||
|
||||
Sound::Sound(const SoundBuffer* soundBuffer)
|
||||
{
|
||||
SetBuffer(soundBuffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sound object which is a copy of another
|
||||
*
|
||||
* \param sound Sound to copy
|
||||
*/
|
||||
|
||||
Sound::Sound(const Sound& sound) :
|
||||
SoundEmitter(sound)
|
||||
{
|
||||
SetBuffer(sound.m_buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls Stop
|
||||
*
|
||||
* \see Stop
|
||||
*/
|
||||
|
||||
Sound::~Sound()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enables the looping of the music
|
||||
*
|
||||
* \param loop Should sound loop
|
||||
*/
|
||||
|
||||
void Sound::EnableLooping(bool loop)
|
||||
{
|
||||
alSourcei(m_source, AL_LOOPING, loop);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the internal buffer
|
||||
* \return Internal buffer
|
||||
*/
|
||||
|
||||
const SoundBuffer* Sound::GetBuffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the duration of the sound
|
||||
* \return Duration of the music in milliseconds
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no buffer
|
||||
*/
|
||||
|
||||
UInt32 Sound::GetDuration() const
|
||||
{
|
||||
NazaraAssert(m_buffer, "Invalid sound buffer");
|
||||
@@ -47,6 +91,11 @@ namespace Nz
|
||||
return m_buffer->GetDuration();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the current offset in the sound
|
||||
* \return Offset in milliseconds (works with entire seconds)
|
||||
*/
|
||||
|
||||
UInt32 Sound::GetPlayingOffset() const
|
||||
{
|
||||
ALint samples = 0;
|
||||
@@ -55,11 +104,21 @@ namespace Nz
|
||||
return static_cast<UInt32>(1000ULL * samples / m_buffer->GetSampleRate());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the status of the music
|
||||
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
|
||||
*/
|
||||
|
||||
SoundStatus Sound::GetStatus() const
|
||||
{
|
||||
return GetInternalStatus();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the sound is looping
|
||||
* \return true if it is the case
|
||||
*/
|
||||
|
||||
bool Sound::IsLooping() const
|
||||
{
|
||||
ALint loop;
|
||||
@@ -68,16 +127,36 @@ namespace Nz
|
||||
return loop != AL_FALSE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the sound is playable
|
||||
* \return true if it is the case
|
||||
*/
|
||||
|
||||
bool Sound::IsPlayable() const
|
||||
{
|
||||
return m_buffer != nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the sound is playing
|
||||
* \return true if it is the case
|
||||
*/
|
||||
|
||||
bool Sound::IsPlaying() const
|
||||
{
|
||||
return GetStatus() == SoundStatus_Playing;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the sound from file
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param filePath Path to the file
|
||||
* \param params Parameters for the sound
|
||||
*
|
||||
* \remark Produces a NazaraError if loading failed
|
||||
*/
|
||||
|
||||
bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params)
|
||||
{
|
||||
SoundBufferRef buffer = SoundBuffer::New();
|
||||
@@ -91,6 +170,17 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the sound from memory
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param data Raw memory
|
||||
* \param size Size of the memory
|
||||
* \param params Parameters for the sound
|
||||
*
|
||||
* \remark Produces a NazaraError if loading failed
|
||||
*/
|
||||
|
||||
bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
||||
{
|
||||
SoundBufferRef buffer = SoundBuffer::New();
|
||||
@@ -104,6 +194,16 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the sound from stream
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param stream Stream to the sound
|
||||
* \param params Parameters for the sound
|
||||
*
|
||||
* \remark Produces a NazaraError if loading failed
|
||||
*/
|
||||
|
||||
bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
||||
{
|
||||
SoundBufferRef buffer = SoundBuffer::New();
|
||||
@@ -117,15 +217,25 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pauses the sound
|
||||
*/
|
||||
|
||||
void Sound::Pause()
|
||||
{
|
||||
alSourcePause(m_source);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Plays the music
|
||||
*
|
||||
* \remark Produces a NazaraError if the sound is not playable with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
void Sound::Play()
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_buffer)
|
||||
if (!IsPlayable())
|
||||
{
|
||||
NazaraError("Invalid sound buffer");
|
||||
return;
|
||||
@@ -135,6 +245,14 @@ namespace Nz
|
||||
alSourcePlay(m_source);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the internal buffer
|
||||
*
|
||||
* \param buffer Internal buffer
|
||||
*
|
||||
* \remark Produces a NazaraError if buffer is invalid with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
void Sound::SetBuffer(const SoundBuffer* buffer)
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -158,11 +276,21 @@ namespace Nz
|
||||
alSourcei(m_source, AL_BUFFER, AL_NONE);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the playing offset for the sound
|
||||
*
|
||||
* \param offset Offset in the sound in milliseconds
|
||||
*/
|
||||
|
||||
void Sound::SetPlayingOffset(UInt32 offset)
|
||||
{
|
||||
alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast<ALint>(offset/1000.f * m_buffer->GetSampleRate()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Stops the sound
|
||||
*/
|
||||
|
||||
void Sound::Stop()
|
||||
{
|
||||
alSourceStop(m_source);
|
||||
|
||||
@@ -12,10 +12,23 @@
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
///FIXME: Adapter la création
|
||||
///FIXME: Adapt the creation
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup audio
|
||||
* \class Nz::SoundBuffer
|
||||
* \brief Audio class that represents a buffer for sound
|
||||
*
|
||||
* \remark Module Audio needs to be initialized to use this class
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the parameters for the buffer' sound are correct
|
||||
* \return true If parameters are valid
|
||||
*/
|
||||
|
||||
bool SoundBufferParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
@@ -31,6 +44,20 @@ namespace Nz
|
||||
UInt32 sampleRate;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Constructs a SoundBuffer object
|
||||
*
|
||||
* \param format Format for the audio
|
||||
* \param sampleCount Number of samples
|
||||
* \param sampleRate Rate of samples
|
||||
* \param samples Samples raw data
|
||||
*
|
||||
* \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined
|
||||
* \remark Produces a std::runtime_error if creation went wrong with NAZARA_AUDIO_SAFE defined
|
||||
*
|
||||
* \see Create
|
||||
*/
|
||||
|
||||
SoundBuffer::SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
|
||||
{
|
||||
Create(format, sampleCount, sampleRate, samples);
|
||||
@@ -44,6 +71,12 @@ namespace Nz
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls Destroy
|
||||
*
|
||||
* \see Destroy
|
||||
*/
|
||||
|
||||
SoundBuffer::~SoundBuffer()
|
||||
{
|
||||
OnSoundBufferRelease(this);
|
||||
@@ -51,6 +84,19 @@ namespace Nz
|
||||
Destroy();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates the SoundBuffer object
|
||||
* \return true if creation is successful
|
||||
*
|
||||
* \param format Format for the audio
|
||||
* \param sampleCount Number of samples
|
||||
* \param sampleRate Rate of samples
|
||||
* \param samples Samples raw data
|
||||
*
|
||||
* \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined,
|
||||
* this could happen if parameters are invalid or creation of OpenAL buffers failed
|
||||
*/
|
||||
|
||||
bool SoundBuffer::Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
|
||||
{
|
||||
Destroy();
|
||||
@@ -81,7 +127,7 @@ namespace Nz
|
||||
}
|
||||
#endif
|
||||
|
||||
// On vide le stack d'erreurs
|
||||
// We empty the error stack
|
||||
while (alGetError() != AL_NO_ERROR);
|
||||
|
||||
ALuint buffer;
|
||||
@@ -115,6 +161,10 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destroys the current sound buffer and frees resources
|
||||
*/
|
||||
|
||||
void SoundBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
@@ -126,6 +176,13 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the duration of the sound buffer
|
||||
* \return Duration of the sound buffer in milliseconds
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
UInt32 SoundBuffer::GetDuration() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -139,6 +196,13 @@ namespace Nz
|
||||
return m_impl->duration;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the format of the sound buffer
|
||||
* \return Enumeration of type AudioFormat (mono, stereo, ...)
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
AudioFormat SoundBuffer::GetFormat() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -152,6 +216,13 @@ namespace Nz
|
||||
return m_impl->format;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the internal raw samples
|
||||
* \return Pointer to raw data
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
const Int16* SoundBuffer::GetSamples() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -165,6 +236,13 @@ namespace Nz
|
||||
return m_impl->samples.get();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of samples in the sound buffer
|
||||
* \return Count of samples (number of seconds * sample rate * channel count)
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
unsigned int SoundBuffer::GetSampleCount() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -178,6 +256,13 @@ namespace Nz
|
||||
return m_impl->sampleCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the rates of sample in the sound buffer
|
||||
* \return Rate of sample in Hertz (Hz)
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
unsigned int SoundBuffer::GetSampleRate() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
@@ -191,31 +276,75 @@ namespace Nz
|
||||
return m_impl->sampleRate;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the sound buffer is valid
|
||||
* \return true if it is the case
|
||||
*/
|
||||
|
||||
bool SoundBuffer::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the sound buffer from file
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param filePath Path to the file
|
||||
* \param params Parameters for the sound buffer
|
||||
*/
|
||||
|
||||
bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params)
|
||||
{
|
||||
return SoundBufferLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the sound buffer from memory
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param data Raw memory
|
||||
* \param size Size of the memory
|
||||
* \param params Parameters for the sound buffer
|
||||
*/
|
||||
|
||||
bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
||||
{
|
||||
return SoundBufferLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the sound buffer from stream
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param stream Stream to the sound buffer
|
||||
* \param params Parameters for the sound buffer
|
||||
*/
|
||||
|
||||
bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
||||
{
|
||||
return SoundBufferLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the format is supported by the engine
|
||||
* \return true if it is the case
|
||||
*
|
||||
* \param format Format to check
|
||||
*/
|
||||
|
||||
bool SoundBuffer::IsFormatSupported(AudioFormat format)
|
||||
{
|
||||
return Audio::IsFormatSupported(format);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the internal OpenAL buffer
|
||||
* \return The index of the OpenAL buffer
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
|
||||
unsigned int SoundBuffer::GetOpenALBuffer() const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
@@ -229,6 +358,13 @@ namespace Nz
|
||||
return m_impl->buffer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes the libraries and managers
|
||||
* \return true if initialization is successful
|
||||
*
|
||||
* \remark Produces a NazaraError if sub-initialization failed
|
||||
*/
|
||||
|
||||
bool SoundBuffer::Initialize()
|
||||
{
|
||||
if (!SoundBufferLibrary::Initialize())
|
||||
@@ -246,6 +382,10 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Uninitializes the libraries and managers
|
||||
*/
|
||||
|
||||
void SoundBuffer::Uninitialize()
|
||||
{
|
||||
SoundBufferManager::Uninitialize();
|
||||
|
||||
@@ -11,11 +11,32 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup audio
|
||||
* \class Nz::SoundEmitter
|
||||
* \brief Audio class that represents a sound source, that emits sound
|
||||
*
|
||||
* \remark Module Audio needs to be initialized to use this class
|
||||
* \remark This class is abstract
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a SoundEmitter object
|
||||
*/
|
||||
|
||||
SoundEmitter::SoundEmitter()
|
||||
{
|
||||
alGenSources(1, &m_source);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a SoundEmitter object which is a copy of another
|
||||
*
|
||||
* \param emitter SoundEmitter to copy
|
||||
*
|
||||
* \remark Position and velocity are not copied
|
||||
*/
|
||||
|
||||
SoundEmitter::SoundEmitter(const SoundEmitter& emitter)
|
||||
{
|
||||
alGenSources(1, &m_source);
|
||||
@@ -23,20 +44,35 @@ namespace Nz
|
||||
SetAttenuation(emitter.GetAttenuation());
|
||||
SetMinDistance(emitter.GetMinDistance());
|
||||
SetPitch(emitter.GetPitch());
|
||||
// Pas de copie de position ou de vitesse
|
||||
// No copy for position or velocity
|
||||
SetVolume(emitter.GetVolume());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object
|
||||
*/
|
||||
|
||||
SoundEmitter::~SoundEmitter()
|
||||
{
|
||||
alDeleteSources(1, &m_source);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enables spatialization
|
||||
*
|
||||
* \param spatialization True if spatialization is enabled
|
||||
*/
|
||||
|
||||
void SoundEmitter::EnableSpatialization(bool spatialization)
|
||||
{
|
||||
alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the attenuation
|
||||
* \return Amount that your sound will drop off as by the inverse square law
|
||||
*/
|
||||
|
||||
float SoundEmitter::GetAttenuation() const
|
||||
{
|
||||
ALfloat attenuation;
|
||||
@@ -45,6 +81,11 @@ namespace Nz
|
||||
return attenuation;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the minimum distance to hear
|
||||
* \return Distance to begin to hear
|
||||
*/
|
||||
|
||||
float SoundEmitter::GetMinDistance() const
|
||||
{
|
||||
ALfloat distance;
|
||||
@@ -53,6 +94,11 @@ namespace Nz
|
||||
return distance;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the pitch
|
||||
* \return Pitch of the sound
|
||||
*/
|
||||
|
||||
float SoundEmitter::GetPitch() const
|
||||
{
|
||||
ALfloat pitch;
|
||||
@@ -61,6 +107,11 @@ namespace Nz
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the emitter
|
||||
* \return Position of the sound
|
||||
*/
|
||||
|
||||
Vector3f SoundEmitter::GetPosition() const
|
||||
{
|
||||
Vector3f position;
|
||||
@@ -69,6 +120,11 @@ namespace Nz
|
||||
return position;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the velocity of the emitter
|
||||
* \return Velocity of the sound
|
||||
*/
|
||||
|
||||
Vector3f SoundEmitter::GetVelocity() const
|
||||
{
|
||||
Vector3f velocity;
|
||||
@@ -77,6 +133,11 @@ namespace Nz
|
||||
return velocity;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the volume of the emitter
|
||||
* \param volume Float between [0, inf) with 100.f being the default
|
||||
*/
|
||||
|
||||
float SoundEmitter::GetVolume() const
|
||||
{
|
||||
ALfloat gain;
|
||||
@@ -85,6 +146,11 @@ namespace Nz
|
||||
return gain * 100.f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the sound emitter has spatialization enabled
|
||||
* \return true if it the case
|
||||
*/
|
||||
|
||||
bool SoundEmitter::IsSpatialized() const
|
||||
{
|
||||
ALint relative;
|
||||
@@ -93,46 +159,99 @@ namespace Nz
|
||||
return relative == AL_FALSE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the attenuation
|
||||
*
|
||||
* \param attenuation Amount that your sound will drop off as by the inverse square law
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetAttenuation(float attenuation)
|
||||
{
|
||||
alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the minimum distance to hear
|
||||
*
|
||||
* \param minDistance to begin to hear
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetMinDistance(float minDistance)
|
||||
{
|
||||
alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the pitch
|
||||
*
|
||||
* \param pitch of the sound
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetPitch(float pitch)
|
||||
{
|
||||
alSourcef(m_source, AL_PITCH, pitch);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the emitter
|
||||
*
|
||||
* \param position Position of the sound
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetPosition(const Vector3f& position)
|
||||
{
|
||||
alSourcefv(m_source, AL_POSITION, position);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the emitter
|
||||
*
|
||||
* \param position Position of the sound with (x, y, z)
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetPosition(float x, float y, float z)
|
||||
{
|
||||
alSource3f(m_source, AL_POSITION, x, y, z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the velocity of the emitter
|
||||
*
|
||||
* \param velocity Velocity of the sound
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetVelocity(const Vector3f& velocity)
|
||||
{
|
||||
alSourcefv(m_source, AL_VELOCITY, velocity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the velocity of the emitter
|
||||
*
|
||||
* \param velocity Velocity with (velX, velY, velZ)
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetVelocity(float velX, float velY, float velZ)
|
||||
{
|
||||
alSource3f(m_source, AL_VELOCITY, velX, velY, velZ);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the volume of the emitter
|
||||
*
|
||||
* \param volume Float between [0, inf) with 100.f being the default
|
||||
*/
|
||||
|
||||
void SoundEmitter::SetVolume(float volume)
|
||||
{
|
||||
alSourcef(m_source, AL_GAIN, volume*0.01f);
|
||||
alSourcef(m_source, AL_GAIN, volume * 0.01f);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the status of the sound emitter
|
||||
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
|
||||
*/
|
||||
|
||||
SoundStatus SoundEmitter::GetInternalStatus() const
|
||||
{
|
||||
ALint state;
|
||||
|
||||
@@ -6,5 +6,13 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup audio
|
||||
* \class Nz::SoundStream
|
||||
* \brief Audio class that represents a sound stream
|
||||
*
|
||||
* \remark This class is abstract
|
||||
*/
|
||||
|
||||
SoundStream::~SoundStream() = default;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user