audio::play
This commit is contained in:
@@ -61,6 +61,14 @@ void ALSpeaker::setPitch(float pitch) {
|
|||||||
AL_CHECK(alSourcef(source, AL_PITCH, pitch));
|
AL_CHECK(alSourcef(source, AL_PITCH, pitch));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ALSpeaker::isLoop() const {
|
||||||
|
return AL::getSourcei(source, AL_LOOPING) == AL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ALSpeaker::setLoop(bool loop) {
|
||||||
|
AL_CHECK(alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
void ALSpeaker::play() {
|
void ALSpeaker::play() {
|
||||||
AL_CHECK(alSourcePlay(source));
|
AL_CHECK(alSourcePlay(source));
|
||||||
}
|
}
|
||||||
@@ -240,5 +248,4 @@ void ALAudio::setListener(glm::vec3 position, glm::vec3 velocity, glm::vec3 at,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ALAudio::update(double delta) {
|
void ALAudio::update(double delta) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ namespace audio {
|
|||||||
float getPitch() const override;
|
float getPitch() const override;
|
||||||
void setPitch(float pitch) override;
|
void setPitch(float pitch) override;
|
||||||
|
|
||||||
|
bool isLoop() const override;
|
||||||
|
void setLoop(bool loop) override;
|
||||||
|
|
||||||
void play() override;
|
void play() override;
|
||||||
void pause() override;
|
void pause() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|||||||
+74
-9
@@ -6,35 +6,100 @@
|
|||||||
#include "NoAudio.h"
|
#include "NoAudio.h"
|
||||||
|
|
||||||
namespace audio {
|
namespace audio {
|
||||||
extern Backend* backend;
|
static speakerid_t nextId = 1;
|
||||||
|
static Backend* backend;
|
||||||
|
static std::unordered_map<speakerid_t, std::unique_ptr<Speaker>> speakers;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio::Backend* audio::backend = nullptr;
|
using namespace audio;
|
||||||
|
|
||||||
void audio::initialize(bool enabled) {
|
void audio::initialize(bool enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
audio::backend = ALAudio::create();
|
backend = ALAudio::create();
|
||||||
}
|
}
|
||||||
if (audio::backend == nullptr) {
|
if (backend == nullptr) {
|
||||||
std::cerr << "could not to initialize audio" << std::endl;
|
std::cerr << "could not to initialize audio" << std::endl;
|
||||||
audio::backend = NoAudio::create();
|
backend = NoAudio::create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sound* audio::createSound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
||||||
|
return backend->createSound(pcm, keepPCM);
|
||||||
|
}
|
||||||
|
|
||||||
void audio::setListener(
|
void audio::setListener(
|
||||||
glm::vec3 position,
|
glm::vec3 position,
|
||||||
glm::vec3 velocity,
|
glm::vec3 velocity,
|
||||||
glm::vec3 lookAt,
|
glm::vec3 lookAt,
|
||||||
glm::vec3 up
|
glm::vec3 up
|
||||||
) {
|
) {
|
||||||
audio::backend->setListener(position, velocity, lookAt, up);
|
backend->setListener(position, velocity, lookAt, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_lower_priority_speaker(int priority) {
|
||||||
|
for (auto it = speakers.begin(); it != speakers.end();) {
|
||||||
|
if (it->second->getPriority() < priority && it->second->isPaused()) {
|
||||||
|
speakers.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
for (auto it = speakers.begin(); it != speakers.end();) {
|
||||||
|
if (it->second->getPriority() < priority) {
|
||||||
|
speakers.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
speakerid_t audio::play(
|
||||||
|
Sound* sound,
|
||||||
|
glm::vec3 position,
|
||||||
|
float volume,
|
||||||
|
float pitch,
|
||||||
|
bool loop,
|
||||||
|
int priority
|
||||||
|
) {
|
||||||
|
Speaker* speaker = sound->newInstance(priority);
|
||||||
|
if (speaker == nullptr) {
|
||||||
|
remove_lower_priority_speaker(priority);
|
||||||
|
speaker = sound->newInstance(priority);
|
||||||
|
}
|
||||||
|
if (speaker == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
speakerid_t id = nextId++;
|
||||||
|
speakers[id].reset(speaker);
|
||||||
|
speaker->setPosition(position);
|
||||||
|
speaker->setVolume(volume);
|
||||||
|
speaker->setPitch(pitch);
|
||||||
|
speaker->setLoop(loop);
|
||||||
|
speaker->play();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Speaker* audio::get(speakerid_t id) {
|
||||||
|
auto found = speakers.find(id);
|
||||||
|
if (found == speakers.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return found->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio::update(double delta) {
|
void audio::update(double delta) {
|
||||||
audio::backend->update(delta);
|
backend->update(delta);
|
||||||
|
|
||||||
|
for (auto it = speakers.begin(); it != speakers.end();) {
|
||||||
|
if (it->second->isStopped()) {
|
||||||
|
speakers.erase(it);
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio::close() {
|
void audio::close() {
|
||||||
delete audio::backend;
|
delete backend;
|
||||||
audio::backend = nullptr;
|
backend = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,13 @@ namespace audio {
|
|||||||
/// @brief duration unit is second
|
/// @brief duration unit is second
|
||||||
using duration_t = float;
|
using duration_t = float;
|
||||||
|
|
||||||
|
constexpr inline int PRIORITY_LOW = 0;
|
||||||
|
constexpr inline int PRIORITY_NORMAL = 5;
|
||||||
|
constexpr inline int PRIORITY_HIGH = 10;
|
||||||
|
|
||||||
class Speaker;
|
class Speaker;
|
||||||
|
|
||||||
|
/// @brief Audio speaker states
|
||||||
enum class State {
|
enum class State {
|
||||||
playing,
|
playing,
|
||||||
paused,
|
paused,
|
||||||
@@ -84,6 +89,14 @@ namespace audio {
|
|||||||
/// @param pitch new pitch multiplier (must be positive)
|
/// @param pitch new pitch multiplier (must be positive)
|
||||||
virtual void setPitch(float pitch) = 0;
|
virtual void setPitch(float pitch) = 0;
|
||||||
|
|
||||||
|
/// @brief Check if speaker audio is in loop
|
||||||
|
/// @return true if audio is in loop
|
||||||
|
virtual bool isLoop() const = 0;
|
||||||
|
|
||||||
|
/// @brief Enable/disable audio loop
|
||||||
|
/// @param loop loop mode
|
||||||
|
virtual void setLoop(bool loop) = 0;
|
||||||
|
|
||||||
/// @brief Play, replay or resume audio
|
/// @brief Play, replay or resume audio
|
||||||
virtual void play() = 0;
|
virtual void play() = 0;
|
||||||
|
|
||||||
@@ -120,6 +133,14 @@ namespace audio {
|
|||||||
/// @brief Get speaker priority
|
/// @brief Get speaker priority
|
||||||
/// @return speaker priority value
|
/// @return speaker priority value
|
||||||
virtual int getPriority() const = 0;
|
virtual int getPriority() const = 0;
|
||||||
|
|
||||||
|
inline constexpr bool isPaused() const {
|
||||||
|
return getState() == State::paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr bool isStopped() const {
|
||||||
|
return getState() == State::stopped;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Backend {
|
class Backend {
|
||||||
@@ -161,6 +182,26 @@ namespace audio {
|
|||||||
glm::vec3 up
|
glm::vec3 up
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// @brief Play 3D sound in the world
|
||||||
|
/// @param sound target sound
|
||||||
|
/// @param position sound world position
|
||||||
|
/// @param volume sound volume [0.0-1.0]
|
||||||
|
/// @param pitch sound pitch multiplier [0.0-...]
|
||||||
|
/// @param loop loop sound
|
||||||
|
/// @param priority sound priority
|
||||||
|
/// (PRIORITY_LOW, PRIORITY_NORMAL, PRIORITY_HIGH)
|
||||||
|
/// @return speaker id or 0
|
||||||
|
extern speakerid_t play(
|
||||||
|
Sound* sound,
|
||||||
|
glm::vec3 position,
|
||||||
|
float volume,
|
||||||
|
float pitch,
|
||||||
|
bool loop,
|
||||||
|
int priority
|
||||||
|
);
|
||||||
|
|
||||||
|
extern Speaker* get(speakerid_t id);
|
||||||
|
|
||||||
/// @brief Update audio streams and sound instanced
|
/// @brief Update audio streams and sound instanced
|
||||||
/// @param delta time since the last update (seconds)
|
/// @param delta time since the last update (seconds)
|
||||||
extern void update(double delta);
|
extern void update(double delta);
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ void Engine::mainloop() {
|
|||||||
updateTimers();
|
updateTimers();
|
||||||
updateHotkeys();
|
updateHotkeys();
|
||||||
|
|
||||||
|
audio::update(delta);
|
||||||
|
|
||||||
gui->act(delta);
|
gui->act(delta);
|
||||||
screen->update(delta);
|
screen->update(delta);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user