- 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())
{
return new MemoryReader(mMainConfigForSF2.GetChars(), mMainConfigForSF2.Len());
return new MemoryReader(mMainConfigForSF2.GetChars(), (long)mMainConfigForSF2.Len());
}
else
{
@ -208,7 +208,7 @@ FileReader *FSF2Reader::OpenFile(const char *name)
FZipPatReader::FZipPatReader(const char *filename)
{
resf = FResourceFile::OpenResourceFile(filename, nullptr);
resf = FResourceFile::OpenResourceFile(filename, nullptr, true);
}
FZipPatReader::~FZipPatReader()
@ -308,6 +308,7 @@ FileReader *FPatchSetReader::OpenFile(const char *name)
void FSoundFontManager::ProcessOneFile(const FString &fn, TArray<FString> &sffiles)
{
auto fb = ExtractFileBase(fn, false);
auto fbe = ExtractFileBase(fn, true);
for (auto &sfi : soundfonts)
{
// 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))
{
sffiles.Push(fn);
FSoundFontInfo sft = { fb, fn, SF_SF2 };
FSoundFontInfo sft = { fb, fbe, fn, SF_SF2 };
soundfonts.Push(sft);
}
else if (!memcmp(head, "PK", 2))
{
auto zip = FResourceFile::OpenResourceFile(fn, nullptr);
auto zip = FResourceFile::OpenResourceFile(fn, nullptr, true);
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
@ -338,7 +339,7 @@ void FSoundFontManager::ProcessOneFile(const FString &fn, TArray<FString> &sffil
{
// It seems like this is what we are looking for
sffiles.Push(fn);
FSoundFontInfo sft = { fb, fn, SF_GUS };
FSoundFontInfo sft = { fb, fbe, fn, SF_GUS };
soundfonts.Push(sft);
}
}
@ -394,6 +395,8 @@ void FSoundFontManager::CollectSoundfonts()
}
}
}
if (sffiles.Size() > 0)
soundfontcollection.InitMultipleFiles(sffiles);
}
@ -408,7 +411,8 @@ const FSoundFontInfo *FSoundFontManager::FindSoundFont(const char *name, int all
{
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;
}
@ -440,7 +444,8 @@ FSoundFontReader *FSoundFontManager::OpenSoundFont(const char *name, int allowed
fr.Read(head, 16);
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);
}

View File

@ -13,6 +13,7 @@ enum
struct FSoundFontInfo
{
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.
int type;
};
@ -125,3 +126,4 @@ public:
};
extern FSoundFontManager sfmanager;

View File

@ -45,6 +45,7 @@
#include "v_text.h"
#include "version.h"
#include "cmdlib.h"
#include "i_soundfont.h"
// MACROS ------------------------------------------------------------------
@ -325,6 +326,11 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
{
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__
// This is the standard location on Ubuntu.
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
// 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);
@ -495,6 +495,9 @@ void FluidSynthMIDIDevice::ComputeOutput(float *buffer, int len)
int FluidSynthMIDIDevice::LoadPatchSets(const char *patches)
{
auto info = sfmanager.FindSoundFont(patches, SF_SF2);
if (info != nullptr) patches = info->mFilename.GetChars();
int count;
char *wpatches = strdup(patches);
char *tok;