From fb12c585333711923f059155c0d01e9d790d94cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 18 Apr 2017 14:42:08 +0200 Subject: [PATCH] - restart the music if the OPL core or the config file for the softsynths is changed, except for the GUS synth, which loads all its data during engine startup and cannot swap it out. - added arrays to the config to hold entries for the softsynths' config files. This is not active yet, but will later be used to give the user a list of config options instead of having to type it by hand. --- src/s_sound.h | 12 ----- src/sound/i_music.h | 2 + src/sound/i_musicinterns.h | 7 +++ src/sound/i_soundinternal.h | 13 ++++++ .../music_fluidsynth_mididevice.cpp | 8 +++- .../music_timiditypp_mididevice.cpp | 12 ++++- .../mididevices/music_wildmidi_mididevice.cpp | 9 +++- src/sound/music_midi_base.cpp | 46 +++++++++++++++++-- src/sound/musicformats/music_opl.cpp | 8 +++- src/sound/timidity/timidity.cpp | 1 + 10 files changed, 98 insertions(+), 20 deletions(-) diff --git a/src/s_sound.h b/src/s_sound.h index 779bae295..4d67c0514 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -401,18 +401,6 @@ ReverbContainer *S_FindEnvironment (const char *name); ReverbContainer *S_FindEnvironment (int id); void S_AddEnvironment (ReverbContainer *settings); -enum EMidiDevice -{ - MDEV_DEFAULT = -1, - MDEV_MMAPI = 0, - MDEV_OPL = 1, - MDEV_SNDSYS = 2, - MDEV_TIMIDITY = 3, - MDEV_FLUIDSYNTH = 4, - MDEV_GUS = 5, - MDEV_WILDMIDI = 6, -}; - struct MidiDeviceSetting { int device; diff --git a/src/sound/i_music.h b/src/sound/i_music.h index 069d2f142..9939868a7 100644 --- a/src/sound/i_music.h +++ b/src/sound/i_music.h @@ -35,6 +35,7 @@ #define __I_MUSIC_H__ #include "doomdef.h" +#include "i_soundinternal.h" class FileReader; struct FOptionValues; @@ -77,6 +78,7 @@ public: virtual bool SetPosition (unsigned int ms); virtual bool SetSubsong (int subsong); virtual void Update(); + virtual int GetDeviceType() const { return MDEV_DEFAULT; } // MDEV_DEFAULT stands in for anything that cannot change playback parameters which needs a restart. virtual FString GetStats(); virtual MusInfo *GetOPLDumper(const char *filename); virtual MusInfo *GetWaveDumper(const char *filename, int rate); diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 6cb2e05a2..596093a06 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -83,6 +83,7 @@ public: virtual void WildMidiSetOption(int opt, int set); virtual bool Preprocess(MIDIStreamer *song, bool looping); virtual FString GetStats(); + virtual int GetDeviceType() const { return MDEV_DEFAULT; } }; @@ -191,6 +192,7 @@ protected: void HandleLongEvent(const uint8_t *data, int len); void ComputeOutput(float *buffer, int len); bool ServiceStream(void *buff, int numbytes); + int GetDeviceType() const override { return MDEV_OPL; } }; // OPL dumper implementation of a MIDI output device ------------------------ @@ -217,6 +219,7 @@ public: int Open(MidiCallback, void *userdata); void PrecacheInstruments(const uint16_t *instruments, int count); FString GetStats(); + int GetDeviceType() const override { return MDEV_GUS; } protected: Timidity::Renderer *Renderer; @@ -251,6 +254,7 @@ public: int Open(MidiCallback, void *userdata); void PrecacheInstruments(const uint16_t *instruments, int count); FString GetStats(); + int GetDeviceType() const override { return MDEV_WILDMIDI; } protected: WildMidi_Renderer *Renderer; @@ -285,6 +289,7 @@ public: void FluidSettingInt(const char *setting, int value); void FluidSettingNum(const char *setting, double value); void FluidSettingStr(const char *setting, const char *value); + int GetDeviceType() const override { return MDEV_FLUIDSYNTH; } protected: void HandleEvent(int status, int parm1, int parm2); @@ -358,6 +363,7 @@ public: void WildMidiSetOption(int opt, int set); void CreateSMF(TArray &file, int looplimit=0); int ServiceEvent(); + int GetDeviceType() const override { return MIDI->GetDeviceType(); } protected: MIDIStreamer(const char *dumpname, EMidiDevice type); @@ -676,5 +682,6 @@ MusInfo *SndFile_OpenSong(FileReader &fr); // -------------------------------------------------------------------------- extern MusInfo *currSong; +void MIDIDeviceChanged(int newdev, bool force = false); EXTERN_CVAR (Float, snd_musicvolume) diff --git a/src/sound/i_soundinternal.h b/src/sound/i_soundinternal.h index bb154a195..f5f49f560 100644 --- a/src/sound/i_soundinternal.h +++ b/src/sound/i_soundinternal.h @@ -149,4 +149,17 @@ private: SoundDecoder& operator=(const SoundDecoder &rhs); }; +enum EMidiDevice +{ + MDEV_DEFAULT = -1, + MDEV_MMAPI = 0, + MDEV_OPL = 1, + MDEV_SNDSYS = 2, + MDEV_TIMIDITY = 3, + MDEV_FLUIDSYNTH = 4, + MDEV_GUS = 5, + MDEV_WILDMIDI = 6, +}; + + #endif diff --git a/src/sound/mididevices/music_fluidsynth_mididevice.cpp b/src/sound/mididevices/music_fluidsynth_mididevice.cpp index 711cf7480..47378ff56 100644 --- a/src/sound/mididevices/music_fluidsynth_mididevice.cpp +++ b/src/sound/mididevices/music_fluidsynth_mididevice.cpp @@ -103,7 +103,13 @@ extern "C" unsigned __stdcall GetSystemDirectoryA(char *lpBuffer, unsigned uSize CVAR(String, fluid_lib, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR(String, fluid_patchset, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR(String, fluid_patchset, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_FLUIDSYNTH) + { + MIDIDeviceChanged(-1, true); + } +} CUSTOM_CVAR(Float, fluid_gain, 0.5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { diff --git a/src/sound/mididevices/music_timiditypp_mididevice.cpp b/src/sound/mididevices/music_timiditypp_mididevice.cpp index e2166c0a1..b6ba6997d 100644 --- a/src/sound/mididevices/music_timiditypp_mididevice.cpp +++ b/src/sound/mididevices/music_timiditypp_mididevice.cpp @@ -71,6 +71,7 @@ public: void Stop(); bool IsOpen(); void TimidityVolumeChanged(); + int GetDeviceType() const override { return MDEV_TIMIDITY; } protected: bool LaunchTimidity(); @@ -105,10 +106,17 @@ BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode); static char TimidityTitle[] = "TiMidity (" GAMENAME " Launched)"; const char TimidityPPMIDIDevice::EventName[] = "TiMidity Killer"; -CVAR (String, timidity_exe, "timidity.exe", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR (String, timidity_exe, "timidity.exe", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) #else -CVAR (String, timidity_exe, "timidity", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR(String, timidity_exe, "timidity", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) #endif +{ + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_TIMIDITY) + { + MIDIDeviceChanged(-1, true); + } +} + CVAR (String, timidity_extargs, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // extra args to pass to Timidity CVAR (String, timidity_chorus, "0", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (String, timidity_reverb, "0", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) diff --git a/src/sound/mididevices/music_wildmidi_mididevice.cpp b/src/sound/mididevices/music_wildmidi_mididevice.cpp index c446105a8..b3599d1e8 100644 --- a/src/sound/mididevices/music_wildmidi_mididevice.cpp +++ b/src/sound/mididevices/music_wildmidi_mididevice.cpp @@ -59,7 +59,14 @@ static FString CurrentConfig; // PUBLIC DATA DEFINITIONS ------------------------------------------------- -CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_WILDMIDI) + { + MIDIDeviceChanged(-1, true); + } +} + CVAR(Int, wildmidi_frequency, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { diff --git a/src/sound/music_midi_base.cpp b/src/sound/music_midi_base.cpp index 20711d2a0..b7af50d6a 100644 --- a/src/sound/music_midi_base.cpp +++ b/src/sound/music_midi_base.cpp @@ -38,6 +38,9 @@ #include "c_dispatch.h" #include "i_music.h" #include "i_system.h" +#include "gameconfigfile.h" +#include "cmdlib.h" +#include "m_misc.h" #include "templates.h" #include "v_text.h" @@ -52,6 +55,42 @@ static bool nummididevicesset; #define NUM_DEF_DEVICES 5 #endif +//Provide some lists from which the user can choose the music resources in the menu instead of having to type them in manually +// These lists have to be maintained manually for the moment. +TArray SoundFonts; +TArray PatchSets; +TArray TimidityExes; + +static void ReadSoundFonts() +{ + const char *key, *value; + // Do not check for missing files here so that they will be saved back. + // Deletion should be done explicitly im the menu, equivalent to how the savegame menu works. + if (GameConfig->SetSection("SoundFonts")) + { + while (GameConfig->NextInSection(key, value)) + { + if (FileExists(value)) SoundFonts.Push(value); + } + } + if (GameConfig->SetSection("PatchSets")) + { + while (GameConfig->NextInSection(key, value)) + { + if (FileExists(value)) PatchSets.Push(value); + } + } +#ifdef _WIN32 // Different Timidity paths only make sense if they can be stored in arbitrary paths with local configs (i.e. not if things are done the Linux way) + if (GameConfig->SetSection("TimidityExes")) + { + while (GameConfig->NextInSection(key, value)) + { + if (FileExists(value)) PatchSets.Push(value); + } + } +#endif +} + static void AddDefaultMidiDevices(FOptionValues *opt) { int p; @@ -76,12 +115,12 @@ static void AddDefaultMidiDevices(FOptionValues *opt) } -static void MIDIDeviceChanged(int newdev) +void MIDIDeviceChanged(int newdev, bool force) { static int oldmididev = INT_MIN; // If a song is playing, move it to the new device. - if (oldmididev != newdev) + if (oldmididev != newdev || force) { if (currSong != NULL && currSong->IsMIDI()) { @@ -97,7 +136,8 @@ static void MIDIDeviceChanged(int newdev) S_MIDIDeviceChanged(); } } - oldmididev = newdev; + // 'force' + if (!force) oldmididev = newdev; } #ifdef _WIN32 diff --git a/src/sound/musicformats/music_opl.cpp b/src/sound/musicformats/music_opl.cpp index 0f949fae0..64596c2fb 100644 --- a/src/sound/musicformats/music_opl.cpp +++ b/src/sound/musicformats/music_opl.cpp @@ -53,7 +53,13 @@ CUSTOM_CVAR (Int, opl_numchips, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) } } -CVAR(Int, opl_core, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Int, opl_core, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_OPL) + { + MIDIDeviceChanged(-1, true); + } +} int current_opl_core; // Get OPL core override from $mididevice diff --git a/src/sound/timidity/timidity.cpp b/src/sound/timidity/timidity.cpp index 86fe9d11d..a74d6baeb 100644 --- a/src/sound/timidity/timidity.cpp +++ b/src/sound/timidity/timidity.cpp @@ -32,6 +32,7 @@ #include "files.h" #include "w_wad.h" +// Unlike the other softsynths, this one cannot change its config data at run time. CVAR(String, midi_config, CONFIG_FILE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, midi_voices, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(String, gus_patchdir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)