- 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 ---------------------------------------------
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 ----------------------------------------------
@ -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];

View File

@ -43,6 +43,7 @@
#include "m_swap.h"
#include "w_wad.h"
#include "v_text.h"
#include "version.h"
#include "cmdlib.h"
// MACROS ------------------------------------------------------------------
@ -53,6 +54,7 @@
// do this without including windows.h for this one single prototype
extern "C" unsigned __stdcall GetSystemDirectoryA(char *lpBuffer, unsigned uSize);
const char *BaseFileSearch(const char *file, const char *ext, bool lookfirstinprogdir = false);
#ifndef _M_X64
#define FLUIDSYNTHLIB1 "fluidsynth.dll"
@ -315,44 +317,54 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
int res = 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__
// 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
return;
}
#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

View File

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

View File

@ -181,11 +181,6 @@ EMidiDevice MIDIStreamer::SelectMIDIDevice(EMidiDevice device)
- if explicitly selected by $mididevice
- 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):
- 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
@ -233,16 +228,19 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
assert(0);
// Intentional fall-through for non-Windows systems.
case MDEV_GUS:
return new TimidityMIDIDevice(Args);
#ifdef HAVE_FLUIDSYNTH
case MDEV_FLUIDSYNTH:
return new FluidSynthMIDIDevice(Args);
#endif
case MDEV_SNDSYS:
return GSnd->CreateMIDIDevice();
case MDEV_GUS:
return new TimidityMIDIDevice(Args);
#ifdef HAVE_FLUIDSYNTH
return new FluidSynthMIDIDevice(nullptr);
#endif
// if no FluidSynth, fall through to OPL.
case MDEV_OPL:
try
@ -252,8 +250,13 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
catch (CRecoverableError &err)
{
// 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());
return GSnd->CreateMIDIDevice();
Printf("Unable to create OPL MIDI device: %s\nFalling back to default playback", err.GetMessage());
#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:

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)
{
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.
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)
{
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.
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
#define GAMESIG "GZDOOM"
#define BASEWAD "gzdoom.pk3"
#define BASESF "gzdoom.sf2"
// More stuff that needs to be different for derivatives.
#define GAMENAME "GZDoom"