foxygit / doom Log in
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 =