commit ba766541ed30ccb1f5419f81ddbca227f14d19b9
Author: FozzeY <tehfozzey@gmail.com>
AuthorDate: Sat Oct 29 21:21:55 2022 +0300
Commit: FozzeY <tehfozzey@gmail.com>
CommitDate: Fri Nov 4 17:38:42 2022 +0200
Use SDL_mixer built-in looping
---
src/i_musicpack.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/src/i_musicpack.c b/src/i_musicpack.c
index f2f62146..06b0eb47 100644
--- a/src/i_musicpack.c
+++ b/src/i_musicpack.c
@@ -54,6 +54,21 @@ char *music_pack_path = "";
#define MID_HEADER_MAGIC "MThd"
#define MUS_HEADER_MAGIC "MUS\x1a"
+// Starting with 2.6.0, SDL_mixer supports OGG and FLAC looping natively.
+// TODO: Once SDL_mixer 2.6.0+ is a requirement, delete the old looping code.
+#if !defined(USE_SDL_MIXER_LOOPING)
+#if defined(SDL_MIXER_VERSION_ATLEAST)
+#if SDL_MIXER_VERSION_ATLEAST(2, 6, 0)
+#define USE_SDL_MIXER_LOOPING 1
+#else
+#define USE_SDL_MIXER_LOOPING 0
+#endif // SDL_MIXER_VERSION_ATLEAST(2, 6, 0)
+#else
+#define USE_SDL_MIXER_LOOPING 0
+#endif // defined(SDL_MIXER_VERSION_ATLEAST)
+#endif // !defined(USE_SDL_MIXER_LOOPING)
+
+#if !USE_SDL_MIXER_LOOPING
#define FLAC_HEADER "fLaC"
#define OGG_HEADER "OggS"
@@ -71,6 +86,7 @@ char *music_pack_path = "";
// Ogg metadata headers that we care about.
#define OGG_ID_HEADER 1
#define OGG_COMMENT_HEADER 3
+#endif // !USE_SDL_MIXER_LOOPING
// Structure for music substitution.
// We store a mapping based on SHA1 checksum -> filename of substitute music
@@ -88,6 +104,7 @@ typedef struct
const char *filename;
} subst_music_t;
+#if !USE_SDL_MIXER_LOOPING
// Structure containing parsed metadata read from a digital music track:
typedef struct
{
@@ -95,6 +112,7 @@ typedef struct
unsigned int samplerate_hz;
int start_time, end_time;
} file_metadata_t;
+#endif // !USE_SDL_MIXER_LOOPING
static subst_music_t *subst_music = NULL;
static unsigned int subst_music_len = 0;
@@ -106,7 +124,7 @@ static boolean music_initialized = false;
static boolean sdl_was_initialized = false;
-
+#if !USE_SDL_MIXER_LOOPING
// If true, we are playing a substitute digital track rather than in-WAD
// MIDI/MUS track, and file_metadata contains loop metadata.
static file_metadata_t file_metadata;
@@ -114,6 +132,7 @@ static file_metadata_t file_metadata;
// Position (in samples) that we have reached in the current track.
// This is updated by the TrackPositionCallback function.
static unsigned int current_track_pos;
+#endif // !USE_SDL_MIXER_LOOPING
// Currently playing music track.
static Mix_Music *current_track_music = NULL;
@@ -338,6 +357,7 @@ static const subst_music_t known_filenames[] = {
//{"ec8fa484c4e85adbf700", "d_intro.{ext}"}, // 5
};
+#if !USE_SDL_MIXER_LOOPING
// Given a time string (for LOOP_START/LOOP_END), parse it and return
// the time (in # samples since start of track) it represents.
static unsigned int ParseVorbisTime(unsigned int samplerate_hz, char *value)
@@ -623,6 +643,7 @@ static void ReadLoopPoints(const char *filename, file_metadata_t *metadata)
metadata->valid = false;
}
}
+#endif // !USE_SDL_MIXER_LOOPING
// Given a MUS lump, look up a substitute MUS file to play instead
// (or NULL to just use normal MIDI playback).
@@ -1093,12 +1114,14 @@ static boolean SDLIsInitialized(void)
return Mix_QuerySpec(&freq, &format, &channels) != 0;
}
+#if !USE_SDL_MIXER_LOOPING
// Callback function that is invoked to track current track position.
void TrackPositionCallback(int chan, void *stream, int len, void *udata)
{
// Position is doubled up twice: for 16-bit samples and for stereo.
current_track_pos += len / 4;
}
+#endif // !USE_SDL_MIXER_LOOPING
// Initialize music subsystem
static boolean I_MP_InitMusic(void)
@@ -1156,8 +1179,10 @@ static boolean I_MP_InitMusic(void)
// Initialize SDL_Mixer for digital music playback
Mix_Init(MIX_INIT_FLAC | MIX_INIT_OGG | MIX_INIT_MP3);
+#if !USE_SDL_MIXER_LOOPING
// Register an effect function to track the music position.
Mix_RegisterEffect(MIX_CHANNEL_POST, TrackPositionCallback, NULL, NULL);
+#endif // !USE_SDL_MIXER_LOOPING
return music_initialized;
}
@@ -1197,6 +1222,7 @@ static void I_MP_PlaySong(void *handle, boolean looping)
loops = 1;
}
+#if !USE_SDL_MIXER_LOOPING
// Don't loop when playing substitute music, as we do it
// ourselves instead.
if (file_metadata.valid)
@@ -1206,6 +1232,7 @@ static void I_MP_PlaySong(void *handle, boolean looping)
current_track_pos = 0; // start of track
SDL_UnlockAudio();
}
+#endif // !USE_SDL_MIXER_LOOPING
if (Mix_PlayMusic(current_track_music, loops) == -1)
{
@@ -1289,9 +1316,11 @@ static void *I_MP_RegisterSong(void *data, int len)
return NULL;
}
+#if !USE_SDL_MIXER_LOOPING
// Read loop point metadata from the file so that we know where
// to loop the music.
ReadLoopPoints(filename, &file_metadata);
+#endif // !USE_SDL_MIXER_LOOPING
return music;
}
@@ -1306,6 +1335,7 @@ static boolean I_MP_MusicIsPlaying(void)
return Mix_PlayingMusic();
}
+#if !USE_SDL_MIXER_LOOPING
// Get position in substitute music track, in seconds since start of track.
static double GetMusicPosition(void)
{
@@ -1337,11 +1367,13 @@ static void RestartCurrentTrack(void)
current_track_pos = file_metadata.start_time;
SDL_UnlockAudio();
}
+#endif // !USE_SDL_MIXER_LOOPING
// Poll music position; if we have passed the loop point end position
// then we need to go back.
static void I_MP_PollMusic(void)
{
+#if !USE_SDL_MIXER_LOOPING
// When playing substitute tracks, loop tags only apply if we're playing
// a looping track. Tracks like the title screen music have the loop
// tags ignored.
@@ -1362,6 +1394,7 @@ static void I_MP_PollMusic(void)
RestartCurrentTrack();
}
}
+#endif // !USE_SDL_MIXER_LOOPING
}
music_module_t music_pack_module =