Really nice audio API

This commit is contained in:
2023-01-17 11:53:34 -08:00
parent a403a292be
commit ae3b07202f
6 changed files with 206 additions and 24 deletions

View File

@@ -4,7 +4,7 @@
// https://opensource.org/licenses/MIT
#include "AudioSource.hpp"
#include "scene/SceneItem.hpp"
#include "game/DawnGame.hpp"
using namespace Dawn;
@@ -12,20 +12,71 @@ AudioSource::AudioSource(SceneItem *i) : SceneItemComponent(i) {
}
void AudioSource::updateAudioSource() {
if(!this->ready || data == nullptr || !data->ready) return;
switch(this->requestedAudioState) {
// When the engine wants the sound to stop
case AUDIO_SOURCE_STATE_STOPPED:
if(this->currentAudioState == AUDIO_SOURCE_STATE_STOPPED) return;
this->currentAudioState = AUDIO_SOURCE_STATE_STOPPED;
alSourceStop(this->source);
this->eventStopped.invoke();
break;
// When the engine wants the sound to pause
case AUDIO_SOURCE_STATE_PAUSED:
if(this->currentAudioState != AUDIO_SOURCE_STATE_PLAYING) return;
this->currentAudioState = AUDIO_SOURCE_STATE_PAUSED;
alSourcePause(this->source);
this->eventPaused.invoke();
break;
// When the engine wants the sound to play...
case AUDIO_SOURCE_STATE_PLAYING:
switch(this->playMode) {
// This should be playing, right now.
case AUDIO_PLAY_MODE_ALWAYS:
if(this->currentAudioState == AUDIO_SOURCE_STATE_PLAYING) return;
this->currentAudioState = AUDIO_SOURCE_STATE_PLAYING;
alSourcePlay(this->source);
this->eventPlaying.invoke();
break;
case AUDIO_PLAY_MODE_UNPAUSED:
if(this->getGame()->timeManager.isPaused) {
if(this->currentAudioState != AUDIO_SOURCE_STATE_PLAYING) return;
this->currentAudioState = AUDIO_SOURCE_STATE_PAUSED;
alSourcePause(this->source);
this->eventPaused.invoke();
} else {
if(this->currentAudioState == AUDIO_SOURCE_STATE_PLAYING) return;
this->currentAudioState = AUDIO_SOURCE_STATE_PLAYING;
alSourcePlay(this->source);
this->eventPlaying.invoke();
}
break;
default:
assertUnreachable();
}
break;
default:
assertUnreachable();
}
}
void AudioSource::onStart() {
alGenSources((ALuint)1, &this->source);
// In future these will probably be tied to the layer
alSourcef(this->source, AL_PITCH, 1);
// alSourcef(this->source, AL_GAIN, AL_MAX_GAIN);
alSourcef(this->source, AL_GAIN, 1);
glm::vec3 position = this->transform->getLocalPosition();
alSource3f(this->source, AL_POSITION, position.x, position.y, position.z);
// alSourcei(this->source, AL_SOURCE_RELATIVE, AL_TRUE);
// alSourcef(this->source, AL_REFERENCE_DISTANCE, 0);
// alSourcef(this->source, AL_ROLLOFF_FACTOR, 0);
// Velocity is always zero for now
alSource3f(this->source, AL_VELOCITY, 0, 0, 0);
@@ -37,13 +88,17 @@ void AudioSource::onStart() {
alSourcei(source, AL_BUFFER, this->data->buffer);
}
// Playing
if(this->playing) alSourcePlay(this->source);
// Ready.
this->ready = true;
// Update the source now we are ready.
this->updateAudioSource();
// Listen for events
this->transform->eventTransformUpdated.addListener(this, &AudioSource::onTransformUpdate);
this->getGame()->timeManager.eventTimePaused.addListener(this, &AudioSource::onGamePause);
this->getGame()->timeManager.eventTimeResumed.addListener(this, &AudioSource::onGameUnpause);
this->ready = true;
}
bool_t AudioSource::isLooping() {
@@ -55,30 +110,63 @@ void AudioSource::setLoop(bool_t loop) {
if(this->ready) alSourcei(this->source, AL_LOOPING, loop);
}
bool_t AudioSource::isPlaying() {
return this->playing;
AudioSourceState AudioSource::getPlayingState() {
return this->requestedAudioState;
}
void AudioSource::setPlayingState(enum AudioSourceState state) {
this->requestedAudioState = state;
this->updateAudioSource();
}
AudioSourceState AudioSource::getRealState() {
return this->currentAudioState;
}
void AudioSource::play() {
this->playing = true;
if(this->ready && data != nullptr && data->ready) {
alSourcePlay(this->source);
}
this->setPlayingState(AUDIO_SOURCE_STATE_PLAYING);
}
void AudioSource::pause() {
this->setPlayingState(AUDIO_SOURCE_STATE_PAUSED);
}
void AudioSource::stop() {
this->setPlayingState(AUDIO_SOURCE_STATE_STOPPED);
}
// void AudioSource::rewind() {
// if(this->ready && data != nullptr && data->ready) {
// alSourceRewind(this->source);
// }
// }
AudioData * AudioSource::getAudioData() {
return this->data;
}
void AudioSource::setAudioData(AudioData *data) {
this->data = data;
// Set up source.
if(this->ready && data != nullptr && data->ready) {
alSourcei(source, AL_BUFFER, data->buffer);
}
this->data = data;
this->updateAudioSource();
}
enum AudioSourcePlayMode AudioSource::getPlayMode() {
return this->playMode;
}
void AudioSource::setPlayMode(enum AudioSourcePlayMode playMode) {
this->playMode = playMode;
this->updateAudioSource();
}
void AudioSource::onDispose() {
this->transform->eventTransformUpdated.removeListener(this, &AudioSource::onTransformUpdate);
this->getGame()->timeManager.eventTimePaused.removeListener(this, &AudioSource::onGamePause);
this->getGame()->timeManager.eventTimeResumed.removeListener(this, &AudioSource::onGameUnpause);
this->ready = false;
alDeleteSources((ALuint)1, &this->source);
@@ -87,4 +175,12 @@ void AudioSource::onDispose() {
void AudioSource::onTransformUpdate() {
glm::vec3 position = this->transform->getWorldPosition();
alSource3f(this->source, AL_POSITION, position.x, position.y, position.z);
}
void AudioSource::onGamePause() {
this->updateAudioSource();
}
void AudioSource::onGameUnpause() {
this->updateAudioSource();
}