- made the sound font loading a bit more error resistant.

- implemented a fallback both for sound font lookup and for MIDI device selection so that if some non-working combination is set up, the player will fall back to something that works.
This commit is contained in:
Christoph Oelckers 2018-02-26 16:34:58 +01:00
parent d45a50b0db
commit eb124f6160
10 changed files with 79 additions and 37 deletions

View File

@ -390,6 +390,14 @@ const FSoundFontInfo *FSoundFontManager::FindSoundFont(const char *name, int all
return &sfi;
}
}
// We did not find what we were looking for. Let's just return the first valid item that works with the given device.
for (auto &sfi : soundfonts)
{
if (allowed & sfi.type)
{
return &sfi;
}
}
return nullptr;
}

View File

@ -162,6 +162,8 @@ enum EMidiDevice
MDEV_FLUIDSYNTH = 4,
MDEV_GUS = 5,
MDEV_WILDMIDI = 6,
MDEV_COUNT
};
class MusInfo;

View File

@ -357,9 +357,9 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
#endif
Printf("Failed to load any MIDI patches.\n");
delete_fluid_synth(FluidSynth);
FluidSynth = NULL;
I_Error("Failed to load any MIDI patches.\n");
}

View File

@ -32,8 +32,6 @@
**
*/
#include "i_midi_win32.h"
#include <string>
#include <vector>
@ -130,6 +128,10 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
{
Renderer = new TimidityPlus::Player(timidity_frequency, instruments);
}
else
{
I_Error("Failed to load any MIDI patches");
}
sampletime = 0;
}

View File

@ -40,6 +40,7 @@
#include "m_swap.h"
#include "w_wad.h"
#include "v_text.h"
#include "i_system.h"
// MACROS ------------------------------------------------------------------
@ -123,6 +124,10 @@ WildMIDIDevice::WildMIDIDevice(const char *args)
if (wildmidi_reverb) flags |= WM_MO_REVERB;
Renderer->SetOption(WM_MO_ENHANCED_RESAMPLING | WM_MO_REVERB, flags);
}
else
{
I_Error("Failed to load any MIDI patches");
}
}
//==========================================================================

View File

@ -42,6 +42,7 @@
#include "templates.h"
#include "doomdef.h"
#include "m_swap.h"
#include "i_system.h"
#ifndef __GNUC__
#include <mmdeviceapi.h>
@ -682,7 +683,7 @@ MIDIDevice *CreateWinMIDIDevice(int mididevice)
if (d->BufferDoneEvent == nullptr || d->ExitEvent == nullptr)
{
delete d;
return nullptr;
I_Error("failed to create MIDI events");
}
return d;
}

View File

@ -126,7 +126,7 @@ CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
return;
}
else if (self == -1) self = DEF_MIDIDEV;
mididevice = MAX<UINT>(0, self);
mididevice = MAX<int>(0, self);
MIDIDeviceChanged(self);
}

View File

@ -183,42 +183,60 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
{
// fixme: This should check up front if the device can be started.
// Checks to ensure that a device finds a compatible sound font are entirely missing here.
bool checked[MDEV_COUNT] = { false };
switch (devtype)
if (devtype == MDEV_SNDSYS) devtype = MDEV_FLUIDSYNTH;
while (true)
{
case MDEV_GUS:
return new TimidityMIDIDevice(Args);
case MDEV_MMAPI:
#ifdef _WIN32
return CreateWinMIDIDevice(mididevice);
#endif
// Intentional fall-through for non-Windows systems.
case MDEV_FLUIDSYNTH:
case MDEV_SNDSYS:
return new FluidSynthMIDIDevice(Args);
case MDEV_OPL:
try
{
return new OPLMIDIDevice(Args);
switch (devtype)
{
case MDEV_GUS:
return new TimidityMIDIDevice(Args);
case MDEV_MMAPI:
#ifdef _WIN32
return CreateWinMIDIDevice(mididevice);
#endif
// Intentional fall-through for non-Windows systems.
case MDEV_FLUIDSYNTH:
return new FluidSynthMIDIDevice(Args);
case MDEV_OPL:
return new OPLMIDIDevice(Args);
case MDEV_TIMIDITY:
return CreateTimidityPPMIDIDevice(Args);
case MDEV_WILDMIDI:
return new WildMIDIDevice(Args);
default:
break;
}
}
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 default playback", err.GetMessage());
return new FluidSynthMIDIDevice(nullptr);
checked[devtype] = true;
devtype = MDEV_DEFAULT;
// Opening the requested device did not work out so choose another one.
if (!checked[MDEV_FLUIDSYNTH]) devtype = MDEV_FLUIDSYNTH;
else if (!checked[MDEV_TIMIDITY]) devtype = MDEV_TIMIDITY;
else if (!checked[MDEV_WILDMIDI]) devtype = MDEV_WILDMIDI;
else if (!checked[MDEV_GUS]) devtype = MDEV_GUS;
#ifdef _WIN32
else if (!checked[MDEV_MMAPI]) devtype = MDEV_MMAPI;
#endif
else if (!checked[MDEV_OPL]) devtype = MDEV_OPL;
if (devtype == MDEV_DEFAULT)
{
Printf("Failed to play music: Unable to open any MIDI Device.");
return nullptr;
}
}
case MDEV_TIMIDITY:
return CreateTimidityPPMIDIDevice(Args);
case MDEV_WILDMIDI:
return new WildMIDIDevice(Args);
default:
return NULL;
}
}

View File

@ -161,7 +161,7 @@ static Instrument *load_instrument(Renderer *song, const char *name, int percuss
int i, j;
bool noluck = false;
if (!name) return 0;
if (!name || gus_sfreader == nullptr) return nullptr;
/* Open patch file */
fp = gus_sfreader->LookupFile(name).first;

View File

@ -720,15 +720,21 @@ void FreeDLS(DLS_Data *data);
Renderer::Renderer(float sample_rate, const char *args)
{
int res = 0;
// Load explicitly stated sound font if so desired.
if (args != nullptr && *args != 0)
{
if (!stricmp(args, "DMXGUS")) LoadDMXGUS();
LoadConfig(args);
if (!stricmp(args, "DMXGUS")) res = LoadDMXGUS();
res = LoadConfig(args);
}
else if (tonebank[0] == nullptr)
{
LoadConfig();
res = LoadConfig();
}
if (res < 0)
{
I_Error("Failed to load any MIDI patches");
}
// These can be left empty here if an error occured during sound font initialization.