Added Audio module
Fixed examples resources not being commited Temporary removed static build configurations
This commit is contained in:
parent
71b777e732
commit
40ec2003b4
|
|
@ -1,5 +1,6 @@
|
|||
# Codeblocks
|
||||
*.cbp
|
||||
*.cbTemp
|
||||
*.cscope_file_list
|
||||
*.depend
|
||||
*.layout
|
||||
|
|
@ -126,7 +127,6 @@ publish
|
|||
*.Publish.xml
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
-- Configuration générale
|
||||
configurations
|
||||
{
|
||||
"DebugStatic",
|
||||
"ReleaseStatic",
|
||||
-- "DebugStatic",
|
||||
-- "ReleaseStatic",
|
||||
"DebugDLL",
|
||||
"ReleaseDLL"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
-- Configuration générale
|
||||
configurations
|
||||
{
|
||||
"DebugStatic",
|
||||
"ReleaseStatic",
|
||||
-- "DebugStatic",
|
||||
-- "ReleaseStatic",
|
||||
"DebugDLL",
|
||||
"ReleaseDLL"
|
||||
}
|
||||
|
|
@ -10,10 +10,18 @@ configurations
|
|||
language "C++"
|
||||
location("../examples/build/" .. _ACTION)
|
||||
|
||||
debugdir "../examples/bin"
|
||||
|
||||
includedirs "../include"
|
||||
|
||||
debugdir "../examples/bin"
|
||||
libdirs "../lib"
|
||||
|
||||
if (_OPTIONS["x64"]) then
|
||||
libdirs "../extlibs/lib/x64"
|
||||
end
|
||||
|
||||
libdirs "../extlibs/lib/x86"
|
||||
|
||||
targetdir "../examples/bin"
|
||||
|
||||
configuration "Debug*"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
if (not _OPTIONS["one-library"]) then
|
||||
project "NazaraAudio"
|
||||
end
|
||||
|
||||
files
|
||||
{
|
||||
"../include/Nazara/Audio/**.hpp",
|
||||
"../include/Nazara/Audio/**.inl",
|
||||
"../src/Nazara/Audio/**.hpp",
|
||||
"../src/Nazara/Audio/**.cpp"
|
||||
}
|
||||
|
||||
if (os.is("windows")) then
|
||||
excludes { "../src/Nazara/Audio/Posix/*.hpp", "../src/Nazara/Audio/Posix/*.cpp" }
|
||||
links "OpenAL32"
|
||||
links "sndfile-1"
|
||||
else
|
||||
excludes { "../src/Nazara/Audio/Win32/*.hpp", "../src/Nazara/Audio/Win32/*.cpp" }
|
||||
-- Link posix ?
|
||||
end
|
||||
|
||||
if (_OPTIONS["one-library"]) then
|
||||
excludes "../src/Nazara/Audio/Debug/Leaks.cpp"
|
||||
else
|
||||
configuration "DebugStatic"
|
||||
links "NazaraCore-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "NazaraCore-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraCore-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraCore"
|
||||
end
|
||||
|
|
@ -27,8 +27,8 @@ else
|
|||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraRenderer-d"
|
||||
links "NazaraCore-d"
|
||||
links "NazaraUtility-d"
|
||||
links "NazaraCore-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraRenderer"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
kind "ConsoleApp"
|
||||
|
||||
files "main.cpp"
|
||||
|
||||
if (_OPTIONS["one-library"]) then
|
||||
configuration "DebugStatic"
|
||||
links "NazaraEngine-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "NazaraEngine-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraEngine-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraEngine"
|
||||
else
|
||||
configuration "DebugStatic"
|
||||
links "NazaraAudio-s-d"
|
||||
links "NazaraUtility-s-d"
|
||||
links "NazaraCore-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "NazaraAudio-s"
|
||||
links "NazaraUtility-s"
|
||||
links "NazaraCore-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraAudio-d"
|
||||
links "NazaraUtility-d"
|
||||
links "NazaraCore-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraAudio"
|
||||
links "NazaraUtility"
|
||||
links "NazaraCore"
|
||||
end
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#include <Nazara/Audio.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/Thread.hpp> // Thread::Sleep
|
||||
#include <Nazara/Utility/Keyboard.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
// NzKeyboard ne nécessite pas l'initialisation d'Utility
|
||||
NzInitializer<NzAudio> audio;
|
||||
if (!audio)
|
||||
{
|
||||
std::cout << "Failed to initialize audio module" << std::endl;
|
||||
std::getchar();
|
||||
return 1;
|
||||
}
|
||||
|
||||
NzSound sound;
|
||||
if (!sound.LoadFromFile("resources/siren.wav"))
|
||||
{
|
||||
std::cout << "Failed to load sound" << std::endl;
|
||||
std::getchar();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Demonstration de l'effet doppler avec Nazara" << std::endl;
|
||||
std::cout << "Appuyez sur entree pour demarrer" << std::endl;
|
||||
std::cout << "Appuyez sur echap pour arreter" << std::endl;
|
||||
|
||||
std::getchar();
|
||||
|
||||
// On fait en sorte de répéter le son
|
||||
sound.EnableLooping(true);
|
||||
|
||||
// La source du son se situe en (50, 0, 5)
|
||||
sound.SetPosition(50, 0, 5);
|
||||
|
||||
// Et possède une vitesse de -10 par seconde sur l'axe X
|
||||
sound.SetVelocity(-10, 0, 0);
|
||||
|
||||
// On joue le son
|
||||
sound.Play();
|
||||
|
||||
// La boucle du programme (Pour déplacer le son)
|
||||
NzClock clock;
|
||||
while (sound.GetStatus() == nzSoundStatus_Playing)
|
||||
{
|
||||
// Comme le son se joue dans un thread séparé, on peut mettre en pause celui-ci régulièrement
|
||||
int sleepTime = 1000/60 - clock.GetMilliseconds(); // 60 FPS
|
||||
|
||||
if (sleepTime > 0)
|
||||
NzThread::Sleep(sleepTime);
|
||||
|
||||
// On bouge la source du son en fonction du au temps depuis chaque mise à jour
|
||||
NzVector3f pos = sound.GetPosition() + sound.GetVelocity()*clock.GetSeconds();
|
||||
sound.SetPosition(pos);
|
||||
|
||||
std::cout << "Sound position: " << pos << std::endl;
|
||||
|
||||
// Si la position de la source atteint une certaine position, ou si l'utilisateur appuie sur echap
|
||||
if (pos.x < -50.f || NzKeyboard::IsKeyPressed(NzKeyboard::Escape))
|
||||
sound.Stop(); // On arrête le son (Stoppant également la boucle)
|
||||
|
||||
clock.Restart();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -16,18 +16,18 @@ if (_OPTIONS["one-library"]) then
|
|||
links "NazaraEngine"
|
||||
else
|
||||
configuration "DebugStatic"
|
||||
links "NazaraCore-s-d"
|
||||
links "NazaraUtility-s-d"
|
||||
links "NazaraCore-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "NazaraCore-s"
|
||||
links "NazaraUtility-s"
|
||||
links "NazaraCore-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraCore-d"
|
||||
links "NazaraUtility-d"
|
||||
links "NazaraCore-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraCore"
|
||||
links "NazaraUtility"
|
||||
links "NazaraCore"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
#version 110
|
||||
|
||||
varying vec2 TexCoord;
|
||||
|
||||
uniform sampler2D texture;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(texture, TexCoord);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#version 110
|
||||
|
||||
attribute vec3 Position;
|
||||
attribute vec2 TexCoord0;
|
||||
|
||||
uniform mat4 WorldViewProjMatrix;
|
||||
|
||||
varying vec2 TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = WorldViewProjMatrix * vec4(Position, 1.0);
|
||||
TexCoord = TexCoord0;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// This file was automatically generated by Nazara
|
||||
|
||||
/*
|
||||
Nazara Engine - Audio module
|
||||
|
||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Audio/Music.hpp>
|
||||
#include <Nazara/Audio/Sound.hpp>
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <Nazara/Audio/SoundEmitter.hpp>
|
||||
#include <Nazara/Audio/SoundStream.hpp>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2012 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_AUDIO_HPP
|
||||
#define NAZARA_AUDIO_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/Initializer.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
class NAZARA_API NzAudio
|
||||
{
|
||||
friend class NzMusic;
|
||||
friend class NzSoundBuffer;
|
||||
|
||||
public:
|
||||
NzAudio() = delete;
|
||||
~NzAudio() = delete;
|
||||
|
||||
static nzAudioFormat GetAudioFormat(unsigned int channelCount);
|
||||
static float GetDopplerFactor();
|
||||
static float GetGlobalVolume();
|
||||
static NzVector3f GetListenerDirection();
|
||||
static NzVector3f GetListenerPosition();
|
||||
//static NzQuaternionf GetListenerRotation();
|
||||
static NzVector3f GetListenerVelocity();
|
||||
static float GetSpeedOfSound();
|
||||
|
||||
static bool Initialize();
|
||||
|
||||
static bool IsFormatSupported(nzAudioFormat format);
|
||||
static bool IsInitialized();
|
||||
|
||||
static void SetDopplerFactor(float dopplerFactor);
|
||||
static void SetGlobalVolume(float volume);
|
||||
static void SetListenerDirection(const NzVector3f& direction);
|
||||
static void SetListenerDirection(float dirX, float dirY, float dirZ);
|
||||
static void SetListenerPosition(const NzVector3f& position);
|
||||
static void SetListenerPosition(float x, float y, float z);
|
||||
//static void SetListenerRotation(const NzQuaternionf& rotation);
|
||||
static void SetListenerVelocity(const NzVector3f& velocity);
|
||||
static void SetListenerVelocity(float velX, float velY, float velZ);
|
||||
static void SetSpeedOfSound(float speed);
|
||||
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
static unsigned int GetOpenALFormat(nzAudioFormat format);
|
||||
|
||||
static unsigned int s_moduleReferenceCouter;
|
||||
};
|
||||
|
||||
#endif // NAZARA_AUDIO_HPP
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Nazara Engine - Audio module
|
||||
|
||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_AUDIO_HPP
|
||||
#define NAZARA_CONFIG_AUDIO_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||
#define NAZARA_AUDIO_MEMORYLEAKTRACKER 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_AUDIO_SAFE 1
|
||||
|
||||
// Le nombre de buffers utilisés lors du streaming d'objets audio (Au moins deux)
|
||||
#define NAZARA_AUDIO_STREAMEDBUFFERCOUNT 2
|
||||
|
||||
#endif // NAZARA_CONFIG_AUDIO_HPP
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2012 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/Config.hpp>
|
||||
#if NAZARA_AUDIO_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
|
||||
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
|
||||
|
||||
#define delete NzMemoryManager::NextFree(__FILE__, __LINE__), delete
|
||||
#define new new(__FILE__, __LINE__)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (C) 2012 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
|
||||
|
||||
#if NAZARA_AUDIO_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
|
||||
#undef delete
|
||||
#undef new
|
||||
#endif
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (C) 2012 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_ENUMS_HPP
|
||||
#define NAZARA_ENUMS_HPP
|
||||
|
||||
enum nzAudioFormat
|
||||
{
|
||||
nzAudioFormat_Unknown = -1,
|
||||
|
||||
// La valeur entière est le nombre de canaux possédés par ce format
|
||||
nzAudioFormat_Mono = 1,
|
||||
nzAudioFormat_Stereo = 2,
|
||||
nzAudioFormat_Quad = 4,
|
||||
nzAudioFormat_5_1 = 6,
|
||||
nzAudioFormat_6_1 = 7,
|
||||
nzAudioFormat_7_1 = 8,
|
||||
|
||||
nzAudioFormat_Max = nzAudioFormat_7_1
|
||||
};
|
||||
|
||||
enum nzSoundStatus
|
||||
{
|
||||
nzSoundStatus_Playing,
|
||||
nzSoundStatus_Paused,
|
||||
nzSoundStatus_Stopped
|
||||
};
|
||||
|
||||
#endif // NAZARA_ENUMS_HPP
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (C) 2012 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SOUND_HPP
|
||||
#define NAZARA_SOUND_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <Nazara/Audio/SoundEmitter.hpp>
|
||||
|
||||
class NAZARA_API NzSound : public NzSoundEmitter
|
||||
{
|
||||
public:
|
||||
NzSound() = default;
|
||||
NzSound(const NzSoundBuffer* soundBuffer);
|
||||
NzSound(const NzSound& sound);
|
||||
~NzSound();
|
||||
|
||||
void EnableLooping(bool loop);
|
||||
|
||||
const NzSoundBuffer* GetBuffer() const;
|
||||
nzUInt32 GetDuration() const;
|
||||
nzUInt32 GetPlayingOffset() const;
|
||||
nzSoundStatus GetStatus() const;
|
||||
|
||||
bool IsLooping() const;
|
||||
|
||||
bool LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params = NzSoundBufferParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params = NzSoundBufferParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params = NzSoundBufferParams());
|
||||
|
||||
void Pause();
|
||||
bool Play();
|
||||
|
||||
void SetBuffer(const NzSoundBuffer* buffer);
|
||||
void SetPlayingOffset(nzUInt32 offset);
|
||||
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
const NzSoundBuffer* m_buffer = nullptr;
|
||||
};
|
||||
|
||||
#endif // NAZARA_SOUND_HPP
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (C) 2012 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SOUNDBUFFER_HPP
|
||||
#define NAZARA_SOUNDBUFFER_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
|
||||
struct NzSoundBufferParams
|
||||
{
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class NzSound;
|
||||
class NzSoundBuffer;
|
||||
|
||||
using NzSoundBufferLoader = NzResourceLoader<NzSoundBuffer, NzSoundBufferParams>;
|
||||
|
||||
struct NzSoundBufferImpl;
|
||||
|
||||
class NAZARA_API NzSoundBuffer : public NzResource, public NzNonCopyable
|
||||
{
|
||||
friend NzSound;
|
||||
friend NzSoundBufferLoader;
|
||||
|
||||
public:
|
||||
NzSoundBuffer() = default;
|
||||
NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples);
|
||||
~NzSoundBuffer();
|
||||
|
||||
bool Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples);
|
||||
void Destroy();
|
||||
|
||||
nzUInt32 GetDuration() const;
|
||||
nzAudioFormat GetFormat() const;
|
||||
const nzInt16* GetSamples() const;
|
||||
unsigned int GetSampleCount() const;
|
||||
unsigned int GetSampleRate() const;
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params = NzSoundBufferParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params = NzSoundBufferParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params = NzSoundBufferParams());
|
||||
|
||||
static bool IsFormatSupported(nzAudioFormat format);
|
||||
|
||||
private:
|
||||
unsigned int GetOpenALBuffer() const;
|
||||
|
||||
NzSoundBufferImpl* m_impl = nullptr;
|
||||
|
||||
static NzSoundBufferLoader::LoaderList s_loaders;
|
||||
};
|
||||
|
||||
#endif // NAZARA_SOUNDBUFFER_HPP
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (C) 2012 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SOUNDEMITTER_HPP
|
||||
#define NAZARA_SOUNDEMITTER_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
class NAZARA_API NzSoundEmitter
|
||||
{
|
||||
public:
|
||||
virtual ~NzSoundEmitter();
|
||||
|
||||
virtual void EnableLooping(bool loop) = 0;
|
||||
void EnableSpatialization(bool spatialization);
|
||||
|
||||
float GetAttenuation() const;
|
||||
virtual nzUInt32 GetDuration() const = 0;
|
||||
float GetMinDistance() const;
|
||||
float GetPitch() const;
|
||||
virtual nzUInt32 GetPlayingOffset() const = 0;
|
||||
NzVector3f GetPosition() const;
|
||||
NzVector3f GetVelocity() const;
|
||||
virtual nzSoundStatus GetStatus() const = 0;
|
||||
float GetVolume() const;
|
||||
|
||||
virtual bool IsLooping() const = 0;
|
||||
bool IsSpatialized() const;
|
||||
|
||||
virtual void Pause() = 0;
|
||||
virtual bool Play() = 0;
|
||||
|
||||
void SetAttenuation(float attenuation);
|
||||
void SetMinDistance(float minDistance);
|
||||
void SetPitch(float pitch);
|
||||
void SetPosition(const NzVector3f& position);
|
||||
void SetPosition(float x, float y, float z);
|
||||
void SetVelocity(const NzVector3f& velocity);
|
||||
void SetVelocity(float velX, float velY, float velZ);
|
||||
void SetVolume(float volume);
|
||||
|
||||
virtual void Stop() = 0;
|
||||
|
||||
protected:
|
||||
NzSoundEmitter();
|
||||
NzSoundEmitter(const NzSoundEmitter& emitter);
|
||||
|
||||
nzSoundStatus GetInternalStatus() const;
|
||||
|
||||
unsigned int m_source;
|
||||
};
|
||||
|
||||
#endif // NAZARA_SOUNDEMITTER_HPP
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef NAZARA_INITIALIZER_HPP
|
||||
#define NAZARA_INITIALIZER_HPP
|
||||
|
||||
///TODO: Utiliser les variadic template pour initialiser plusieurs modules à la fois ?
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
template<typename T>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ NzInitializer<T>::NzInitializer(Args... args)
|
|||
template<typename T>
|
||||
NzInitializer<T>::~NzInitializer()
|
||||
{
|
||||
T::Uninitialize();
|
||||
if (T::IsInitialized())
|
||||
T::Uninitialize();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ T NzNormalizeAngle(T angle)
|
|||
template<typename T>
|
||||
bool NzNumberEquals(T a, T b)
|
||||
{
|
||||
return std::fabs(a-b) <= std::numeric_limits<T>::epsilon();
|
||||
return std::fabs(a-b) < std::numeric_limits<T>::epsilon();
|
||||
}
|
||||
|
||||
NzString NzNumberToString(long long number, nzUInt8 radix)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
// Copyright (C) 2012 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/Core/Core.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Audio/Loaders/sndfile.hpp>
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
ALenum formats[nzAudioFormat_Max+1] = {0};
|
||||
ALCdevice* device = nullptr;
|
||||
ALCcontext* context = nullptr;
|
||||
}
|
||||
|
||||
nzAudioFormat NzAudio::GetAudioFormat(unsigned int channelCount)
|
||||
{
|
||||
switch (channelCount)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
return static_cast<nzAudioFormat>(channelCount);
|
||||
|
||||
default:
|
||||
NazaraError("Invalid channel count: " + NzString::Number(channelCount));
|
||||
return nzAudioFormat_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
float NzAudio::GetDopplerFactor()
|
||||
{
|
||||
return alGetFloat(AL_DOPPLER_FACTOR);
|
||||
}
|
||||
|
||||
float NzAudio::GetGlobalVolume()
|
||||
{
|
||||
ALfloat gain = 0.f;
|
||||
alGetListenerf(AL_GAIN, &gain);
|
||||
|
||||
return gain*100.f;
|
||||
}
|
||||
|
||||
NzVector3f NzAudio::GetListenerDirection()
|
||||
{
|
||||
ALfloat orientation[6];
|
||||
alGetListenerfv(AL_ORIENTATION, orientation);
|
||||
|
||||
return NzVector3f(orientation[0], orientation[1], orientation[2]);
|
||||
}
|
||||
|
||||
NzVector3f NzAudio::GetListenerPosition()
|
||||
{
|
||||
NzVector3f position;
|
||||
alGetListenerfv(AL_POSITION, position);
|
||||
|
||||
return position;
|
||||
}
|
||||
/*
|
||||
NzQuaternionf NzAudio::GetListenerRotation()
|
||||
{
|
||||
// http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another
|
||||
float orientation[6];
|
||||
alGetListenerfv(AL_ORIENTATION, orientation);
|
||||
|
||||
NzVector3f forward(orientation[0], orientation[1], orientation[2]);
|
||||
NzVector3f up(orientation[3], orientation[4], orientation[5]);
|
||||
|
||||
NzQuaternionf rotation;
|
||||
NzVector3f a = NzVector3f::CrossProduct(forward, up);
|
||||
rotation.x = a.x;
|
||||
rotation.y = a.y;
|
||||
rotation.z = a.z;
|
||||
rotation.w = std::sqrt(forward.SquaredLength() * up.SquaredLength()) + NzVector3f::DotProduct(forward, up);
|
||||
|
||||
return rotation;
|
||||
}
|
||||
*/
|
||||
NzVector3f NzAudio::GetListenerVelocity()
|
||||
{
|
||||
NzVector3f velocity;
|
||||
alGetListenerfv(AL_VELOCITY, velocity);
|
||||
|
||||
return velocity;
|
||||
}
|
||||
|
||||
float NzAudio::GetSpeedOfSound()
|
||||
{
|
||||
return alGetFloat(AL_SPEED_OF_SOUND);
|
||||
}
|
||||
|
||||
bool NzAudio::Initialize()
|
||||
{
|
||||
if (s_moduleReferenceCouter++ != 0)
|
||||
return true; // Déjà initialisé
|
||||
|
||||
// Initialisation des dépendances
|
||||
if (!NzCore::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize core module");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialisation du module
|
||||
device = alcOpenDevice(nullptr); // On choisit le device par défaut
|
||||
if (!device)
|
||||
{
|
||||
NazaraError("Failed to open default device");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Un seul contexte nous suffira
|
||||
context = alcCreateContext(device, nullptr);
|
||||
if (!context)
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
|
||||
alcCloseDevice(device);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!alcMakeContextCurrent(context))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(device);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Définition de l'orientation
|
||||
/*{
|
||||
NzVector3f forward = NzVector3f::Forward();
|
||||
NzVector3f up = NzVector3f::Up();
|
||||
|
||||
ALfloat orientation[6] =
|
||||
{
|
||||
forward.x, forward.y, forward.z,
|
||||
up.x, up.y, up.z
|
||||
};
|
||||
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}*/
|
||||
|
||||
formats[nzAudioFormat_Mono] = AL_FORMAT_MONO16;
|
||||
formats[nzAudioFormat_Stereo] = AL_FORMAT_STEREO16;
|
||||
formats[nzAudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16");
|
||||
formats[nzAudioFormat_5_1] = alGetEnumValue("AL_FORMAT_51CHN16");
|
||||
formats[nzAudioFormat_6_1] = alGetEnumValue("AL_FORMAT_61CHN16");
|
||||
formats[nzAudioFormat_7_1] = alGetEnumValue("AL_FORMAT_71CHN16");
|
||||
|
||||
NzLoaders_sndfile_Register();
|
||||
|
||||
NazaraNotice("Initialized: Audio module");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzAudio::IsFormatSupported(nzAudioFormat format)
|
||||
{
|
||||
if (format == nzAudioFormat_Unknown)
|
||||
return false;
|
||||
|
||||
return formats[format] != 0;
|
||||
}
|
||||
|
||||
bool NzAudio::IsInitialized()
|
||||
{
|
||||
return s_moduleReferenceCouter != 0;
|
||||
}
|
||||
|
||||
void NzAudio::SetDopplerFactor(float dopplerFactor)
|
||||
{
|
||||
alDopplerFactor(dopplerFactor);
|
||||
}
|
||||
|
||||
void NzAudio::SetGlobalVolume(float volume)
|
||||
{
|
||||
alListenerf(AL_GAIN, volume*0.01f);
|
||||
}
|
||||
|
||||
void NzAudio::SetListenerDirection(const NzVector3f& direction)
|
||||
{
|
||||
ALfloat orientation[6] =
|
||||
{
|
||||
direction.x, direction.y, direction.z,
|
||||
0.f, 1.f, 0.f
|
||||
};
|
||||
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
void NzAudio::SetListenerDirection(float dirX, float dirY, float dirZ)
|
||||
{
|
||||
ALfloat orientation[6] =
|
||||
{
|
||||
dirX, dirY, dirZ,
|
||||
0.f, 1.f, 0.f
|
||||
};
|
||||
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
void NzAudio::SetListenerPosition(const NzVector3f& position)
|
||||
{
|
||||
alListenerfv(AL_POSITION, position);
|
||||
}
|
||||
|
||||
void NzAudio::SetListenerPosition(float x, float y, float z)
|
||||
{
|
||||
alListener3f(AL_POSITION, x, y, z);
|
||||
}
|
||||
/*
|
||||
void NzAudio::SetListenerRotation(const NzQuaternionf& rotation)
|
||||
{
|
||||
NzVector3f forward = rotation * NzVector3f::Forward();
|
||||
NzVector3f up = NzVector3f::Up();
|
||||
|
||||
ALfloat orientation[6] =
|
||||
{
|
||||
forward.x, forward.y, forward.z,
|
||||
up.x, up.y, up.z
|
||||
};
|
||||
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
*/
|
||||
void NzAudio::SetListenerVelocity(const NzVector3f& velocity)
|
||||
{
|
||||
alListenerfv(AL_VELOCITY, velocity);
|
||||
}
|
||||
|
||||
void NzAudio::SetListenerVelocity(float velX, float velY, float velZ)
|
||||
{
|
||||
alListener3f(AL_VELOCITY, velX, velY, velZ);
|
||||
}
|
||||
|
||||
void NzAudio::SetSpeedOfSound(float speed)
|
||||
{
|
||||
alSpeedOfSound(speed);
|
||||
}
|
||||
|
||||
void NzAudio::Uninitialize()
|
||||
{
|
||||
if (--s_moduleReferenceCouter != 0)
|
||||
return; // Encore utilisé
|
||||
|
||||
// Libération du module
|
||||
alcMakeContextCurrent(nullptr);
|
||||
alcDestroyContext(context);
|
||||
|
||||
if (!alcCloseDevice(device))
|
||||
// Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation
|
||||
NazaraWarning("Failed to close device");
|
||||
|
||||
NazaraNotice("Uninitialized: Audio module");
|
||||
|
||||
// Libération des dépendances
|
||||
NzCore::Uninitialize();
|
||||
}
|
||||
|
||||
unsigned int NzAudio::GetOpenALFormat(nzAudioFormat format)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (format == nzAudioFormat_Unknown)
|
||||
{
|
||||
NazaraInternalError("Invalid audio format");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return formats[format];
|
||||
}
|
||||
|
||||
unsigned int NzAudio::s_moduleReferenceCouter = 0;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_LOADERS_SNDFILE_HPP
|
||||
#define NAZARA_LOADERS_SNDFILE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
void NzLoaders_sndfile_Register();
|
||||
void NzLoaders_sndfile_Unregister();
|
||||
|
||||
#endif // NAZARA_LOADERS_SNDFILE_HPP
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright (C) 2012 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/Loaders/sndfile.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <sndfile/sndfile.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
sf_count_t GetSize(void* user_data)
|
||||
{
|
||||
NzInputStream* stream = reinterpret_cast<NzInputStream*>(user_data);
|
||||
return stream->GetSize();
|
||||
}
|
||||
|
||||
sf_count_t Read(void* ptr, sf_count_t count, void* user_data)
|
||||
{
|
||||
NzInputStream* stream = reinterpret_cast<NzInputStream*>(user_data);
|
||||
return stream->Read(ptr, count);
|
||||
}
|
||||
|
||||
sf_count_t Seek(sf_count_t offset, int whence, void* user_data)
|
||||
{
|
||||
NzInputStream* stream = reinterpret_cast<NzInputStream*>(user_data);
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_CUR:
|
||||
stream->Read(nullptr, offset);
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
stream->SetCursorPos(stream->GetSize()+offset);
|
||||
break;
|
||||
|
||||
case SEEK_SET:
|
||||
stream->SetCursorPos(offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
NazaraInternalError("Seek mode not handled");
|
||||
}
|
||||
|
||||
return stream->GetCursorPos();
|
||||
}
|
||||
|
||||
sf_count_t Tell(void* user_data)
|
||||
{
|
||||
NzInputStream* stream = reinterpret_cast<NzInputStream*>(user_data);
|
||||
return stream->GetCursorPos();
|
||||
}
|
||||
|
||||
static SF_VIRTUAL_IO callbacks = {GetSize, Seek, Read, nullptr, Tell};
|
||||
|
||||
bool NzLoader_sndfile_Check(NzInputStream& stream, const NzSoundBufferParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
SF_INFO info;
|
||||
SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream);
|
||||
if (file)
|
||||
{
|
||||
sf_close(file);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NzLoader_sndfile_Load(NzSoundBuffer* soundBuffer, NzInputStream& stream, const NzSoundBufferParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
SF_INFO infos;
|
||||
SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream);
|
||||
if (!file)
|
||||
{
|
||||
NazaraError("Failed to load sound file: " + NzString(sf_strerror(file)));
|
||||
return false;
|
||||
}
|
||||
|
||||
nzAudioFormat format = NzAudio::GetAudioFormat(infos.channels);
|
||||
if (format == nzAudioFormat_Unknown)
|
||||
{
|
||||
NazaraError("Channel count not handled");
|
||||
sf_close(file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int sampleCount = infos.frames*infos.channels;
|
||||
nzInt16* samples = new nzInt16[sampleCount];
|
||||
if (sf_read_short(file, samples, sampleCount) != sampleCount)
|
||||
{
|
||||
NazaraError("Failed to read samples");
|
||||
delete[] samples;
|
||||
sf_close(file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBuffer->Create(format, infos.frames*infos.channels, infos.samplerate, samples))
|
||||
{
|
||||
NazaraError("Failed to create sound buffer");
|
||||
sf_close(file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
delete[] samples;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void NzLoaders_sndfile_Register()
|
||||
{
|
||||
NzSoundBufferLoader::RegisterLoader("aiff,au,avr,caf,flac,htk,ircam,mat4,mat5,mpc2k,nist,ogg,paf,pvf,raw,rf64,sd2,sds,svx,voc,w64,wav,wve",
|
||||
NzLoader_sndfile_Check,
|
||||
NzLoader_sndfile_Load);
|
||||
}
|
||||
|
||||
void NzLoaders_sndfile_Unregister()
|
||||
{
|
||||
NzSoundBufferLoader::UnregisterLoader("aiff,au,avr,caf,flac,htk,ircam,mat4,mat5,mpc2k,nist,ogg,paf,pvf,raw,rf64,sd2,sds,svx,voc,w64,wav,wve",
|
||||
NzLoader_sndfile_Check,
|
||||
NzLoader_sndfile_Load);
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
// Copyright (C) 2012 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/Sound.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <AL/al.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
NzSound::NzSound(const NzSoundBuffer* soundBuffer)
|
||||
{
|
||||
SetBuffer(soundBuffer);
|
||||
}
|
||||
|
||||
NzSound::NzSound(const NzSound& sound) :
|
||||
NzSoundEmitter(sound)
|
||||
{
|
||||
SetBuffer(sound.m_buffer);
|
||||
}
|
||||
|
||||
NzSound::~NzSound()
|
||||
{
|
||||
Stop();
|
||||
|
||||
if (m_buffer)
|
||||
m_buffer->RemoveResourceReference();
|
||||
}
|
||||
|
||||
void NzSound::EnableLooping(bool loop)
|
||||
{
|
||||
alSourcei(m_source, AL_LOOPING, loop);
|
||||
}
|
||||
|
||||
const NzSoundBuffer* NzSound::GetBuffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
nzUInt32 NzSound::GetDuration() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("No sound buffer");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->GetDuration();
|
||||
}
|
||||
|
||||
nzUInt32 NzSound::GetPlayingOffset() const
|
||||
{
|
||||
ALfloat seconds = -1.f;
|
||||
alGetSourcef(m_source, AL_SEC_OFFSET, &seconds);
|
||||
|
||||
return static_cast<nzUInt32>(seconds*1000);
|
||||
}
|
||||
|
||||
nzSoundStatus NzSound::GetStatus() const
|
||||
{
|
||||
return GetInternalStatus();
|
||||
}
|
||||
|
||||
bool NzSound::IsLooping() const
|
||||
{
|
||||
ALint loop;
|
||||
alGetSourcei(m_source, AL_LOOPING, &loop);
|
||||
|
||||
return loop != AL_FALSE;
|
||||
}
|
||||
|
||||
bool NzSound::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
|
||||
{
|
||||
NzSoundBuffer* buffer = new NzSoundBuffer;
|
||||
if (!buffer->LoadFromFile(filePath, params))
|
||||
{
|
||||
NazaraError("Failed to load buffer from file (" + filePath + ')');
|
||||
delete buffer;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SetBuffer(buffer);
|
||||
|
||||
buffer->SetPersistent(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzSound::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
|
||||
{
|
||||
NzSoundBuffer* buffer = new NzSoundBuffer;
|
||||
if (!buffer->LoadFromMemory(data, size, params))
|
||||
{
|
||||
NazaraError("Failed to load buffer from memory (" + NzString::Pointer(data) + ')');
|
||||
delete buffer;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SetBuffer(buffer);
|
||||
|
||||
buffer->SetPersistent(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzSound::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
|
||||
{
|
||||
NzSoundBuffer* buffer = new NzSoundBuffer;
|
||||
if (!buffer->LoadFromStream(stream, params))
|
||||
{
|
||||
NazaraError("Failed to load buffer from stream");
|
||||
delete buffer;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SetBuffer(buffer);
|
||||
|
||||
buffer->SetPersistent(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzSound::Pause()
|
||||
{
|
||||
alSourcePause(m_source);
|
||||
}
|
||||
|
||||
bool NzSound::Play()
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("No sound buffer to play");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
alSourcePlay(m_source);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzSound::SetBuffer(const NzSoundBuffer* buffer)
|
||||
{
|
||||
if (m_buffer == buffer)
|
||||
return;
|
||||
|
||||
Stop();
|
||||
|
||||
if (m_buffer)
|
||||
m_buffer->RemoveResourceReference();
|
||||
|
||||
m_buffer = buffer;
|
||||
|
||||
if (m_buffer)
|
||||
{
|
||||
m_buffer->AddResourceReference();
|
||||
alSourcei(m_source, AL_BUFFER, m_buffer->GetOpenALBuffer());
|
||||
}
|
||||
else
|
||||
alSourcei(m_source, AL_BUFFER, AL_NONE);
|
||||
}
|
||||
|
||||
void NzSound::SetPlayingOffset(nzUInt32 offset)
|
||||
{
|
||||
alSourcef(m_source, AL_SEC_OFFSET, offset/1000.f);
|
||||
}
|
||||
|
||||
void NzSound::Stop()
|
||||
{
|
||||
alSourceStop(m_source);
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
// Copyright (C) 2012 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/SoundBuffer.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <AL/al.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
///FIXME: Adapter la création
|
||||
|
||||
bool NzSoundBufferParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct NzSoundBufferImpl
|
||||
{
|
||||
ALuint buffer;
|
||||
nzAudioFormat format;
|
||||
nzUInt32 duration;
|
||||
nzInt16* samples;
|
||||
unsigned int sampleCount;
|
||||
unsigned int sampleRate;
|
||||
};
|
||||
|
||||
NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||
{
|
||||
Create(format, sampleCount, sampleRate, samples);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create sound buffer");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSoundBuffer::~NzSoundBuffer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (sampleCount == 0)
|
||||
return true;
|
||||
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!IsFormatSupported(format))
|
||||
{
|
||||
NazaraError("Audio format is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sampleRate == 0)
|
||||
{
|
||||
NazaraError("Sample rate must be different from zero");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!samples)
|
||||
{
|
||||
NazaraError("Invalid sample source");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// On vide le stack d'erreurs
|
||||
while (alGetError() != AL_NO_ERROR);
|
||||
|
||||
ALuint buffer;
|
||||
alGenBuffers(1, &buffer);
|
||||
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
NazaraError("Failed to create OpenAL buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
alBufferData(buffer, NzAudio::GetOpenALFormat(format), samples, sampleCount*sizeof(nzInt16), sampleRate);
|
||||
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
NazaraError("Failed to set OpenAL buffer");
|
||||
alDeleteBuffers(1, &buffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = new NzSoundBufferImpl;
|
||||
m_impl->buffer = buffer;
|
||||
m_impl->duration = 1000 * (sampleCount / (format * sampleRate));
|
||||
m_impl->format = format;
|
||||
m_impl->sampleCount = sampleCount;
|
||||
m_impl->sampleRate = sampleRate;
|
||||
m_impl->samples = new nzInt16[sampleCount];
|
||||
std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzSoundBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
delete[] m_impl->samples;
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nzUInt32 NzSoundBuffer::GetDuration() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->duration;
|
||||
}
|
||||
|
||||
nzAudioFormat NzSoundBuffer::GetFormat() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return nzAudioFormat_Unknown;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->format;
|
||||
}
|
||||
|
||||
const nzInt16* NzSoundBuffer::GetSamples() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->samples;
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetSampleCount() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sampleCount;
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetSampleRate() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sampleRate;
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::IsFormatSupported(nzAudioFormat format)
|
||||
{
|
||||
return NzAudio::IsFormatSupported(format);
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetOpenALBuffer() const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraInternalError("Sound buffer not created");
|
||||
return AL_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->buffer;
|
||||
}
|
||||
|
||||
NzSoundBufferLoader::LoaderList NzSoundBuffer::s_loaders;
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
// Copyright (C) 2012 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
|
||||
|
||||
// http://connect.creativelabs.com/openal/Documentation/OpenAL_Programmers_Guide.pdf
|
||||
|
||||
#include <Nazara/Audio/SoundEmitter.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <AL/al.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
NzSoundEmitter::NzSoundEmitter()
|
||||
{
|
||||
alGenSources(1, &m_source);
|
||||
}
|
||||
|
||||
NzSoundEmitter::NzSoundEmitter(const NzSoundEmitter& emitter)
|
||||
{
|
||||
alGenSources(1, &m_source);
|
||||
|
||||
SetAttenuation(emitter.GetAttenuation());
|
||||
SetMinDistance(emitter.GetMinDistance());
|
||||
SetPitch(emitter.GetPitch());
|
||||
// Pas de copie de position ou de vitesse
|
||||
SetVolume(emitter.GetVolume());
|
||||
}
|
||||
|
||||
NzSoundEmitter::~NzSoundEmitter()
|
||||
{
|
||||
alDeleteSources(1, &m_source);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::EnableSpatialization(bool spatialization)
|
||||
{
|
||||
alSourcei(m_source, AL_SOURCE_RELATIVE, spatialization);
|
||||
}
|
||||
|
||||
float NzSoundEmitter::GetAttenuation() const
|
||||
{
|
||||
ALfloat attenuation;
|
||||
alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &attenuation);
|
||||
|
||||
return attenuation;
|
||||
}
|
||||
|
||||
float NzSoundEmitter::GetMinDistance() const
|
||||
{
|
||||
ALfloat distance;
|
||||
alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &distance);
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
float NzSoundEmitter::GetPitch() const
|
||||
{
|
||||
ALfloat pitch;
|
||||
alGetSourcef(m_source, AL_PITCH, &pitch);
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
NzVector3f NzSoundEmitter::GetPosition() const
|
||||
{
|
||||
NzVector3f position;
|
||||
alGetSourcefv(m_source, AL_POSITION, position);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
NzVector3f NzSoundEmitter::GetVelocity() const
|
||||
{
|
||||
NzVector3f velocity;
|
||||
alGetSourcefv(m_source, AL_VELOCITY, velocity);
|
||||
|
||||
return velocity;
|
||||
}
|
||||
|
||||
float NzSoundEmitter::GetVolume() const
|
||||
{
|
||||
ALfloat gain;
|
||||
alGetSourcef(m_source, AL_GAIN, &gain);
|
||||
|
||||
return gain * 100.f;
|
||||
}
|
||||
|
||||
bool NzSoundEmitter::IsSpatialized() const
|
||||
{
|
||||
ALint relative;
|
||||
alGetSourcei(m_source, AL_SOURCE_RELATIVE, &relative);
|
||||
|
||||
return relative != AL_FALSE;
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetAttenuation(float attenuation)
|
||||
{
|
||||
alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetMinDistance(float minDistance)
|
||||
{
|
||||
alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetPitch(float pitch)
|
||||
{
|
||||
alSourcef(m_source, AL_PITCH, pitch);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetPosition(const NzVector3f& position)
|
||||
{
|
||||
alSourcefv(m_source, AL_POSITION, position);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetPosition(float x, float y, float z)
|
||||
{
|
||||
alSource3f(m_source, AL_POSITION, x, y, z);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetVelocity(const NzVector3f& velocity)
|
||||
{
|
||||
alSourcefv(m_source, AL_VELOCITY, velocity);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetVelocity(float velX, float velY, float velZ)
|
||||
{
|
||||
alSource3f(m_source, AL_VELOCITY, velX, velY, velZ);
|
||||
}
|
||||
|
||||
void NzSoundEmitter::SetVolume(float volume)
|
||||
{
|
||||
alSourcef(m_source, AL_GAIN, volume*0.01f);
|
||||
}
|
||||
|
||||
nzSoundStatus NzSoundEmitter::GetInternalStatus() const
|
||||
{
|
||||
ALint state;
|
||||
alGetSourcei(m_source, AL_SOURCE_STATE, &state);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case AL_INITIAL:
|
||||
case AL_STOPPED:
|
||||
return nzSoundStatus_Stopped;
|
||||
|
||||
case AL_PAUSED:
|
||||
return nzSoundStatus_Paused;
|
||||
|
||||
case AL_PLAYING:
|
||||
return nzSoundStatus_Playing;
|
||||
|
||||
default:
|
||||
NazaraInternalError("Source state unrecognized");
|
||||
}
|
||||
|
||||
return nzSoundStatus_Stopped;
|
||||
}
|
||||
Loading…
Reference in New Issue