Program Listing for File audio_source.hpp¶
↰ Return to documentation for file (/home/runner/work/Legion-Engine/Legion-Engine/legion/engine/audio/components/audio_source.hpp
)
#pragma once
#if !defined(DOXY_EXCLUDE)
#include <AL/al.h>
#include <AL/alc.h>
#endif
#include <audio/data/audio_segment.hpp>
namespace legion::audio
{
struct audio_source
{
friend class AudioSystem;
public:
enum sound_properties
{
pitch = 1 << 0,
gain = 1 << 1,
playState = 1 << 2,
doRewind = 1 << 3,
audioHandle = 1 << 4,
rollOffFactor = 1 << 5,
looping = 1 << 6
};
enum playstate
{
stopped,
playing,
paused,
};
void setPitch(float pitch) noexcept
{
m_changes |= sound_properties::pitch; // set b0
m_pitch = legion::math::max(0.0f, pitch);
}
float getPitch() const noexcept { return m_pitch; }
void setGain(float gain) noexcept
{
m_changes |= sound_properties::gain; // set b1
m_gain = legion::math::max(0.0f, gain);
}
float getGain() const noexcept { return m_gain; }
void setRollOffFactor(float factor) noexcept
{
m_changes = sound_properties::rollOffFactor;
m_rolloffFactor = factor;
}
void disableSpatialAudio() noexcept
{
setRollOffFactor(0.0f);
}
void enableSpatialAudio() noexcept
{
setRollOffFactor(1.0f);
}
void play() noexcept
{
// If the file is already playing or if the file will be played on next update > return
if (m_nextPlayState == playstate::playing) return;
m_changes |= sound_properties::playState;
m_nextPlayState = playstate::playing;
// Do not set playstate to playing - audiosystem will set it accordingly
}
void pause() noexcept
{
// If the file is already playing or if the file will be played on next update > return
if (m_nextPlayState == playstate::paused) return;
m_changes |= sound_properties::playState;
m_nextPlayState = playstate::paused;
// Do not set playstate to paused - audiosystem will set it accordingly
}
void stop() noexcept
{
// If the file is already playing or if the file will be played on next update > return
if (m_nextPlayState == playstate::stopped) return;
m_changes |= sound_properties::playState;
m_nextPlayState = playstate::stopped;
// Do not set playstate to stopped - audiosystem will set it accordingly
}
bool isPlaying() const noexcept
{
return m_playState == playstate::playing;
}
bool isPaused() const noexcept
{
return m_playState == playstate::paused;
}
bool isStopped() const noexcept
{
return m_playState == playstate::stopped;
}
void setAudioHandle(audio_segment_handle handle) noexcept
{
if (handle == m_audio_handle) return;
m_changes |= sound_properties::audioHandle;
m_audio_handle = handle;
}
void rewind() noexcept
{
m_changes |= sound_properties::doRewind;
}
audio_segment_handle getAudioHandle() const noexcept
{
return m_audio_handle;
}
int getChannels() const
{
async::readonly_guard guard(m_audio_handle.get().first);
return m_audio_handle.get().second.channels;
}
bool isStereo() const noexcept
{
return getChannels() == 2;
}
bool isMono() const noexcept
{
return getChannels() == 1;
}
void setLooping(bool state = false) noexcept
{
if (state != m_looping) {
m_looping = state;
m_changes |= looping;
}
}
bool isLooping() const noexcept
{
return m_looping;
}
operator ALuint() const
{
return m_sourceId;
}
private:
void clearChanges()
{
m_changes ^= m_changes; // Reset
// The next play state also needs to be reset to be able to properly switch play states
m_nextPlayState = m_playState;
}
ALuint m_sourceId;
audio_segment_handle m_audio_handle = invalid_audio_segment_handle;
float m_pitch = 1.0f;
float m_gain = 1.0f;
bool m_looping = false;
playstate m_playState = playstate::stopped;
playstate m_nextPlayState = playstate::stopped;
float m_rolloffFactor;
// Byte to keep track of changes made to audio source
// For all the values > see enum sound_properties
// b0 - pitch
// b1 - gain
// b2 - play state
// b3 - rewind (doRewind)
// b4 - audio handle
// b5 - roll off factor 3D
byte m_changes = 0;
};
}