mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-28 06:41:59 +00:00
- Fixed snd_mididevice so that changing it immediately restarts the song for all devices, not
just Windows system devices. - Remove SMF generation from i_music.cpp, since the psuedo-MIDI devices do this now. SVN r2875 (trunk)
This commit is contained in:
parent
90dd40c58f
commit
b2b84ad11f
9 changed files with 167 additions and 217 deletions
|
@ -247,6 +247,11 @@ bool MusInfo::SetPosition (unsigned int ms)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MusInfo::IsMIDI() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool MusInfo::SetSubsong (int subsong)
|
bool MusInfo::SetSubsong (int subsong)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -297,7 +302,7 @@ MusInfo *MusInfo::GetWaveDumper(const char *filename, int rate)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static MIDIStreamer *CreateMIDIStreamer(FILE *file, BYTE *musiccache, int len, EMIDIDevice devtype, EMIDIType miditype)
|
static MIDIStreamer *CreateMIDIStreamer(FILE *file, BYTE *musiccache, int len, EMidiDevice devtype, EMIDIType miditype)
|
||||||
{
|
{
|
||||||
switch (miditype)
|
switch (miditype)
|
||||||
{
|
{
|
||||||
|
@ -318,29 +323,6 @@ static MIDIStreamer *CreateMIDIStreamer(FILE *file, BYTE *musiccache, int len, E
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// create a MIDI player
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static MusInfo *CreateMIDISong(FILE *file, const char *filename, BYTE *musiccache, int offset, int len, EMIDIDevice devtype, EMIDIType miditype)
|
|
||||||
{
|
|
||||||
if (devtype >= MIDI_Null)
|
|
||||||
{
|
|
||||||
assert(miditype == MIDI_MIDI);
|
|
||||||
if (musiccache != NULL)
|
|
||||||
{
|
|
||||||
return new StreamSong((char *)musiccache, -1, len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new StreamSong(filename, offset, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return CreateMIDIStreamer(file, musiccache, len, devtype, miditype);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// identify MIDI file type
|
// identify MIDI file type
|
||||||
|
@ -390,66 +372,6 @@ static EMIDIType IdentifyMIDIType(DWORD *id, int size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// 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
|
// identify a music lump's type and set up a player for it
|
||||||
|
@ -557,45 +479,24 @@ MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int
|
||||||
{
|
{
|
||||||
TArray<BYTE> midi;
|
TArray<BYTE> midi;
|
||||||
|
|
||||||
EMIDIDevice devtype = SelectMIDIDevice(device);
|
EMidiDevice devtype = (EMidiDevice)device;
|
||||||
|
|
||||||
retry_as_fmod:
|
retry_as_fmod:
|
||||||
if (devtype >= MIDI_Null)
|
info = CreateMIDIStreamer(file, musiccache, len, devtype, miditype);
|
||||||
{
|
|
||||||
// Convert to standard MIDI for external sequencers.
|
|
||||||
MIDIStreamer *streamer = CreateMIDIStreamer(file, musiccache, len, MIDI_Null, miditype);
|
|
||||||
if (streamer != NULL)
|
|
||||||
{
|
|
||||||
if (streamer->IsValid())
|
|
||||||
{
|
|
||||||
streamer->CreateSMF(midi);
|
|
||||||
miditype = MIDI_MIDI;
|
|
||||||
musiccache = &midi[0];
|
|
||||||
len = midi.Size();
|
|
||||||
if (file != NULL)
|
|
||||||
{
|
|
||||||
fclose(file);
|
|
||||||
file = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete streamer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info = CreateMIDISong(file, filename, musiccache, offset, len, devtype, miditype);
|
|
||||||
if (info != NULL && !info->IsValid())
|
if (info != NULL && !info->IsValid())
|
||||||
{
|
{
|
||||||
delete info;
|
delete info;
|
||||||
info = NULL;
|
info = NULL;
|
||||||
}
|
}
|
||||||
if (info == NULL && devtype != MIDI_FMOD && snd_mididevice < 0)
|
if (info == NULL && devtype != MDEV_FMOD && snd_mididevice < 0)
|
||||||
{
|
{
|
||||||
devtype = MIDI_FMOD;
|
devtype = MDEV_FMOD;
|
||||||
goto retry_as_fmod;
|
goto retry_as_fmod;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (info == NULL && devtype != MIDI_Win && snd_mididevice >= 0)
|
if (info == NULL && devtype != MDEV_MMAPI && snd_mididevice >= 0)
|
||||||
{
|
{
|
||||||
info = CreateMIDISong(file, filename, musiccache, offset, len, MIDI_Win, miditype);
|
info = CreateMIDIStreamer(file, musiccache, len, MDEV_MMAPI, miditype);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
virtual void Resume () = 0;
|
virtual void Resume () = 0;
|
||||||
virtual void Stop () = 0;
|
virtual void Stop () = 0;
|
||||||
virtual bool IsPlaying () = 0;
|
virtual bool IsPlaying () = 0;
|
||||||
virtual bool IsMIDI () const = 0;
|
virtual bool IsMIDI () const;
|
||||||
virtual bool IsValid () const = 0;
|
virtual bool IsValid () const = 0;
|
||||||
virtual bool SetPosition (unsigned int ms);
|
virtual bool SetPosition (unsigned int ms);
|
||||||
virtual bool SetSubsong (int subsong);
|
virtual bool SetSubsong (int subsong);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "mus2midi.h"
|
#include "mus2midi.h"
|
||||||
#include "i_sound.h"
|
#include "i_sound.h"
|
||||||
#include "i_music.h"
|
#include "i_music.h"
|
||||||
|
#include "s_sound.h"
|
||||||
|
|
||||||
void I_InitMusicWin32 ();
|
void I_InitMusicWin32 ();
|
||||||
void I_ShutdownMusicWin32 ();
|
void I_ShutdownMusicWin32 ();
|
||||||
|
@ -404,24 +405,10 @@ protected:
|
||||||
|
|
||||||
// Base class for streaming MUS and MIDI files ------------------------------
|
// Base class for streaming MUS and MIDI files ------------------------------
|
||||||
|
|
||||||
// MIDI device selection.
|
|
||||||
enum EMIDIDevice
|
|
||||||
{
|
|
||||||
MIDI_Win,
|
|
||||||
MIDI_OPL,
|
|
||||||
MIDI_GUS,
|
|
||||||
MIDI_Fluid,
|
|
||||||
MIDI_FMOD,
|
|
||||||
MIDI_Timidity,
|
|
||||||
|
|
||||||
// only used by I_RegisterSong
|
|
||||||
MIDI_Null,
|
|
||||||
};
|
|
||||||
|
|
||||||
class MIDIStreamer : public MusInfo
|
class MIDIStreamer : public MusInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MIDIStreamer(EMIDIDevice type);
|
MIDIStreamer(EMidiDevice type);
|
||||||
~MIDIStreamer();
|
~MIDIStreamer();
|
||||||
|
|
||||||
void MusicVolumeChanged();
|
void MusicVolumeChanged();
|
||||||
|
@ -442,7 +429,7 @@ public:
|
||||||
void CreateSMF(TArray<BYTE> &file);
|
void CreateSMF(TArray<BYTE> &file);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MIDIStreamer(const char *dumpname, EMIDIDevice type);
|
MIDIStreamer(const char *dumpname, EMidiDevice type);
|
||||||
|
|
||||||
void OutputVolume (DWORD volume);
|
void OutputVolume (DWORD volume);
|
||||||
int FillBuffer(int buffer_num, int max_events, DWORD max_time);
|
int FillBuffer(int buffer_num, int max_events, DWORD max_time);
|
||||||
|
@ -450,6 +437,8 @@ protected:
|
||||||
int VolumeControllerChange(int channel, int volume);
|
int VolumeControllerChange(int channel, int volume);
|
||||||
int ClampLoopCount(int loopcount);
|
int ClampLoopCount(int loopcount);
|
||||||
void SetTempo(int new_tempo);
|
void SetTempo(int new_tempo);
|
||||||
|
static EMidiDevice SelectMIDIDevice(EMidiDevice devtype);
|
||||||
|
MIDIDevice *CreateMIDIDevice(EMidiDevice devtype) const;
|
||||||
|
|
||||||
static void Callback(unsigned int uMsg, void *userdata, DWORD dwParam1, DWORD dwParam2);
|
static void Callback(unsigned int uMsg, void *userdata, DWORD dwParam1, DWORD dwParam2);
|
||||||
|
|
||||||
|
@ -498,7 +487,7 @@ protected:
|
||||||
int InitialTempo;
|
int InitialTempo;
|
||||||
BYTE ChannelVolumes[16];
|
BYTE ChannelVolumes[16];
|
||||||
DWORD Volume;
|
DWORD Volume;
|
||||||
EMIDIDevice DeviceType;
|
EMidiDevice DeviceType;
|
||||||
bool CallbackIsThreaded;
|
bool CallbackIsThreaded;
|
||||||
int LoopLimit;
|
int LoopLimit;
|
||||||
FString DumpFilename;
|
FString DumpFilename;
|
||||||
|
@ -509,14 +498,14 @@ protected:
|
||||||
class MUSSong2 : public MIDIStreamer
|
class MUSSong2 : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MUSSong2(FILE *file, BYTE *musiccache, int length, EMIDIDevice type);
|
MUSSong2(FILE *file, BYTE *musiccache, int length, EMidiDevice type);
|
||||||
~MUSSong2();
|
~MUSSong2();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
MusInfo *GetWaveDumper(const char *filename, int rate);
|
MusInfo *GetWaveDumper(const char *filename, int rate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MUSSong2(const MUSSong2 *original, const char *filename, EMIDIDevice type); // file dump constructor
|
MUSSong2(const MUSSong2 *original, const char *filename, EMidiDevice type); // file dump constructor
|
||||||
|
|
||||||
void DoInitialSetup();
|
void DoInitialSetup();
|
||||||
void DoRestart();
|
void DoRestart();
|
||||||
|
@ -535,14 +524,14 @@ protected:
|
||||||
class MIDISong2 : public MIDIStreamer
|
class MIDISong2 : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MIDISong2(FILE *file, BYTE *musiccache, int length, EMIDIDevice type);
|
MIDISong2(FILE *file, BYTE *musiccache, int length, EMidiDevice type);
|
||||||
~MIDISong2();
|
~MIDISong2();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
MusInfo *GetWaveDumper(const char *filename, int rate);
|
MusInfo *GetWaveDumper(const char *filename, int rate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MIDISong2(const MIDISong2 *original, const char *filename, EMIDIDevice type); // file dump constructor
|
MIDISong2(const MIDISong2 *original, const char *filename, EMidiDevice type); // file dump constructor
|
||||||
|
|
||||||
void CheckCaps(int tech);
|
void CheckCaps(int tech);
|
||||||
void DoInitialSetup();
|
void DoInitialSetup();
|
||||||
|
@ -592,14 +581,14 @@ protected:
|
||||||
class HMISong : public MIDIStreamer
|
class HMISong : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HMISong(FILE *file, BYTE *musiccache, int length, EMIDIDevice type);
|
HMISong(FILE *file, BYTE *musiccache, int length, EMidiDevice type);
|
||||||
~HMISong();
|
~HMISong();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
MusInfo *GetWaveDumper(const char *filename, int rate);
|
MusInfo *GetWaveDumper(const char *filename, int rate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HMISong(const HMISong *original, const char *filename, EMIDIDevice type); // file dump constructor
|
HMISong(const HMISong *original, const char *filename, EMidiDevice type); // file dump constructor
|
||||||
|
|
||||||
void SetupForHMI(int len);
|
void SetupForHMI(int len);
|
||||||
void SetupForHMP(int len);
|
void SetupForHMP(int len);
|
||||||
|
@ -634,7 +623,7 @@ protected:
|
||||||
class XMISong : public MIDIStreamer
|
class XMISong : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XMISong(FILE *file, BYTE *musiccache, int length, EMIDIDevice type);
|
XMISong(FILE *file, BYTE *musiccache, int length, EMidiDevice type);
|
||||||
~XMISong();
|
~XMISong();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
|
@ -644,7 +633,7 @@ protected:
|
||||||
struct TrackInfo;
|
struct TrackInfo;
|
||||||
enum EventSource { EVENT_None, EVENT_Real, EVENT_Fake };
|
enum EventSource { EVENT_None, EVENT_Real, EVENT_Fake };
|
||||||
|
|
||||||
XMISong(const XMISong *original, const char *filename, EMIDIDevice type); // file dump constructor
|
XMISong(const XMISong *original, const char *filename, EMidiDevice type); // file dump constructor
|
||||||
|
|
||||||
int FindXMIDforms(const BYTE *chunk, int len, TrackInfo *songs) const;
|
int FindXMIDforms(const BYTE *chunk, int len, TrackInfo *songs) const;
|
||||||
void FoundXMID(const BYTE *chunk, int len, TrackInfo *song) const;
|
void FoundXMID(const BYTE *chunk, int len, TrackInfo *song) const;
|
||||||
|
@ -680,7 +669,6 @@ public:
|
||||||
void Resume ();
|
void Resume ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
bool IsPlaying ();
|
bool IsPlaying ();
|
||||||
bool IsMIDI () const { return false; }
|
|
||||||
bool IsValid () const { return m_Stream != NULL; }
|
bool IsValid () const { return m_Stream != NULL; }
|
||||||
bool SetPosition (unsigned int pos);
|
bool SetPosition (unsigned int pos);
|
||||||
bool SetSubsong (int subsong);
|
bool SetSubsong (int subsong);
|
||||||
|
@ -732,7 +720,6 @@ public:
|
||||||
void Resume ();
|
void Resume ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
bool IsPlaying ();
|
bool IsPlaying ();
|
||||||
bool IsMIDI () const { return false; }
|
|
||||||
bool IsValid () const { return m_Inited; }
|
bool IsValid () const { return m_Inited; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -127,7 +127,7 @@ extern char MIDI_CommonLengths[15];
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
HMISong::HMISong (FILE *file, BYTE *musiccache, int len, EMIDIDevice type)
|
HMISong::HMISong (FILE *file, BYTE *musiccache, int len, EMidiDevice type)
|
||||||
: MIDIStreamer(type), MusHeader(0), Tracks(0)
|
: MIDIStreamer(type), MusHeader(0), Tracks(0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -983,7 +983,7 @@ HMISong::TrackInfo *HMISong::FindNextDue ()
|
||||||
|
|
||||||
MusInfo *HMISong::GetOPLDumper(const char *filename)
|
MusInfo *HMISong::GetOPLDumper(const char *filename)
|
||||||
{
|
{
|
||||||
return new HMISong(this, filename, MIDI_OPL);
|
return new HMISong(this, filename, MDEV_OPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -994,7 +994,7 @@ MusInfo *HMISong::GetOPLDumper(const char *filename)
|
||||||
|
|
||||||
MusInfo *HMISong::GetWaveDumper(const char *filename, int rate)
|
MusInfo *HMISong::GetWaveDumper(const char *filename, int rate)
|
||||||
{
|
{
|
||||||
return new HMISong(this, filename, MIDI_GUS);
|
return new HMISong(this, filename, MDEV_GUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1003,7 +1003,7 @@ MusInfo *HMISong::GetWaveDumper(const char *filename, int rate)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
HMISong::HMISong(const HMISong *original, const char *filename, EMIDIDevice type)
|
HMISong::HMISong(const HMISong *original, const char *filename, EMidiDevice type)
|
||||||
: MIDIStreamer(filename, type)
|
: MIDIStreamer(filename, type)
|
||||||
{
|
{
|
||||||
SongLen = original->SongLen;
|
SongLen = original->SongLen;
|
||||||
|
|
|
@ -38,13 +38,28 @@ static void AddDefaultMidiDevices(FOptionValues *opt)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MIDIDeviceChanged(int newdev)
|
||||||
|
{
|
||||||
|
static int oldmididev = INT_MIN;
|
||||||
|
|
||||||
|
// If a song is playing, move it to the new device.
|
||||||
|
if (oldmididev != newdev && currSong != NULL && currSong->IsMIDI())
|
||||||
|
{
|
||||||
|
MusInfo *song = currSong;
|
||||||
|
if (song->m_Status == MusInfo::STATE_Playing)
|
||||||
|
{
|
||||||
|
song->Stop();
|
||||||
|
song->Start(song->m_Looping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oldmididev = newdev;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
UINT mididevice;
|
UINT mididevice;
|
||||||
|
|
||||||
CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
{
|
{
|
||||||
UINT oldmididev = mididevice;
|
|
||||||
|
|
||||||
if (!nummididevicesset)
|
if (!nummididevicesset)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -54,26 +69,8 @@ CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
self = 0;
|
self = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (self < 0)
|
mididevice = MAX<UINT>(0, self);
|
||||||
{
|
MIDIDeviceChanged(self);
|
||||||
mididevice = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mididevice = self;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a song is playing, move it to the new device.
|
|
||||||
if (oldmididev != mididevice && currSong != NULL && currSong->IsMIDI())
|
|
||||||
{
|
|
||||||
// Does this even work, except for Windows system devices?
|
|
||||||
MusInfo *song = currSong;
|
|
||||||
if (song->m_Status == MusInfo::STATE_Playing)
|
|
||||||
{
|
|
||||||
song->Stop();
|
|
||||||
song->Start(song->m_Looping);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_InitMusicWin32 ()
|
void I_InitMusicWin32 ()
|
||||||
|
@ -196,6 +193,8 @@ CUSTOM_CVAR(Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
self = -5;
|
self = -5;
|
||||||
else if (self > -1)
|
else if (self > -1)
|
||||||
self = -1;
|
self = -1;
|
||||||
|
else
|
||||||
|
MIDIDeviceChanged(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_BuildMIDIMenuList (FOptionValues *opt)
|
void I_BuildMIDIMenuList (FOptionValues *opt)
|
||||||
|
|
|
@ -57,6 +57,7 @@ static void WriteVarLen (TArray<BYTE> &file, DWORD value);
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
EXTERN_CVAR(Float, snd_musicvolume)
|
EXTERN_CVAR(Float, snd_musicvolume)
|
||||||
|
EXTERN_CVAR(Int, snd_mididevice)
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern UINT mididevice;
|
extern UINT mididevice;
|
||||||
|
@ -87,7 +88,7 @@ static const BYTE StaticMIDIhead[] =
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MIDIStreamer::MIDIStreamer(EMIDIDevice type)
|
MIDIStreamer::MIDIStreamer(EMidiDevice type)
|
||||||
:
|
:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
|
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
|
||||||
|
@ -115,7 +116,7 @@ MIDIStreamer::MIDIStreamer(EMIDIDevice type)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MIDIStreamer::MIDIStreamer(const char *dumpname, EMIDIDevice type)
|
MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type)
|
||||||
:
|
:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
|
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
|
||||||
|
@ -194,6 +195,98 @@ void MIDIStreamer::CheckCaps(int tech)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// MIDIStreamer :: SelectMIDIDevice static
|
||||||
|
//
|
||||||
|
// Select the MIDI device to play on
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
EMidiDevice MIDIStreamer::SelectMIDIDevice(EMidiDevice 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Choose the type of MIDI device we want.
|
||||||
|
if (device != MDEV_DEFAULT)
|
||||||
|
{
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
switch (snd_mididevice)
|
||||||
|
{
|
||||||
|
case -1: return MDEV_FMOD;
|
||||||
|
case -2: return MDEV_TIMIDITY;
|
||||||
|
case -3: return MDEV_OPL;
|
||||||
|
case -4: return MDEV_GUS;
|
||||||
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
|
case -5: return MDEV_FLUIDSYNTH;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
#ifdef _WIN32
|
||||||
|
return MDEV_MMAPI;
|
||||||
|
#else
|
||||||
|
return MDEV_FMOD;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// MIDIStreamer :: CreateMIDIDevice
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const
|
||||||
|
{
|
||||||
|
switch (devtype)
|
||||||
|
{
|
||||||
|
case MDEV_MMAPI:
|
||||||
|
#ifdef _WIN32
|
||||||
|
return new WinMIDIDevice(mididevice);
|
||||||
|
#endif
|
||||||
|
assert(0);
|
||||||
|
// Intentional fall-through for non-Windows systems.
|
||||||
|
|
||||||
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
|
case MDEV_FLUIDSYNTH:
|
||||||
|
return new FluidSynthMIDIDevice;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case MDEV_FMOD:
|
||||||
|
return new FMODMIDIDevice;
|
||||||
|
|
||||||
|
case MDEV_GUS:
|
||||||
|
return new TimidityMIDIDevice;
|
||||||
|
|
||||||
|
case MDEV_OPL:
|
||||||
|
return new OPLMIDIDevice;
|
||||||
|
|
||||||
|
case MDEV_TIMIDITY:
|
||||||
|
return new TimidityPPMIDIDevice;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// MIDIStreamer :: Play
|
// MIDIStreamer :: Play
|
||||||
|
@ -203,6 +296,7 @@ void MIDIStreamer::CheckCaps(int tech)
|
||||||
void MIDIStreamer::Play(bool looping, int subsong)
|
void MIDIStreamer::Play(bool looping, int subsong)
|
||||||
{
|
{
|
||||||
DWORD tid;
|
DWORD tid;
|
||||||
|
EMidiDevice devtype;
|
||||||
|
|
||||||
m_Status = STATE_Stopped;
|
m_Status = STATE_Stopped;
|
||||||
m_Looping = looping;
|
m_Looping = looping;
|
||||||
|
@ -212,52 +306,21 @@ void MIDIStreamer::Play(bool looping, int subsong)
|
||||||
InitialPlayback = true;
|
InitialPlayback = true;
|
||||||
|
|
||||||
assert(MIDI == NULL);
|
assert(MIDI == NULL);
|
||||||
|
devtype = SelectMIDIDevice(DeviceType);
|
||||||
if (DumpFilename.IsNotEmpty())
|
if (DumpFilename.IsNotEmpty())
|
||||||
{
|
{
|
||||||
if (DeviceType == MIDI_OPL)
|
if (devtype == MDEV_OPL)
|
||||||
{
|
{
|
||||||
MIDI = new OPLDumperMIDIDevice(DumpFilename);
|
MIDI = new OPLDumperMIDIDevice(DumpFilename);
|
||||||
}
|
}
|
||||||
else if (DeviceType == MIDI_GUS)
|
else if (devtype == MDEV_GUS)
|
||||||
{
|
{
|
||||||
MIDI = new TimidityWaveWriterMIDIDevice(DumpFilename, 0);
|
MIDI = new TimidityWaveWriterMIDIDevice(DumpFilename, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else switch(DeviceType)
|
else
|
||||||
{
|
{
|
||||||
case MIDI_Win:
|
MIDI = CreateMIDIDevice(devtype);
|
||||||
#ifdef _WIN32
|
|
||||||
MIDI = new WinMIDIDevice(mididevice);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
assert(0);
|
|
||||||
// Intentional fall-through for non-Windows systems.
|
|
||||||
|
|
||||||
#ifdef HAVE_FLUIDSYNTH
|
|
||||||
case MIDI_Fluid:
|
|
||||||
MIDI = new FluidSynthMIDIDevice;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case MIDI_FMOD:
|
|
||||||
MIDI = new FMODMIDIDevice;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MIDI_GUS:
|
|
||||||
MIDI = new TimidityMIDIDevice;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MIDI_OPL:
|
|
||||||
MIDI = new OPLMIDIDevice;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MIDI_Timidity:
|
|
||||||
MIDI = new TimidityPPMIDIDevice;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
MIDI = NULL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
|
@ -91,7 +91,7 @@ static const BYTE CtrlTranslate[15] =
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type)
|
MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMidiDevice type)
|
||||||
: MIDIStreamer(type), MusHeader(0), MusBuffer(0)
|
: MIDIStreamer(type), MusHeader(0), MusBuffer(0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -371,7 +371,7 @@ end:
|
||||||
|
|
||||||
MusInfo *MUSSong2::GetOPLDumper(const char *filename)
|
MusInfo *MUSSong2::GetOPLDumper(const char *filename)
|
||||||
{
|
{
|
||||||
return new MUSSong2(this, filename, MIDI_OPL);
|
return new MUSSong2(this, filename, MDEV_OPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -382,7 +382,7 @@ MusInfo *MUSSong2::GetOPLDumper(const char *filename)
|
||||||
|
|
||||||
MusInfo *MUSSong2::GetWaveDumper(const char *filename, int rate)
|
MusInfo *MUSSong2::GetWaveDumper(const char *filename, int rate)
|
||||||
{
|
{
|
||||||
return new MUSSong2(this, filename, MIDI_GUS);
|
return new MUSSong2(this, filename, MDEV_GUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -391,7 +391,7 @@ MusInfo *MUSSong2::GetWaveDumper(const char *filename, int rate)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MUSSong2::MUSSong2(const MUSSong2 *original, const char *filename, EMIDIDevice type)
|
MUSSong2::MUSSong2(const MUSSong2 *original, const char *filename, EMidiDevice type)
|
||||||
: MIDIStreamer(filename, type)
|
: MIDIStreamer(filename, type)
|
||||||
{
|
{
|
||||||
int songstart = LittleShort(original->MusHeader->SongStart);
|
int songstart = LittleShort(original->MusHeader->SongStart);
|
||||||
|
|
|
@ -101,7 +101,7 @@ char MIDI_CommonLengths[15] = { 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MIDISong2::MIDISong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type)
|
MIDISong2::MIDISong2 (FILE *file, BYTE *musiccache, int len, EMidiDevice type)
|
||||||
: MIDIStreamer(type), MusHeader(0), Tracks(0)
|
: MIDIStreamer(type), MusHeader(0), Tracks(0)
|
||||||
{
|
{
|
||||||
int p;
|
int p;
|
||||||
|
@ -782,7 +782,7 @@ MIDISong2::TrackInfo *MIDISong2::FindNextDue ()
|
||||||
|
|
||||||
MusInfo *MIDISong2::GetOPLDumper(const char *filename)
|
MusInfo *MIDISong2::GetOPLDumper(const char *filename)
|
||||||
{
|
{
|
||||||
return new MIDISong2(this, filename, MIDI_OPL);
|
return new MIDISong2(this, filename, MDEV_OPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -793,7 +793,7 @@ MusInfo *MIDISong2::GetOPLDumper(const char *filename)
|
||||||
|
|
||||||
MusInfo *MIDISong2::GetWaveDumper(const char *filename, int rate)
|
MusInfo *MIDISong2::GetWaveDumper(const char *filename, int rate)
|
||||||
{
|
{
|
||||||
return new MIDISong2(this, filename, MIDI_GUS);
|
return new MIDISong2(this, filename, MDEV_GUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -802,7 +802,7 @@ MusInfo *MIDISong2::GetWaveDumper(const char *filename, int rate)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MIDISong2::MIDISong2(const MIDISong2 *original, const char *filename, EMIDIDevice type)
|
MIDISong2::MIDISong2(const MIDISong2 *original, const char *filename, EMidiDevice type)
|
||||||
: MIDIStreamer(filename, type)
|
: MIDIStreamer(filename, type)
|
||||||
{
|
{
|
||||||
SongLen = original->SongLen;
|
SongLen = original->SongLen;
|
||||||
|
|
|
@ -107,7 +107,7 @@ extern char MIDI_CommonLengths[15];
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
XMISong::XMISong (FILE *file, BYTE *musiccache, int len, EMIDIDevice type)
|
XMISong::XMISong (FILE *file, BYTE *musiccache, int len, EMidiDevice type)
|
||||||
: MIDIStreamer(type), MusHeader(0), Songs(0)
|
: MIDIStreamer(type), MusHeader(0), Songs(0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -683,7 +683,7 @@ XMISong::EventSource XMISong::FindNextDue()
|
||||||
|
|
||||||
MusInfo *XMISong::GetOPLDumper(const char *filename)
|
MusInfo *XMISong::GetOPLDumper(const char *filename)
|
||||||
{
|
{
|
||||||
return new XMISong(this, filename, MIDI_OPL);
|
return new XMISong(this, filename, MDEV_OPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -694,7 +694,7 @@ MusInfo *XMISong::GetOPLDumper(const char *filename)
|
||||||
|
|
||||||
MusInfo *XMISong::GetWaveDumper(const char *filename, int rate)
|
MusInfo *XMISong::GetWaveDumper(const char *filename, int rate)
|
||||||
{
|
{
|
||||||
return new XMISong(this, filename, MIDI_GUS);
|
return new XMISong(this, filename, MDEV_GUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -703,7 +703,7 @@ MusInfo *XMISong::GetWaveDumper(const char *filename, int rate)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
XMISong::XMISong(const XMISong *original, const char *filename, EMIDIDevice type)
|
XMISong::XMISong(const XMISong *original, const char *filename, EMidiDevice type)
|
||||||
: MIDIStreamer(filename, type)
|
: MIDIStreamer(filename, type)
|
||||||
{
|
{
|
||||||
SongLen = original->SongLen;
|
SongLen = original->SongLen;
|
||||||
|
|
Loading…
Reference in a new issue