mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
- cleaned up i_music.cpp.
SVN r2866 (trunk)
This commit is contained in:
parent
5be9729872
commit
5464676603
5 changed files with 308 additions and 295 deletions
|
@ -1688,7 +1688,7 @@ void S_PauseSound (bool notmusic, bool notsfx)
|
||||||
{
|
{
|
||||||
if (!notmusic && mus_playing.handle && !MusicPaused)
|
if (!notmusic && mus_playing.handle && !MusicPaused)
|
||||||
{
|
{
|
||||||
I_PauseSong (mus_playing.handle);
|
mus_playing.handle->Pause();
|
||||||
MusicPaused = true;
|
MusicPaused = true;
|
||||||
}
|
}
|
||||||
if (!notsfx)
|
if (!notsfx)
|
||||||
|
@ -1709,7 +1709,7 @@ void S_ResumeSound (bool notsfx)
|
||||||
{
|
{
|
||||||
if (mus_playing.handle && MusicPaused)
|
if (mus_playing.handle && MusicPaused)
|
||||||
{
|
{
|
||||||
I_ResumeSong (mus_playing.handle);
|
mus_playing.handle->Resume();
|
||||||
MusicPaused = false;
|
MusicPaused = false;
|
||||||
}
|
}
|
||||||
if (!notsfx)
|
if (!notsfx)
|
||||||
|
@ -1868,11 +1868,11 @@ void S_UpdateSounds (AActor *listenactor)
|
||||||
|
|
||||||
I_UpdateMusic();
|
I_UpdateMusic();
|
||||||
|
|
||||||
// [RH] Update music and/or playlist. I_QrySongPlaying() must be called
|
// [RH] Update music and/or playlist. IsPlaying() must be called
|
||||||
// to attempt to reconnect to broken net streams and to advance the
|
// to attempt to reconnect to broken net streams and to advance the
|
||||||
// playlist when the current song finishes.
|
// playlist when the current song finishes.
|
||||||
if (mus_playing.handle != NULL &&
|
if (mus_playing.handle != NULL &&
|
||||||
!I_QrySongPlaying(mus_playing.handle) &&
|
!mus_playing.handle->IsPlaying() &&
|
||||||
PlayList)
|
PlayList)
|
||||||
{
|
{
|
||||||
PlayList->Advance();
|
PlayList->Advance();
|
||||||
|
@ -2479,7 +2479,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
||||||
|
|
||||||
if (mus_playing.handle != 0)
|
if (mus_playing.handle != 0)
|
||||||
{ // play it
|
{ // play it
|
||||||
I_PlaySong (mus_playing.handle, looping, S_GetMusicVolume (musicname), order);
|
mus_playing.handle->Start(looping, S_GetMusicVolume (musicname), order);
|
||||||
mus_playing.baseorder = order;
|
mus_playing.baseorder = order;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2537,15 +2537,17 @@ void S_StopMusic (bool force)
|
||||||
// [RH] Don't stop if a playlist is active.
|
// [RH] Don't stop if a playlist is active.
|
||||||
if ((force || PlayList == NULL) && !mus_playing.name.IsEmpty())
|
if ((force || PlayList == NULL) && !mus_playing.name.IsEmpty())
|
||||||
{
|
{
|
||||||
if (MusicPaused)
|
if (mus_playing.handle != NULL)
|
||||||
I_ResumeSong(mus_playing.handle);
|
{
|
||||||
|
if (MusicPaused)
|
||||||
I_StopSong(mus_playing.handle);
|
mus_playing.handle->Resume();
|
||||||
I_UnRegisterSong(mus_playing.handle);
|
|
||||||
|
|
||||||
|
mus_playing.handle->Stop();
|
||||||
|
delete mus_playing.handle;
|
||||||
|
mus_playing.handle = NULL;
|
||||||
|
}
|
||||||
LastSong = mus_playing.name;
|
LastSong = mus_playing.name;
|
||||||
mus_playing.name = "";
|
mus_playing.name = "";
|
||||||
mus_playing.handle = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,68 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void I_InitMusic (void)
|
||||||
|
{
|
||||||
|
static bool setatterm = false;
|
||||||
|
|
||||||
|
Timidity::LoadConfig();
|
||||||
|
|
||||||
|
snd_musicvolume.Callback ();
|
||||||
|
|
||||||
|
nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound");
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
I_InitMusicWin32 ();
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
if (!setatterm)
|
||||||
|
{
|
||||||
|
setatterm = true;
|
||||||
|
atterm (I_ShutdownMusic);
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
signal (SIGCHLD, ChildSigHandler);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
MusicDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void I_ShutdownMusic(void)
|
||||||
|
{
|
||||||
|
if (MusicDown)
|
||||||
|
return;
|
||||||
|
MusicDown = true;
|
||||||
|
if (currSong)
|
||||||
|
{
|
||||||
|
S_StopMusic (true);
|
||||||
|
assert (currSong == NULL);
|
||||||
|
}
|
||||||
|
Timidity::FreeAll();
|
||||||
|
#ifdef _WIN32
|
||||||
|
I_ShutdownMusicWin32();
|
||||||
|
#endif // _WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
MusInfo::MusInfo()
|
MusInfo::MusInfo()
|
||||||
: m_Status(STATE_Stopped), m_Looping(false), m_NotStartedYet(true)
|
: m_Status(STATE_Stopped), m_Looping(false), m_NotStartedYet(true)
|
||||||
{
|
{
|
||||||
|
@ -147,8 +209,39 @@ MusInfo::MusInfo()
|
||||||
|
|
||||||
MusInfo::~MusInfo ()
|
MusInfo::~MusInfo ()
|
||||||
{
|
{
|
||||||
|
if (currSong == this) currSong = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// starts playing this song
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void MusInfo::Start(bool loop, float rel_vol, int subsong)
|
||||||
|
{
|
||||||
|
if (nomusic) return;
|
||||||
|
|
||||||
|
if (rel_vol > 0.f) saved_relative_volume = relative_volume = rel_vol;
|
||||||
|
Stop ();
|
||||||
|
Play (loop, subsong);
|
||||||
|
m_NotStartedYet = false;
|
||||||
|
|
||||||
|
if (m_Status == MusInfo::STATE_Playing)
|
||||||
|
currSong = this;
|
||||||
|
else
|
||||||
|
currSong = NULL;
|
||||||
|
|
||||||
|
// Notify the sound system of the changed relative volume
|
||||||
|
snd_musicvolume.Callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
bool MusInfo::SetPosition (unsigned int ms)
|
bool MusInfo::SetPosition (unsigned int ms)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -198,121 +291,38 @@ MusInfo *MusInfo::GetWaveDumper(const char *filename, int rate)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_InitMusic (void)
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// create a streamer based on MIDI file type
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static MIDIStreamer *CreateMIDIStreamer(FILE *file, BYTE *musiccache, int len, EMIDIDevice devtype, EMIDIType miditype)
|
||||||
{
|
{
|
||||||
static bool setatterm = false;
|
switch (miditype)
|
||||||
|
|
||||||
Timidity::LoadConfig();
|
|
||||||
|
|
||||||
snd_musicvolume.Callback ();
|
|
||||||
|
|
||||||
nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound");
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
I_InitMusicWin32 ();
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
if (!setatterm)
|
|
||||||
{
|
{
|
||||||
setatterm = true;
|
case MIDI_MUS:
|
||||||
atterm (I_ShutdownMusic);
|
return new MUSSong2(file, musiccache, len, devtype);
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
signal (SIGCHLD, ChildSigHandler);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
MusicDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
case MIDI_MIDI:
|
||||||
|
return new MIDISong2(file, musiccache, len, devtype);
|
||||||
|
|
||||||
void I_ShutdownMusic(void)
|
case MIDI_HMI:
|
||||||
{
|
return new HMISong(file, musiccache, len, devtype);
|
||||||
if (MusicDown)
|
|
||||||
return;
|
|
||||||
MusicDown = true;
|
|
||||||
if (currSong)
|
|
||||||
{
|
|
||||||
S_StopMusic (true);
|
|
||||||
assert (currSong == NULL);
|
|
||||||
}
|
|
||||||
Timidity::FreeAll();
|
|
||||||
#ifdef _WIN32
|
|
||||||
I_ShutdownMusicWin32();
|
|
||||||
#endif // _WIN32
|
|
||||||
}
|
|
||||||
|
|
||||||
|
case MIDI_XMI:
|
||||||
|
return new XMISong(file, musiccache, len, devtype);
|
||||||
|
|
||||||
void I_PlaySong (void *handle, int _looping, float rel_vol, int subsong)
|
default:
|
||||||
{
|
return NULL;
|
||||||
MusInfo *info = (MusInfo *)handle;
|
|
||||||
|
|
||||||
if (!info || nomusic)
|
|
||||||
return;
|
|
||||||
|
|
||||||
saved_relative_volume = relative_volume = rel_vol;
|
|
||||||
info->Stop ();
|
|
||||||
info->Play (!!_looping, subsong);
|
|
||||||
info->m_NotStartedYet = false;
|
|
||||||
|
|
||||||
if (info->m_Status == MusInfo::STATE_Playing)
|
|
||||||
currSong = info;
|
|
||||||
else
|
|
||||||
currSong = NULL;
|
|
||||||
|
|
||||||
// Notify the sound system of the changed relative volume
|
|
||||||
snd_musicvolume.Callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void I_PauseSong (void *handle)
|
|
||||||
{
|
|
||||||
MusInfo *info = (MusInfo *)handle;
|
|
||||||
|
|
||||||
if (info)
|
|
||||||
info->Pause ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_ResumeSong (void *handle)
|
|
||||||
{
|
|
||||||
MusInfo *info = (MusInfo *)handle;
|
|
||||||
|
|
||||||
if (info)
|
|
||||||
info->Resume ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopSong (void *handle)
|
|
||||||
{
|
|
||||||
MusInfo *info = (MusInfo *)handle;
|
|
||||||
|
|
||||||
if (info)
|
|
||||||
info->Stop ();
|
|
||||||
|
|
||||||
if (info == currSong)
|
|
||||||
currSong = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_UnRegisterSong (void *handle)
|
|
||||||
{
|
|
||||||
MusInfo *info = (MusInfo *)handle;
|
|
||||||
|
|
||||||
if (info)
|
|
||||||
{
|
|
||||||
delete info;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MusInfo *I_RegisterURLSong (const char *url)
|
//==========================================================================
|
||||||
{
|
//
|
||||||
StreamSong *song;
|
// create a MIDI player
|
||||||
|
//
|
||||||
song = new StreamSong(url, 0, 0);
|
//==========================================================================
|
||||||
if (song->IsValid())
|
|
||||||
{
|
|
||||||
return song;
|
|
||||||
}
|
|
||||||
delete song;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MusInfo *CreateMIDISong(FILE *file, const char *filename, BYTE *musiccache, int offset, int len, EMIDIDevice devtype, EMIDIType miditype)
|
static MusInfo *CreateMIDISong(FILE *file, const char *filename, BYTE *musiccache, int offset, int len, EMIDIDevice devtype, EMIDIType miditype)
|
||||||
{
|
{
|
||||||
|
@ -333,35 +343,130 @@ static MusInfo *CreateMIDISong(FILE *file, const char *filename, BYTE *musiccach
|
||||||
return new StreamSong(filename, offset, len);
|
return new StreamSong(filename, offset, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (miditype == MIDI_MUS)
|
else return CreateMIDIStreamer(file, musiccache, len, devtype, miditype);
|
||||||
{
|
|
||||||
return new MUSSong2(file, musiccache, len, devtype);
|
|
||||||
}
|
|
||||||
else if (miditype == MIDI_MIDI)
|
|
||||||
{
|
|
||||||
return new MIDISong2(file, musiccache, len, devtype);
|
|
||||||
}
|
|
||||||
else if (miditype == MIDI_HMI)
|
|
||||||
{
|
|
||||||
return new HMISong(file, musiccache, len, devtype);
|
|
||||||
}
|
|
||||||
else if (miditype == MIDI_XMI)
|
|
||||||
{
|
|
||||||
return new XMISong(file, musiccache, len, devtype);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// identify MIDI file type
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static EMIDIType IdentifyMIDIType(DWORD *id, int size)
|
||||||
|
{
|
||||||
|
// Check for MUS format
|
||||||
|
// Tolerate sloppy wads by searching up to 32 bytes for the header
|
||||||
|
if (MUSHeaderSearch((BYTE*)id, size) >= 0)
|
||||||
|
{
|
||||||
|
return MIDI_MUS;
|
||||||
|
}
|
||||||
|
// Check for HMI format
|
||||||
|
else
|
||||||
|
if (id[0] == MAKE_ID('H','M','I','-') &&
|
||||||
|
id[1] == MAKE_ID('M','I','D','I') &&
|
||||||
|
id[2] == MAKE_ID('S','O','N','G'))
|
||||||
|
{
|
||||||
|
return MIDI_HMI;
|
||||||
|
}
|
||||||
|
// Check for HMP format
|
||||||
|
else
|
||||||
|
if (id[0] == MAKE_ID('H','M','I','M') &&
|
||||||
|
id[1] == MAKE_ID('I','D','I','P'))
|
||||||
|
{
|
||||||
|
return MIDI_HMI;
|
||||||
|
}
|
||||||
|
// Check for XMI format
|
||||||
|
else
|
||||||
|
if ((id[0] == MAKE_ID('F','O','R','M') &&
|
||||||
|
id[2] == MAKE_ID('X','D','I','R')) ||
|
||||||
|
((id[0] == MAKE_ID('C','A','T',' ') || id[0] == MAKE_ID('F','O','R','M')) &&
|
||||||
|
id[2] == MAKE_ID('X','M','I','D')))
|
||||||
|
{
|
||||||
|
return MIDI_XMI;
|
||||||
|
}
|
||||||
|
// Check for MIDI format
|
||||||
|
else if (id[0] == MAKE_ID('M','T','h','d'))
|
||||||
|
{
|
||||||
|
return MIDI_MIDI;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MIDI_NOTMIDI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// select the MIDI device to play on
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static EMIDIDevice SelectMIDIDevice(int device)
|
||||||
|
{
|
||||||
|
/* MIDI are played as:
|
||||||
|
- OPL:
|
||||||
|
- if explicitly selected by $mididevice
|
||||||
|
- when snd_mididevice is -3 and no midi device is set for the song
|
||||||
|
|
||||||
|
- Timidity:
|
||||||
|
- if explicitly selected by $mididevice
|
||||||
|
- when snd_mididevice is -2 and no midi device is set for the song
|
||||||
|
|
||||||
|
- FMod:
|
||||||
|
- if explicitly selected by $mididevice
|
||||||
|
- when snd_mididevice is -1 and no midi device is set for the song
|
||||||
|
- as fallback when both OPL and Timidity failed unless snd_mididevice is >= 0
|
||||||
|
|
||||||
|
- MMAPI (Win32 only):
|
||||||
|
- if explicitly selected by $mididevice (non-Win32 redirects this to FMOD)
|
||||||
|
- when snd_mididevice is >= 0 and no midi device is set for the song
|
||||||
|
- as fallback when both OPL and Timidity failed and snd_mididevice is >= 0
|
||||||
|
*/
|
||||||
|
EMIDIDevice devtype = MIDI_Null;
|
||||||
|
|
||||||
|
// Choose the type of MIDI device we want.
|
||||||
|
if (device == MDEV_FMOD || (snd_mididevice == -1 && device == MDEV_DEFAULT))
|
||||||
|
{
|
||||||
|
return MIDI_FMOD;
|
||||||
|
}
|
||||||
|
else if (device == MDEV_TIMIDITY || (snd_mididevice == -2 && device == MDEV_DEFAULT))
|
||||||
|
{
|
||||||
|
return MIDI_Timidity;
|
||||||
|
}
|
||||||
|
else if (device == MDEV_OPL || (snd_mididevice == -3 && device == MDEV_DEFAULT))
|
||||||
|
{
|
||||||
|
return MIDI_OPL;
|
||||||
|
}
|
||||||
|
else if (device == MDEV_GUS || (snd_mididevice == -4 && device == MDEV_DEFAULT))
|
||||||
|
{
|
||||||
|
return MIDI_GUS;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
|
else if (device == MDEV_FLUIDSYNTH || (snd_mididevice == -5 && device == MDEV_DEFAULT))
|
||||||
|
{
|
||||||
|
return MIDI_Fluid;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
return MIDI_Win;
|
||||||
|
#else
|
||||||
|
return MIDI_Null;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// identify a music lump's type and set up a player for it
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int len, int device)
|
MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int len, int device)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
MusInfo *info = NULL;
|
MusInfo *info = NULL;
|
||||||
union
|
|
||||||
{
|
|
||||||
DWORD id[32/4];
|
|
||||||
BYTE idstr[32];
|
|
||||||
};
|
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
DWORD id[32/4];
|
||||||
BYTE *ungzipped;
|
BYTE *ungzipped;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -452,134 +557,34 @@ MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EMIDIType miditype = MIDI_NOTMIDI;
|
EMIDIType miditype = IdentifyMIDIType(id, sizeof(id));
|
||||||
|
|
||||||
// Check for MUS format
|
|
||||||
// Tolerate sloppy wads by searching up to 32 bytes for the header
|
|
||||||
if (MUSHeaderSearch(idstr, sizeof(idstr)) >= 0)
|
|
||||||
{
|
|
||||||
miditype = MIDI_MUS;
|
|
||||||
}
|
|
||||||
// Check for HMI format
|
|
||||||
else
|
|
||||||
if (id[0] == MAKE_ID('H','M','I','-') &&
|
|
||||||
id[1] == MAKE_ID('M','I','D','I') &&
|
|
||||||
id[2] == MAKE_ID('S','O','N','G'))
|
|
||||||
{
|
|
||||||
miditype = MIDI_HMI;
|
|
||||||
}
|
|
||||||
// Check for HMP format
|
|
||||||
else
|
|
||||||
if (id[0] == MAKE_ID('H','M','I','M') &&
|
|
||||||
id[1] == MAKE_ID('I','D','I','P'))
|
|
||||||
{
|
|
||||||
miditype = MIDI_HMI;
|
|
||||||
}
|
|
||||||
// Check for XMI format
|
|
||||||
else
|
|
||||||
if ((id[0] == MAKE_ID('F','O','R','M') &&
|
|
||||||
id[2] == MAKE_ID('X','D','I','R')) ||
|
|
||||||
((id[0] == MAKE_ID('C','A','T',' ') || id[0] == MAKE_ID('F','O','R','M')) &&
|
|
||||||
id[2] == MAKE_ID('X','M','I','D')))
|
|
||||||
{
|
|
||||||
miditype = MIDI_XMI;
|
|
||||||
}
|
|
||||||
// Check for MIDI format
|
|
||||||
else if (id[0] == MAKE_ID('M','T','h','d'))
|
|
||||||
{
|
|
||||||
miditype = MIDI_MIDI;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (miditype != MIDI_NOTMIDI)
|
if (miditype != MIDI_NOTMIDI)
|
||||||
{
|
{
|
||||||
TArray<BYTE> midi;
|
TArray<BYTE> midi;
|
||||||
/* MIDI are played as:
|
|
||||||
- OPL:
|
|
||||||
- if explicitly selected by $mididevice
|
|
||||||
- when snd_mididevice is -3 and no midi device is set for the song
|
|
||||||
|
|
||||||
- Timidity:
|
EMIDIDevice devtype = SelectMIDIDevice(device);
|
||||||
- if explicitly selected by $mididevice
|
|
||||||
- when snd_mididevice is -2 and no midi device is set for the song
|
|
||||||
|
|
||||||
- FMod:
|
|
||||||
- if explicitly selected by $mididevice
|
|
||||||
- when snd_mididevice is -1 and no midi device is set for the song
|
|
||||||
- as fallback when both OPL and Timidity failed unless snd_mididevice is >= 0
|
|
||||||
|
|
||||||
- MMAPI (Win32 only):
|
|
||||||
- if explicitly selected by $mididevice (non-Win32 redirects this to FMOD)
|
|
||||||
- when snd_mididevice is >= 0 and no midi device is set for the song
|
|
||||||
- as fallback when both OPL and Timidity failed and snd_mididevice is >= 0
|
|
||||||
*/
|
|
||||||
EMIDIDevice devtype = MIDI_Null;
|
|
||||||
|
|
||||||
// Choose the type of MIDI device we want.
|
|
||||||
if (device == MDEV_FMOD || (snd_mididevice == -1 && device == MDEV_DEFAULT))
|
|
||||||
{
|
|
||||||
devtype = MIDI_FMOD;
|
|
||||||
}
|
|
||||||
else if (device == MDEV_TIMIDITY || (snd_mididevice == -2 && device == MDEV_DEFAULT))
|
|
||||||
{
|
|
||||||
devtype = MIDI_Timidity;
|
|
||||||
}
|
|
||||||
else if (device == MDEV_OPL || (snd_mididevice == -3 && device == MDEV_DEFAULT))
|
|
||||||
{
|
|
||||||
devtype = MIDI_OPL;
|
|
||||||
}
|
|
||||||
else if (device == MDEV_GUS || (snd_mididevice == -4 && device == MDEV_DEFAULT))
|
|
||||||
{
|
|
||||||
devtype = MIDI_GUS;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_FLUIDSYNTH
|
|
||||||
else if (device == MDEV_FLUIDSYNTH || (snd_mididevice == -5 && device == MDEV_DEFAULT))
|
|
||||||
{
|
|
||||||
devtype = MIDI_Fluid;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
else
|
|
||||||
{
|
|
||||||
devtype = MIDI_Win;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
retry_as_fmod:
|
retry_as_fmod:
|
||||||
if (devtype >= MIDI_Null)
|
if (devtype >= MIDI_Null)
|
||||||
{
|
{
|
||||||
// Convert to standard MIDI for external sequencers.
|
// Convert to standard MIDI for external sequencers.
|
||||||
MIDIStreamer *streamer;
|
MIDIStreamer *streamer = CreateMIDIStreamer(file, musiccache, len, MIDI_Null, miditype);
|
||||||
|
if (streamer != NULL)
|
||||||
if (miditype == MIDI_MIDI)
|
|
||||||
{
|
{
|
||||||
streamer = new MIDISong2(file, musiccache, len, MIDI_Null);
|
if (streamer->IsValid())
|
||||||
}
|
|
||||||
else if (miditype == MIDI_MUS)
|
|
||||||
{
|
|
||||||
streamer = new MUSSong2(file, musiccache, len, MIDI_Null);
|
|
||||||
}
|
|
||||||
else if (miditype == MIDI_XMI)
|
|
||||||
{
|
|
||||||
streamer = new XMISong(file, musiccache, len, MIDI_Null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(miditype == MIDI_HMI);
|
|
||||||
streamer = new HMISong(file, musiccache, len, MIDI_Null);
|
|
||||||
}
|
|
||||||
if (streamer->IsValid())
|
|
||||||
{
|
|
||||||
streamer->CreateSMF(midi);
|
|
||||||
miditype = MIDI_MIDI;
|
|
||||||
musiccache = &midi[0];
|
|
||||||
len = midi.Size();
|
|
||||||
if (file != NULL)
|
|
||||||
{
|
{
|
||||||
fclose(file);
|
streamer->CreateSMF(midi);
|
||||||
file = NULL;
|
miditype = MIDI_MIDI;
|
||||||
|
musiccache = &midi[0];
|
||||||
|
len = midi.Size();
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
fclose(file);
|
||||||
|
file = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
delete streamer;
|
||||||
}
|
}
|
||||||
delete streamer;
|
|
||||||
}
|
}
|
||||||
info = CreateMIDISong(file, filename, musiccache, offset, len, devtype, miditype);
|
info = CreateMIDISong(file, filename, musiccache, offset, len, devtype, miditype);
|
||||||
if (info != NULL && !info->IsValid())
|
if (info != NULL && !info->IsValid())
|
||||||
|
@ -678,6 +683,12 @@ retry_as_fmod:
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// play CD music
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
MusInfo *I_RegisterCDSong (int track, int id)
|
MusInfo *I_RegisterCDSong (int track, int id)
|
||||||
{
|
{
|
||||||
MusInfo *info = new CDSong (track, id);
|
MusInfo *info = new CDSong (track, id);
|
||||||
|
@ -691,6 +702,25 @@ MusInfo *I_RegisterCDSong (int track, int id)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
MusInfo *I_RegisterURLSong (const char *url)
|
||||||
|
{
|
||||||
|
StreamSong *song;
|
||||||
|
|
||||||
|
song = new StreamSong(url, 0, 0);
|
||||||
|
if (song->IsValid())
|
||||||
|
{
|
||||||
|
return song;
|
||||||
|
}
|
||||||
|
delete song;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// ungzip
|
// ungzip
|
||||||
|
@ -773,6 +803,12 @@ BYTE *ungzip(BYTE *data, int *complen)
|
||||||
return newdata;
|
return newdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void I_UpdateMusic()
|
void I_UpdateMusic()
|
||||||
{
|
{
|
||||||
if (currSong != NULL)
|
if (currSong != NULL)
|
||||||
|
@ -781,22 +817,12 @@ void I_UpdateMusic()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the song playing?
|
//==========================================================================
|
||||||
bool I_QrySongPlaying (void *handle)
|
//
|
||||||
{
|
|
||||||
MusInfo *info = (MusInfo *)handle;
|
|
||||||
|
|
||||||
return info ? info->IsPlaying () : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change to a different part of the song
|
|
||||||
bool I_SetSongPosition (void *handle, int order)
|
|
||||||
{
|
|
||||||
MusInfo *info = (MusInfo *)handle;
|
|
||||||
return info ? info->SetPosition (order) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets relative music volume. Takes $musicvolume in SNDINFO into consideration
|
// Sets relative music volume. Takes $musicvolume in SNDINFO into consideration
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void I_SetMusicVolume (float factor)
|
void I_SetMusicVolume (float factor)
|
||||||
{
|
{
|
||||||
factor = clamp<float>(factor, 0, 2.0f);
|
factor = clamp<float>(factor, 0, 2.0f);
|
||||||
|
@ -804,6 +830,12 @@ void I_SetMusicVolume (float factor)
|
||||||
snd_musicvolume.Callback();
|
snd_musicvolume.Callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// test a relative music volume
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
CCMD(testmusicvol)
|
CCMD(testmusicvol)
|
||||||
{
|
{
|
||||||
if (argv.argc() > 1)
|
if (argv.argc() > 1)
|
||||||
|
|
|
@ -50,33 +50,12 @@ void I_UpdateMusic ();
|
||||||
// Volume.
|
// Volume.
|
||||||
void I_SetMusicVolume (float volume);
|
void I_SetMusicVolume (float volume);
|
||||||
|
|
||||||
// PAUSE game handling.
|
|
||||||
void I_PauseSong (void *handle);
|
|
||||||
void I_ResumeSong (void *handle);
|
|
||||||
|
|
||||||
// Registers a song handle to song data.
|
// Registers a song handle to song data.
|
||||||
class MusInfo;
|
class MusInfo;
|
||||||
MusInfo *I_RegisterSong (const char *file, BYTE *musiccache, int offset, int length, int device);
|
MusInfo *I_RegisterSong (const char *file, BYTE *musiccache, int offset, int length, int device);
|
||||||
MusInfo *I_RegisterCDSong (int track, int cdid = 0);
|
MusInfo *I_RegisterCDSong (int track, int cdid = 0);
|
||||||
MusInfo *I_RegisterURLSong (const char *url);
|
MusInfo *I_RegisterURLSong (const char *url);
|
||||||
|
|
||||||
// Called by anything that wishes to start music.
|
|
||||||
// Plays a song, and when the song is done,
|
|
||||||
// starts playing it again in an endless loop.
|
|
||||||
void I_PlaySong (void *handle, int looping, float relative_vol=1.f, int subsong=0);
|
|
||||||
|
|
||||||
// Stops a song.
|
|
||||||
void I_StopSong (void *handle);
|
|
||||||
|
|
||||||
// See above (register), then think backwards
|
|
||||||
void I_UnRegisterSong (void *handle);
|
|
||||||
|
|
||||||
// Set the current order (position) for a MOD
|
|
||||||
bool I_SetSongPosition (void *handle, int order);
|
|
||||||
|
|
||||||
// Is the song still playing?
|
|
||||||
bool I_QrySongPlaying (void *handle);
|
|
||||||
|
|
||||||
// The base music class. Everything is derived from this --------------------
|
// The base music class. Everything is derived from this --------------------
|
||||||
|
|
||||||
class MusInfo
|
class MusInfo
|
||||||
|
@ -103,6 +82,8 @@ public:
|
||||||
virtual void FluidSettingNum(const char *setting, double value); // "
|
virtual void FluidSettingNum(const char *setting, double value); // "
|
||||||
virtual void FluidSettingStr(const char *setting, const char *value); // "
|
virtual void FluidSettingStr(const char *setting, const char *value); // "
|
||||||
|
|
||||||
|
void Start(bool loop, float rel_vol = -1.f, int subsong = 0);
|
||||||
|
|
||||||
enum EState
|
enum EState
|
||||||
{
|
{
|
||||||
STATE_Stopped,
|
STATE_Stopped,
|
||||||
|
|
|
@ -66,11 +66,12 @@ CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
// If a song is playing, move it to the new device.
|
// If a song is playing, move it to the new device.
|
||||||
if (oldmididev != mididevice && currSong != NULL && currSong->IsMIDI())
|
if (oldmididev != mididevice && currSong != NULL && currSong->IsMIDI())
|
||||||
{
|
{
|
||||||
|
// Does this even work, except for Windows system devices?
|
||||||
MusInfo *song = currSong;
|
MusInfo *song = currSong;
|
||||||
if (song->m_Status == MusInfo::STATE_Playing)
|
if (song->m_Status == MusInfo::STATE_Playing)
|
||||||
{
|
{
|
||||||
I_StopSong (song);
|
song->Stop();
|
||||||
I_PlaySong (song, song->m_Looping);
|
song->Start(song->m_Looping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,6 @@
|
||||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
**---------------------------------------------------------------------------
|
**---------------------------------------------------------------------------
|
||||||
**
|
**
|
||||||
** This file also supports the Apogee Sound System's EMIDI files. That
|
|
||||||
** basically means you can play the Duke3D songs without any editing and
|
|
||||||
** have them sound right.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue