27 std::expected<void, Core::CoriError<>>
SetSound(
const std::shared_ptr<Sound>& sound);
51 if (!m_ActiveSequence) {
52 m_SoundSequence.clear();
53 m_SoundSequence.reserve(
sizeof...(sequence));
54 (..., m_SoundSequence.push_back(sequence));
55 m_EraseLastInSequence =
false;
56 m_SequenceIntroFinished =
false;
58 m_CurrentLoopedSequenceIndex = 0;
59 auto& initialPart = m_SoundSequence.back();
61 const auto success = PlaySoundWithParams(initialPart);
66 m_ActiveSequence =
true;
67 if constexpr (
sizeof...(sequence) > 2) {
68 if (!initialPart.second.LoopedInSequence) {
69 m_EraseLastInSequence =
true;
72 m_SequenceIntroFinished =
true;
73 m_CurrentLoopedSequenceIndex = m_SoundSequence.size() - 2;
76 SetTrackStopCallbackInternal([
this] {
77 if (m_EraseLastInSequence) {
78 m_SoundSequence.pop_back();
79 m_EraseLastInSequence =
false;
81 if (!m_SoundSequence.empty()) {
84 if (m_SequenceIntroFinished) {
85 part = &m_SoundSequence.at(m_CurrentLoopedSequenceIndex);
88 part = &m_SoundSequence.back();
91 m_ActiveSequence =
false;
92 const auto success_ = PlaySoundWithParams(*part);
96 m_ActiveSequence =
true;
98 if (!part->second.LoopedInSequence && !m_SequenceIntroFinished) {
99 m_EraseLastInSequence =
true;
102 if (m_SequenceIntroFinished) {
103 if (m_CurrentLoopedSequenceIndex == 0) {
104 m_CurrentLoopedSequenceIndex = m_SoundSequence.size() - 1;
107 --m_CurrentLoopedSequenceIndex;
111 m_SequenceIntroFinished =
true;
112 if (m_CurrentLoopedSequenceIndex == 0) {
113 m_CurrentLoopedSequenceIndex = m_SoundSequence.size() - 2;
116 --m_CurrentLoopedSequenceIndex;
122 const auto success_ =
Stop(
false);
131 if (initialPart.second.LoopedInSequence) {
132 SetTrackStopCallbackInternal([
this] {
134 m_ActiveSequence =
false;
135 const auto success_ = PlaySoundWithParams(*part);
139 m_ActiveSequence =
true;
144 m_ActiveSequence =
false;
149 return std::unexpected(
Core::CoriError(std::format(
"Failed to play sequence on Track '{} (TrackID: {})'. A sequence is already playing on this track.",
m_Name, m_ID)));
152 return std::unexpected(
Core::CoriError(std::format(
"Failed to play sequence on Track '{} (TrackID: {})'. Track object is invalid.",
m_Name, m_ID)));
163 std::expected<void, Core::CoriError<>>
Stop(
const bool abruptStop,
const int64_t fadeOutMS = 0);
171 std::expected<void, Core::CoriError<>>
Pause();
178 std::expected<void, Core::CoriError<>>
Resume();
184 [[nodiscard]]
bool IsPaused()
const;
200 std::expected<void, Core::CoriError<>>
SetGain(
const float gain);
207 [[nodiscard]]
float GetGain()
const;
214 std::expected<void, Core::CoriError<>>
SetTag(
const char* tag);
222 void RemoveTag(
const char* tag,
const bool preserveCachedTag =
false);
228 [[nodiscard]] std::string_view
GetTag()
const;
235 [[nodiscard]]
bool IsValid()
const;
254 [[nodiscard]]
static std::shared_ptr<Track>
Create(std::string name);
266 explicit Track(std::string name);
268 std::expected<void, Core::CoriError<>> PlaySoundWithParams(
SoundWithParams&
object);
270 std::expected<void, Core::CoriError<>> StopInternal(
const int64_t fadeOutMS)
const;
275 std::expected<void, Core::CoriError<>> ProcessSequencePart(
const SoundWithParams& part);
280 bool m_Valid{
false };
281 bool m_ActiveSequence{
false };
282 bool m_EraseLastInSequence{
false };
283 bool m_SequenceIntroFinished{
false };
284 uint32_t m_CurrentLoopedSequenceIndex{ 0 };
285 std::string m_CurrentTag{};
286 std::vector<SoundWithParams> m_SoundSequence;
287 inline static std::atomic<TrackID> s_NextIndex{ 1 };
#define CORI_CORE_ERROR_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.
std::expected< void, Core::CoriError<> > Play(const IsSoundWithParams auto &... sequence)
Plays a single or a sequence of SoundWithParams objects.
Custom error class mainly used in std::expected.
For InstanceMetrics to work with a type it should derive from this.
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...