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 0bc9576eb0
commit e42defa299
7 changed files with 145 additions and 228 deletions

View File

@ -136,14 +136,6 @@ void I_ResumeSong(INT32 handle);
// 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.
\param data pointer to song data
@ -153,7 +145,7 @@ void I_ShutdownMIDIMusic(void);
\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
@ -164,7 +156,7 @@ INT32 I_RegisterSong(void *data, size_t len);
\todo pass music name, not handle
*/
boolean I_PlaySong(INT32 handle, boolean looping);
boolean I_PlaySong(void);
/** \brief Stops a song over 3 seconds
@ -173,46 +165,25 @@ boolean I_PlaySong(INT32 handle, boolean looping);
/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
\sa I_RegisterSong
\sa I_LoadSong
\todo remove midi handle
*/
void I_UnRegisterSong(INT32 handle);
void I_UnloadSong(void);
//
// 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_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
\param volume volume to set at

View File

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

View File

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

View File

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

View File

@ -807,7 +807,7 @@ void S_UpdateSounds(void)
if (actualsfxvolume != cv_soundvolume.value)
S_SetSfxVolume (cv_soundvolume.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.
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
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;
void *mdata;
@ -1323,51 +1321,57 @@ static boolean S_MIDIMusic(const char *mname, boolean looping)
if (nomidimusic || music_disabled)
return false; // didn't search.
if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
return false;
mlumpnum = W_GetNumForName(va("d_%s", mname));
if (mus_forcemidi)
{
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
mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum));
#ifdef MUSSERV
if (msg_id != -1)
if (I_LoadSong(mdata, W_LumpLength(mlumpnum)))
{
struct musmsg msg_buffer;
msg_buffer.msg_type = 6;
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);
strncpy(music_name, mname, 7);
music_name[6] = 0;
return true;
}
#endif
// play it
if (!I_PlaySong(mhandle, looping))
else
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)
return false; // try midi
if (!I_StartDigSong(mname, looping))
if (!S_LoadSong(mname, looping))
return false;
if (!I_PlaySong())
{
S_UnloadSong();
return false;
}
strncpy(music_name, mname, 7);
music_name[6] = 0;
music_lumpnum = LUMPERROR;
music_data = NULL;
music_handle = 0;
return true;
}
@ -1386,7 +1390,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
if (strncmp(music_name, mmusic, 6))
{
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);
return;
@ -1408,12 +1412,9 @@ void S_StopMusic(void)
if (mus_paused)
I_ResumeSong(music_handle);
if (!nodigimusic)
I_StopDigSong();
S_SpeedMusic(1.0f);
I_StopSong(music_handle);
I_UnRegisterSong(music_handle);
I_StopSong();
I_UnloadSong();
#ifndef HAVE_SDL //SDL uses RWOPS
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)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
@ -1460,7 +1461,7 @@ void S_Init(INT32 sfxVolume, INT32 digMusicVolume)
return;
S_SetSfxVolume(sfxVolume);
S_SetDigMusicVolume(digMusicVolume);
S_SetMusicVolume(digMusicVolume);
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);
void S_SetDigMusicVolume(INT32 volume);
void S_SetMusicVolume(INT32 volume);
void S_SetSfxVolume(INT32 volume);
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)
{
#ifdef HAVE_LIBGME
gme = NULL;
current_track = -1;
#endif
}
void I_ShutdownMusic(void)
{
I_ShutdownDigMusic();
I_ShutdownMIDIMusic();
if (midimode)
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)
@ -492,51 +509,74 @@ void I_ResumeSong(INT32 handle)
// Digital Music
//
void I_InitDigMusic(void)
void I_SetDigMusicVolume(UINT8 volume)
{
#ifdef HAVE_LIBGME
gme = NULL;
current_track = -1;
#endif
music_volume = volume;
if (midimode || !music)
return;
Mix_VolumeMusic((UINT32)volume*128/31);
}
void I_ShutdownDigMusic(void)
boolean I_SetSongSpeed(float speed)
{
if (midimode)
return;
if (speed > 250.0f)
speed = 250.0f; //limit speed up to 250x
#ifdef HAVE_LIBGME
if (gme)
{
Mix_HookMusic(NULL, NULL);
gme_delete(gme);
gme = NULL;
SDL_LockAudio();
gme_set_tempo(gme, speed);
SDL_UnlockAudio();
return true;
}
#else
(void)speed;
#endif
if (!music)
return;
Mix_HookMusicFinished(NULL);
Mix_FreeMusic(music);
music = NULL;
return false;
}
boolean I_StartDigSong(const char *musicname, boolean looping)
boolean I_SetSongTrack(int track)
{
char *data;
size_t len;
lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname));
#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
//
boolean I_LoadSong(void *data, size_t len)
{
I_Assert(!music);
#ifdef HAVE_LIBGME
I_Assert(!gme);
#endif
if (lumpnum == LUMPERROR)
return false;
midimode = false;
data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
len = W_LumpLength(lumpnum);
#ifdef HAVE_LIBGME
if ((UINT8)data[0] == 0x1F
&& (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))
{
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;
}
#endif
@ -639,7 +675,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
if (!music)
{
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
return true;
return false;
}
// 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)
{
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return true;
return false;
}
Mix_VolumeMusic((UINT32)music_volume*128/31);
@ -689,7 +743,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
return true;
}
void I_StopDigSong(void)
void I_StopSong(void)
{
if (midimode)
return;
@ -710,116 +764,7 @@ void I_StopDigSong(void)
music = NULL;
}
void I_SetDigMusicVolume(UINT8 volume)
{
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)
void I_UnloadSong(void)
{
if (!midimode || !music)
return;