- Soundfont manager works for FluidSynth.

This commit is contained in:
Christoph Oelckers 2018-02-22 18:03:22 +01:00
parent 8b8a7e5e45
commit 1361956072
3 changed files with 24 additions and 14 deletions

View file

@ -86,7 +86,7 @@ FileReader *FSoundFontReader::OpenMainConfigFile()
{ {
if (mMainConfigForSF2.IsNotEmpty()) if (mMainConfigForSF2.IsNotEmpty())
{ {
return new MemoryReader(mMainConfigForSF2.GetChars(), mMainConfigForSF2.Len()); return new MemoryReader(mMainConfigForSF2.GetChars(), (long)mMainConfigForSF2.Len());
} }
else else
{ {
@ -208,7 +208,7 @@ FileReader *FSF2Reader::OpenFile(const char *name)
FZipPatReader::FZipPatReader(const char *filename) FZipPatReader::FZipPatReader(const char *filename)
{ {
resf = FResourceFile::OpenResourceFile(filename, nullptr); resf = FResourceFile::OpenResourceFile(filename, nullptr, true);
} }
FZipPatReader::~FZipPatReader() FZipPatReader::~FZipPatReader()
@ -308,6 +308,7 @@ FileReader *FPatchSetReader::OpenFile(const char *name)
void FSoundFontManager::ProcessOneFile(const FString &fn, TArray<FString> &sffiles) void FSoundFontManager::ProcessOneFile(const FString &fn, TArray<FString> &sffiles)
{ {
auto fb = ExtractFileBase(fn, false); auto fb = ExtractFileBase(fn, false);
auto fbe = ExtractFileBase(fn, true);
for (auto &sfi : soundfonts) for (auto &sfi : soundfonts)
{ {
// We already got a soundfont with this name. Do not add again. // We already got a soundfont with this name. Do not add again.
@ -323,12 +324,12 @@ void FSoundFontManager::ProcessOneFile(const FString &fn, TArray<FString> &sffil
if (!memcmp(head, "RIFF", 4) && !memcmp(head+8, "sfbkLIST", 8)) if (!memcmp(head, "RIFF", 4) && !memcmp(head+8, "sfbkLIST", 8))
{ {
sffiles.Push(fn); sffiles.Push(fn);
FSoundFontInfo sft = { fb, fn, SF_SF2 }; FSoundFontInfo sft = { fb, fbe, fn, SF_SF2 };
soundfonts.Push(sft); soundfonts.Push(sft);
} }
else if (!memcmp(head, "PK", 2)) else if (!memcmp(head, "PK", 2))
{ {
auto zip = FResourceFile::OpenResourceFile(fn, nullptr); auto zip = FResourceFile::OpenResourceFile(fn, nullptr, true);
if (zip != nullptr) if (zip != nullptr)
{ {
if (zip->LumpCount() > 1) // Anything with just one lump cannot possibly be a packed GUS patch set so skip it right away and simplify the lookup code if (zip->LumpCount() > 1) // Anything with just one lump cannot possibly be a packed GUS patch set so skip it right away and simplify the lookup code
@ -338,7 +339,7 @@ void FSoundFontManager::ProcessOneFile(const FString &fn, TArray<FString> &sffil
{ {
// It seems like this is what we are looking for // It seems like this is what we are looking for
sffiles.Push(fn); sffiles.Push(fn);
FSoundFontInfo sft = { fb, fn, SF_GUS }; FSoundFontInfo sft = { fb, fbe, fn, SF_GUS };
soundfonts.Push(sft); soundfonts.Push(sft);
} }
} }
@ -394,6 +395,8 @@ void FSoundFontManager::CollectSoundfonts()
} }
} }
} }
if (sffiles.Size() > 0) if (sffiles.Size() > 0)
soundfontcollection.InitMultipleFiles(sffiles); soundfontcollection.InitMultipleFiles(sffiles);
} }
@ -408,7 +411,8 @@ const FSoundFontInfo *FSoundFontManager::FindSoundFont(const char *name, int all
{ {
for(auto &sfi : soundfonts) for(auto &sfi : soundfonts)
{ {
if (allowed & sfi.type && !sfi.mFilename.CompareNoCase(name)) // an empty name will pick the first one in a compatible format.
if (allowed & sfi.type && (name == nullptr || *name == 0 || !sfi.mName.CompareNoCase(name) || !sfi.mNameExt.CompareNoCase(name)))
{ {
return &sfi; return &sfi;
} }
@ -440,7 +444,8 @@ FSoundFontReader *FSoundFontManager::OpenSoundFont(const char *name, int allowed
fr.Read(head, 16); fr.Read(head, 16);
if (!memcmp(head, "RIFF", 4) && !memcmp(head+8, "sfbkLIST", 8)) if (!memcmp(head, "RIFF", 4) && !memcmp(head+8, "sfbkLIST", 8))
{ {
FSoundFontInfo sft = { name, name, SF_SF2 }; FString fname = name;
FSoundFontInfo sft = { fname, fname, fname, SF_SF2 };
soundfonts.Push(sft); soundfonts.Push(sft);
} }

View file

@ -13,6 +13,7 @@ enum
struct FSoundFontInfo struct FSoundFontInfo
{ {
FString mName; // This is what the sounfont is identified with. It's the extension-less base file name FString mName; // This is what the sounfont is identified with. It's the extension-less base file name
FString mNameExt; // Same with extension. Used for comparing with input names so they can be done with or without extension.
FString mFilename; // Full path to the backing file - this is needed by FluidSynth to load the sound font. FString mFilename; // Full path to the backing file - this is needed by FluidSynth to load the sound font.
int type; int type;
}; };
@ -125,3 +126,4 @@ public:
}; };
extern FSoundFontManager sfmanager;

View file

@ -45,6 +45,7 @@
#include "v_text.h" #include "v_text.h"
#include "version.h" #include "version.h"
#include "cmdlib.h" #include "cmdlib.h"
#include "i_soundfont.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -325,6 +326,11 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
{ {
return; return;
} }
if (LoadPatchSets(nullptr))
{
return;
}
// The following will only be used if no soundfont at all is provided, i.e. even the standard one coming with GZDoom is missing.
#ifdef __unix__ #ifdef __unix__
// This is the standard location on Ubuntu. // This is the standard location on Ubuntu.
if (LoadPatchSets("/usr/share/sounds/sf2/FluidR3_GS.sf2:/usr/share/sounds/sf2/FluidR3_GM.sf2")) if (LoadPatchSets("/usr/share/sounds/sf2/FluidR3_GS.sf2:/usr/share/sounds/sf2/FluidR3_GM.sf2"))
@ -352,12 +358,6 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
} }
#endif #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"); Printf("Failed to load any MIDI patches.\n");
delete_fluid_synth(FluidSynth); delete_fluid_synth(FluidSynth);
@ -495,6 +495,9 @@ void FluidSynthMIDIDevice::ComputeOutput(float *buffer, int len)
int FluidSynthMIDIDevice::LoadPatchSets(const char *patches) int FluidSynthMIDIDevice::LoadPatchSets(const char *patches)
{ {
auto info = sfmanager.FindSoundFont(patches, SF_SF2);
if (info != nullptr) patches = info->mFilename.GetChars();
int count; int count;
char *wpatches = strdup(patches); char *wpatches = strdup(patches);
char *tok; char *tok;