I_GetMusicLoopPoint and I_SetMusicLoopPoint implementation

* Stub pause for MIDI
* Fix MP3 tag wide char search
* Reset songpaused bool where appropriate
This commit is contained in:
mazmazz 2018-08-18 20:19:44 -04:00
parent 137291d50b
commit fdd1af62a8
4 changed files with 97 additions and 23 deletions

View File

@ -237,6 +237,10 @@ boolean I_SetSongSpeed(float speed);
UINT32 I_GetMusicLength(void); UINT32 I_GetMusicLength(void);
boolean I_SetMusicLoopPoint(UINT32 looppoint);
UINT32 I_GetMusicLoopPoint(void);
boolean I_SetMusicPosition(UINT32 position); boolean I_SetMusicPosition(UINT32 position);
UINT32 I_GetMusicPosition(void); UINT32 I_GetMusicPosition(void);

View File

@ -1427,6 +1427,16 @@ UINT32 S_GetMusicLength(void)
return I_GetMusicLength(); return I_GetMusicLength();
} }
boolean S_SetMusicLoopPoint(UINT32 looppoint)
{
return I_SetMusicPosition(looppoint);
}
UINT32 S_GetMusicLoopPoint(void)
{
return I_GetMusicLoopPoint();
}
boolean S_SetMusicPosition(UINT32 position) boolean S_SetMusicPosition(UINT32 position)
{ {
return I_SetMusicPosition(position); return I_SetMusicPosition(position);

View File

@ -142,6 +142,12 @@ boolean S_SpeedMusic(float speed);
// Get Length of Music // Get Length of Music
UINT32 S_GetMusicLength(void); UINT32 S_GetMusicLength(void);
// Set LoopPoint of Music
boolean S_SetMusicLoopPoint(UINT32 looppoint);
// Get LoopPoint of Music
UINT32 S_GetMusicLoopPoint(void);
// Set Position of Music // Set Position of Music
boolean S_SetMusicPosition(UINT32 position); boolean S_SetMusicPosition(UINT32 position);

View File

@ -477,6 +477,7 @@ static void music_loop(void)
{ {
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
music_bytes = 0; music_bytes = 0;
songpaused = false;
// be consistent with FMOD, otherwise I'd prefer to freeze music_bytes // be consistent with FMOD, otherwise I'd prefer to freeze music_bytes
// since the other flags indicate music is still playing. // since the other flags indicate music is still playing.
} }
@ -516,8 +517,13 @@ void I_ShutdownMusic(void)
void I_PauseSong(INT32 handle) void I_PauseSong(INT32 handle)
{ {
(void)handle; (void)handle;
if(!midimode)
if(midimode) // really, SDL Mixer? why can't you pause MIDI???
return;
if(!gme && I_MusicType() != MU_MOD)
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_PauseMusic(); Mix_PauseMusic();
songpaused = true; songpaused = true;
} }
@ -525,14 +531,19 @@ void I_PauseSong(INT32 handle)
void I_ResumeSong(INT32 handle) void I_ResumeSong(INT32 handle)
{ {
(void)handle; (void)handle;
if(!midimode)
if (midimode)
return;
if (!gme && I_MusicType() != MU_MOD)
{ {
while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { } while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { }
// HACK: fixes issue of multiple effect callbacks being registered // HACK: fixes issue of multiple effect callbacks being registered
if(music && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL)) if(music && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
// midimode and music must be checked in case nothing is actually playing
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError()); CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
} }
Mix_ResumeMusic(); Mix_ResumeMusic();
songpaused = false; songpaused = false;
} }
@ -544,7 +555,7 @@ boolean I_MusicPlaying(void)
boolean I_MusicPaused(void) boolean I_MusicPaused(void)
{ {
return Mix_PausedMusic(); return songpaused;
} }
// //
@ -574,6 +585,7 @@ void I_ShutdownDigMusic(void)
if (!music) if (!music)
return; return;
is_looping = false; is_looping = false;
songpaused = false;
music_bytes = 0; music_bytes = 0;
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_HookMusicFinished(NULL); Mix_HookMusicFinished(NULL);
@ -714,16 +726,19 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
const char *key2 = "POINT="; const char *key2 = "POINT=";
const char *key3 = "MS="; const char *key3 = "MS=";
const char *key4 = "LENGTHMS="; const char *key4 = "LENGTHMS=";
const char *key1w = "L\0O\0O\0P\0";
const char *key2w = "P\0O\0I\0N\0T\0=\0";
const char *key3w = "M\0S\0=\0";
const char *key4w = "L\0E\0N\0G\0T\0H\0M\0S\0=\0";
const char *wterm = "\0\0";
const size_t key1len = strlen(key1); const size_t key1len = strlen(key1);
const size_t key2len = strlen(key2); const size_t key2len = strlen(key2);
const size_t key3len = strlen(key3); const size_t key3len = strlen(key3);
const size_t key4len = strlen(key4); const size_t key4len = strlen(key4);
char wval[10]; // millisecond range up to 30 hours!
// for mp3 wide chars
const char *key1w = "L\0O\0O\0P\0";
const char *key2w = "P\0O\0I\0N\0T\0\0\0\xFF\xFE";
const char *key3w = "M\0S\0\0\0\xFF\xFE";
const char *key4w = "L\0E\0N\0G\0T\0H\0M\0S\0\0\0\xFF\xFE";
const char *wterm = "\0\0";
char wval[10];
size_t wstart, wp; size_t wstart, wp;
char *p = data; char *p = data;
while ((UINT32)(p - data) < len) while ((UINT32)(p - data) < len)
@ -753,15 +768,15 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
music_length = (float)(atoi(p) / 1000.0L); music_length = (float)(atoi(p) / 1000.0L);
} }
// below: search MP3 or other tags that use wide char encoding // below: search MP3 or other tags that use wide char encoding
else if (!loop_point && !strncmp(p, key1w, key1len*2)) // LOOP wide char else if (!loop_point && !memcmp(p, key1w, key1len*2)) // LOOP wide char
{ {
p += key1len*2; p += key1len*2;
if (!strncmp(p, key2w, key2len*2)) // POINT= wide char if (!memcmp(p, key2w, (key2len+1)*2)) // POINT= wide char
{ {
p += key2len*2+2; p += (key2len+1)*2;
wstart = (size_t)p; wstart = (size_t)p;
wp = 0; wp = 0;
while (wp < 9 && strncmp(p, wterm, 2)) while (wp < 9 && memcmp(p, wterm, 2))
{ {
wval[wp] = *p; wval[wp] = *p;
p += 2; p += 2;
@ -770,12 +785,12 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
wval[min(wp, 9)] = 0; wval[min(wp, 9)] = 0;
loop_point = (float)((44.1L+atoi(wval) / 44100.0L)); loop_point = (float)((44.1L+atoi(wval) / 44100.0L));
} }
else if (!strncmp(p, key3w, key3len*2)) // MS= wide char else if (!memcmp(p, key3w, (key3len+1)*2)) // MS= wide char
{ {
p += key3len*2+2; p += (key3len+1)*2;
wstart = (size_t)p; wstart = (size_t)p;
wp = 0; wp = 0;
while (wp < 9 && strncmp(p, wterm, 2)) while (wp < 9 && memcmp(p, wterm, 2))
{ {
wval[wp] = *p; wval[wp] = *p;
p += 2; p += 2;
@ -785,12 +800,12 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
loop_point = (float)(atoi(wval) / 1000.0L); loop_point = (float)(atoi(wval) / 1000.0L);
} }
} }
else if (!music_length && !strncmp(p, key4w, key4len*2)) // LENGTHMS= wide char else if (!music_length && !memcmp(p, key4w, (key4len+1)*2)) // LENGTHMS= wide char
{ {
p += key4len*2+2; p += (key4len+1)*2;
wstart = (size_t)p; wstart = (size_t)p;
wp = 0; wp = 0;
while (wp < 9 && strncmp(p, wterm, 2)) while (wp < 9 && memcmp(p, wterm, 2))
{ {
wval[wp] = *p; wval[wp] = *p;
p += 2; p += 2;
@ -824,6 +839,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
if (I_MusicType() != MU_MOD) if (I_MusicType() != MU_MOD)
Mix_HookMusicFinished(music_loop); // don't bother counting if MOD Mix_HookMusicFinished(music_loop); // don't bother counting if MOD
songpaused = false;
music_bytes = 0; music_bytes = 0;
if(I_MusicType() != MU_MOD && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL)) if(I_MusicType() != MU_MOD && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError()); CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
@ -848,6 +864,7 @@ void I_StopDigSong(void)
if (!music) if (!music)
return; return;
is_looping = false; is_looping = false;
songpaused = false;
music_bytes = 0; music_bytes = 0;
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_HookMusicFinished(NULL); Mix_HookMusicFinished(NULL);
@ -924,6 +941,42 @@ UINT32 I_GetMusicLength(void)
} }
} }
boolean I_SetMusicLoopPoint(UINT32 looppoint)
{
if (midimode || gme || !music || I_MusicType() == MU_MOD)
return false;
else
{
loop_point = max((float)(looppoint / 1000.0L), 0);
return true;
}
}
UINT32 I_GetMusicLoopPoint(void)
{
if (gme)
{
INT32 looppoint;
gme_info_t *info;
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
looppoint = 0;
}
else
looppoint = info->intro_length > 0 ? info->intro_length : 0;
gme_free_info(info);
return max(looppoint, 0);
}
else if (midimode || !music || I_MusicType() == MU_MOD)
return 0;
else
return (UINT32)(loop_point * 1000);
}
boolean I_SetMusicPosition(UINT32 position) boolean I_SetMusicPosition(UINT32 position)
{ {
UINT32 length; UINT32 length;
@ -1056,6 +1109,7 @@ void I_ShutdownMIDIMusic(void)
if (!midimode || !music) if (!midimode || !music)
return; return;
is_looping = false; is_looping = false;
songpaused = false;
//MIDI does count correctly, but dummy out because unsupported //MIDI does count correctly, but dummy out because unsupported
//music_bytes = 0; //music_bytes = 0;
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); //Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
@ -1100,7 +1154,7 @@ boolean I_PlaySong(INT32 handle, boolean looping)
} }
is_looping = looping; is_looping = looping;
songpaused = false;
//MIDI does count correctly, but dummy out because unsupported //MIDI does count correctly, but dummy out because unsupported
//If this is enabled, you need to edit Mix_PlayMusic above to never loop (0) //If this is enabled, you need to edit Mix_PlayMusic above to never loop (0)
//and register the music_loop callback //and register the music_loop callback
@ -1118,7 +1172,7 @@ void I_StopSong(INT32 handle)
return; return;
is_looping = false; is_looping = false;
songpaused = false;
//MIDI does count correctly, but dummy out because unsupported //MIDI does count correctly, but dummy out because unsupported
//music_bytes = 0; //music_bytes = 0;
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); //Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
@ -1132,7 +1186,7 @@ void I_UnRegisterSong(INT32 handle)
return; return;
is_looping = false; is_looping = false;
songpaused = false;
//MIDI does count correctly, but dummy out because unsupported //MIDI does count correctly, but dummy out because unsupported
//music_bytes = 0; //music_bytes = 0;
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); //Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);