diff --git a/src/sound/i_soundfont.cpp b/src/sound/i_soundfont.cpp index c0d767bbf..fbd6ae8b0 100644 --- a/src/sound/i_soundfont.cpp +++ b/src/sound/i_soundfont.cpp @@ -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 &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 &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 &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); } diff --git a/src/sound/i_soundfont.h b/src/sound/i_soundfont.h index d2eefd99d..7e1aabbe0 100644 --- a/src/sound/i_soundfont.h +++ b/src/sound/i_soundfont.h @@ -13,7 +13,8 @@ enum struct FSoundFontInfo { FString mName; // This is what the sounfont is identified with. It's the extension-less base file name - FString mFilename; // Full path to the backing file - this is needed by FluidSynth to load the sound font. + 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; diff --git a/src/sound/mididevices/music_fluidsynth_mididevice.cpp b/src/sound/mididevices/music_fluidsynth_mididevice.cpp index 42244b61a..b89b280ab 100644 --- a/src/sound/mididevices/music_fluidsynth_mididevice.cpp +++ b/src/sound/mididevices/music_fluidsynth_mididevice.cpp @@ -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;