mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
- Add on-demand loading for fluidsynth.dll. This also lets you build with FluidSynth support
without actually having the FluidSynth development files installed. SVN r2557 (trunk)
This commit is contained in:
parent
2136ef2aba
commit
f389cd8b0f
3 changed files with 184 additions and 11 deletions
|
@ -261,7 +261,12 @@ protected:
|
||||||
// FluidSynth implementation of a MIDI device -------------------------------
|
// FluidSynth implementation of a MIDI device -------------------------------
|
||||||
|
|
||||||
#ifdef HAVE_FLUIDSYNTH
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
|
#ifndef DYN_FLUIDSYNTH
|
||||||
#include <fluidsynth.h>
|
#include <fluidsynth.h>
|
||||||
|
#else
|
||||||
|
struct fluid_settings_t;
|
||||||
|
struct fluid_synth_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
class FluidSynthMIDIDevice : public MIDIDevice
|
class FluidSynthMIDIDevice : public MIDIDevice
|
||||||
{
|
{
|
||||||
|
@ -313,6 +318,39 @@ protected:
|
||||||
MIDIHDR *Events;
|
MIDIHDR *Events;
|
||||||
bool Started;
|
bool Started;
|
||||||
DWORD Position;
|
DWORD Position;
|
||||||
|
|
||||||
|
#ifdef DYN_FLUIDSYNTH
|
||||||
|
enum { FLUID_FAILED = 1, FLUID_OK = 0 };
|
||||||
|
fluid_settings_t *(STACK_ARGS *new_fluid_settings)();
|
||||||
|
fluid_synth_t *(STACK_ARGS *new_fluid_synth)(fluid_settings_t *);
|
||||||
|
int (STACK_ARGS *delete_fluid_synth)(fluid_synth_t *);
|
||||||
|
void (STACK_ARGS *delete_fluid_settings)(fluid_settings_t *);
|
||||||
|
int (STACK_ARGS *fluid_settings_setnum)(fluid_settings_t *, const char *, double);
|
||||||
|
int (STACK_ARGS *fluid_settings_setstr)(fluid_settings_t *, const char *, const char *);
|
||||||
|
int (STACK_ARGS *fluid_settings_setint)(fluid_settings_t *, const char *, int);
|
||||||
|
int (STACK_ARGS *fluid_settings_getstr)(fluid_settings_t *, const char *, char **);
|
||||||
|
int (STACK_ARGS *fluid_settings_getint)(fluid_settings_t *, const char *, int *);
|
||||||
|
int (STACK_ARGS *fluid_synth_set_interp_method)(fluid_synth_t *, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_set_polyphony)(fluid_synth_t *, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_get_polyphony)(fluid_synth_t *);
|
||||||
|
int (STACK_ARGS *fluid_synth_get_active_voice_count)(fluid_synth_t *);
|
||||||
|
double (STACK_ARGS *fluid_synth_get_cpu_load)(fluid_synth_t *);
|
||||||
|
int (STACK_ARGS *fluid_synth_system_reset)(fluid_synth_t *);
|
||||||
|
int (STACK_ARGS *fluid_synth_noteon)(fluid_synth_t *, int, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_noteoff)(fluid_synth_t *, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_cc)(fluid_synth_t *, int, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_program_change)(fluid_synth_t *, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_channel_pressure)(fluid_synth_t *, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_pitch_bend)(fluid_synth_t *, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_write_float)(fluid_synth_t *, int, void *, int, int, void *, int, int);
|
||||||
|
int (STACK_ARGS *fluid_synth_sfload)(fluid_synth_t *, const char *, int);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
HMODULE FluidSynthDLL;
|
||||||
|
#endif
|
||||||
|
bool LoadFluidSynth();
|
||||||
|
void UnloadFluidSynth();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,20 @@
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef DYN_FLUIDSYNTH
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifndef _M_X64
|
||||||
|
#define FLUIDSYNTHLIB "fluidsynth.dll"
|
||||||
|
#else
|
||||||
|
#define FLUIDSYNTHLIB "fluidsynth64.dll"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error "TODO: Write a dlopen() version of this code."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// TYPES -------------------------------------------------------------------
|
// TYPES -------------------------------------------------------------------
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
@ -93,16 +107,22 @@ CUSTOM_CVAR(Int, fluid_voices, 128, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
currSong->FluidSettingInt("synth.polyphony", self);
|
currSong->FluidSettingInt("synth.polyphony", self);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, fluid_interp, FLUID_INTERP_LINEAR, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR(Int, fluid_interp, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
{
|
{
|
||||||
// Values are: 0 = FLUID_INTERP_NONE
|
// Values are: 0 = FLUID_INTERP_NONE
|
||||||
// 1 = FLUID_INTERP_LINEAR
|
// 1 = FLUID_INTERP_LINEAR
|
||||||
// 2 = FLUID_INTERP_4THORDER (the FluidSynth default)
|
// 4 = FLUID_INTERP_4THORDER (the FluidSynth default)
|
||||||
// 3 = FLUID_INTERP_7THORDER
|
// 7 = FLUID_INTERP_7THORDER
|
||||||
if (self < FLUID_INTERP_NONE)
|
// (And here I thought it was just a linear list.)
|
||||||
self = FLUID_INTERP_NONE;
|
// Round undefined values to the nearest valid one.
|
||||||
else if (self > FLUID_INTERP_HIGHEST)
|
if (self < 0)
|
||||||
self = FLUID_INTERP_HIGHEST;
|
self = 0;
|
||||||
|
else if (self == 2)
|
||||||
|
self = 1;
|
||||||
|
else if (self == 3 || self == 5)
|
||||||
|
self = 4;
|
||||||
|
else if (self == 6 || self > 7)
|
||||||
|
self = 7;
|
||||||
else if (currSong != NULL)
|
else if (currSong != NULL)
|
||||||
currSong->FluidSettingInt("synth.interpolation", self);
|
currSong->FluidSettingInt("synth.interpolation", self);
|
||||||
}
|
}
|
||||||
|
@ -123,6 +143,13 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice()
|
||||||
Events = NULL;
|
Events = NULL;
|
||||||
Started = false;
|
Started = false;
|
||||||
FluidSynth = NULL;
|
FluidSynth = NULL;
|
||||||
|
FluidSettings = NULL;
|
||||||
|
#ifdef DYN_FLUIDSYNTH
|
||||||
|
if (!LoadFluidSynth())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
FluidSettings = new_fluid_settings();
|
FluidSettings = new_fluid_settings();
|
||||||
if (FluidSettings == NULL)
|
if (FluidSettings == NULL)
|
||||||
{
|
{
|
||||||
|
@ -195,6 +222,9 @@ FluidSynthMIDIDevice::~FluidSynthMIDIDevice()
|
||||||
{
|
{
|
||||||
delete_fluid_settings(FluidSettings);
|
delete_fluid_settings(FluidSettings);
|
||||||
}
|
}
|
||||||
|
#ifdef DYN_FLUIDSYNTH
|
||||||
|
UnloadFluidSynth();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -814,5 +844,106 @@ FString FluidSynthMIDIDevice::GetStats()
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DYN_FLUIDSYNTH
|
||||||
|
|
||||||
|
struct LibFunc
|
||||||
|
{
|
||||||
|
void **FuncPointer;
|
||||||
|
const char *FuncName;
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FluidSynthMIDIDevice :: LoadFluidSynth
|
||||||
|
//
|
||||||
|
// Returns true if the FluidSynth library was successfully loaded.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool FluidSynthMIDIDevice::LoadFluidSynth()
|
||||||
|
{
|
||||||
|
LibFunc imports[] =
|
||||||
|
{
|
||||||
|
{ (void **)&new_fluid_settings, "new_fluid_settings" },
|
||||||
|
{ (void **)&new_fluid_synth, "new_fluid_synth" },
|
||||||
|
{ (void **)&delete_fluid_synth, "delete_fluid_synth" },
|
||||||
|
{ (void **)&delete_fluid_settings, "delete_fluid_settings" },
|
||||||
|
{ (void **)&fluid_settings_setnum, "fluid_settings_setnum" },
|
||||||
|
{ (void **)&fluid_settings_setstr, "fluid_settings_setstr" },
|
||||||
|
{ (void **)&fluid_settings_setint, "fluid_settings_setint" },
|
||||||
|
{ (void **)&fluid_settings_getstr, "fluid_settings_getstr" },
|
||||||
|
{ (void **)&fluid_settings_getint, "fluid_settings_getint" },
|
||||||
|
{ (void **)&fluid_synth_set_interp_method, "fluid_synth_set_interp_method" },
|
||||||
|
{ (void **)&fluid_synth_set_polyphony, "fluid_synth_set_polyphony" },
|
||||||
|
{ (void **)&fluid_synth_get_polyphony, "fluid_synth_get_polyphony" },
|
||||||
|
{ (void **)&fluid_synth_get_active_voice_count, "fluid_synth_get_active_voice_count" },
|
||||||
|
{ (void **)&fluid_synth_get_cpu_load, "fluid_synth_get_cpu_load" },
|
||||||
|
{ (void **)&fluid_synth_system_reset, "fluid_synth_system_reset" },
|
||||||
|
{ (void **)&fluid_synth_noteon, "fluid_synth_noteon" },
|
||||||
|
{ (void **)&fluid_synth_noteoff, "fluid_synth_noteoff" },
|
||||||
|
{ (void **)&fluid_synth_cc, "fluid_synth_cc" },
|
||||||
|
{ (void **)&fluid_synth_program_change, "fluid_synth_program_change" },
|
||||||
|
{ (void **)&fluid_synth_channel_pressure, "fluid_synth_channel_pressure" },
|
||||||
|
{ (void **)&fluid_synth_pitch_bend, "fluid_synth_pitch_bend" },
|
||||||
|
{ (void **)&fluid_synth_write_float, "fluid_synth_write_float" },
|
||||||
|
{ (void **)&fluid_synth_sfload, "fluid_synth_sfload" }
|
||||||
|
};
|
||||||
|
int fail = 0;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
FluidSynthDLL = LoadLibrary(FLUIDSYNTHLIB);
|
||||||
|
#endif
|
||||||
|
if (FluidSynthDLL == NULL)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_RED"Could not load " FLUIDSYNTHLIB "\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < countof(imports); ++i)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
FARPROC proc = GetProcAddress(FluidSynthDLL, imports[i].FuncName);
|
||||||
|
if (proc == NULL)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_RED"Failed to find %s in %s\n", imports[i].FuncName, FLUIDSYNTHLIB);
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
*imports[i].FuncPointer = proc;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (fail == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
FreeLibrary(FluidSynthDLL);
|
||||||
|
FluidSynthDLL = NULL;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FluidSynthMIDIDevice :: UnloadFluidSynth
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FluidSynthMIDIDevice::UnloadFluidSynth()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (FluidSynthDLL != NULL)
|
||||||
|
{
|
||||||
|
FreeLibrary(FluidSynthDLL);
|
||||||
|
FluidSynthDLL = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
12
zdoom.vcproj
12
zdoom.vcproj
|
@ -56,8 +56,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="false"
|
WholeProgramOptimization="false"
|
||||||
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;"jpeg-6b";game-music-emu\gme;gdtoa;bzip2;lzma\C"
|
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;"jpeg-6b";"game-music-emu\gme";gdtoa;bzip2;lzma\C"
|
||||||
PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH"
|
PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH,HAVE_FLUIDSYNTH,DYN_FLUIDSYNTH"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
ExceptionHandling="1"
|
ExceptionHandling="1"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
@ -286,8 +286,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;"jpeg-6b";game-music-emu\gme;gdtoa;bzip2;lzma\C"
|
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;"jpeg-6b";"game-music-emu\gme";gdtoa;bzip2;lzma\C"
|
||||||
PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH"
|
PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH,HAVE_FLUIDSYNTH,DYN_FLUIDSYNTH"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
|
@ -5445,6 +5445,10 @@
|
||||||
RelativePath=".\src\sound\music_dumb.cpp"
|
RelativePath=".\src\sound\music_dumb.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\sound\music_fluidsynth_mididevice.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sound\music_gme.cpp"
|
RelativePath=".\src\sound\music_gme.cpp"
|
||||||
>
|
>
|
||||||
|
|
Loading…
Reference in a new issue