Files
NazaraEngine/src/Nazara/Audio/Audio.cpp
Gawaboumga 8336c05522 Documentation for module: Audio
Former-commit-id: acb9e00a7af8bf1c36f42b45fe7e7df99e03c0f9
2016-05-30 13:36:52 +02:00

404 lines
7.8 KiB
C++

// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Audio/Enums.hpp>
#include <Nazara/Audio/OpenAL.hpp>
#include <Nazara/Audio/SoundBuffer.hpp>
#include <Nazara/Audio/Formats/sndfileLoader.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Audio/Debug.hpp>
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)
{
case 1:
case 2:
case 4:
case 6:
case 7:
case 8:
return static_cast<AudioFormat>(channelCount);
default:
NazaraError("Invalid channel count: " + String::Number(channelCount));
return AudioFormat_Unknown;
}
}
/*!
* \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;
}
/*!
* \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];
alGetListenerfv(AL_ORIENTATION, orientation);
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;
alGetListenerfv(AL_POSITION, position);
return position;
}
/*!
* \brief Gets the rotation of the listener
* \return Rotation of the listener
*/
Quaternionf Audio::GetListenerRotation()
{
ALfloat orientation[6];
alGetListenerfv(AL_ORIENTATION, orientation);
Vector3f forward(orientation[0], orientation[1], orientation[2]);
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;
alGetListenerfv(AL_VELOCITY, velocity);
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 (IsInitialized())
{
s_moduleReferenceCounter++;
return true; // Already initialized
}
// Initialisation of dependencies
if (!Core::Initialize())
{
NazaraError("Failed to initialize core module");
return false;
}
s_moduleReferenceCounter++;
// Initialisation of the module
CallOnExit onExit(Audio::Uninitialize);
// Initialisation of OpenAL
if (!OpenAL::Initialize())
{
NazaraError("Failed to initialize OpenAL");
return false;
}
if (!SoundBuffer::Initialize())
{
NazaraError("Failed to initialize sound buffers");
return false;
}
// Definition of the orientation by default
SetListenerDirection(Vector3f::Forward());
// Loaders
Loaders::Register_sndfile();
onExit.Reset();
NazaraNotice("Initialized: Audio module");
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)
return false;
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);
}
/*!
* \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();
ALfloat orientation[6] =
{
direction.x, direction.y, direction.z,
up.x, up.y, up.z
};
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();
ALfloat orientation[6] =
{
dirX, dirY, dirZ,
up.x, up.y, up.z
};
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();
Vector3f up = Vector3f::Up();
ALfloat orientation[6] =
{
forward.x, forward.y, forward.z,
up.x, up.y, up.z
};
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)
{
// The module is still in use, or can not be uninitialized
if (s_moduleReferenceCounter > 1)
s_moduleReferenceCounter--;
return;
}
// Free of module
s_moduleReferenceCounter = 0;
// Loaders
Loaders::Unregister_sndfile();
SoundBuffer::Uninitialize();
OpenAL::Uninitialize();
NazaraNotice("Uninitialized: Audio module");
// Free of dependencies
Core::Uninitialize();
}
unsigned int Audio::s_moduleReferenceCounter = 0;
}