From b3b870d67ee093820cde78f643c2ccccf5667efa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 27 Sep 2019 01:51:05 +0200 Subject: [PATCH] - Gave OPN device the same treatment Also made some improvements to the interface. --- src/sound/mididevices/midi_cvars.cpp | 120 ++++++++++++++++-- .../mididevices/music_adlmidi_mididevice.cpp | 17 +-- .../music_fluidsynth_mididevice.cpp | 8 +- .../mididevices/music_opl_mididevice.cpp | 6 +- .../mididevices/music_opnmidi_mididevice.cpp | 84 +++--------- src/sound/music/i_musicinterns.h | 26 +++- src/sound/musicformats/music_midistream.cpp | 9 +- 7 files changed, 172 insertions(+), 98 deletions(-) diff --git a/src/sound/mididevices/midi_cvars.cpp b/src/sound/mididevices/midi_cvars.cpp index 99a9de6eaf..7120df3cf4 100644 --- a/src/sound/mididevices/midi_cvars.cpp +++ b/src/sound/mididevices/midi_cvars.cpp @@ -40,7 +40,9 @@ #include "doomerrors.h" // do this without including windows.h for this one single prototype +#ifdef _WIN32 extern "C" unsigned __stdcall GetSystemDirectoryA(char* lpBuffer, unsigned uSize); +#endif static void CheckRestart(int devtype) { @@ -53,7 +55,7 @@ static void CheckRestart(int devtype) ADLConfig adlConfig; FluidConfig fluidConfig; OPLMidiConfig oplMidiConfig; - +OpnConfig opnConfig; CUSTOM_CVAR(Int, adl_chips_count, 6, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { @@ -87,20 +89,38 @@ CUSTOM_CVAR(Int, adl_bank, 14, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CUSTOM_CVAR(Bool, adl_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { - adlConfig.adl_use_custom_bank = self; CheckRestart(MDEV_ADL); } CUSTOM_CVAR(String, adl_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { - CheckRestart(MDEV_ADL); - - //Resolve the path here, so that the renderer does not have to do the work itself and only needs to process final names. - auto info = sfmanager.FindSoundFont(self, SF_WOPL); - if (info == nullptr) adlConfig.adl_custom_bank = nullptr; - else adlConfig.adl_custom_bank = info->mFilename; + if (adl_use_custom_bank) CheckRestart(MDEV_ADL); } +void SetAdlCustomBank(const char *Args) +{ + //Resolve the path here, so that the renderer does not have to do the work itself and only needs to process final names. + const char *bank = Args && *Args? Args : adl_use_custom_bank? *adl_custom_bank : nullptr; + adlConfig.adl_bank = adl_bank; + if (bank && *bank) + { + auto info = sfmanager.FindSoundFont(bank, SF_WOPL); + if (info == nullptr) + { + if (*bank >= '0' && *bank <= '9') + { + adlConfig.adl_bank = (int)strtoll(bank, nullptr, 10); + } + adlConfig.adl_custom_bank = nullptr; + } + else + { + adlConfig.adl_custom_bank = info->mFilename; + } + } +} + + CUSTOM_CVAR(Int, adl_volume_model, ADLMIDI_VolumeModel_DMX, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { adlConfig.adl_volume_model = self; @@ -469,3 +489,87 @@ int getOPLCore(const char* args) if (args != NULL && *args >= '0' && *args < '4') current_opl_core = *args - '0'; return current_opl_core; } + + + + + +CUSTOM_CVAR(Int, opn_chips_count, 8, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + opnConfig.opn_chips_count = self; + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) + { + MIDIDeviceChanged(-1, true); + } +} + +CUSTOM_CVAR(Int, opn_emulator_id, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + opnConfig.opn_emulator_id = self; + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) + { + MIDIDeviceChanged(-1, true); + } +} + +CUSTOM_CVAR(Bool, opn_run_at_pcm_rate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + opnConfig.opn_run_at_pcm_rate = self; + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) + { + MIDIDeviceChanged(-1, true); + } +} + +CUSTOM_CVAR(Bool, opn_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + opnConfig.opn_fullpan = self; + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) + { + MIDIDeviceChanged(-1, true); + } +} + +CUSTOM_CVAR(Bool, opn_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) + { + MIDIDeviceChanged(-1, true); + } +} + +CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (opn_use_custom_bank && currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) + { + MIDIDeviceChanged(-1, true); + } +} + +void SetOpnCustomBank(const char *Args) +{ + //Resolve the path here, so that the renderer does not have to do the work itself and only needs to process final names. + const char *bank = Args && *Args? Args : opn_use_custom_bank? *opn_custom_bank : nullptr; + if (bank && *bank) + { + auto info = sfmanager.FindSoundFont(bank, SF_WOPN); + if (info == nullptr) + { + opnConfig.opn_custom_bank = ""; + } + else + { + opnConfig.opn_custom_bank = info->mFilename; + } + } + + int lump = Wads.CheckNumForFullName("xg.wopn"); + if (lump < 0) + { + opnConfig.default_bank.resize(0); + return; + } + FMemLump data = Wads.ReadLump(lump); + opnConfig.default_bank.resize(data.GetSize()); + memcpy(opnConfig.default_bank.data(), data.GetMem(), data.GetSize()); +} diff --git a/src/sound/mididevices/music_adlmidi_mididevice.cpp b/src/sound/mididevices/music_adlmidi_mididevice.cpp index 01fe9a3732..27090446a7 100644 --- a/src/sound/mididevices/music_adlmidi_mididevice.cpp +++ b/src/sound/mididevices/music_adlmidi_mididevice.cpp @@ -41,7 +41,7 @@ class ADLMIDIDevice : public SoftSynthMIDIDevice { struct ADL_MIDIPlayer *Renderer; public: - ADLMIDIDevice(const char *args, const ADLConfig *config); + ADLMIDIDevice(const ADLConfig *config); ~ADLMIDIDevice(); int Open(MidiCallback, void *userdata); @@ -54,7 +54,7 @@ protected: void ComputeOutput(float *buffer, int len); private: - int LoadCustomBank(const char *bankfile, const ADLConfig *config); + int LoadCustomBank(const ADLConfig *config); }; @@ -75,7 +75,7 @@ enum // //========================================================================== -ADLMIDIDevice::ADLMIDIDevice(const char *args, const ADLConfig *config) +ADLMIDIDevice::ADLMIDIDevice(const ADLConfig *config) :SoftSynthMIDIDevice(44100) { Renderer = adl_init(44100); // todo: make it configurable @@ -83,7 +83,7 @@ ADLMIDIDevice::ADLMIDIDevice(const char *args, const ADLConfig *config) { adl_switchEmulator(Renderer, config->adl_emulator_id); adl_setRunAtPcmRate(Renderer, config->adl_run_at_pcm_rate); - if (!LoadCustomBank(config->adl_custom_bank, config)) + if (!LoadCustomBank(config)) adl_setBank(Renderer, config->adl_bank); adl_setNumChips(Renderer, config->adl_chips_count); adl_setVolumeRangeModel(Renderer, config->adl_volume_model); @@ -116,9 +116,10 @@ ADLMIDIDevice::~ADLMIDIDevice() // //========================================================================== -int ADLMIDIDevice::LoadCustomBank(const char *bankfile, const ADLConfig *config) +int ADLMIDIDevice::LoadCustomBank(const ADLConfig *config) { - if(!config->adl_use_custom_bank || !bankfile || !*bankfile) + const char *bankfile = config->adl_custom_bank.c_str(); + if(!*bankfile) return 0; return (adl_openBankFile(Renderer, bankfile) == 0); } @@ -225,9 +226,9 @@ void ADLMIDIDevice::ComputeOutput(float *buffer, int len) // //========================================================================== -MIDIDevice *CreateADLMIDIDevice(const char *args, const ADLConfig *config) +MIDIDevice *CreateADLMIDIDevice(const ADLConfig *config) { - return new ADLMIDIDevice(args, config); + return new ADLMIDIDevice(config); } diff --git a/src/sound/mididevices/music_fluidsynth_mididevice.cpp b/src/sound/mididevices/music_fluidsynth_mididevice.cpp index 69493ee6e4..f0c1c04496 100644 --- a/src/sound/mididevices/music_fluidsynth_mididevice.cpp +++ b/src/sound/mididevices/music_fluidsynth_mididevice.cpp @@ -51,7 +51,7 @@ struct fluid_synth_t; class FluidSynthMIDIDevice : public SoftSynthMIDIDevice { public: - FluidSynthMIDIDevice(int samplerate, FluidConfig *config, int (*printfunc_)(const char *, ...)); + FluidSynthMIDIDevice(int samplerate, const FluidConfig *config, int (*printfunc_)(const char *, ...)); ~FluidSynthMIDIDevice(); int Open(MidiCallback, void *userdata); @@ -162,7 +162,7 @@ const char *BaseFileSearch(const char *file, const char *ext, bool lookfirstinpr // //========================================================================== -FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, FluidConfig *config, int (*printfunc_)(const char*, ...) = nullptr) +FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, const FluidConfig *config, int (*printfunc_)(const char*, ...) = nullptr) : SoftSynthMIDIDevice(samplerate <= 0? config->fluid_samplerate : samplerate, 22050, 96000) { // These are needed for changing the settings. If something posts a transient config in here we got no way to retrieve the values afterward. @@ -180,7 +180,7 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, FluidConfig *config, FluidSynth = NULL; FluidSettings = NULL; #ifdef DYN_FLUIDSYNTH - if (!LoadFluidSynth(config->fluid_lib)) + if (!LoadFluidSynth(config->fluid_lib.c_str())) { throw std::runtime_error("Failed to load FluidSynth.\n"); } @@ -621,7 +621,7 @@ void FluidSynthMIDIDevice::UnloadFluidSynth() // //========================================================================== -MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, FluidConfig *config, int (*printfunc)(const char*, ...)) +MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, const FluidConfig *config, int (*printfunc)(const char*, ...)) { return new FluidSynthMIDIDevice(samplerate, config, printfunc); } diff --git a/src/sound/mididevices/music_opl_mididevice.cpp b/src/sound/mididevices/music_opl_mididevice.cpp index 66074dd94c..744581d6bf 100644 --- a/src/sound/mididevices/music_opl_mididevice.cpp +++ b/src/sound/mididevices/music_opl_mididevice.cpp @@ -55,7 +55,7 @@ class OPLMIDIDevice : public SoftSynthMIDIDevice, protected OPLmusicBlock { public: - OPLMIDIDevice(OPLMidiConfig *config); + OPLMIDIDevice(const OPLMidiConfig *config); int Open(MidiCallback, void *userdata); void Close(); int GetTechnology() const; @@ -82,7 +82,7 @@ protected: // //========================================================================== -OPLMIDIDevice::OPLMIDIDevice(OPLMidiConfig *config) +OPLMIDIDevice::OPLMIDIDevice(const OPLMidiConfig *config) : SoftSynthMIDIDevice((int)OPL_SAMPLE_RATE), OPLmusicBlock(config->core, config->numchips) { FullPan = config->fullpan; @@ -314,7 +314,7 @@ FString OPLMIDIDevice::GetStats() return out; } -MIDIDevice* CreateOplMIDIDevice(OPLMidiConfig* config) +MIDIDevice* CreateOplMIDIDevice(const OPLMidiConfig* config) { return new OPLMIDIDevice(config); } diff --git a/src/sound/mididevices/music_opnmidi_mididevice.cpp b/src/sound/mididevices/music_opnmidi_mididevice.cpp index 1a08d6c722..1ca9c04354 100644 --- a/src/sound/mididevices/music_opnmidi_mididevice.cpp +++ b/src/sound/mididevices/music_opnmidi_mididevice.cpp @@ -44,7 +44,7 @@ class OPNMIDIDevice : public SoftSynthMIDIDevice { struct OPN2_MIDIPlayer *Renderer; public: - OPNMIDIDevice(const char *args); + OPNMIDIDevice(const OpnConfig *config); ~OPNMIDIDevice(); @@ -72,53 +72,6 @@ enum ME_PITCHWHEEL = 0xE0 }; -CUSTOM_CVAR(Int, opn_chips_count, 8, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) - { - MIDIDeviceChanged(-1, true); - } -} - -CUSTOM_CVAR(Int, opn_emulator_id, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) - { - MIDIDeviceChanged(-1, true); - } -} - -CUSTOM_CVAR(Bool, opn_run_at_pcm_rate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) - { - MIDIDeviceChanged(-1, true); - } -} - -CUSTOM_CVAR(Bool, opn_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) - { - MIDIDeviceChanged(-1, true); - } -} - -CUSTOM_CVAR(Bool, opn_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) - { - MIDIDeviceChanged(-1, true); - } -} - -CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (opn_use_custom_bank && currSong != nullptr && currSong->GetDeviceType() == MDEV_OPN) - { - MIDIDeviceChanged(-1, true); - } -} //========================================================================== // @@ -126,27 +79,30 @@ CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // //========================================================================== -OPNMIDIDevice::OPNMIDIDevice(const char *args) +OPNMIDIDevice::OPNMIDIDevice(const OpnConfig *config) :SoftSynthMIDIDevice(44100) { Renderer = opn2_init(44100); // todo: make it configurable if (Renderer != nullptr) { - if (!LoadCustomBank(opn_custom_bank)) + if (!LoadCustomBank(config->opn_custom_bank.c_str())) { - int lump = Wads.CheckNumForFullName("xg.wopn"); - if (lump < 0) + if(config->default_bank.size() == 0) { - I_Error("No OPN bank found"); + opn2_close(Renderer); + throw std::runtime_error("No OPN bank found"); } - FMemLump data = Wads.ReadLump(lump); - opn2_openBankData(Renderer, data.GetMem(), (long)data.GetSize()); + opn2_openBankData(Renderer, config->default_bank.data(), (long)config->default_bank.size()); } - opn2_switchEmulator(Renderer, (int)opn_emulator_id); - opn2_setRunAtPcmRate(Renderer, (int)opn_run_at_pcm_rate); - opn2_setNumChips(Renderer, opn_chips_count); - opn2_setSoftPanEnabled(Renderer, (int)opn_fullpan); + opn2_switchEmulator(Renderer, (int)config->opn_emulator_id); + opn2_setRunAtPcmRate(Renderer, (int)config->opn_run_at_pcm_rate); + opn2_setNumChips(Renderer, config->opn_chips_count); + opn2_setSoftPanEnabled(Renderer, (int)config->opn_fullpan); + } + else + { + throw std::runtime_error("Unable to create OPN renderer."); } } @@ -177,12 +133,8 @@ OPNMIDIDevice::~OPNMIDIDevice() int OPNMIDIDevice::LoadCustomBank(const char *bankfile) { - if(!opn_use_custom_bank) + if(!bankfile || !*bankfile) return 0; - auto info = sfmanager.FindSoundFont(bankfile, SF_WOPN); - if(info == nullptr) - return 0; - bankfile = info->mFilename.GetChars(); return (opn2_openBankFile(Renderer, bankfile) == 0); } @@ -283,9 +235,9 @@ void OPNMIDIDevice::ComputeOutput(float *buffer, int len) // //========================================================================== -MIDIDevice *CreateOPNMIDIDevice(const char *args) +MIDIDevice *CreateOPNMIDIDevice(const OpnConfig *config) { - return new OPNMIDIDevice(args); + return new OPNMIDIDevice(config); } diff --git a/src/sound/music/i_musicinterns.h b/src/sound/music/i_musicinterns.h index 2d0beeaf99..ab4ac488d0 100644 --- a/src/sound/music/i_musicinterns.h +++ b/src/sound/music/i_musicinterns.h @@ -35,15 +35,14 @@ struct ADLConfig int adl_volume_model = 3; // DMX bool adl_run_at_pcm_rate = 0; bool adl_fullpan = 1; - bool adl_use_custom_bank = 0; - const char *adl_custom_bank = nullptr; + std::string adl_custom_bank; }; extern ADLConfig adlConfig; struct FluidConfig { - const char* fluid_lib = nullptr; + std::string fluid_lib; std::vector fluid_patchset; bool fluid_reverb = false; bool fluid_chorus = false; @@ -73,6 +72,18 @@ struct OPLMidiConfig struct GenMidiInstrument OPLinstruments[GENMIDI_NUM_TOTAL]; }; +struct OpnConfig +{ + int opn_chips_count = 8; + int opn_emulator_id = 0; + bool opn_run_at_pcm_rate = false; + bool opn_fullpan = 1; + std::string opn_custom_bank; + std::vector default_bank; +}; + + + extern OPLMidiConfig oplMidiConfig; @@ -351,11 +362,20 @@ public: CDDAFile (FileReader &reader); }; +// MIDI devices + +MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, const FluidConfig* config, int (*printfunc)(const char*, ...)); +MIDIDevice *CreateADLMIDIDevice(const ADLConfig* config); +MIDIDevice *CreateOPNMIDIDevice(const OpnConfig *args); +MIDIDevice *CreateOplMIDIDevice(const OPLMidiConfig* config); + // Data interface int BuildFluidPatchSetList(const char* patches, bool systemfallback); +void SetAdlCustomBank(const char *Args); void LoadGenMidi(); int getOPLCore(const char* args); +void SetOpnCustomBank(const char *Args); // Module played via foo_dumb ----------------------------------------------- diff --git a/src/sound/musicformats/music_midistream.cpp b/src/sound/musicformats/music_midistream.cpp index 75a345e284..4bdc133d60 100644 --- a/src/sound/musicformats/music_midistream.cpp +++ b/src/sound/musicformats/music_midistream.cpp @@ -50,14 +50,9 @@ #ifdef _WIN32 MIDIDevice *CreateWinMIDIDevice(int mididevice); #endif -MIDIDevice* CreateFluidSynthMIDIDevice(int samplerate, FluidConfig* config, int (*printfunc)(const char*, ...)); MIDIDevice *CreateTimidityMIDIDevice(const char *args, int samplerate); MIDIDevice *CreateTimidityPPMIDIDevice(const char *args, int samplerate); -MIDIDevice *CreateADLMIDIDevice(const char *args, const ADLConfig* config); -MIDIDevice *CreateOPNMIDIDevice(const char *args); MIDIDevice *CreateWildMIDIDevice(const char *args, int samplerate); -MIDIDevice* CreateOplMIDIDevice(OPLMidiConfig* config); -int BuildFluidPatchSetList(const char* patches, bool systemfallback); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -213,10 +208,12 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) break; case MDEV_ADL: - dev = CreateADLMIDIDevice(Args, &adlConfig); + SetAdlCustomBank(Args); + dev = CreateADLMIDIDevice(&adlConfig); break; case MDEV_OPN: + SetOpnCustomBank(Args); dev = CreateOPNMIDIDevice(Args); break;