Playback routines: Load, Play, Pause, Stop, Unload

* Re-purpose I_LoadSong for digital music loading
* I_StartDigSong logic split between I_LoadSong and I_PlaySong
* Pause, Stop, and Unload routines are combined from Digi and MIDI
* music_lumpnum, music_data, music_handle from s_sound.c are gone
This commit is contained in:
mazmazz 2018-08-23 09:02:14 -04:00
parent d159d8cad7
commit e8815df145
7 changed files with 145 additions and 228 deletions

View file

@ -136,14 +136,6 @@ void I_ResumeSong(INT32 handle);
// MIDI I/O // MIDI I/O
// //
/** \brief Startup the MIDI music system
*/
void I_InitMIDIMusic(void);
/** \brief Shutdown the MIDI music system
*/
void I_ShutdownMIDIMusic(void);
/** \brief Registers a song handle to song data. /** \brief Registers a song handle to song data.
\param data pointer to song data \param data pointer to song data
@ -153,7 +145,7 @@ void I_ShutdownMIDIMusic(void);
\todo Remove this \todo Remove this
*/ */
INT32 I_RegisterSong(void *data, size_t len); boolean I_LoadSong(void *data, size_t len);
/** \brief Called by anything that wishes to start music /** \brief Called by anything that wishes to start music
@ -164,7 +156,7 @@ INT32 I_RegisterSong(void *data, size_t len);
\todo pass music name, not handle \todo pass music name, not handle
*/ */
boolean I_PlaySong(INT32 handle, boolean looping); boolean I_PlaySong(void);
/** \brief Stops a song over 3 seconds /** \brief Stops a song over 3 seconds
@ -173,46 +165,25 @@ boolean I_PlaySong(INT32 handle, boolean looping);
/todo drop handle /todo drop handle
*/ */
void I_StopSong(INT32 handle); void I_StopSong(void);
/** \brief See ::I_RegisterSong, then think backwards /** \brief See ::I_LoadSong, then think backwards
\param handle song handle \param handle song handle
\sa I_RegisterSong \sa I_LoadSong
\todo remove midi handle \todo remove midi handle
*/ */
void I_UnRegisterSong(INT32 handle); void I_UnloadSong(void);
// //
// DIGMUSIC I/O // DIGMUSIC I/O
// //
/** \brief Startup the music system
*/
void I_InitDigMusic(void);
/** \brief Shutdown the music system
*/
void I_ShutdownDigMusic(void);
boolean I_SetSongSpeed(float speed); boolean I_SetSongSpeed(float speed);
boolean I_SetSongTrack(INT32 track); boolean I_SetSongTrack(INT32 track);
/** \brief The I_StartDigSong function
\param musicname music lump name
\param looping if true, loop the song
\return if true, song playing
*/
boolean I_StartDigSong(const char *musicname, boolean looping);
/** \brief stop non-MIDI song
*/
void I_StopDigSong(void);
/** \brief The I_SetDigMusicVolume function /** \brief The I_SetDigMusicVolume function
\param volume volume to set at \param volume volume to set at

View file

@ -3825,7 +3825,7 @@ msgid "Music lump is not MID music format\n"
msgstr "" msgstr ""
#: win32/win_snd.c:2128 #: win32/win_snd.c:2128
msgid "I_RegisterSong: StreamBufferSetup FAILED" msgid "I_LoadSong: StreamBufferSetup FAILED"
msgstr "" msgstr ""
#: win32/win_sys.c:892 #: win32/win_sys.c:892

View file

@ -4021,7 +4021,7 @@ msgid "Music lump is not MID music format\n"
msgstr "" msgstr ""
#: win32/win_snd.c:2126 #: win32/win_snd.c:2126
msgid "I_RegisterSong: StreamBufferSetup FAILED" msgid "I_LoadSong: StreamBufferSetup FAILED"
msgstr "" msgstr ""
#: win32/win_sys.c:894 #: win32/win_sys.c:894

View file

@ -9469,7 +9469,7 @@ static void M_ToggleDigital(INT32 choice)
if (nodigimusic) if (nodigimusic)
{ {
nodigimusic = false; nodigimusic = false;
I_InitDigMusic(); I_InitMusic();
if (nodigimusic) return; if (nodigimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value); S_Init(cv_soundvolume.value, cv_digmusicvolume.value);
S_StopMusic(); S_StopMusic();
@ -9526,7 +9526,7 @@ static void M_ToggleMIDI(INT32 choice)
if (nomidimusic) if (nomidimusic)
{ {
nomidimusic = false; nomidimusic = false;
I_InitMIDIMusic(); I_InitMusic();
if (nomidimusic) return; if (nomidimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value); S_Init(cv_soundvolume.value, cv_digmusicvolume.value);
if (Playing()) if (Playing())

View file

@ -807,7 +807,7 @@ void S_UpdateSounds(void)
if (actualsfxvolume != cv_soundvolume.value) if (actualsfxvolume != cv_soundvolume.value)
S_SetSfxVolume (cv_soundvolume.value); S_SetSfxVolume (cv_soundvolume.value);
if (actualdigmusicvolume != cv_digmusicvolume.value) if (actualdigmusicvolume != cv_digmusicvolume.value)
S_SetDigMusicVolume (cv_digmusicvolume.value); S_SetMusicVolume (cv_digmusicvolume.value);
// We're done now, if we're not in a level. // We're done now, if we're not in a level.
if (gamestate != GS_LEVEL) if (gamestate != GS_LEVEL)
@ -1308,13 +1308,11 @@ const char *compat_special_music_slots[16] =
#define music_playing (music_name[0]) // String is empty if no music is playing #define music_playing (music_name[0]) // String is empty if no music is playing
static char music_name[7]; // up to 6-character name static char music_name[7]; // up to 6-character name
static lumpnum_t music_lumpnum; // lump number of music (used??)
static void *music_data; // music raw data
static INT32 music_handle; // once registered, the handle for the music
static boolean mus_paused = 0; // whether songs are mus_paused static boolean mus_forcemidi = 0; // force midi even when digital exists
static boolean mus_paused = 0; // whether songs are mus_paused
static boolean S_MIDIMusic(const char *mname, boolean looping) static boolean S_LoadMusic(const char *mname, boolean looping)
{ {
lumpnum_t mlumpnum; lumpnum_t mlumpnum;
void *mdata; void *mdata;
@ -1323,51 +1321,57 @@ static boolean S_MIDIMusic(const char *mname, boolean looping)
if (nomidimusic || music_disabled) if (nomidimusic || music_disabled)
return false; // didn't search. return false; // didn't search.
if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR) if (mus_forcemidi)
return false; {
mlumpnum = W_GetNumForName(va("d_%s", mname)); if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
return false;
mlumpnum = W_GetNumForName(va("d_%s", mname));
}
else
{
if (W_CheckNumForName(va("o_%s", mname)) != LUMPERROR)
mlumpnum = W_GetNumForName(va("o_%s", mname));
else if (W_CheckNumForName(va("d_%s", mname)) != LUMPERROR)
mlumpnum = W_GetNumForName(va("d_%s", mname));
else
return false;
}
// load & register it // load & register it
mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC); mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum));
#ifdef MUSSERV if (I_LoadSong(mdata, W_LumpLength(mlumpnum)))
if (msg_id != -1)
{ {
struct musmsg msg_buffer; strncpy(music_name, mname, 7);
music_name[6] = 0;
msg_buffer.msg_type = 6; return true;
memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text));
sprintf(msg_buffer.msg_text, "d_%s", mname);
msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT);
} }
#endif else
// play it
if (!I_PlaySong(mhandle, looping))
return false; return false;
strncpy(music_name, mname, 7);
music_name[6] = 0;
music_lumpnum = mlumpnum;
music_data = mdata;
music_handle = mhandle;
return true;
} }
static boolean S_DigMusic(const char *mname, boolean looping) static void S_UnloadSong(void)
{
I_UnloadSong();
music_name[0] = 0;
}
static boolean S_PlayMusic(const char *mname, boolean looping)
{ {
if (nodigimusic || digital_disabled) if (nodigimusic || digital_disabled)
return false; // try midi return false; // try midi
if (!I_StartDigSong(mname, looping)) if (!S_LoadSong(mname, looping))
return false; return false;
if (!I_PlaySong())
{
S_UnloadSong();
return false;
}
strncpy(music_name, mname, 7); strncpy(music_name, mname, 7);
music_name[6] = 0; music_name[6] = 0;
music_lumpnum = LUMPERROR;
music_data = NULL;
music_handle = 0;
return true; return true;
} }
@ -1386,7 +1390,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
if (strncmp(music_name, mmusic, 6)) if (strncmp(music_name, mmusic, 6))
{ {
S_StopMusic(); // shutdown old music S_StopMusic(); // shutdown old music
if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping)) if (!S_LoadMusic(mmusic, looping) && !S_PlayMusic(mmusic, looping))
{ {
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic); CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic);
return; return;
@ -1408,12 +1412,9 @@ void S_StopMusic(void)
if (mus_paused) if (mus_paused)
I_ResumeSong(music_handle); I_ResumeSong(music_handle);
if (!nodigimusic)
I_StopDigSong();
S_SpeedMusic(1.0f); S_SpeedMusic(1.0f);
I_StopSong(music_handle); I_StopSong();
I_UnRegisterSong(music_handle); I_UnloadSong();
#ifndef HAVE_SDL //SDL uses RWOPS #ifndef HAVE_SDL //SDL uses RWOPS
Z_ChangeTag(music_data, PU_CACHE); Z_ChangeTag(music_data, PU_CACHE);
@ -1429,7 +1430,7 @@ void S_StopMusic(void)
} }
} }
void S_SetDigMusicVolume(INT32 volume) void S_SetMusicVolume(INT32 volume)
{ {
if (volume < 0 || volume > 31) if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
@ -1460,7 +1461,7 @@ void S_Init(INT32 sfxVolume, INT32 digMusicVolume)
return; return;
S_SetSfxVolume(sfxVolume); S_SetSfxVolume(sfxVolume);
S_SetDigMusicVolume(digMusicVolume); S_SetMusicVolume(digMusicVolume);
SetChannelsNum(); SetChannelsNum();

View file

@ -149,7 +149,7 @@ void S_UpdateSounds(void);
FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2); FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
void S_SetDigMusicVolume(INT32 volume); void S_SetMusicVolume(INT32 volume);
void S_SetSfxVolume(INT32 volume); void S_SetSfxVolume(INT32 volume);
INT32 S_OriginPlaying(void *origin); INT32 S_OriginPlaying(void *origin);

View file

@ -466,12 +466,29 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
FUNCMATH void I_InitMusic(void) FUNCMATH void I_InitMusic(void)
{ {
#ifdef HAVE_LIBGME
gme = NULL;
current_track = -1;
#endif
} }
void I_ShutdownMusic(void) void I_ShutdownMusic(void)
{ {
I_ShutdownDigMusic(); if (midimode)
I_ShutdownMIDIMusic(); return;
#ifdef HAVE_LIBGME
if (gme)
{
Mix_HookMusic(NULL, NULL);
gme_delete(gme);
gme = NULL;
}
#endif
if (!music)
return;
Mix_HookMusicFinished(NULL);
Mix_FreeMusic(music);
music = NULL;
} }
void I_PauseSong(INT32 handle) void I_PauseSong(INT32 handle)
@ -492,51 +509,74 @@ void I_ResumeSong(INT32 handle)
// Digital Music // Digital Music
// //
void I_InitDigMusic(void) void I_SetDigMusicVolume(UINT8 volume)
{ {
#ifdef HAVE_LIBGME music_volume = volume;
gme = NULL; if (midimode || !music)
current_track = -1; return;
#endif Mix_VolumeMusic((UINT32)volume*128/31);
} }
void I_ShutdownDigMusic(void) boolean I_SetSongSpeed(float speed)
{ {
if (midimode) if (speed > 250.0f)
return; speed = 250.0f; //limit speed up to 250x
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
if (gme) if (gme)
{ {
Mix_HookMusic(NULL, NULL); SDL_LockAudio();
gme_delete(gme); gme_set_tempo(gme, speed);
gme = NULL; SDL_UnlockAudio();
return true;
} }
#else
(void)speed;
#endif #endif
if (!music) return false;
return;
Mix_HookMusicFinished(NULL);
Mix_FreeMusic(music);
music = NULL;
} }
boolean I_StartDigSong(const char *musicname, boolean looping) boolean I_SetSongTrack(int track)
{ {
char *data; #ifdef HAVE_LIBGME
size_t len; if (current_track == track)
lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); return false;
// If the specified track is within the number of tracks playing, then change it
if (gme)
{
SDL_LockAudio();
if (track >= 0
&& track < gme_track_count(gme))
{
gme_err_t gme_e = gme_start_track(gme, track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
return false;
}
current_track = track;
SDL_UnlockAudio();
return true;
}
SDL_UnlockAudio();
return false;
}
#endif
(void)track;
return false;
}
//
// MIDI Music
//
boolean I_LoadSong(void *data, size_t len)
{
I_Assert(!music); I_Assert(!music);
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
I_Assert(!gme); I_Assert(!gme);
#endif #endif
if (lumpnum == LUMPERROR)
return false;
midimode = false;
data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
len = W_LumpLength(lumpnum);
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
if ((UINT8)data[0] == 0x1F if ((UINT8)data[0] == 0x1F
&& (UINT8)data[1] == 0x8B) && (UINT8)data[1] == 0x8B)
@ -627,10 +667,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
else if (!gme_open_data(data, len, &gme, 44100)) else if (!gme_open_data(data, len, &gme, 44100))
{ {
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
gme_start_track(gme, 0);
current_track = 0;
gme_set_equalizer(gme, &eq);
Mix_HookMusic(mix_gme, gme);
return true; return true;
} }
#endif #endif
@ -639,7 +675,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
if (!music) if (!music)
{ {
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
return true; return false;
} }
// Find the OGG loop point. // Find the OGG loop point.
@ -677,10 +713,28 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
} }
} }
return true;
}
boolean I_PlaySong(void)
{
if (!music)
return false;
#ifdef HAVE_GME
if (gme)
{
gme_start_track(gme, 0);
current_track = 0;
gme_set_equalizer(gme, &eq);
Mix_HookMusic(mix_gme, gme);
return true;
}
#endif
if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1) if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1)
{ {
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return true; return false;
} }
Mix_VolumeMusic((UINT32)music_volume*128/31); Mix_VolumeMusic((UINT32)music_volume*128/31);
@ -689,7 +743,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
return true; return true;
} }
void I_StopDigSong(void) void I_StopSong(void)
{ {
if (midimode) if (midimode)
return; return;
@ -710,116 +764,7 @@ void I_StopDigSong(void)
music = NULL; music = NULL;
} }
void I_SetDigMusicVolume(UINT8 volume) void I_UnloadSong(void)
{
music_volume = volume;
if (midimode || !music)
return;
Mix_VolumeMusic((UINT32)volume*128/31);
}
boolean I_SetSongSpeed(float speed)
{
if (speed > 250.0f)
speed = 250.0f; //limit speed up to 250x
#ifdef HAVE_LIBGME
if (gme)
{
SDL_LockAudio();
gme_set_tempo(gme, speed);
SDL_UnlockAudio();
return true;
}
#else
(void)speed;
#endif
return false;
}
boolean I_SetSongTrack(int track)
{
#ifdef HAVE_LIBGME
if (current_track == track)
return false;
// If the specified track is within the number of tracks playing, then change it
if (gme)
{
SDL_LockAudio();
if (track >= 0
&& track < gme_track_count(gme))
{
gme_err_t gme_e = gme_start_track(gme, track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
return false;
}
current_track = track;
SDL_UnlockAudio();
return true;
}
SDL_UnlockAudio();
return false;
}
#endif
(void)track;
return false;
}
//
// MIDI Music
//
FUNCMATH void I_InitMIDIMusic(void)
{
}
void I_ShutdownMIDIMusic(void)
{
if (!midimode || !music)
return;
Mix_FreeMusic(music);
music = NULL;
}
INT32 I_RegisterSong(void *data, size_t len)
{
music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE);
if (!music)
{
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
return -1;
}
return 1337;
}
boolean I_PlaySong(INT32 handle, boolean looping)
{
(void)handle;
midimode = true;
if (Mix_PlayMusic(music, looping ? -1 : 0) == -1)
{
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return false;
}
Mix_VolumeMusic((UINT32)midi_volume*128/31);
return true;
}
void I_StopSong(INT32 handle)
{
if (!midimode || !music)
return;
(void)handle;
Mix_HaltMusic();
}
void I_UnRegisterSong(INT32 handle)
{ {
if (!midimode || !music) if (!midimode || !music)
return; return;