From 44a6b6e87c1f72dd687f50f15dc6e2ca65441ee7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Sep 2019 22:01:19 +0200 Subject: [PATCH] - moved all configuration code to zmusic project. The CVARs are now just getting forwarded without any own logic. --- libraries/zmusic/mididevices/mididevice.h | 10 +- .../mididevices/music_adlmidi_mididevice.cpp | 2 + .../music_fluidsynth_mididevice.cpp | 2 + .../mididevices/music_opl_mididevice.cpp | 20 +- .../mididevices/music_opnmidi_mididevice.cpp | 34 +- .../mididevices/music_timidity_mididevice.cpp | 99 +++-- .../music_timiditypp_mididevice.cpp | 61 ++- .../mididevices/music_wildmidi_mididevice.cpp | 73 ++- libraries/zmusic/streamsources/music_dumb.cpp | 34 +- libraries/zmusic/streamsources/music_gme.cpp | 4 +- libraries/zmusic/streamsources/streamsource.h | 4 +- libraries/zmusic/zmusic/configuration.cpp | 165 +------ libraries/zmusic/zmusic/midiconfig.h | 2 +- libraries/zmusic/zmusic/zmusic.h | 13 + src/sound/music/i_music.cpp | 87 +++- src/sound/music/i_musicinterns.h | 9 - src/sound/music/midi_cvars.cpp | 419 ++++-------------- src/sound/musicformats/music_midistream.cpp | 15 +- 18 files changed, 441 insertions(+), 612 deletions(-) diff --git a/libraries/zmusic/mididevices/mididevice.h b/libraries/zmusic/mididevices/mididevice.h index 8ced9d824d..27e06e1702 100644 --- a/libraries/zmusic/mididevices/mididevice.h +++ b/libraries/zmusic/mididevices/mididevice.h @@ -148,11 +148,11 @@ protected: MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, const char *Args); MIDIDevice *CreateADLMIDIDevice(const char* args); -MIDIDevice *CreateOPNMIDIDevice(const OpnConfig *args); -MIDIDevice *CreateOplMIDIDevice(const OPLConfig* config); -MIDIDevice *CreateTimidityMIDIDevice(GUSConfig *config, int samplerate); -MIDIDevice *CreateTimidityPPMIDIDevice(TimidityConfig *config, int samplerate); -MIDIDevice *CreateWildMIDIDevice(WildMidiConfig *config, int samplerate); +MIDIDevice *CreateOPNMIDIDevice(const char *args); +MIDIDevice *CreateOplMIDIDevice(const char* Args); +MIDIDevice *CreateTimidityMIDIDevice(const char* Args, int samplerate); +MIDIDevice *CreateTimidityPPMIDIDevice(const char *Args, int samplerate); +MIDIDevice *CreateWildMIDIDevice(const char *Args, int samplerate); #ifdef _WIN32 MIDIDevice* CreateWinMIDIDevice(int mididevice); diff --git a/libraries/zmusic/mididevices/music_adlmidi_mididevice.cpp b/libraries/zmusic/mididevices/music_adlmidi_mididevice.cpp index 8599de9182..54f7e6ef35 100644 --- a/libraries/zmusic/mididevices/music_adlmidi_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_adlmidi_mididevice.cpp @@ -37,6 +37,8 @@ #include "mididevice.h" #include "adlmidi.h" +ADLConfig adlConfig; + class ADLMIDIDevice : public SoftSynthMIDIDevice { struct ADL_MIDIPlayer *Renderer; diff --git a/libraries/zmusic/mididevices/music_fluidsynth_mididevice.cpp b/libraries/zmusic/mididevices/music_fluidsynth_mididevice.cpp index be42dad4af..e9b009950a 100644 --- a/libraries/zmusic/mididevices/music_fluidsynth_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_fluidsynth_mididevice.cpp @@ -41,6 +41,8 @@ // FluidSynth implementation of a MIDI device ------------------------------- +FluidConfig fluidConfig; + #if !defined DYN_FLUIDSYNTH #include #else diff --git a/libraries/zmusic/mididevices/music_opl_mididevice.cpp b/libraries/zmusic/mididevices/music_opl_mididevice.cpp index 0f5e3adb3c..075499429e 100644 --- a/libraries/zmusic/mididevices/music_opl_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_opl_mididevice.cpp @@ -52,12 +52,14 @@ // PRIVATE DATA DEFINITIONS ------------------------------------------------ +OPLConfig oplConfig; + // OPL implementation of a MIDI output device ------------------------------- class OPLMIDIDevice : public SoftSynthMIDIDevice, protected OPLmusicBlock { public: - OPLMIDIDevice(const OPLConfig *config); + OPLMIDIDevice(int core); int OpenRenderer(); void Close(); int GetTechnology() const; @@ -84,11 +86,11 @@ protected: // //========================================================================== -OPLMIDIDevice::OPLMIDIDevice(const OPLConfig *config) - : SoftSynthMIDIDevice((int)OPL_SAMPLE_RATE), OPLmusicBlock(config->core, config->numchips) +OPLMIDIDevice::OPLMIDIDevice(int core) + : SoftSynthMIDIDevice((int)OPL_SAMPLE_RATE), OPLmusicBlock(core, oplConfig.numchips) { - FullPan = config->fullpan; - memcpy(OPLinstruments, config->OPLinstruments, sizeof(OPLinstruments)); + FullPan = oplConfig.fullpan; + memcpy(OPLinstruments, oplConfig.OPLinstruments, sizeof(OPLinstruments)); StreamBlockSize = 14; } @@ -314,7 +316,11 @@ std::string OPLMIDIDevice::GetStats() return out; } -MIDIDevice* CreateOplMIDIDevice(const OPLConfig* config) + +MIDIDevice* CreateOplMIDIDevice(const char *Args) { - return new OPLMIDIDevice(config); + if (!oplConfig.genmidiset) throw std::runtime_error("Cannot play OPL without GENMIDI data"); + int core = oplConfig.core; + if (Args != NULL && *Args >= '0' && *Args < '4') core = *Args - '0'; + return new OPLMIDIDevice(core); } diff --git a/libraries/zmusic/mididevices/music_opnmidi_mididevice.cpp b/libraries/zmusic/mididevices/music_opnmidi_mididevice.cpp index bff8384780..81fee8a886 100644 --- a/libraries/zmusic/mididevices/music_opnmidi_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_opnmidi_mididevice.cpp @@ -37,11 +37,13 @@ #include "mididevice.h" #include "opnmidi.h" +OpnConfig opnConfig; + class OPNMIDIDevice : public SoftSynthMIDIDevice { struct OPN2_MIDIPlayer *Renderer; public: - OPNMIDIDevice(const OpnConfig *config); + OPNMIDIDevice(const char *bank); ~OPNMIDIDevice(); @@ -76,26 +78,26 @@ enum // //========================================================================== -OPNMIDIDevice::OPNMIDIDevice(const OpnConfig *config) +OPNMIDIDevice::OPNMIDIDevice(const char *bank) :SoftSynthMIDIDevice(44100) { Renderer = opn2_init(44100); // todo: make it configurable if (Renderer != nullptr) { - if (!LoadCustomBank(config->opn_custom_bank.c_str())) + if (!opnConfig.opn_use_custom_bank || !LoadCustomBank(opnConfig.opn_custom_bank.c_str())) { - if(config->default_bank.size() == 0) + if(opnConfig.default_bank.size() == 0) { opn2_close(Renderer); throw std::runtime_error("No OPN bank found"); } - opn2_openBankData(Renderer, config->default_bank.data(), (long)config->default_bank.size()); + opn2_openBankData(Renderer, opnConfig.default_bank.data(), (long)opnConfig.default_bank.size()); } - 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); + opn2_switchEmulator(Renderer, (int)opnConfig.opn_emulator_id); + opn2_setRunAtPcmRate(Renderer, (int)opnConfig.opn_run_at_pcm_rate); + opn2_setNumChips(Renderer, opnConfig.opn_chips_count); + opn2_setSoftPanEnabled(Renderer, (int)opnConfig.opn_fullpan); } else { @@ -228,9 +230,19 @@ void OPNMIDIDevice::ComputeOutput(float *buffer, int len) // //========================================================================== -MIDIDevice *CreateOPNMIDIDevice(const OpnConfig *config) +MIDIDevice *CreateOPNMIDIDevice(const char *Args) { - return new OPNMIDIDevice(config); + const char* bank = Args && *Args ? Args : opnConfig.opn_use_custom_bank ? opnConfig.opn_custom_bank.c_str() : nullptr; + if (bank && *bank) + { + if (musicCallbacks.PathForSoundfont) + { + auto info = musicCallbacks.PathForSoundfont(bank, SF_WOPN); + if (info != nullptr) bank = info; + } + } + + return new OPNMIDIDevice(bank); } diff --git a/libraries/zmusic/mididevices/music_timidity_mididevice.cpp b/libraries/zmusic/mididevices/music_timidity_mididevice.cpp index f56aa06518..981c03dc65 100644 --- a/libraries/zmusic/mididevices/music_timidity_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_timidity_mididevice.cpp @@ -54,6 +54,7 @@ // PRIVATE DATA DEFINITIONS ------------------------------------------------ +GUSConfig gusConfig; //========================================================================== // @@ -65,9 +66,9 @@ namespace Timidity { struct Renderer; } class TimidityMIDIDevice : public SoftSynthMIDIDevice { - void LoadInstruments(GUSConfig *config); + void LoadInstruments(); public: - TimidityMIDIDevice(GUSConfig *config, int samplerate); + TimidityMIDIDevice(int samplerate); ~TimidityMIDIDevice(); int OpenRenderer(); @@ -76,7 +77,6 @@ public: protected: Timidity::Renderer *Renderer; - std::shared_ptr instruments; // The device needs to hold a reference to this while the renderer is in use. void HandleEvent(int status, int parm1, int parm2); void HandleLongEvent(const uint8_t *data, int len); @@ -87,13 +87,13 @@ protected: // CODE -------------------------------------------------------------------- -void TimidityMIDIDevice::LoadInstruments(GUSConfig *config) +void TimidityMIDIDevice::LoadInstruments() { - if (config->dmxgus.size()) + if (gusConfig.dmxgus.size()) { // Check if we got some GUS data before using it. std::string ultradir = getenv("ULTRADIR"); - if (ultradir.length() || config->gus_patchdir.length() != 0) + if (ultradir.length() || gusConfig.gus_patchdir.length() != 0) { auto psreader = new MusicIO::FileSystemSoundFontReader(""); @@ -104,42 +104,41 @@ void TimidityMIDIDevice::LoadInstruments(GUSConfig *config) psreader->add_search_path(ultradir.c_str()); } // Load DMXGUS lump and patches from gus_patchdir - if (config->gus_patchdir.length() != 0) psreader->add_search_path(config->gus_patchdir.c_str()); + if (gusConfig.gus_patchdir.length() != 0) psreader->add_search_path(gusConfig.gus_patchdir.c_str()); - config->instruments.reset(new Timidity::Instruments(psreader)); - bool success = config->instruments->LoadDMXGUS(config->gus_memsize, (const char*)config->dmxgus.data(), config->dmxgus.size()) >= 0; + gusConfig.instruments.reset(new Timidity::Instruments(psreader)); + bool success = gusConfig.instruments->LoadDMXGUS(gusConfig.gus_memsize, (const char*)gusConfig.dmxgus.data(), gusConfig.dmxgus.size()) >= 0; - config->dmxgus.clear(); + gusConfig.dmxgus.clear(); if (success) { - config->loadedConfig = "DMXGUS"; + gusConfig.loadedConfig = "DMXGUS"; return; } } - config->loadedConfig = ""; - config->instruments.reset(); + gusConfig.loadedConfig = ""; + gusConfig.instruments.reset(); throw std::runtime_error("Unable to initialize DMXGUS for GUS MIDI device"); } - else if (config->reader) + else if (gusConfig.reader) { - config->loadedConfig = config->readerName; - config->instruments.reset(new Timidity::Instruments(config->reader)); - bool err = config->instruments->LoadConfig() < 0; - config->reader = nullptr; + gusConfig.loadedConfig = gusConfig.readerName; + gusConfig.instruments.reset(new Timidity::Instruments(gusConfig.reader)); + bool err = gusConfig.instruments->LoadConfig() < 0; + gusConfig.reader = nullptr; if (err) { - config->instruments.reset(); - config->loadedConfig = ""; + gusConfig.instruments.reset(); + gusConfig.loadedConfig = ""; throw std::runtime_error("Unable to initialize instruments for GUS MIDI device"); } } - else if (config->instruments == nullptr) + else if (gusConfig.instruments == nullptr) { throw std::runtime_error("No instruments set for GUS device"); } - instruments = config->instruments; } //========================================================================== @@ -148,11 +147,11 @@ void TimidityMIDIDevice::LoadInstruments(GUSConfig *config) // //========================================================================== -TimidityMIDIDevice::TimidityMIDIDevice(GUSConfig *config, int samplerate) +TimidityMIDIDevice::TimidityMIDIDevice(int samplerate) : SoftSynthMIDIDevice(samplerate, 11025, 65535) { - LoadInstruments(config); - Renderer = new Timidity::Renderer((float)SampleRate, config->midi_voices, instruments.get()); + LoadInstruments(); + Renderer = new Timidity::Renderer((float)SampleRate, gusConfig.midi_voices, gusConfig.instruments.get()); } //========================================================================== @@ -244,7 +243,53 @@ void TimidityMIDIDevice::ComputeOutput(float *buffer, int len) // //========================================================================== -MIDIDevice *CreateTimidityMIDIDevice(GUSConfig *config, int samplerate) +//========================================================================== +// +// Sets up the date to load the instruments for the GUS device. +// The actual instrument loader is part of the device. +// +//========================================================================== + +bool GUS_SetupConfig(const char* args) { - return new TimidityMIDIDevice(config, samplerate); + gusConfig.reader = nullptr; + if ((gusConfig.gus_dmxgus && *args == 0) || !stricmp(args, "DMXGUS")) + { + if (stricmp(gusConfig.loadedConfig.c_str(), "DMXGUS") == 0) return false; // aleady loaded + if (gusConfig.dmxgus.size() > 0) + { + gusConfig.readerName = "DMXGUS"; + return true; + } + } + if (*args == 0) args = gusConfig.gus_config.c_str(); + if (stricmp(gusConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded + + MusicIO::SoundFontReaderInterface *reader; + if (musicCallbacks.OpenSoundFont) + { + reader = musicCallbacks.OpenSoundFont(args, SF_GUS | SF_SF2); + } + else if (MusicIO::fileExists(args)) + { + reader = new MusicIO::FileSystemSoundFontReader(args, true); + } + + if (reader == nullptr) + { + char error[80]; + snprintf(error, 80, "GUS: %s: Unable to load sound font\n", args); + throw std::runtime_error(error); + } + gusConfig.reader = reader; + gusConfig.readerName = args; + return true; +} + + + +MIDIDevice *CreateTimidityMIDIDevice(const char *Args, int samplerate) +{ + GUS_SetupConfig(Args); + return new TimidityMIDIDevice(samplerate); } diff --git a/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp b/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp index cc2a815385..7b43f34b6d 100644 --- a/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp @@ -39,13 +39,13 @@ #include "timiditypp/playmidi.h" - +TimidityConfig timidityConfig; class TimidityPPMIDIDevice : public SoftSynthMIDIDevice { std::shared_ptr instruments; public: - TimidityPPMIDIDevice(TimidityConfig *config, int samplerate); + TimidityPPMIDIDevice(int samplerate); ~TimidityPPMIDIDevice(); int OpenRenderer(); @@ -61,7 +61,7 @@ protected: void HandleEvent(int status, int parm1, int parm2); void HandleLongEvent(const uint8_t *data, int len); void ComputeOutput(float *buffer, int len); - void LoadInstruments(TimidityConfig* config); + void LoadInstruments(); }; //========================================================================== @@ -70,27 +70,27 @@ protected: // //========================================================================== -void TimidityPPMIDIDevice::LoadInstruments(TimidityConfig* config) +void TimidityPPMIDIDevice::LoadInstruments() { - if (config->reader) + if (timidityConfig.reader) { - config->loadedConfig = config->readerName; - config->instruments.reset(new TimidityPlus::Instruments()); - bool success = config->instruments->load(config->reader); - config->reader = nullptr; + timidityConfig.loadedConfig = timidityConfig.readerName; + timidityConfig.instruments.reset(new TimidityPlus::Instruments()); + bool success = timidityConfig.instruments->load(timidityConfig.reader); + timidityConfig.reader = nullptr; if (!success) { - config->instruments.reset(); - config->loadedConfig = ""; + timidityConfig.instruments.reset(); + timidityConfig.loadedConfig = ""; throw std::runtime_error("Unable to initialize instruments for Timidity++ MIDI device"); } } - else if (config->instruments == nullptr) + else if (timidityConfig.instruments == nullptr) { throw std::runtime_error("No instruments set for Timidity++ device"); } - instruments = config->instruments; + instruments = timidityConfig.instruments; } //========================================================================== @@ -99,11 +99,11 @@ void TimidityPPMIDIDevice::LoadInstruments(TimidityConfig* config) // //========================================================================== -TimidityPPMIDIDevice::TimidityPPMIDIDevice(TimidityConfig *config, int samplerate) +TimidityPPMIDIDevice::TimidityPPMIDIDevice(int samplerate) :SoftSynthMIDIDevice(samplerate, 4000, 65000) { TimidityPlus::set_playback_rate(SampleRate); - LoadInstruments(config); + LoadInstruments(); Renderer = new TimidityPlus::Player(instruments.get()); } @@ -193,9 +193,36 @@ void TimidityPPMIDIDevice::ComputeOutput(float *buffer, int len) // //========================================================================== -MIDIDevice *CreateTimidityPPMIDIDevice(TimidityConfig* config, int samplerate) +bool Timidity_SetupConfig(const char* args) { - return new TimidityPPMIDIDevice(config, samplerate); + if (*args == 0) args = timidityConfig.timidity_config.c_str(); + if (stricmp(timidityConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded + + MusicIO::SoundFontReaderInterface* reader; + if (musicCallbacks.OpenSoundFont) + { + reader = musicCallbacks.OpenSoundFont(args, SF_GUS | SF_SF2); + } + else if (MusicIO::fileExists(args)) + { + reader = new MusicIO::FileSystemSoundFontReader(args, true); + } + + if (reader == nullptr) + { + char error[80]; + snprintf(error, 80, "Timidity++: %s: Unable to load sound font\n", args); + throw std::runtime_error(error); + } + timidityConfig.reader = reader; + timidityConfig.readerName = args; + return true; +} + +MIDIDevice *CreateTimidityPPMIDIDevice(const char *Args, int samplerate) +{ + Timidity_SetupConfig(Args); + return new TimidityPPMIDIDevice(samplerate); } diff --git a/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp b/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp index 2cce68f70d..0ffea96abf 100644 --- a/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp @@ -41,12 +41,14 @@ // TYPES ------------------------------------------------------------------- +WildMidiConfig wildMidiConfig; + // WildMidi implementation of a MIDI device --------------------------------- class WildMIDIDevice : public SoftSynthMIDIDevice { public: - WildMIDIDevice(WildMidiConfig* config, int samplerate); + WildMIDIDevice(int samplerate); ~WildMIDIDevice(); int OpenRenderer(); @@ -62,7 +64,7 @@ protected: void HandleLongEvent(const uint8_t *data, int len); void ComputeOutput(float *buffer, int len); void ChangeSettingInt(const char *opt, int set); - void LoadInstruments(WildMidiConfig* config); + void LoadInstruments(); }; @@ -75,27 +77,27 @@ protected: // //========================================================================== -void WildMIDIDevice::LoadInstruments(WildMidiConfig* config) +void WildMIDIDevice::LoadInstruments() { - if (config->reader) + if (wildMidiConfig.reader) { - config->loadedConfig = config->readerName; - config->instruments.reset(new WildMidi::Instruments(config->reader, SampleRate)); - bool success = config->instruments->LoadConfig(config->readerName.c_str()); - config->reader = nullptr; + wildMidiConfig.loadedConfig = wildMidiConfig.readerName; + wildMidiConfig.instruments.reset(new WildMidi::Instruments(wildMidiConfig.reader, SampleRate)); + bool success = wildMidiConfig.instruments->LoadConfig(wildMidiConfig.readerName.c_str()); + wildMidiConfig.reader = nullptr; if (!success) { - config->instruments.reset(); - config->loadedConfig = ""; + wildMidiConfig.instruments.reset(); + wildMidiConfig.loadedConfig = ""; throw std::runtime_error("Unable to initialize instruments for WildMidi device"); } } - else if (config->instruments == nullptr) + else if (wildMidiConfig.instruments == nullptr) { throw std::runtime_error("No instruments set for WildMidi device"); } - instruments = config->instruments; + instruments = wildMidiConfig.instruments; if (instruments->LoadConfig(nullptr) < 0) { throw std::runtime_error("Unable to load instruments set for WildMidi device"); @@ -108,16 +110,16 @@ void WildMIDIDevice::LoadInstruments(WildMidiConfig* config) // //========================================================================== -WildMIDIDevice::WildMIDIDevice(WildMidiConfig *config, int samplerate) +WildMIDIDevice::WildMIDIDevice(int samplerate) :SoftSynthMIDIDevice(samplerate, 11025, 65535) { Renderer = NULL; - LoadInstruments(config); + LoadInstruments(); Renderer = new WildMidi::Renderer(instruments.get()); int flags = 0; - if (config->enhanced_resampling) flags |= WildMidi::WM_MO_ENHANCED_RESAMPLING; - if (config->reverb) flags |= WildMidi::WM_MO_REVERB; + if (wildMidiConfig.enhanced_resampling) flags |= WildMidi::WM_MO_ENHANCED_RESAMPLING; + if (wildMidiConfig.reverb) flags |= WildMidi::WM_MO_REVERB; Renderer->SetOption(WildMidi::WM_MO_ENHANCED_RESAMPLING | WildMidi::WM_MO_REVERB, flags); } @@ -237,8 +239,43 @@ void WildMIDIDevice::ChangeSettingInt(const char *opt, int set) // //========================================================================== -MIDIDevice *CreateWildMIDIDevice(WildMidiConfig *config, int samplerate) +bool WildMidi_SetupConfig(const char* args) { - return new WildMIDIDevice(config, samplerate); + if (*args == 0) args = wildMidiConfig.config.c_str(); + if (stricmp(wildMidiConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded + + MusicIO::SoundFontReaderInterface* reader; + if (musicCallbacks.OpenSoundFont) + { + reader = musicCallbacks.OpenSoundFont(args, SF_GUS); + } + else if (MusicIO::fileExists(args)) + { + reader = new MusicIO::FileSystemSoundFontReader(args, true); + } + + if (reader == nullptr) + { + char error[80]; + snprintf(error, 80, "WildMidi: %s: Unable to load sound font\n", args); + throw std::runtime_error(error); + } + + wildMidiConfig.reader = reader; + wildMidiConfig.readerName = args; + return true; +} + + +//========================================================================== +// +// +// +//========================================================================== + +MIDIDevice *CreateWildMIDIDevice(const char *Args, int samplerate) +{ + WildMidi_SetupConfig(Args); + return new WildMIDIDevice(samplerate); } diff --git a/libraries/zmusic/streamsources/music_dumb.cpp b/libraries/zmusic/streamsources/music_dumb.cpp index 54721fa032..95de21e774 100644 --- a/libraries/zmusic/streamsources/music_dumb.cpp +++ b/libraries/zmusic/streamsources/music_dumb.cpp @@ -54,10 +54,12 @@ // TYPES ------------------------------------------------------------------- +DumbConfig dumbConfig; + class DumbSong : public StreamSource { public: - DumbSong(DUH *myduh, DumbConfig *config, int samplerate); + DumbSong(DUH *myduh, int samplerate); ~DumbSong(); //bool SetPosition(int ms); bool SetSubsong(int subsong) override; @@ -582,12 +584,12 @@ DUMBFILE *dumb_read_allfile(dumbfile_mem_status *filestate, uint8_t *start, Musi // //========================================================================== -static void MOD_SetAutoChip(DUH *duh, DumbConfig *config) +static void MOD_SetAutoChip(DUH *duh) { - int size_force = config->mod_autochip_size_force; - int size_scan = config->mod_autochip_size_scan; - int scan_threshold_8 = ((config->mod_autochip_scan_threshold * 0x100) + 50) / 100; - int scan_threshold_16 = ((config->mod_autochip_scan_threshold * 0x10000) + 50) / 100; + int size_force = dumbConfig.mod_autochip_size_force; + int size_scan = dumbConfig.mod_autochip_size_scan; + int scan_threshold_8 = ((dumbConfig.mod_autochip_scan_threshold * 0x100) + 50) / 100; + int scan_threshold_16 = ((dumbConfig.mod_autochip_scan_threshold * 0x10000) + 50) / 100; DUMB_IT_SIGDATA * itsd = duh_get_it_sigdata(duh); if (itsd) @@ -768,7 +770,7 @@ static void MOD_SetAutoChip(DUH *duh, DumbConfig *config) // //========================================================================== -StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, DumbConfig* config, int samplerate) +StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, int samplerate) { DUH *duh = 0; int headsize; @@ -925,11 +927,11 @@ StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, DumbConfig* config, i } if ( duh ) { - if (config->mod_autochip) + if (dumbConfig.mod_autochip) { - MOD_SetAutoChip(duh, config); + MOD_SetAutoChip(duh); } - state = new DumbSong(duh, config, samplerate); + state = new DumbSong(duh, samplerate); if (is_it) ReadIT(filestate.ptr, size, state, false); else ReadDUH(duh, state, false, is_dos); @@ -1005,20 +1007,20 @@ void DumbSong::ChangeSettingNum(const char* setting, double val) // //========================================================================== -DumbSong::DumbSong(DUH* myduh, DumbConfig* config, int samplerate) +DumbSong::DumbSong(DUH* myduh, int samplerate) { duh = myduh; sr = NULL; eof = false; - interp = config->mod_interp; - volramp = config->mod_volramp; + interp = dumbConfig.mod_interp; + volramp = dumbConfig.mod_volramp; written = 0; length = 0; start_order = 0; - MasterVolume = (float)config->mod_dumb_mastervolume; - if (config->mod_samplerate != 0) + MasterVolume = (float)dumbConfig.mod_dumb_mastervolume; + if (dumbConfig.mod_samplerate != 0) { - srate = config->mod_samplerate; + srate = dumbConfig.mod_samplerate; } else { diff --git a/libraries/zmusic/streamsources/music_gme.cpp b/libraries/zmusic/streamsources/music_gme.cpp index f196f761ad..f298700717 100644 --- a/libraries/zmusic/streamsources/music_gme.cpp +++ b/libraries/zmusic/streamsources/music_gme.cpp @@ -105,7 +105,7 @@ const char *GME_CheckFormat(uint32_t id) // //========================================================================== -StreamSource *GME_OpenSong(MusicIO::FileInterface *reader, const char *fmt, float stereo_depth, int sample_rate) +StreamSource *GME_OpenSong(MusicIO::FileInterface *reader, const char *fmt, int sample_rate) { gme_type_t type; gme_err_t err; @@ -143,7 +143,7 @@ StreamSource *GME_OpenSong(MusicIO::FileInterface *reader, const char *fmt, floa gme_delete(emu); throw std::runtime_error(err); } - gme_set_stereo_depth(emu, std::min(std::max(stereo_depth, 0.f), 1.f)); + gme_set_stereo_depth(emu, std::min(std::max(miscConfig.gme_stereodepth, 0.f), 1.f)); gme_set_fade(emu, -1); // Enable infinite loop return new GMESong(emu, sample_rate); } diff --git a/libraries/zmusic/streamsources/streamsource.h b/libraries/zmusic/streamsources/streamsource.h index 4b01579c46..48b1810c4e 100644 --- a/libraries/zmusic/streamsources/streamsource.h +++ b/libraries/zmusic/streamsources/streamsource.h @@ -32,8 +32,8 @@ protected: }; -StreamSource *MOD_OpenSong(MusicIO::FileInterface* reader, DumbConfig* config, int samplerate); -StreamSource* GME_OpenSong(MusicIO::FileInterface* reader, const char* fmt, float stereo_depth, int sample_rate); +StreamSource *MOD_OpenSong(MusicIO::FileInterface* reader, int samplerate); +StreamSource* GME_OpenSong(MusicIO::FileInterface* reader, const char* fmt, int sample_rate); StreamSource *SndFile_OpenSong(MusicIO::FileInterface* fr); StreamSource* XA_OpenSong(MusicIO::FileInterface* reader); StreamSource* OPL_OpenSong(MusicIO::FileInterface* reader, OPLConfig *config); diff --git a/libraries/zmusic/zmusic/configuration.cpp b/libraries/zmusic/zmusic/configuration.cpp index 852b3b39c5..c94064216d 100644 --- a/libraries/zmusic/zmusic/configuration.cpp +++ b/libraries/zmusic/zmusic/configuration.cpp @@ -54,23 +54,33 @@ int devType() else*/ return MDEV_DEFAULT; } -// Ordered by configurable device. -ADLConfig adlConfig; -FluidConfig fluidConfig; -OPLConfig oplConfig; -OpnConfig opnConfig; -GUSConfig gusConfig; -TimidityConfig timidityConfig; -WildMidiConfig wildMidiConfig; -DumbConfig dumbConfig; MiscConfig miscConfig; Callbacks musicCallbacks; void SetCallbacks(const Callbacks* cb) { + dumb_decode_vorbis = cb->DumbVorbisDecode; musicCallbacks = *cb; } +void SetGenMidi(const uint8_t* data) +{ + memcpy(oplConfig.OPLinstruments, data, 175 * 36); + oplConfig.genmidiset = true; +} + +void SetWgOpn(const void* data, unsigned len) +{ + opnConfig.default_bank.resize(len); + memcpy(opnConfig.default_bank.data(), data, len); +} + +void SetDmxGus(const void* data, unsigned len) +{ + gusConfig.dmxgus.resize(len); + memcpy(gusConfig.dmxgus.data(), data, len); +} + template void ChangeAndReturn(valtype &variable, valtype value, valtype *realv) { @@ -268,6 +278,8 @@ bool ChangeMusicSetting(ZMusic::EIntConfigKey key, int value, int *pRealValue) return false; case opl_core: + if (value < 0) value = 0; + else if (value > 3) value = 3; ChangeAndReturn(oplConfig.core, value, pRealValue); return devType() == MDEV_OPL; @@ -620,138 +632,3 @@ bool ChangeMusicSetting(ZMusic::EStringConfigKey key, const char *value) return false; } -#if 0 - -void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi) -{ - // This needs to be done only once. - if (!config->genmidiset && midi) - { - // The OPL renderer should not care about where this comes from. - // Note: No I_Error here - this needs to be consistent with the rest of the music code. - auto lump = Wads.CheckNumForName("GENMIDI", ns_global); - if (lump < 0) throw std::runtime_error("No GENMIDI lump found"); - auto data = Wads.OpenLumpReader(lump); - - uint8_t filehdr[8]; - data.Read(filehdr, 8); - if (memcmp(filehdr, "#OPL_II#", 8)) throw std::runtime_error("Corrupt GENMIDI lump"); - data.Read(oplConfig.OPLinstruments, 175 * 36); - config->genmidiset = true; - } - - config->core = opl_core; - if (args != NULL && *args >= '0' && *args < '4') config->core = *args - '0'; -} - - -void OPN_SetupConfig(OpnConfig *config, 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) - { - config->opn_custom_bank = ""; - } - else - { - config->opn_custom_bank = info->mFilename; - } - } - - int lump = Wads.CheckNumForFullName("xg.wopn"); - if (lump < 0) - { - config->default_bank.resize(0); - return; - } - FMemLump data = Wads.ReadLump(lump); - config->default_bank.resize(data.GetSize()); - memcpy(config->default_bank.data(), data.GetMem(), data.GetSize()); -} - - -//========================================================================== -// -// Sets up the date to load the instruments for the GUS device. -// The actual instrument loader is part of the device. -// -//========================================================================== - -bool GUS_SetupConfig(GUSConfig *config, const char *args) -{ - config->errorfunc = gus_printfunc; - if ((midi_dmxgus && *args == 0) || !stricmp(args, "DMXGUS")) - { - if (stricmp(config->loadedConfig.c_str(), "DMXGUS") == 0) return false; // aleady loaded - int lump = Wads.CheckNumForName("DMXGUS"); - if (lump == -1) lump = Wads.CheckNumForName("DMXGUSC"); - if (lump >= 0) - { - auto data = Wads.OpenLumpReader(lump); - if (data.GetLength() > 0) - { - config->dmxgus.resize(data.GetLength()); - data.Read(config->dmxgus.data(), data.GetLength()); - return true; - } - } - } - if (*args == 0) args = midi_config; - if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded - - auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2); - if (reader == nullptr) - { - char error[80]; - snprintf(error, 80, "GUS: %s: Unable to load sound font\n",args); - throw std::runtime_error(error); - } - config->reader = reader; - config->readerName = args; - return true; -} - - -bool Timidity_SetupConfig(TimidityConfig* config, const char* args) -{ - config->errorfunc = gus_printfunc; - if (*args == 0) args = timidity_config; - if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded - - auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2); - if (reader == nullptr) - { - char error[80]; - snprintf(error, 80, "Timidity++: %s: Unable to load sound font\n", args); - throw std::runtime_error(error); - } - config->reader = reader; - config->readerName = args; - return true; -} - -bool WildMidi_SetupConfig(WildMidiConfig* config, const char* args) -{ - config->errorfunc = wm_printfunc; - if (*args == 0) args = wildmidi_config; - if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded - - auto reader = sfmanager.OpenSoundFont(args, SF_GUS); - if (reader == nullptr) - { - char error[80]; - snprintf(error, 80, "WildMidi: %s: Unable to load sound font\n", args); - throw std::runtime_error(error); - } - config->reader = reader; - config->readerName = args; - config->reverb = wildmidi_reverb; - config->enhanced_resampling = wildmidi_enhanced_resampling; - return true; -} - -#endif \ No newline at end of file diff --git a/libraries/zmusic/zmusic/midiconfig.h b/libraries/zmusic/zmusic/midiconfig.h index f6d800229b..b249a95f42 100644 --- a/libraries/zmusic/zmusic/midiconfig.h +++ b/libraries/zmusic/zmusic/midiconfig.h @@ -81,7 +81,7 @@ struct GUSConfig MusicIO::SoundFontReaderInterface *reader; std::string readerName; std::string loadedConfig; - std::shared_ptr instruments; // this is held both by the config and the device + std::unique_ptr instruments; }; namespace TimidityPlus diff --git a/libraries/zmusic/zmusic/zmusic.h b/libraries/zmusic/zmusic/zmusic.h index d810525ea5..fcbcbcb96c 100644 --- a/libraries/zmusic/zmusic/zmusic.h +++ b/libraries/zmusic/zmusic/zmusic.h @@ -1,6 +1,7 @@ #pragma once #include "mididefs.h" +#include "../../music_common/fileio.h" namespace ZMusic // Namespaced because these conflict with the same-named CVARs { @@ -122,12 +123,24 @@ struct Callbacks // The sound font callbacks are for allowing the client to customize sound font management // Without them only paths to real files can be used. const char *(*PathForSoundfont)(const char *name, int type) = nullptr; + MusicIO::SoundFontReaderInterface *(*OpenSoundFont)(const char* name, int type) = nullptr; // Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion. std::string (*NicePath)(const char *path) = nullptr; + + // For playing modules with compressed samples. + short* (*DumbVorbisDecode)(int outlen, const void* oggstream, int sizebytes); + }; +// Sets callbacks for functionality that the client needs to provide. void SetCallbacks(const Callbacks *callbacks); +// Sets GenMidi data for OPL playback. If this isn't provided the OPL synth will not work. +void SetGenMidi(const uint8_t* data); +// Set default bank for OPN. Without this OPN only works with custom banks. +void SetWgOpn(const void* data, unsigned len); +// Set DMXGUS data for running the GUS synth in actual GUS mode. +void SetDmxGus(const void* data, unsigned len); // These exports is needed by the MIDI dumpers which need to remain on the client side. class MIDISource; // abstract for the client diff --git a/src/sound/music/i_music.cpp b/src/sound/music/i_music.cpp index 511e55c1c4..23bf4bbed9 100644 --- a/src/sound/music/i_music.cpp +++ b/src/sound/music/i_music.cpp @@ -56,9 +56,6 @@ #include "../libraries/zmusic/midisources/midisource.h" #include "../libraries/dumb/include/dumb.h" -EXTERN_CVAR(Float, gme_stereodepth) - - #define GZIP_ID1 31 #define GZIP_ID2 139 #define GZIP_CM 8 @@ -86,17 +83,6 @@ int nomusic = 0; float relative_volume = 1.f; float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function -//========================================================================== -// -// dumb_decode_vorbis -// -//========================================================================== - -static short* dumb_decode_vorbis_(int outlen, const void* oggstream, int sizebytes) -{ - return GSnd->DecodeSample(outlen, oggstream, sizebytes, CODEC_Vorbis); -} - //========================================================================== // // CVAR snd_musicvolume @@ -168,6 +154,17 @@ static void wm_printfunc(const char* wmfmt, va_list args) VPrintf(PRINT_HIGH, wmfmt, args); } +//========================================================================== +// +// other callbacks +// +//========================================================================== + +static short* dumb_decode_vorbis_(int outlen, const void* oggstream, int sizebytes) +{ + return GSnd->DecodeSample(outlen, oggstream, sizebytes, CODEC_Vorbis); +} + static std::string mus_NicePath(const char* str) { FString strv = NicePath(str); @@ -180,6 +177,56 @@ static const char* mus_pathToSoundFont(const char* sfname, int type) return info ? info->mFilename.GetChars() : nullptr; } +static MusicIO::SoundFontReaderInterface* mus_openSoundFont(const char* sfname, int type) +{ + return sfmanager.OpenSoundFont(sfname, type); +} + + +//========================================================================== +// +// Pass some basic working data to the music backend +// We do this once at startup for everything available. +// +//========================================================================== + +static void SetupGenMidi() +{ + // The OPL renderer should not care about where this comes from. + // Note: No I_Error here - this needs to be consistent with the rest of the music code. + auto lump = Wads.CheckNumForName("GENMIDI", ns_global); + if (lump < 0) Printf("No GENMIDI lump found. OPL playback not available."); + auto data = Wads.OpenLumpReader(lump); + + auto genmidi = data.Read(); + if (genmidi.Size() < 8 + 175 * 36 || memcmp(genmidi.Data(), "#OPL_II#", 8)) return; + SetGenMidi(genmidi.Data()+8); +} + +static void SetupWgOpn() +{ + int lump = Wads.CheckNumForFullName("xg.wopn"); + if (lump < 0) + { + return; + } + FMemLump data = Wads.ReadLump(lump); + SetWgOpn(data.GetMem(), (uint32_t)data.GetSize()); +} + +static void SetupDMXGUS() +{ + int lump = Wads.CheckNumForFullName("DMXGUS"); + if (lump < 0) + { + return; + } + FMemLump data = Wads.ReadLump(lump); + SetDmxGus(data.GetMem(), (uint32_t)data.GetSize()); +} + + + //========================================================================== // // @@ -199,7 +246,6 @@ void I_InitMusic (void) #endif // _WIN32 MusicDown = false; - dumb_decode_vorbis = dumb_decode_vorbis_; Callbacks callbacks; @@ -208,7 +254,12 @@ void I_InitMusic (void) callbacks.WildMidi_MessageFunc = wm_printfunc; callbacks.NicePath = mus_NicePath; callbacks.PathForSoundfont = mus_pathToSoundFont; + callbacks.OpenSoundFont = mus_openSoundFont; + callbacks.DumbVorbisDecode = dumb_decode_vorbis_; + SetCallbacks(&callbacks); + SetupGenMidi(); + SetupDMXGUS(); } @@ -460,7 +511,6 @@ MusInfo *I_RegisterSong (MusicIO::FileInterface *reader, MidiDeviceSetting *devi (id[0] == MAKE_ID('D', 'B', 'R', 'A') && id[1] == MAKE_ID('W', 'O', 'P', 'L')) || // DosBox Raw OPL (id[0] == MAKE_ID('A', 'D', 'L', 'I') && *((uint8_t*)id + 4) == 'B')) // Martin Fernandez's modified IMF { - OPL_SetupConfig(&oplConfig, device->args.GetChars(), false); streamsource = OPL_OpenSong(reader, &oplConfig); } else if ((id[0] == MAKE_ID('R', 'I', 'F', 'F') && id[2] == MAKE_ID('C', 'D', 'X', 'A'))) @@ -471,13 +521,12 @@ MusInfo *I_RegisterSong (MusicIO::FileInterface *reader, MidiDeviceSetting *devi // Check for game music else if ((fmt = GME_CheckFormat(id[0])) != nullptr && fmt[0] != '\0') { - streamsource = GME_OpenSong(reader, fmt, gme_stereodepth, (int)GSnd->GetOutputRate()); + streamsource = GME_OpenSong(reader, fmt, (int)GSnd->GetOutputRate()); } // Check for module formats else { - Dumb_SetupConfig(&dumbConfig); - streamsource = MOD_OpenSong(reader, &dumbConfig, (int)GSnd->GetOutputRate()); + streamsource = MOD_OpenSong(reader, (int)GSnd->GetOutputRate()); } if (streamsource == nullptr) { diff --git a/src/sound/music/i_musicinterns.h b/src/sound/music/i_musicinterns.h index 90fc82cf97..a07e435090 100644 --- a/src/sound/music/i_musicinterns.h +++ b/src/sound/music/i_musicinterns.h @@ -138,15 +138,6 @@ public: // Data interface -void Fluid_SetupConfig(FluidConfig *config, const char* patches, bool systemfallback); -void ADL_SetupConfig(ADLConfig *config, const char *Args); -void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi = true); -void OPN_SetupConfig(OpnConfig *config, const char *Args); -bool GUS_SetupConfig(GUSConfig *config, const char *args); -bool Timidity_SetupConfig(TimidityConfig* config, const char* args); -bool WildMidi_SetupConfig(WildMidiConfig* config, const char* args); -void Dumb_SetupConfig(DumbConfig* config); - // Module played via foo_dumb ----------------------------------------------- class StreamSource; diff --git a/src/sound/music/midi_cvars.cpp b/src/sound/music/midi_cvars.cpp index f63f0cf408..b69ada192c 100644 --- a/src/sound/music/midi_cvars.cpp +++ b/src/sound/music/midi_cvars.cpp @@ -1,7 +1,6 @@ /* ** music_config.cpp -** This forwards all CVAR changes to the music system which -** was designed for any kind of configuration system. +** This forwards all CVAR changes to the music system. ** **--------------------------------------------------------------------------- ** Copyright 1999-2016 Randy Heit @@ -33,32 +32,11 @@ **--------------------------------------------------------------------------- ** */ + #include "i_musicinterns.h" -#include "i_soundfont.h" -#include "cmdlib.h" -#include "doomerrors.h" -#include "v_text.h" -#include "c_console.h" +#include "c_cvars.h" #include "zmusic/zmusic.h" -#include "zmusic/midiconfig.h" -#include "../libraries/timidity/timidity/timidity.h" -#include "../libraries/timidityplus/timiditypp/timidity.h" -#include "../libraries/oplsynth/oplsynth/oplio.h" -#include "../libraries/dumb/include/dumb.h" - -#ifdef _WIN32 -// do this without including windows.h for this one single prototype -extern "C" unsigned __stdcall GetSystemDirectoryA(char* lpBuffer, unsigned uSize); -#endif // _WIN32 - -static void CheckRestart(int devtype) -{ - if (currSong != nullptr && currSong->GetDeviceType() == devtype) - { - MIDIDeviceChanged(-1, true); - } -} //========================================================================== // @@ -229,55 +207,19 @@ CUSTOM_CVAR(Int, fluid_chorus_type, 0/*FLUID_CHORUS_DEFAULT_TYPE*/, CVAR_ARCHIVE CUSTOM_CVAR(Int, opl_numchips, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (*self <= 0) - { - self = 1; - } - else if (*self > MAXOPL2CHIPS) - { - self = MAXOPL2CHIPS; - } - else - { - if (currSong != NULL) - currSong->ChangeSettingInt("opl.numchips", self); - oplConfig.numchips = self; - } + FORWARD_CVAR(opl_numchips); } CUSTOM_CVAR(Int, opl_core, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - CheckRestart(MDEV_OPL); + FORWARD_CVAR(opl_core); } CUSTOM_CVAR(Bool, opl_fullpan, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - oplConfig.fullpan = self; + FORWARD_BOOL_CVAR(opl_fullpan); } -void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi) -{ - // This needs to be done only once. - if (!config->genmidiset && midi) - { - // The OPL renderer should not care about where this comes from. - // Note: No I_Error here - this needs to be consistent with the rest of the music code. - auto lump = Wads.CheckNumForName("GENMIDI", ns_global); - if (lump < 0) throw std::runtime_error("No GENMIDI lump found"); - auto data = Wads.OpenLumpReader(lump); - - uint8_t filehdr[8]; - data.Read(filehdr, 8); - if (memcmp(filehdr, "#OPL_II#", 8)) throw std::runtime_error("Corrupt GENMIDI lump"); - data.Read(oplConfig.OPLinstruments, 175 * 36); - config->genmidiset = true; - } - - config->core = opl_core; - if (args != NULL && *args >= '0' && *args < '4') config->core = *args - '0'; -} - - //========================================================================== // // OPN MIDI device @@ -287,74 +229,34 @@ void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi) CUSTOM_CVAR(Int, opn_chips_count, 8, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - opnConfig.opn_chips_count = self; - CheckRestart(MDEV_OPN); + FORWARD_CVAR(opn_chips_count); } CUSTOM_CVAR(Int, opn_emulator_id, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - opnConfig.opn_emulator_id = self; - CheckRestart(MDEV_OPN); - + FORWARD_CVAR(opn_emulator_id); } CUSTOM_CVAR(Bool, opn_run_at_pcm_rate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - opnConfig.opn_run_at_pcm_rate = self; - CheckRestart(MDEV_OPN); - + FORWARD_BOOL_CVAR(opn_run_at_pcm_rate); } CUSTOM_CVAR(Bool, opn_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - opnConfig.opn_fullpan = self; - CheckRestart(MDEV_OPN); - + FORWARD_BOOL_CVAR(opn_fullpan); } CUSTOM_CVAR(Bool, opn_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - CheckRestart(MDEV_OPN); - + FORWARD_BOOL_CVAR(opn_use_custom_bank); } CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (opn_use_custom_bank) - { - CheckRestart(MDEV_OPN); - } + FORWARD_STRING_CVAR(opn_custom_bank); } -void OPN_SetupConfig(OpnConfig *config, 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) - { - config->opn_custom_bank = ""; - } - else - { - config->opn_custom_bank = info->mFilename; - } - } - - int lump = Wads.CheckNumForFullName("xg.wopn"); - if (lump < 0) - { - config->default_bank.resize(0); - return; - } - FMemLump data = Wads.ReadLump(lump); - config->default_bank.resize(data.GetSize()); - memcpy(config->default_bank.data(), data.GetMem(), data.GetSize()); -} - - //========================================================================== // // GUS MIDI device @@ -364,240 +266,123 @@ void OPN_SetupConfig(OpnConfig *config, const char *Args) CUSTOM_CVAR(String, midi_config, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - CheckRestart(MDEV_GUS); + FORWARD_STRING_CVAR(gus_config); } CUSTOM_CVAR(Bool, midi_dmxgus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) // This was 'true' but since it requires special setup that's not such a good idea. { - CheckRestart(MDEV_GUS); + FORWARD_BOOL_CVAR(gus_dmxgus); } CUSTOM_CVAR(String, gus_patchdir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - gusConfig.gus_patchdir = self; - CheckRestart(MDEV_GUS); + FORWARD_STRING_CVAR(gus_patchdir); } CUSTOM_CVAR(Int, midi_voices, 32, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - gusConfig.midi_voices = self; - CheckRestart(MDEV_GUS); + FORWARD_CVAR(gus_midi_voices); } CUSTOM_CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - gusConfig.gus_memsize = self; - CheckRestart(MDEV_GUS); + FORWARD_CVAR(gus_memsize); } - -// make sure we can use the above function for the Timidity++ device as well. -static_assert(Timidity::CMSG_ERROR == TimidityPlus::CMSG_ERROR, "Timidity constant mismatch"); -static_assert(Timidity::CMSG_WARNING == TimidityPlus::CMSG_WARNING, "Timidity constant mismatch"); -static_assert(Timidity::CMSG_INFO == TimidityPlus::CMSG_INFO, "Timidity constant mismatch"); -static_assert(Timidity::VERB_DEBUG == TimidityPlus::VERB_DEBUG, "Timidity constant mismatch"); - //========================================================================== // -// Sets up the date to load the instruments for the GUS device. -// The actual instrument loader is part of the device. +// Timidity++ device // //========================================================================== -bool GUS_SetupConfig(GUSConfig *config, const char *args) -{ - if ((midi_dmxgus && *args == 0) || !stricmp(args, "DMXGUS")) - { - if (stricmp(config->loadedConfig.c_str(), "DMXGUS") == 0) return false; // aleady loaded - int lump = Wads.CheckNumForName("DMXGUS"); - if (lump == -1) lump = Wads.CheckNumForName("DMXGUSC"); - if (lump >= 0) - { - auto data = Wads.OpenLumpReader(lump); - if (data.GetLength() > 0) - { - config->dmxgus.resize(data.GetLength()); - data.Read(config->dmxgus.data(), data.GetLength()); - return true; - } - } - } - if (*args == 0) args = midi_config; - if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded - - auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2); - if (reader == nullptr) - { - char error[80]; - snprintf(error, 80, "GUS: %s: Unable to load sound font\n",args); - throw std::runtime_error(error); - } - config->reader = reader; - config->readerName = args; - return true; -} - - -//========================================================================== -// -// CVar interface to configurable parameters -// -// Timidity++ uses a static global set of configuration variables -// THese can be changed while the synth is playing but need synchronization. -// -// Currently the synth is not fully reentrant due to this and a handful -// of other global variables. -// -//========================================================================== - -/* -template void ChangeVarSync(T& var, T value) -{ - std::lock_guard lock(TimidityPlus::ConfigMutex); - var = value; -} -*/ - CUSTOM_CVAR(Bool, timidity_modulation_wheel, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - ////ChangeVarSync(TimidityPlus::timidity_modulation_wheel, *self); + FORWARD_BOOL_CVAR(timidity_modulation_wheel); } CUSTOM_CVAR(Bool, timidity_portamento, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - ////ChangeVarSync(TimidityPlus::timidity_portamento, *self); -} -/* -* reverb=0 no reverb 0 -* reverb=1 old reverb 1 -* reverb=1,n set reverb level to n (-1 to -127) -* reverb=2 "global" old reverb 2 -* reverb=2,n set reverb level to n (-1 to -127) - 128 -* reverb=3 new reverb 3 -* reverb=3,n set reverb level to n (-1 to -127) - 256 -* reverb=4 "global" new reverb 4 -* reverb=4,n set reverb level to n (-1 to -127) - 384 -*/ -EXTERN_CVAR(Int, timidity_reverb_level) -EXTERN_CVAR(Int, timidity_reverb) - -static void SetReverb() -{ - int value = 0; - int mode = timidity_reverb; - int level = timidity_reverb_level; - - if (mode == 0 || level == 0) value = mode; - else value = (mode - 1) * -128 - level; - //ChangeVarSync(TimidityPlus::timidity_reverb, value); + FORWARD_BOOL_CVAR(timidity_portamento); } CUSTOM_CVAR(Int, timidity_reverb, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (self < 0 || self > 4) self = 0; - else SetReverb(); + FORWARD_CVAR(timidity_reverb); } CUSTOM_CVAR(Int, timidity_reverb_level, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (self < 0 || self > 127) self = 0; - else SetReverb(); + FORWARD_CVAR(timidity_reverb_level); } CUSTOM_CVAR(Int, timidity_chorus, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_chorus, *self); + FORWARD_CVAR(timidity_chorus); } CUSTOM_CVAR(Bool, timidity_surround_chorus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_surround_chorus, *self); - CheckRestart(MDEV_TIMIDITY); + FORWARD_BOOL_CVAR(timidity_surround_chorus); } CUSTOM_CVAR(Bool, timidity_channel_pressure, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_channel_pressure, *self); + FORWARD_BOOL_CVAR(timidity_channel_pressure); } CUSTOM_CVAR(Int, timidity_lpf_def, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_lpf_def, *self); + FORWARD_CVAR(timidity_lpf_def); } CUSTOM_CVAR(Bool, timidity_temper_control, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_temper_control, *self); + FORWARD_BOOL_CVAR(timidity_temper_control); } CUSTOM_CVAR(Bool, timidity_modulation_envelope, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_modulation_envelope, *self); - CheckRestart(MDEV_TIMIDITY); + FORWARD_BOOL_CVAR(timidity_modulation_envelope); } CUSTOM_CVAR(Bool, timidity_overlap_voice_allow, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_overlap_voice_allow, *self); + FORWARD_BOOL_CVAR(timidity_overlap_voice_allow); } CUSTOM_CVAR(Bool, timidity_drum_effect, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_drum_effect, *self); + FORWARD_BOOL_CVAR(timidity_drum_effect); } CUSTOM_CVAR(Bool, timidity_pan_delay, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - //ChangeVarSync(TimidityPlus::timidity_pan_delay, *self); + FORWARD_BOOL_CVAR(timidity_pan_delay); } CUSTOM_CVAR(Float, timidity_drum_power, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) /* coef. of drum amplitude */ { - if (self < 0) self = 0; - else if (self > MAX_AMPLIFICATION / 100.f) self = MAX_AMPLIFICATION / 100.f; - //ChangeVarSync(TimidityPlus::timidity_drum_power, *self); + FORWARD_CVAR(timidity_drum_power); } + CUSTOM_CVAR(Int, timidity_key_adjust, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (self < -24) self = -24; - else if (self > 24) self = 24; - //ChangeVarSync(TimidityPlus::timidity_key_adjust, *self); + FORWARD_CVAR(timidity_key_adjust); } -// For testing mainly. + CUSTOM_CVAR(Float, timidity_tempo_adjust, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (self < 0.25) self = 0.25; - else if (self > 10) self = 10; - //ChangeVarSync(TimidityPlus::timidity_tempo_adjust, *self); + FORWARD_CVAR(timidity_tempo_adjust); } CUSTOM_CVAR(Float, min_sustain_time, 5000, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (self < 0) self = 0; - //ChangeVarSync(TimidityPlus::min_sustain_time, *self); + FORWARD_CVAR(min_sustain_time); } -// Config file to use CUSTOM_CVAR(String, timidity_config, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - CheckRestart(MDEV_TIMIDITY); -} - -bool Timidity_SetupConfig(TimidityConfig* config, const char* args) -{ - if (*args == 0) args = timidity_config; - if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded - - auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2); - if (reader == nullptr) - { - char error[80]; - snprintf(error, 80, "Timidity++: %s: Unable to load sound font\n", args); - throw std::runtime_error(error); - } - config->reader = reader; - config->readerName = args; - return true; + FORWARD_STRING_CVAR(timidity_config); } //========================================================================== @@ -608,50 +393,30 @@ bool Timidity_SetupConfig(TimidityConfig* config, const char* args) CUSTOM_CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - CheckRestart(MDEV_WILDMIDI); + FORWARD_STRING_CVAR(wildmidi_config); } -CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL | CVAR_NOINITCALL) +CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (currSong != NULL) - currSong->ChangeSettingInt("wildmidi.reverb", *self); - wildMidiConfig.reverb = self; + FORWARD_BOOL_CVAR(wildmidi_reverb); } -CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL | CVAR_NOINITCALL) +CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (currSong != NULL) - currSong->ChangeSettingInt("wildmidi.resampling", *self); - wildMidiConfig.enhanced_resampling = self; + FORWARD_BOOL_CVAR(wildmidi_enhanced_resampling); } -bool WildMidi_SetupConfig(WildMidiConfig* config, const char* args) -{ - if (*args == 0) args = wildmidi_config; - if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded - - auto reader = sfmanager.OpenSoundFont(args, SF_GUS); - if (reader == nullptr) - { - char error[80]; - snprintf(error, 80, "WildMidi: %s: Unable to load sound font\n", args); - throw std::runtime_error(error); - } - config->reader = reader; - config->readerName = args; - config->reverb = wildmidi_reverb; - config->enhanced_resampling = wildmidi_enhanced_resampling; - return true; -} - //========================================================================== // // This one is for Win32 MMAPI. // //========================================================================== -CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); +CUSTOM_CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_BOOL_CVAR(snd_midiprecache); +} //========================================================================== // @@ -661,40 +426,7 @@ CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRT CUSTOM_CVAR(Float, gme_stereodepth, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (currSong != nullptr) - currSong->ChangeSettingNum("GME.stereodepth", *self); -} - -//========================================================================== -// -// Dumb -// -//========================================================================== - -CVAR(Int, mod_samplerate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); -CVAR(Int, mod_volramp, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); -CVAR(Int, mod_interp, DUMB_LQ_CUBIC, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); -CVAR(Bool, mod_autochip, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); -CVAR(Int, mod_autochip_size_force, 100, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); -CVAR(Int, mod_autochip_size_scan, 500, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); -CVAR(Int, mod_autochip_scan_threshold, 12, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL); -CUSTOM_CVAR(Float, mod_dumb_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - if (self < 0.5f) self = 0.5f; - else if (self > 16.f) self = 16.f; -} - - -void Dumb_SetupConfig(DumbConfig* config) -{ - config->mod_samplerate = mod_samplerate; - config->mod_volramp = mod_volramp; - config->mod_interp = mod_interp; - config->mod_autochip = mod_autochip; - config->mod_autochip_size_force = mod_autochip_size_force; - config->mod_autochip_size_scan = mod_autochip_size_scan; - config->mod_autochip_scan_threshold = mod_autochip_scan_threshold; - config->mod_dumb_mastervolume = mod_dumb_mastervolume; + FORWARD_CVAR(gme_stereodepth); } //========================================================================== @@ -705,13 +437,52 @@ void Dumb_SetupConfig(DumbConfig* config) CUSTOM_CVAR(Int, snd_streambuffersize, 64, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { - if (self < 16) - { - self = 16; - } - else if (self > 1024) - { - self = 1024; - } + FORWARD_CVAR(snd_streambuffersize); +} + +//========================================================================== +// +// Dumb +// +//========================================================================== + +CUSTOM_CVAR(Int, mod_samplerate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_CVAR(mod_samplerate); +} + +CUSTOM_CVAR(Int, mod_volramp, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_CVAR(mod_volramp); +} + +CUSTOM_CVAR(Int, mod_interp, 2/*DUMB_LQ_CUBIC*/, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_CVAR(mod_interp); +} + +CUSTOM_CVAR(Bool, mod_autochip, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_BOOL_CVAR(mod_autochip); +} + +CUSTOM_CVAR(Int, mod_autochip_size_force, 100, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_CVAR(mod_autochip_size_force); +} + +CUSTOM_CVAR(Int, mod_autochip_size_scan, 500, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_CVAR(mod_autochip_size_scan); +} + +CUSTOM_CVAR(Int, mod_autochip_scan_threshold, 12, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_CVAR(mod_autochip_scan_threshold); +} + +CUSTOM_CVAR(Float, mod_dumb_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +{ + FORWARD_CVAR(mod_dumb_mastervolume); } diff --git a/src/sound/musicformats/music_midistream.cpp b/src/sound/musicformats/music_midistream.cpp index 535a444efc..adedd44fc6 100644 --- a/src/sound/musicformats/music_midistream.cpp +++ b/src/sound/musicformats/music_midistream.cpp @@ -193,8 +193,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) switch (devtype) { case MDEV_GUS: - GUS_SetupConfig(&gusConfig, Args); - dev = CreateTimidityMIDIDevice(&gusConfig, samplerate); + dev = CreateTimidityMIDIDevice(Args, samplerate); break; case MDEV_ADL: @@ -202,8 +201,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) break; case MDEV_OPN: - OPN_SetupConfig(&opnConfig, Args); - dev = CreateOPNMIDIDevice(&opnConfig); + dev = CreateOPNMIDIDevice(Args); break; case MDEV_MMAPI: @@ -219,18 +217,15 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) break; case MDEV_OPL: - OPL_SetupConfig(&oplConfig, Args); - dev = CreateOplMIDIDevice(&oplConfig); + dev = CreateOplMIDIDevice(Args); break; case MDEV_TIMIDITY: - Timidity_SetupConfig(&timidityConfig, Args); - dev = CreateTimidityPPMIDIDevice(&timidityConfig, samplerate); + dev = CreateTimidityPPMIDIDevice(Args, samplerate); break; case MDEV_WILDMIDI: - WildMidi_SetupConfig(&wildMidiConfig, Args); - dev = CreateWildMIDIDevice(&wildMidiConfig, samplerate); + dev = CreateWildMIDIDevice(Args, samplerate); break; default: