- use FluidSynth as default MIDI device and allow loading a 'gzdoom.sf2' sound font if none is specified. The search rules for this file will be the same as for gzdoom.pk3.

This commit is contained in:
Christoph Oelckers 2017-05-13 12:33:14 +02:00
parent fcafed4e27
commit ba37f093e0
8 changed files with 76 additions and 55 deletions

View file

@ -149,7 +149,7 @@ void ParseGLDefs();
// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
void D_DoomLoop (); void D_DoomLoop ();
static const char *BaseFileSearch (const char *file, const char *ext, bool lookfirstinprogdir=false); const char *BaseFileSearch (const char *file, const char *ext, bool lookfirstinprogdir=false);
// EXTERNAL DATA DECLARATIONS ---------------------------------------------- // EXTERNAL DATA DECLARATIONS ----------------------------------------------
@ -1693,7 +1693,7 @@ static void D_AddDirectory (TArray<FString> &wadfiles, const char *dir)
// //
//========================================================================== //==========================================================================
static const char *BaseFileSearch (const char *file, const char *ext, bool lookfirstinprogdir) const char *BaseFileSearch (const char *file, const char *ext, bool lookfirstinprogdir)
{ {
static char wad[PATH_MAX]; static char wad[PATH_MAX];

View file

@ -43,6 +43,7 @@
#include "m_swap.h" #include "m_swap.h"
#include "w_wad.h" #include "w_wad.h"
#include "v_text.h" #include "v_text.h"
#include "version.h"
#include "cmdlib.h" #include "cmdlib.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -53,6 +54,7 @@
// do this without including windows.h for this one single prototype // do this without including windows.h for this one single prototype
extern "C" unsigned __stdcall GetSystemDirectoryA(char *lpBuffer, unsigned uSize); extern "C" unsigned __stdcall GetSystemDirectoryA(char *lpBuffer, unsigned uSize);
const char *BaseFileSearch(const char *file, const char *ext, bool lookfirstinprogdir = false);
#ifndef _M_X64 #ifndef _M_X64
#define FLUIDSYNTHLIB1 "fluidsynth.dll" #define FLUIDSYNTHLIB1 "fluidsynth.dll"
@ -315,44 +317,54 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
int res = 0; int res = 0;
if (args != NULL && *args != 0) if (args != NULL && *args != 0)
{ {
res = LoadPatchSets(args); if (LoadPatchSets(args)) return;
} }
if (res == 0 && 0 == LoadPatchSets(fluid_patchset)) if (LoadPatchSets(fluid_patchset))
{ {
#ifdef __unix__ return;
// This is the standard location on Ubuntu.
if (0 == LoadPatchSets("/usr/share/sounds/sf2/FluidR3_GS.sf2:/usr/share/sounds/sf2/FluidR3_GM.sf2"))
{
#endif
#ifdef _WIN32
// On Windows, look for the 4 megabyte patch set installed by Creative's drivers as a default.
char sysdir[MAX_PATH+sizeof("\\CT4MGM.SF2")];
uint32_t filepart;
if (0 != (filepart = GetSystemDirectoryA(sysdir, MAX_PATH)))
{
strcat(sysdir, "\\CT4MGM.SF2");
if (0 == LoadPatchSets(sysdir))
{
// Try again with CT2MGM.SF2
sysdir[filepart + 3] = '2';
if (0 == LoadPatchSets(sysdir))
{
#endif
Printf("Failed to load any MIDI patches.\n");
delete_fluid_synth(FluidSynth);
FluidSynth = NULL;
#ifdef _WIN32
}
}
}
#endif
#ifdef __unix__
}
#endif
} }
#ifdef __unix__
// This is the standard location on Ubuntu.
if (LoadPatchSets("/usr/share/sounds/sf2/FluidR3_GS.sf2:/usr/share/sounds/sf2/FluidR3_GM.sf2"))
{
return;
}
#endif
#ifdef _WIN32
// On Windows, look for the 4 megabyte patch set installed by Creative's drivers as a default.
char sysdir[MAX_PATH + sizeof("\\CT4MGM.SF2")];
uint32_t filepart;
if (0 != (filepart = GetSystemDirectoryA(sysdir, MAX_PATH)))
{
strcat(sysdir, "\\CT4MGM.SF2");
if (LoadPatchSets(sysdir))
{
return;
}
// Try again with CT2MGM.SF2
sysdir[filepart + 3] = '2';
if (LoadPatchSets(sysdir))
{
return;
}
}
#endif
// Last try the base sound font which should be provided by the GZDoom binary package.
auto wad = BaseFileSearch(BASESF, NULL, true);
if (wad != NULL && LoadPatchSets(wad))
{
return;
}
Printf("Failed to load any MIDI patches.\n");
delete_fluid_synth(FluidSynth);
FluidSynth = NULL;
} }
//========================================================================== //==========================================================================
// //
// FluidSynthMIDIDevice Destructor // FluidSynthMIDIDevice Destructor

View file

@ -117,10 +117,16 @@ void MIDIDeviceChanged(int newdev, bool force)
if (!force) oldmididev = newdev; if (!force) oldmididev = newdev;
} }
#ifdef HAVE_FLUIDSYNTH
#define DEF_MIDIDEV -5
#else
#define DEF_MIDIDEV -3
#endif
#ifdef _WIN32 #ifdef _WIN32
unsigned mididevice; unsigned mididevice;
CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
if (!nummididevicesset) if (!nummididevicesset)
return; return;
@ -131,10 +137,11 @@ CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
if (self != 0) if (self != 0)
{ {
Printf("ID out of range. Using default device.\n"); Printf("ID out of range. Using default device.\n");
self = 0; self = DEF_MIDIDEV;
} }
return; return;
} }
else if (self == -1) self = DEF_MIDIDEV;
mididevice = MAX<UINT>(0, self); mididevice = MAX<UINT>(0, self);
MIDIDeviceChanged(self); MIDIDeviceChanged(self);
} }
@ -215,7 +222,6 @@ CCMD (snd_listmididevices)
PrintMidiDevice (-4, "Gravis Ultrasound Emulation", MIDIDEV_SWSYNTH, 0); PrintMidiDevice (-4, "Gravis Ultrasound Emulation", MIDIDEV_SWSYNTH, 0);
PrintMidiDevice (-3, "Emulated OPL FM Synth", MIDIDEV_FMSYNTH, 0); PrintMidiDevice (-3, "Emulated OPL FM Synth", MIDIDEV_FMSYNTH, 0);
PrintMidiDevice (-2, "TiMidity++", MIDIDEV_SWSYNTH, 0); PrintMidiDevice (-2, "TiMidity++", MIDIDEV_SWSYNTH, 0);
PrintMidiDevice (-1, "Sound System", 0, 0);
if (nummididevices != 0) if (nummididevices != 0)
{ {
for (id = 0; id < nummididevices; ++id) for (id = 0; id < nummididevices; ++id)
@ -237,12 +243,12 @@ CCMD (snd_listmididevices)
// Everything but Windows uses this code. // Everything but Windows uses this code.
CUSTOM_CVAR(Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR(Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
if (self < -6) if (self < -6)
self = -6; self = -6;
else if (self > -1) else if (self > -2)
self = -1; self = -2;
else else
MIDIDeviceChanged(self); MIDIDeviceChanged(self);
} }
@ -261,6 +267,5 @@ CCMD (snd_listmididevices)
Printf("%s-4. Gravis Ultrasound Emulation\n", -4 == snd_mididevice ? TEXTCOLOR_BOLD : ""); Printf("%s-4. Gravis Ultrasound Emulation\n", -4 == snd_mididevice ? TEXTCOLOR_BOLD : "");
Printf("%s-3. Emulated OPL FM Synth\n", -3 == snd_mididevice ? TEXTCOLOR_BOLD : ""); Printf("%s-3. Emulated OPL FM Synth\n", -3 == snd_mididevice ? TEXTCOLOR_BOLD : "");
Printf("%s-2. TiMidity++\n", -2 == snd_mididevice ? TEXTCOLOR_BOLD : ""); Printf("%s-2. TiMidity++\n", -2 == snd_mididevice ? TEXTCOLOR_BOLD : "");
Printf("%s-1. Sound System\n", -1 == snd_mididevice ? TEXTCOLOR_BOLD : "");
} }
#endif #endif

View file

@ -651,7 +651,7 @@ uint32_t *HMISong::SendCommand (uint32_t *events, TrackInfo *track, uint32_t del
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND) if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
{ {
len = ReadVarLen(track); len = ReadVarLen(track);
if (len >= (MAX_EVENTS-1)*3*4 || DeviceType == MDEV_SNDSYS) if (len >= (MAX_EVENTS-1)*3*4)
{ // This message will never fit. Throw it away. { // This message will never fit. Throw it away.
track->TrackP += len; track->TrackP += len;
} }

View file

@ -181,11 +181,6 @@ EMidiDevice MIDIStreamer::SelectMIDIDevice(EMidiDevice device)
- if explicitly selected by $mididevice - if explicitly selected by $mididevice
- when snd_mididevice is -2 and no midi device is set for the song - when snd_mididevice is -2 and no midi device is set for the song
- Sound System:
- 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): - MMAPI (Win32 only):
- if explicitly selected by $mididevice (non-Win32 redirects this to Sound System) - if explicitly selected by $mididevice (non-Win32 redirects this to Sound System)
- when snd_mididevice is >= 0 and no midi device is set for the song - when snd_mididevice is >= 0 and no midi device is set for the song
@ -233,16 +228,19 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
assert(0); assert(0);
// Intentional fall-through for non-Windows systems. // Intentional fall-through for non-Windows systems.
case MDEV_GUS:
return new TimidityMIDIDevice(Args);
#ifdef HAVE_FLUIDSYNTH #ifdef HAVE_FLUIDSYNTH
case MDEV_FLUIDSYNTH: case MDEV_FLUIDSYNTH:
return new FluidSynthMIDIDevice(Args); return new FluidSynthMIDIDevice(Args);
#endif #endif
case MDEV_SNDSYS: case MDEV_SNDSYS:
return GSnd->CreateMIDIDevice(); #ifdef HAVE_FLUIDSYNTH
return new FluidSynthMIDIDevice(nullptr);
case MDEV_GUS: #endif
return new TimidityMIDIDevice(Args); // if no FluidSynth, fall through to OPL.
case MDEV_OPL: case MDEV_OPL:
try try
@ -252,8 +250,13 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
catch (CRecoverableError &err) catch (CRecoverableError &err)
{ {
// The creation of an OPL MIDI device can abort with an error if no GENMIDI lump can be found. // The creation of an OPL MIDI device can abort with an error if no GENMIDI lump can be found.
Printf("Unable to create OPL MIDI device: %s\nFalling back to Sound System playback", err.GetMessage()); Printf("Unable to create OPL MIDI device: %s\nFalling back to default playback", err.GetMessage());
return GSnd->CreateMIDIDevice(); #ifdef HAVE_FLUIDSYNTH
return new FluidSynthMIDIDevice(nullptr);
#else
// Someone dared to compile GZDoom without FluidSynth support and then started an IWAD without GENMIDI support. Ugh...
return nullptr;
#endif
} }
case MDEV_TIMIDITY: case MDEV_TIMIDITY:

View file

@ -592,7 +592,7 @@ uint32_t *MIDISong2::SendCommand (uint32_t *events, TrackInfo *track, uint32_t d
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND) if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
{ {
len = track->ReadVarLen(); len = track->ReadVarLen();
if (len >= (MAX_EVENTS-1)*3*4 || DeviceType == MDEV_SNDSYS) if (len >= (MAX_EVENTS-1)*3*4)
{ // This message will never fit. Throw it away. { // This message will never fit. Throw it away.
track->TrackP += len; track->TrackP += len;
} }

View file

@ -522,7 +522,7 @@ uint32_t *XMISong::SendCommand (uint32_t *events, EventSource due, uint32_t dela
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND) if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
{ {
len = track->ReadVarLen(); len = track->ReadVarLen();
if (len >= (MAX_EVENTS-1)*3*4 || DeviceType == MDEV_SNDSYS) if (len >= (MAX_EVENTS-1)*3*4)
{ // This message will never fit. Throw it away. { // This message will never fit. Throw it away.
track->EventP += len; track->EventP += len;
} }

View file

@ -96,6 +96,7 @@ const char *GetVersionString();
// This is so that derivates can use the same savegame versions without worrying about engine compatibility // This is so that derivates can use the same savegame versions without worrying about engine compatibility
#define GAMESIG "GZDOOM" #define GAMESIG "GZDOOM"
#define BASEWAD "gzdoom.pk3" #define BASEWAD "gzdoom.pk3"
#define BASESF "gzdoom.sf2"
// More stuff that needs to be different for derivatives. // More stuff that needs to be different for derivatives.
#define GAMENAME "GZDoom" #define GAMENAME "GZDoom"