mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- 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:
parent
d45a50b0db
commit
eb124f6160
10 changed files with 79 additions and 37 deletions
|
@ -390,6 +390,14 @@ const FSoundFontInfo *FSoundFontManager::FindSoundFont(const char *name, int all
|
||||||
return &sfi;
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,8 @@ enum EMidiDevice
|
||||||
MDEV_FLUIDSYNTH = 4,
|
MDEV_FLUIDSYNTH = 4,
|
||||||
MDEV_GUS = 5,
|
MDEV_GUS = 5,
|
||||||
MDEV_WILDMIDI = 6,
|
MDEV_WILDMIDI = 6,
|
||||||
|
|
||||||
|
MDEV_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
class MusInfo;
|
class MusInfo;
|
||||||
|
|
|
@ -357,9 +357,9 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Printf("Failed to load any MIDI patches.\n");
|
|
||||||
delete_fluid_synth(FluidSynth);
|
delete_fluid_synth(FluidSynth);
|
||||||
FluidSynth = NULL;
|
FluidSynth = NULL;
|
||||||
|
I_Error("Failed to load any MIDI patches.\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "i_midi_win32.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -130,6 +128,10 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
||||||
{
|
{
|
||||||
Renderer = new TimidityPlus::Player(timidity_frequency, instruments);
|
Renderer = new TimidityPlus::Player(timidity_frequency, instruments);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_Error("Failed to load any MIDI patches");
|
||||||
|
}
|
||||||
sampletime = 0;
|
sampletime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,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 "i_system.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -123,6 +124,10 @@ WildMIDIDevice::WildMIDIDevice(const char *args)
|
||||||
if (wildmidi_reverb) flags |= WM_MO_REVERB;
|
if (wildmidi_reverb) flags |= WM_MO_REVERB;
|
||||||
Renderer->SetOption(WM_MO_ENHANCED_RESAMPLING | WM_MO_REVERB, flags);
|
Renderer->SetOption(WM_MO_ENHANCED_RESAMPLING | WM_MO_REVERB, flags);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_Error("Failed to load any MIDI patches");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
|
@ -682,7 +683,7 @@ MIDIDevice *CreateWinMIDIDevice(int mididevice)
|
||||||
if (d->BufferDoneEvent == nullptr || d->ExitEvent == nullptr)
|
if (d->BufferDoneEvent == nullptr || d->ExitEvent == nullptr)
|
||||||
{
|
{
|
||||||
delete d;
|
delete d;
|
||||||
return nullptr;
|
I_Error("failed to create MIDI events");
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (self == -1) self = DEF_MIDIDEV;
|
else if (self == -1) self = DEF_MIDIDEV;
|
||||||
mididevice = MAX<UINT>(0, self);
|
mididevice = MAX<int>(0, self);
|
||||||
MIDIDeviceChanged(self);
|
MIDIDeviceChanged(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,42 +183,60 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
|
||||||
{
|
{
|
||||||
// fixme: This should check up front if the device can be started.
|
// 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.
|
// 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
|
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)
|
catch (CRecoverableError &err)
|
||||||
{
|
{
|
||||||
// The creation of an OPL MIDI device can abort with an error if no GENMIDI lump can be found.
|
checked[devtype] = true;
|
||||||
Printf("Unable to create OPL MIDI device: %s\nFalling back to default playback", err.GetMessage());
|
devtype = MDEV_DEFAULT;
|
||||||
return new FluidSynthMIDIDevice(nullptr);
|
// 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ static Instrument *load_instrument(Renderer *song, const char *name, int percuss
|
||||||
int i, j;
|
int i, j;
|
||||||
bool noluck = false;
|
bool noluck = false;
|
||||||
|
|
||||||
if (!name) return 0;
|
if (!name || gus_sfreader == nullptr) return nullptr;
|
||||||
|
|
||||||
/* Open patch file */
|
/* Open patch file */
|
||||||
fp = gus_sfreader->LookupFile(name).first;
|
fp = gus_sfreader->LookupFile(name).first;
|
||||||
|
|
|
@ -720,15 +720,21 @@ void FreeDLS(DLS_Data *data);
|
||||||
|
|
||||||
Renderer::Renderer(float sample_rate, const char *args)
|
Renderer::Renderer(float sample_rate, const char *args)
|
||||||
{
|
{
|
||||||
|
int res = 0;
|
||||||
// Load explicitly stated sound font if so desired.
|
// Load explicitly stated sound font if so desired.
|
||||||
if (args != nullptr && *args != 0)
|
if (args != nullptr && *args != 0)
|
||||||
{
|
{
|
||||||
if (!stricmp(args, "DMXGUS")) LoadDMXGUS();
|
if (!stricmp(args, "DMXGUS")) res = LoadDMXGUS();
|
||||||
LoadConfig(args);
|
res = LoadConfig(args);
|
||||||
}
|
}
|
||||||
else if (tonebank[0] == nullptr)
|
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.
|
// These can be left empty here if an error occured during sound font initialization.
|
||||||
|
|
Loading…
Reference in a new issue