2#include <SDL3_mixer/SDL_mixer.h>
6 std::expected<void, Core::CoriError<>>
Track::SetSound(
const std::shared_ptr<Sound>& sound) {
8 if (!m_ActiveSequence) {
9 if (sound->IsValid()) {
11 if (sound->IsPlaceholder()) {
15 return Mixer::SetTrackSound(m_ID, sound.get());
18 return std::unexpected(
Core::CoriError(std::format(
"Failed to assign Sound '{} (SoundID: {})' to Track '{} (TrackID: {})'. Sound object is invalid.", sound->m_Name, sound->GetID(),
m_Name, m_ID)));
21 return std::unexpected(
Core::CoriError(std::format(
"Failed to assign Sound '{} (SoundID: {})' to Track '{} (TrackID: {})'. A sequence is currently playing on this track. Can't assign Sound when a sequence is playing.", sound->m_Name, sound->GetID(),
m_Name, m_ID)));
26 return std::unexpected(
Core::CoriError(std::format(
"Failed to assign Sound '{} (SoundID: {})' to Track '{} (TrackID: {})'. Track object is invalid.", sound->m_Name, sound->GetID(),
m_Name, m_ID)));
31 if (!m_ActiveSequence) {
33 return Mixer::PlayTrack(m_ID, params);
36 return std::unexpected(
Core::CoriError(std::format(
"Failed to play Track '{} (TrackID: {})'. A sequence is currently playing on this track. Can't play Sound when a sequence is playing.",
m_Name, m_ID)));
39 return std::unexpected(
Core::CoriError(std::format(
"Failed to play Track '{} (TrackID: {})'. Track object is invalid.",
m_Name, m_ID)));
42 std::expected<void, Core::CoriError<>>
Track::Stop(
const bool abruptStop,
const int64_t fadeOutMS) {
44 if (m_ActiveSequence) {
45 SetTrackStopCallbackInternal([
this] {
46 m_ActiveSequence =
false;
49 m_ActiveSequence =
false;
50 return StopInternal(fadeOutMS);
59 return std::unexpected(
Core::CoriError(std::format(
"Failed to stop sequence on Track '{} (TrackID: {})'. Track object is invalid.",
m_Name, m_ID)));
65 return Mixer::PauseTrack(m_ID);
68 return std::unexpected(
Core::CoriError(std::format(
"Failed to pause Track '{} (TrackID: {})'. Track object is invalid.",
m_Name, m_ID)));
74 return Mixer::ResumeTrack(m_ID);
77 return std::unexpected(
Core::CoriError(std::format(
"Failed to resume Track '{} (TrackID: {})'. Track object is invalid.",
m_Name, m_ID)));
82 return Mixer::IsTrackPaused(m_ID);
90 return Mixer::IsTrackPlaying(m_ID);
99 return Mixer::SetTrackGain(m_ID, gain);
102 return std::unexpected(
Core::CoriError(std::format(
"Failed to set Track '{} (TrackID: {})' gain. Track object is invalid.",
m_Name, m_ID)));
107 return Mixer::GetTrackGain(m_ID);
116 m_CurrentTag = std::string(tag);
117 return Mixer::TagTrack(m_ID, tag);
120 return std::unexpected(
Core::CoriError(std::format(
"Failed to assign Tag '{}' to Track '{} (TrackID: {})'. Track object is invalid.", tag,
m_Name, m_ID)));
126 Mixer::UntagTrack(m_ID, tag);
127 if (!preserveCachedTag) {
128 m_CurrentTag.clear();
129 m_CurrentTag.shrink_to_fit();
151 m_ClientCallBack = std::move(callback);
155 return std::shared_ptr<Track>(
new Track(std::move(name)));
159 Mixer::DestroyTrack(m_ID);
164 Track* coriTrack =
static_cast<Track*
>(userdata);
166 if (coriTrack->m_EngineCallBack) {
167 coriTrack->m_EngineCallBack();
170 if (coriTrack->m_ClientCallBack) {
171 coriTrack->m_ClientCallBack();
176 catch (
const std::exception& e) {
182 Track::Track(std::string name): m_Name(std::move(name)), m_ID(s_NextIndex.fetch_add(1, std::memory_order_relaxed)) {
183 auto result = Mixer::CreateTrack(
this);
192 std::expected<void, Core::CoriError<>> Track::PlaySoundWithParams(
SoundWithParams&
object) {
193 return SetSound(
object.first).and_then([
this,
object] {
194 return Start(
object.second);
198 std::expected<void, Core::CoriError<>> Track::StopInternal(
const int64_t fadeOutMS)
const {
200 if (!m_ActiveSequence) {
202 return Mixer::StopTrack(m_ID, fadeOutMS);
205 return std::unexpected(Core::CoriError(std::format(
"Failed to stop Track '{} (TrackID: {})'. A sequence is currently playing on this track. Can't stop when a sequence is playing.",
m_Name, m_ID)));
208 return std::unexpected(Core::CoriError(std::format(
"Failed to stop Track '{} (TrackID: {})'. Track object is invalid.",
m_Name, m_ID)));
211 std::expected<void, Core::CoriError<>> Track::ProcessSequencePart(
const SoundWithParams& part) {
212 m_SoundSequence.push_back(part);
218 m_EngineCallBack = std::move(callback);
#define CORI_CORE_ERROR(...)
#define CORI_CORE_DEBUG_TAGGED(...)
#define CORI_CORE_TRACE_TAGGED(...)
#define CORI_CORE_ERROR_TAGGED(...)
#define CORI_CORE_WARN_TAGGED(...)
void RemoveTag(const char *tag, const bool preserveCachedTag=false)
Removes the tag from the Track.
static void TrackStopCallback(void *userdata, MIX_Track *track)
For internal use only!
std::string_view GetTag() const
Gets the active/cached Track tag.
std::expected< void, Core::CoriError<> > Start(const PlayParams ¶ms=PlayParams{})
Starts the Track that has a preassigned Sound asset.
std::expected< void, Core::CoriError<> > Resume()
Resumes the Track.
std::expected< void, Core::CoriError<> > Stop(const bool abruptStop, const int64_t fadeOutMS=0)
Stops the Track.
bool IsValid() const
Check if the Track is valid.
float GetGain() const
Returns the current Track gain. The default gain for a Track is 1.0f.
TrackID GetID() const
Returns the TrackID associated with Track.
std::expected< void, Core::CoriError<> > SetSound(const std::shared_ptr< Sound > &sound)
Assigns the Sound asset to the Track.
bool IsPaused() const
Checks if the Track is paused.
std::expected< void, Core::CoriError<> > SetGain(const float gain)
Sets the Track gain.
void SetTrackStopCallback(TrackStopCallbackFn callback)
Sets a callback to be run when the Track stops playing.
std::expected< void, Core::CoriError<> > SetTag(const char *tag)
Assigns the tag to the Track.
static std::shared_ptr< Track > Create(std::string name)
Creates a Track object.
std::expected< void, Core::CoriError<> > Pause()
Pauses the Track.
bool IsPlaying() const
Checks if the Track is playing.
Custom error class mainly used in std::expected.
Everything connected to audio is in this namespace.
std::pair< std::shared_ptr< Sound >, PlayParams > SoundWithParams
std::function< void()> TrackStopCallbackFn
Parameters to be used when playing sound, you can mix your audio playback however you want with these...