ref: d609cd45c8165c3a34e22ef1d8a09378d2f05503
parent: a4cb2c15c5e2e6d90c6c69aaf84200b692c0303e
parent: ba766541ed30ccb1f5419f81ddbca227f14d19b9
author: Turo Lamminen <turol@users.noreply.github.com>
date: Mon Nov 7 06:15:20 EST 2022
Merge pull request #1531 from FozzeY/native-looping Use SDL_mixer built-in looping
--- a/src/i_musicpack.c
+++ b/src/i_musicpack.c
@@ -54,6 +54,21 @@
#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 @@
// 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 @@
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 @@
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 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 @@
// 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 @@
//{"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 @@
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,6 +1114,7 @@
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)
{
@@ -1099,6 +1121,7 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
RestartCurrentTrack();
}
}
+#endif // !USE_SDL_MIXER_LOOPING
}
music_module_t music_pack_module =