From e95dbc6859267b5de559394b79dc1c087ca1c25c Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Sun, 21 Dec 2025 22:03:16 -0500
Subject: [PATCH] api: Added MIX_GetTrackFadeFrames.
Fixes #769.
---
include/SDL3_mixer/SDL_mixer.h | 24 ++++++++++++++++++++++++
src/SDL_mixer.c | 13 +++++++++++++
src/SDL_mixer.exports | 1 +
src/SDL_mixer.sym | 1 +
4 files changed, 39 insertions(+)
diff --git a/include/SDL3_mixer/SDL_mixer.h b/include/SDL3_mixer/SDL_mixer.h
index dfa31d7e..69dd2da4 100644
--- a/include/SDL3_mixer/SDL_mixer.h
+++ b/include/SDL3_mixer/SDL_mixer.h
@@ -1315,6 +1315,30 @@ extern SDL_DECLSPEC bool SDLCALL MIX_SetTrackPlaybackPosition(MIX_Track *track,
*/
extern SDL_DECLSPEC Sint64 SDLCALL MIX_GetTrackPlaybackPosition(MIX_Track *track);
+/**
+ * Query whether a given track is fading.
+ *
+ * This specifically checks if the track is _not stopped_ (paused or playing),
+ * and it is fading in or out, and returns the number of frames remaining in
+ * the fade.
+ *
+ * If fading out, the returned value will be negative. When fading in, the
+ * returned value will be positive. If not fading, this function returns zero.
+ *
+ * On various errors (MIX_Init() was not called, the track is NULL), this
+ * returns 0, but there is no mechanism to distinguish errors from tracks that
+ * aren't fading.
+ *
+ * \param track the track to query.
+ * \returns less than 0 if the track is fading out, greater than 0 if fading
+ * in, zero otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL_mixer 3.0.0.
+ */
+extern SDL_DECLSPEC Sint64 SDLCALL MIX_GetTrackFadeFrames(MIX_Track *track);
+
/**
* Query whether a given track is looping.
*
diff --git a/src/SDL_mixer.c b/src/SDL_mixer.c
index 9d72b538..73c7b6e4 100644
--- a/src/SDL_mixer.c
+++ b/src/SDL_mixer.c
@@ -1889,6 +1889,19 @@ Sint64 MIX_GetTrackRemaining(MIX_Track *track)
return retval;
}
+Sint64 MIX_GetTrackFadeFrames(MIX_Track *track)
+{
+ Sint64 retval = 0;
+ if (CheckTrackParam(track)) {
+ LockTrack(track);
+ if (track->state != MIX_STATE_STOPPED) {
+ retval = track->fade_frames * track->fade_direction;
+ }
+ UnlockTrack(track);
+ }
+ return retval;
+}
+
bool MIX_TrackLooping(MIX_Track *track)
{
bool retval = false;
diff --git a/src/SDL_mixer.exports b/src/SDL_mixer.exports
index de6d4065..3e530c11 100644
--- a/src/SDL_mixer.exports
+++ b/src/SDL_mixer.exports
@@ -85,4 +85,5 @@ _MIX_GetAudioDecoderProperties
_MIX_DecodeAudio
_MIX_GetAudioDecoderFormat
_MIX_SetTrackLoops
+_MIX_GetTrackFadeFrames
# extra symbols go here (don't modify this line)
diff --git a/src/SDL_mixer.sym b/src/SDL_mixer.sym
index 0d7a6ddd..be386d38 100644
--- a/src/SDL_mixer.sym
+++ b/src/SDL_mixer.sym
@@ -86,6 +86,7 @@ SDL3_mixer_0.0.0 {
MIX_DecodeAudio;
MIX_GetAudioDecoderFormat;
MIX_SetTrackLoops;
+ MIX_GetTrackFadeFrames;
# extra symbols go here (don't modify this line)
local: *;
};