From 768a7bdd1874cf3196945471bb0e32890053f5ec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 30 Sep 2019 01:34:16 +0200 Subject: [PATCH] - hooked up a few more CVARs and other values the music backend needs to know about and moved the MusInfo base class into zmusic. # Conflicts: # src/sound/musicformats/music_midistream.cpp --- libraries/zmusic/decoder/mpg123_decoder.cpp | 2 +- .../{zmusic => decoder}/mpg123_decoder.h | 2 +- libraries/zmusic/decoder/sndfile_decoder.cpp | 2 +- .../{zmusic => decoder}/sndfile_decoder.h | 2 +- libraries/zmusic/decoder/sounddecoder.cpp | 4 +- libraries/zmusic/zmusic/configuration.cpp | 39 +++-- libraries/zmusic/zmusic/midiconfig.h | 7 +- libraries/zmusic/zmusic/musinfo.h | 40 +++++ libraries/zmusic/zmusic/zmusic.h | 14 +- src/sound/backend/i_sound.cpp | 21 +-- src/sound/backend/i_soundinternal.h | 9 -- src/sound/music/i_music.cpp | 137 ++---------------- src/sound/music/i_music.h | 39 +---- src/sound/music/i_musicinterns.h | 1 - src/sound/music/music_config.cpp | 14 +- src/sound/music/music_midi_base.cpp | 56 +------ src/sound/musicformats/music_cd.cpp | 5 +- src/sound/musicformats/music_midistream.cpp | 57 +++----- src/sound/musicformats/music_stream.cpp | 16 +- src/sound/s_music.cpp | 70 +++++++-- src/sound/s_music.h | 15 +- 21 files changed, 228 insertions(+), 324 deletions(-) rename libraries/zmusic/{zmusic => decoder}/mpg123_decoder.h (97%) rename libraries/zmusic/{zmusic => decoder}/sndfile_decoder.h (97%) create mode 100644 libraries/zmusic/zmusic/musinfo.h diff --git a/libraries/zmusic/decoder/mpg123_decoder.cpp b/libraries/zmusic/decoder/mpg123_decoder.cpp index cadcf4890..dec928fb7 100644 --- a/libraries/zmusic/decoder/mpg123_decoder.cpp +++ b/libraries/zmusic/decoder/mpg123_decoder.cpp @@ -33,7 +33,7 @@ #include #include -#include "zmusic/mpg123_decoder.h" +#include "mpg123_decoder.h" #include "i_module.h" #ifdef HAVE_MPG123 diff --git a/libraries/zmusic/zmusic/mpg123_decoder.h b/libraries/zmusic/decoder/mpg123_decoder.h similarity index 97% rename from libraries/zmusic/zmusic/mpg123_decoder.h rename to libraries/zmusic/decoder/mpg123_decoder.h index abd4d59e4..d6c8675e4 100644 --- a/libraries/zmusic/zmusic/mpg123_decoder.h +++ b/libraries/zmusic/decoder/mpg123_decoder.h @@ -1,7 +1,7 @@ #ifndef MPG123_DECODER_H #define MPG123_DECODER_H -#include "sounddecoder.h" +#include "zmusic/sounddecoder.h" #ifdef HAVE_MPG123 diff --git a/libraries/zmusic/decoder/sndfile_decoder.cpp b/libraries/zmusic/decoder/sndfile_decoder.cpp index 9269d47d7..0da9fbbf3 100644 --- a/libraries/zmusic/decoder/sndfile_decoder.cpp +++ b/libraries/zmusic/decoder/sndfile_decoder.cpp @@ -32,7 +32,7 @@ */ #include -#include "zmusic/sndfile_decoder.h" +#include "sndfile_decoder.h" #include "i_module.h" #ifdef HAVE_SNDFILE diff --git a/libraries/zmusic/zmusic/sndfile_decoder.h b/libraries/zmusic/decoder/sndfile_decoder.h similarity index 97% rename from libraries/zmusic/zmusic/sndfile_decoder.h rename to libraries/zmusic/decoder/sndfile_decoder.h index a931ab349..33aad19d8 100644 --- a/libraries/zmusic/zmusic/sndfile_decoder.h +++ b/libraries/zmusic/decoder/sndfile_decoder.h @@ -1,7 +1,7 @@ #ifndef SNDFILE_DECODER_H #define SNDFILE_DECODER_H -#include "sounddecoder.h" +#include "zmusic/sounddecoder.h" #ifdef HAVE_SNDFILE diff --git a/libraries/zmusic/decoder/sounddecoder.cpp b/libraries/zmusic/decoder/sounddecoder.cpp index 19bba22a0..61600a83e 100644 --- a/libraries/zmusic/decoder/sounddecoder.cpp +++ b/libraries/zmusic/decoder/sounddecoder.cpp @@ -33,8 +33,8 @@ */ -#include "zmusic/sndfile_decoder.h" -#include "zmusic/mpg123_decoder.h" +#include "sndfile_decoder.h" +#include "mpg123_decoder.h" SoundDecoder *SoundDecoder::CreateDecoder(MusicIO::FileInterface *reader) { diff --git a/libraries/zmusic/zmusic/configuration.cpp b/libraries/zmusic/zmusic/configuration.cpp index c94064216..547485a55 100644 --- a/libraries/zmusic/zmusic/configuration.cpp +++ b/libraries/zmusic/zmusic/configuration.cpp @@ -38,6 +38,7 @@ #include "../../libraries/dumb/include/dumb.h" #include "zmusic.h" +#include "musinfo.h" #include "midiconfig.h" struct Dummy @@ -46,13 +47,9 @@ struct Dummy void ChangeSettingNum(const char*, double) {} void ChangeSettingString(const char*, const char*) {} }; -static Dummy* currSong; - //extern MusInfo *CurrSong; -int devType() -{ - /*if (CurrSong) return CurrSong->GetDeviceType(); - else*/ return MDEV_DEFAULT; -} + +#define devType() ((currSong)? (currSong)->GetDeviceType() : MDEV_DEFAULT) + MiscConfig miscConfig; Callbacks musicCallbacks; @@ -147,7 +144,7 @@ using namespace ZMusic; // //========================================================================== -bool ChangeMusicSetting(ZMusic::EIntConfigKey key, int value, int *pRealValue) +bool ChangeMusicSetting(ZMusic::EIntConfigKey key, MusInfo *currSong, int value, int *pRealValue) { switch (key) { @@ -452,11 +449,20 @@ bool ChangeMusicSetting(ZMusic::EIntConfigKey key, int value, int *pRealValue) case mod_autochip_scan_threshold: ChangeAndReturn(dumbConfig.mod_autochip_scan_threshold, value, pRealValue); return false; + + case snd_mididevice: + miscConfig.snd_mididevice = value; + return false; + + case snd_outputrate: + miscConfig.snd_outputrate = value; + return false; + } return false; } -bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, float value, float *pRealValue) +bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, MusInfo* currSong, float value, float *pRealValue) { switch (key) { @@ -588,11 +594,24 @@ bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, float value, float *pRealVa if (value < 0) value = 0; ChangeAndReturn(dumbConfig.mod_dumb_mastervolume, value, pRealValue); return false; + + case snd_musicvolume: + miscConfig.snd_musicvolume = value; + return false; + + case relative_volume: + miscConfig.relative_volume = value; + return false; + + case snd_mastervolume: + miscConfig.snd_mastervolume = value; + return false; + } return false; } -bool ChangeMusicSetting(ZMusic::EStringConfigKey key, const char *value) +bool ChangeMusicSetting(ZMusic::EStringConfigKey key, MusInfo* currSong, const char *value) { switch (key) { diff --git a/libraries/zmusic/zmusic/midiconfig.h b/libraries/zmusic/zmusic/midiconfig.h index b249a95f4..b6bd9d60c 100644 --- a/libraries/zmusic/zmusic/midiconfig.h +++ b/libraries/zmusic/zmusic/midiconfig.h @@ -138,7 +138,12 @@ struct MiscConfig { int snd_midiprecache; float gme_stereodepth; - int snd_streambuffersize; + int snd_streambuffersize = 64; + int snd_mididevice; + int snd_outputrate = 44100; + float snd_musicvolume = 1.f; + float relative_volume = 1.f; + float snd_mastervolume = 1.f; }; extern ADLConfig adlConfig; diff --git a/libraries/zmusic/zmusic/musinfo.h b/libraries/zmusic/zmusic/musinfo.h new file mode 100644 index 000000000..04661d10e --- /dev/null +++ b/libraries/zmusic/zmusic/musinfo.h @@ -0,0 +1,40 @@ +#pragma once + +#include "mididefs.h" + +// The base music class. Everything is derived from this -------------------- + +class MusInfo +{ +public: + MusInfo() = default; + virtual ~MusInfo() {} + virtual void MusicVolumeChanged() {} // snd_musicvolume changed + virtual void Play (bool looping, int subsong) = 0; + virtual void Pause () = 0; + virtual void Resume () = 0; + virtual void Stop () = 0; + virtual bool IsPlaying () = 0; + virtual bool IsMIDI() const { return false; } + virtual bool IsValid () const = 0; + virtual bool SetPosition(unsigned int ms) { return false; } + virtual bool SetSubsong (int subsong) { return false; } + 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 std::string GetStats() { return "No stats available for this song"; } + virtual MusInfo* GetWaveDumper(const char* filename, int rate) { return nullptr; } + virtual void ChangeSettingInt(const char* setting, int value) {} // FluidSynth settings + virtual void ChangeSettingNum(const char* setting, double value) {} // " + virtual void ChangeSettingString(const char* setting, const char* value) {} // " + virtual bool ServiceStream(void *buff, int len) { return false; } + virtual SoundStreamInfo GetStreamInfo() const { return { 0,0,0 }; } + + enum EState + { + STATE_Stopped, + STATE_Playing, + STATE_Paused + } m_Status = STATE_Stopped; + bool m_Looping = false; + bool m_NotStartedYet = false; // Song has been created but not yet played +}; diff --git a/libraries/zmusic/zmusic/zmusic.h b/libraries/zmusic/zmusic/zmusic.h index fcbcbcb96..309a3f26b 100644 --- a/libraries/zmusic/zmusic/zmusic.h +++ b/libraries/zmusic/zmusic/zmusic.h @@ -69,6 +69,9 @@ enum EIntConfigKey snd_streambuffersize, + snd_mididevice, + snd_outputrate, + NUM_INT_CONFIGS }; @@ -90,6 +93,10 @@ enum EFloatConfigKey gme_stereodepth, mod_dumb_mastervolume, + snd_musicvolume, + relative_volume, + snd_mastervolume, + NUM_FLOAT_CONFIGS }; @@ -147,8 +154,9 @@ class MIDISource; // abstract for the client EMIDIType IdentifyMIDIType(uint32_t *id, int size); MIDISource *CreateMIDISource(const uint8_t *data, size_t length, EMIDIType miditype); +class MusInfo; // Configuration interface. The return value specifies if a music restart is needed. // RealValue should be written back to the CVAR or whatever other method the client uses to store configuration state. -bool ChangeMusicSetting(ZMusic::EIntConfigKey key, int value, int *pRealValue = nullptr); -bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, float value, float *pRealValue = nullptr); -bool ChangeMusicSetting(ZMusic::EStringConfigKey key, const char *value); +bool ChangeMusicSetting(ZMusic::EIntConfigKey key, MusInfo *song, int value, int *pRealValue = nullptr); +bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, MusInfo* song, float value, float *pRealValue = nullptr); +bool ChangeMusicSetting(ZMusic::EStringConfigKey key, MusInfo* song, const char *value); diff --git a/src/sound/backend/i_sound.cpp b/src/sound/backend/i_sound.cpp index 1a30276ef..0956109cc 100644 --- a/src/sound/backend/i_sound.cpp +++ b/src/sound/backend/i_sound.cpp @@ -34,38 +34,23 @@ #include #include -#include #include "doomtype.h" -#include #include "oalsound.h" #include "i_module.h" #include "cmdlib.h" -#include "zmusic/mpg123_decoder.h" -#include "zmusic/sndfile_decoder.h" +#include "zmusic/sounddecoder.h" -#include "m_swap.h" -#include "stats.h" -#include "files.h" -#include "c_cvars.h" #include "c_dispatch.h" -#include "i_system.h" -#include "i_sound.h" #include "i_music.h" #include "m_argv.h" -#include "m_misc.h" -#include "w_wad.h" -#include "i_video.h" -#include "s_sound.h" #include "v_text.h" -#include "gi.h" #include "c_cvars.h" #include "stats.h" #include "s_music.h" - -#include "doomdef.h" +#include "zmusic/zmusic.h" EXTERN_CVAR (Float, snd_sfxvolume) EXTERN_CVAR (Float, snd_musicvolume) @@ -108,6 +93,8 @@ CUSTOM_CVAR(Float, snd_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVA self = 0.f; else if (self > 1.f) self = 1.f; + + ChangeMusicSetting(ZMusic::snd_mastervolume, nullptr, self); snd_sfxvolume.Callback(); snd_musicvolume.Callback(); } diff --git a/src/sound/backend/i_soundinternal.h b/src/sound/backend/i_soundinternal.h index 774222e06..80a57b7ec 100644 --- a/src/sound/backend/i_soundinternal.h +++ b/src/sound/backend/i_soundinternal.h @@ -119,16 +119,7 @@ void FindLoopTags(MusicIO::FileInterface *fr, uint32_t *start, bool *startass, u const char *GetSampleTypeName(enum SampleType type); const char *GetChannelConfigName(enum ChannelConfig chan); - -class MusInfo; class SoundStream; -struct MusPlayingInfo -{ - FString name; - MusInfo *handle; - int baseorder; - bool loop; -}; diff --git a/src/sound/music/i_music.cpp b/src/sound/music/i_music.cpp index f0646af2a..0ef50443d 100644 --- a/src/sound/music/i_music.cpp +++ b/src/sound/music/i_music.cpp @@ -35,31 +35,15 @@ #ifndef _WIN32 #include #include -#include -#include -#include -#include #endif -#include -#include -#include #include #include "i_musicinterns.h" -#include "doomtype.h" #include "m_argv.h" -#include "i_music.h" #include "w_wad.h" -#include "c_console.h" #include "c_dispatch.h" -#include "i_system.h" -#include "i_sound.h" -#include "s_sound.h" -#include "m_swap.h" -#include "i_cd.h" #include "templates.h" -#include "m_misc.h" #include "stats.h" #include "c_console.h" #include "vm.h" @@ -67,6 +51,7 @@ #include "i_soundfont.h" #include "s_music.h" #include "zmusic/zmusic.h" +#include "zmusic/musinfo.h" #include "streamsources/streamsource.h" #include "filereadermusicinterface.h" #include "../libraries/zmusic/midisources/midisource.h" @@ -86,6 +71,7 @@ extern int MUSHeaderSearch(const uint8_t *head, int len); void I_InitSoundFonts(); extern "C" void dumb_exit(); +extern MusPlayingInfo mus_playing; EXTERN_CVAR (Int, snd_samplerate) EXTERN_CVAR (Int, snd_mididevice) @@ -96,8 +82,6 @@ static bool ungzip(uint8_t *data, int size, std::vector &newdata); MusInfo *currSong; int nomusic = 0; -float relative_volume = 1.f; -float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function //========================================================================== // @@ -115,15 +99,16 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) else { // Set general music volume. + ChangeMusicSetting(ZMusic::snd_musicvolume, nullptr, self); if (GSnd != nullptr) { GSnd->SetMusicVolume(clamp(self * relative_volume * snd_mastervolume, 0, 1)); } // For music not implemented through the digital sound system, // let them know about the change. - if (currSong != nullptr) + if (mus_playing.handle != nullptr) { - currSong->MusicVolumeChanged(); + mus_playing.handle->MusicVolumeChanged(); } else { // If the music was stopped because volume was 0, start it now. @@ -303,101 +288,6 @@ void I_ShutdownMusic(bool onexit) } } -//========================================================================== -// -// -// -//========================================================================== - -MusInfo::MusInfo() -: m_Status(STATE_Stopped), m_Looping(false), m_NotStartedYet(true) -{ -} - -MusInfo::~MusInfo () -{ - if (currSong == this) currSong = nullptr; -} - -//========================================================================== -// -// starts playing this song -// -//========================================================================== - -void MusInfo::Start(bool loop, float rel_vol, int subsong) -{ - if (rel_vol > 0.f) - { - float factor = relative_volume / saved_relative_volume; - saved_relative_volume = rel_vol; - relative_volume = saved_relative_volume * factor; - } - Stop (); - Play (loop, subsong); - m_NotStartedYet = false; - - if (m_Status == MusInfo::STATE_Playing) - currSong = this; - else - currSong = nullptr; - - // Notify the sound system of the changed relative volume - snd_musicvolume.Callback(); -} - -//========================================================================== -// -// -// -//========================================================================== - -bool MusInfo::SetPosition (unsigned int ms) -{ - return false; -} - -bool MusInfo::IsMIDI() const -{ - return false; -} - -bool MusInfo::SetSubsong (int subsong) -{ - return false; -} - -void MusInfo::Update () -{ -} - -void MusInfo::MusicVolumeChanged() -{ -} - -void MusInfo::ChangeSettingInt(const char *, int) -{ -} - -void MusInfo::ChangeSettingNum(const char *, double) -{ -} - -void MusInfo::ChangeSettingString(const char *, const char *) -{ -} - -FString MusInfo::GetStats() -{ - return "No stats available for this song"; -} - -MusInfo *MusInfo::GetWaveDumper(const char *filename, int rate) -{ - return nullptr; -} - - //========================================================================== // // identify a music lump's type and set up a player for it @@ -664,6 +554,13 @@ void I_UpdateMusic() } } + +void I_SetRelativeVolume(float vol) +{ + relative_volume = (float)vol; + ChangeMusicSetting(ZMusic::relative_volume, nullptr, (float)vol); + snd_musicvolume.Callback(); +} //========================================================================== // // Sets relative music volume. Takes $musicvolume in SNDINFO into consideration @@ -673,8 +570,7 @@ void I_UpdateMusic() void I_SetMusicVolume (double factor) { factor = clamp(factor, 0., 2.0); - relative_volume = saved_relative_volume * float(factor); - snd_musicvolume.Callback(); + I_SetRelativeVolume(factor); } //========================================================================== @@ -687,8 +583,7 @@ CCMD(testmusicvol) { if (argv.argc() > 1) { - relative_volume = (float)strtod(argv[1], nullptr); - snd_musicvolume.Callback(); + I_SetRelativeVolume((float)strtod(argv[1], nullptr)); } else Printf("Current relative volume is %1.2f\n", relative_volume); @@ -702,9 +597,9 @@ CCMD(testmusicvol) ADD_STAT(music) { - if (currSong != nullptr) + if (mus_playing.handle != nullptr) { - return currSong->GetStats(); + return FString(mus_playing.handle->GetStats().c_str()); } return "No song playing"; } diff --git a/src/sound/music/i_music.h b/src/sound/music/i_music.h index fd326e36e..c2639b2f0 100644 --- a/src/sound/music/i_music.h +++ b/src/sound/music/i_music.h @@ -50,6 +50,7 @@ void I_BuildMIDIMenuList (FOptionValues *); void I_UpdateMusic (); // Volume. +void I_SetRelativeVolume(float); void I_SetMusicVolume (double volume); // Registers a song handle to song data. @@ -58,44 +59,6 @@ struct MidiDeviceSetting; MusInfo *I_RegisterSong (MusicIO::FileInterface *reader, MidiDeviceSetting *device); MusInfo *I_RegisterCDSong (int track, int cdid = 0); -// The base music class. Everything is derived from this -------------------- - -class MusInfo -{ -public: - MusInfo (); - virtual ~MusInfo (); - virtual void MusicVolumeChanged(); // snd_musicvolume changed - virtual void Play (bool looping, int subsong) = 0; - virtual void Pause () = 0; - virtual void Resume () = 0; - virtual void Stop () = 0; - virtual bool IsPlaying () = 0; - virtual bool IsMIDI () const; - virtual bool IsValid () const = 0; - 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 *GetWaveDumper(const char *filename, int rate); - virtual void ChangeSettingInt(const char *setting, int value); // FluidSynth settings - virtual void ChangeSettingNum(const char *setting, double value); // " - virtual void ChangeSettingString(const char *setting, const char *value); // " - virtual bool ServiceStream(void *buff, int len) { return false; } - virtual SoundStreamInfo GetStreamInfo() const { return { 0,0,0 }; } - - void Start(bool loop, float rel_vol = -1.f, int subsong = 0); - - enum EState - { - STATE_Stopped, - STATE_Playing, - STATE_Paused - } m_Status; - bool m_Looping; - bool m_NotStartedYet; // Song has been created but not yet played -}; extern int nomusic; #endif //__I_MUSIC_H__ diff --git a/src/sound/music/i_musicinterns.h b/src/sound/music/i_musicinterns.h index 709e8e4c5..95686ef70 100644 --- a/src/sound/music/i_musicinterns.h +++ b/src/sound/music/i_musicinterns.h @@ -13,7 +13,6 @@ void I_InitMusicWin32 (); -extern float relative_volume; class MIDISource; class MIDIDevice; class OPLmusicFile; diff --git a/src/sound/music/music_config.cpp b/src/sound/music/music_config.cpp index b69ada192..ac538c412 100644 --- a/src/sound/music/music_config.cpp +++ b/src/sound/music/music_config.cpp @@ -35,8 +35,10 @@ #include "i_musicinterns.h" #include "c_cvars.h" +#include "s_music.h" #include "zmusic/zmusic.h" +extern MusPlayingInfo mus_playing; //========================================================================== // @@ -46,19 +48,19 @@ #define FORWARD_CVAR(key) \ decltype(*self) newval; \ - auto ret = ChangeMusicSetting(ZMusic::key, *self, &newval); \ + auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle, *self, &newval); \ self = (decltype(*self))newval; \ - if (ret) MIDIDeviceChanged(-1, true); + if (ret) S_MIDIDeviceChanged(-1, true); #define FORWARD_BOOL_CVAR(key) \ int newval; \ - auto ret = ChangeMusicSetting(ZMusic::key, *self, &newval); \ + auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self, &newval); \ self = !!newval; \ - if (ret) MIDIDeviceChanged(-1, true); + if (ret) S_MIDIDeviceChanged(-1, true); #define FORWARD_STRING_CVAR(key) \ - auto ret = ChangeMusicSetting(ZMusic::key, *self); \ - if (ret) MIDIDeviceChanged(-1, true); + auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self); \ + if (ret) S_MIDIDeviceChanged(-1, true); CUSTOM_CVAR(Int, adl_chips_count, 6, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) diff --git a/src/sound/music/music_midi_base.cpp b/src/sound/music/music_midi_base.cpp index e3d3950d0..e335461ff 100644 --- a/src/sound/music/music_midi_base.cpp +++ b/src/sound/music/music_midi_base.cpp @@ -40,16 +40,10 @@ #include "i_musicinterns.h" #include "c_dispatch.h" -#include "i_music.h" -#include "i_system.h" -#include "gameconfigfile.h" -#include "cmdlib.h" -#include "m_misc.h" -#include "s_sound.h" -#include "templates.h" #include "v_text.h" #include "menu/menu.h" +#include "zmusic/zmusic.h" #include "s_music.h" static uint32_t nummididevices; @@ -77,43 +71,6 @@ static void AddDefaultMidiDevices(FOptionValues *opt) } -extern MusPlayingInfo mus_playing; - -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 || force) - { - if (currSong != NULL && currSong->IsMIDI()) - { - MusInfo *song = currSong; - if (song->m_Status == MusInfo::STATE_Playing) - { - if (song->GetDeviceType() == MDEV_FLUIDSYNTH && force) - { - // FluidSynth must reload the song to change the patch set. - auto mi = mus_playing; - S_StopMusic(true); - S_ChangeMusic(mi.name, mi.baseorder, mi.loop); - } - else - { - song->Stop(); - song->Start(song->m_Looping); - } - } - } - else - { - S_MIDIDeviceChanged(); - } - } - // 'force' - if (!force) oldmididev = newdev; -} - #define DEF_MIDIDEV -5 #ifdef _WIN32 @@ -122,8 +79,6 @@ void MIDIDeviceChanged(int newdev, bool force) #include #include -unsigned mididevice; - CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { if (!nummididevicesset) @@ -140,8 +95,8 @@ CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) return; } else if (self == -1) self = DEF_MIDIDEV; - mididevice = MAX(0, self); - MIDIDeviceChanged(self); + ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self); + S_MIDIDeviceChanged(self, false); } void I_InitMusicWin32 () @@ -251,7 +206,10 @@ CUSTOM_CVAR(Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) else if (self > -2) self = -2; else - MIDIDeviceChanged(self); + { + ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self); + S_MIDIDeviceChanged(self, false); + } } void I_BuildMIDIMenuList (FOptionValues *opt) diff --git a/src/sound/musicformats/music_cd.cpp b/src/sound/musicformats/music_cd.cpp index 2d53b7093..e6aeedf71 100644 --- a/src/sound/musicformats/music_cd.cpp +++ b/src/sound/musicformats/music_cd.cpp @@ -31,9 +31,10 @@ ** */ -#include "i_musicinterns.h" +#include "zmusic/musinfo.h" +#include "zmusic/zmusic.h" +#include "zmusic/m_swap.h" #include "i_cd.h" -#include "files.h" // CD track/disk played through the multimedia system ----------------------- diff --git a/src/sound/musicformats/music_midistream.cpp b/src/sound/musicformats/music_midistream.cpp index 902efc179..d22a397b7 100644 --- a/src/sound/musicformats/music_midistream.cpp +++ b/src/sound/musicformats/music_midistream.cpp @@ -35,38 +35,20 @@ // HEADER FILES ------------------------------------------------------------ -#include "i_musicinterns.h" -#include "templates.h" -#include "doomdef.h" -#include "m_swap.h" -#include "doomerrors.h" -#include "v_text.h" - +#include "zmusic/musinfo.h" #include "mididevices/mididevice.h" #include "midisources/midisource.h" // MACROS ------------------------------------------------------------------ -#define MAX_TIME (1000000/10) // Send out 1/10 of a sec of events at a time. - - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- +enum +{ + MAX_TIME = (1000000/10) // Send out 1/10 of a sec of events at a time. +}; // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void WriteVarLen (TArray &file, uint32_t value); - // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -EXTERN_CVAR(Bool, snd_midiprecache); -EXTERN_CVAR(Float, snd_musicvolume) -EXTERN_CVAR(Int, snd_mididevice) - -#ifdef _WIN32 -extern unsigned mididevice; -#endif // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -88,7 +70,7 @@ public: bool IsValid() const override; bool SetSubsong(int subsong) override; void Update() override; - FString GetStats() override; + std::string GetStats() override; void ChangeSettingInt(const char* setting, int value) override; void ChangeSettingNum(const char* setting, double value) override; void ChangeSettingString(const char* setting, const char* value) override; @@ -231,7 +213,7 @@ EMidiDevice MIDIStreamer::SelectMIDIDevice(EMidiDevice device) { return device; } - switch (snd_mididevice) + switch (miscConfig.snd_mididevice) { case -1: return MDEV_SNDSYS; case -2: return MDEV_TIMIDITY; @@ -287,7 +269,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) case MDEV_MMAPI: #ifdef _WIN32 - dev = CreateWinMIDIDevice(mididevice); + dev = CreateWinMIDIDevice(std::max(0, miscConfig.snd_mididevice)); break; #endif // Intentional fall-through for non-Windows systems. @@ -314,7 +296,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) } catch (std::runtime_error &err) { - DPrintf(DMSG_WARNING, "%s\n", err.what()); + //DPrintf(DMSG_WARNING, "%s\n", err.what()); checked[devtype] = true; devtype = MDEV_DEFAULT; // Opening the requested device did not work out so choose another one. @@ -329,8 +311,8 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) if (devtype == MDEV_DEFAULT) { - Printf("Failed to play music: Unable to open any MIDI Device.\n"); - return nullptr; + std::string message = std::string(err.what()) + "\n\nFailed to play music: Unable to open any MIDI Device."; + throw std::runtime_error(message); } } } @@ -348,7 +330,8 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate) lastRequestedDevice = requestedDevice; lastSelectedDevice = selectedDevice; - Printf(TEXTCOLOR_RED "Unable to create " TEXTCOLOR_ORANGE "%s" TEXTCOLOR_RED " MIDI device. Falling back to " TEXTCOLOR_ORANGE "%s\n", devnames[requestedDevice], devnames[selectedDevice]); + if (musicCallbacks.Fluid_MessageFunc) + musicCallbacks.Fluid_MessageFunc("Unable to create %s MIDI device. Falling back to %s\n", devnames[requestedDevice], devnames[selectedDevice]); } return dev; } @@ -369,7 +352,7 @@ void MIDIStreamer::Play(bool looping, int subsong) m_Looping = looping; source->SetMIDISubsong(subsong); devtype = SelectMIDIDevice(DeviceType); - MIDI.reset(CreateMIDIDevice(devtype, (int)GSnd->GetOutputRate())); + MIDI.reset(CreateMIDIDevice(devtype, miscConfig.snd_outputrate)); InitPlayback(); } @@ -605,8 +588,9 @@ void MIDIStreamer::MusicVolumeChanged() { if (MIDI != NULL && MIDI->FakeVolume()) { - float realvolume = clamp(snd_musicvolume * relative_volume * snd_mastervolume, 0.f, 1.f); - Volume = clamp((uint32_t)(realvolume * 65535.f), 0, 65535); + float realvolume = miscConfig.snd_musicvolume * miscConfig.relative_volume * miscConfig.snd_mastervolume; + if (realvolume < 0 || realvolume > 1) realvolume = 1; + Volume = (uint32_t)(realvolume * 65535.f); } else { @@ -845,7 +829,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time) { // Be more responsive when unpausing by only playing each buffer // for a third of the maximum time. - events[0] = MAX(1, (max_time / 3) * source->getDivision() / source->getTempo()); + events[0] = std::max(1, (max_time / 3) * source->getDivision() / source->getTempo()); events[1] = 0; events[2] = MEVENT_NOP << 24; events += 3; @@ -958,14 +942,13 @@ int MIDIStreamer::GetDeviceType() const // //========================================================================== -FString MIDIStreamer::GetStats() +std::string MIDIStreamer::GetStats() { if (MIDI == NULL) { return "No MIDI device in use."; } - auto s = MIDI->GetStats(); - return s.c_str(); + return MIDI->GetStats(); } //========================================================================== diff --git a/src/sound/musicformats/music_stream.cpp b/src/sound/musicformats/music_stream.cpp index 65dbc5c20..db59cd604 100644 --- a/src/sound/musicformats/music_stream.cpp +++ b/src/sound/musicformats/music_stream.cpp @@ -32,7 +32,7 @@ **--------------------------------------------------------------------------- */ -#include "i_musicinterns.h" +#include "zmusic/musinfo.h" #include "streamsources/streamsource.h" class StreamSong : public MusInfo @@ -48,7 +48,7 @@ public: bool IsValid () const override { return m_Source != nullptr; } bool SetPosition (unsigned int pos) override; bool SetSubsong (int subsong) override; - FString GetStats() override; + std::string GetStats() override; void ChangeSettingInt(const char *name, int value) override { if (m_Source) m_Source->ChangeSettingInt(name, value); } void ChangeSettingNum(const char *name, double value) override { if (m_Source) m_Source->ChangeSettingNum(name, value); } void ChangeSettingString(const char *name, const char *value) override { if(m_Source) m_Source->ChangeSettingString(name, value); } @@ -140,18 +140,18 @@ bool StreamSong::SetSubsong(int subsong) return m_Source->SetSubsong(subsong); } -FString StreamSong::GetStats() +std::string StreamSong::GetStats() { - FString s1, s2; + std::string s1, s2; if (m_Source != NULL) { auto stat = m_Source->GetStats(); s2 = stat.c_str(); } - if (s1.IsEmpty() && s2.IsEmpty()) return "No song loaded\n"; - if (s1.IsEmpty()) return s2; - if (s2.IsEmpty()) return s1; - return FStringf("%s\n%s", s1.GetChars(), s2.GetChars()); + if (s1.empty() && s2.empty()) return "No song loaded\n"; + if (s1.empty()) return s2; + if (s2.empty()) return s1; + return s1 + "\n" + s2; } bool StreamSong::ServiceStream (void *buff, int len) diff --git a/src/sound/s_music.cpp b/src/sound/s_music.cpp index a6888a6b3..7f435eed7 100644 --- a/src/sound/s_music.cpp +++ b/src/sound/s_music.cpp @@ -86,6 +86,7 @@ #include "atterm.h" #include "s_music.h" #include "filereadermusicinterface.h" +#include "zmusic/musinfo.h" // MACROS ------------------------------------------------------------------ @@ -102,6 +103,8 @@ static bool MusicPaused; // whether music is paused MusPlayingInfo mus_playing; // music currently being played static FString LastSong; // last music that was played static FPlayList *PlayList; +float relative_volume = 1.f; +float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function DEFINE_GLOBAL_NAMED(mus_playing, musplaying); DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, name); @@ -199,6 +202,30 @@ void S_StopStream() } } + +//========================================================================== +// +// starts playing this song +// +//========================================================================== + +static void S_StartMusicPlaying(MusInfo* song, bool loop, float rel_vol, int subsong) +{ + if (rel_vol > 0.f) + { + float factor = relative_volume / saved_relative_volume; + saved_relative_volume = rel_vol; + I_SetRelativeVolume(saved_relative_volume * factor); + } + song->Stop(); + song->Play(loop, subsong); + song->m_NotStartedYet = false; + + // Notify the sound system of the changed relative volume + snd_musicvolume.Callback(); +} + + //========================================================================== // // S_PauseSound @@ -530,7 +557,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) { // play it try { - mus_playing.handle->Start(looping, S_GetMusicVolume(musicname), order); + S_StartMusicPlaying(mus_playing.handle, looping, S_GetMusicVolume(musicname), order); S_CreateStream(); mus_playing.baseorder = order; } @@ -577,21 +604,36 @@ void S_RestartMusic () // //========================================================================== -void S_MIDIDeviceChanged() -{ - if (mus_playing.handle != nullptr && mus_playing.handle->IsMIDI()) - { - try - { - mus_playing.handle->Start(mus_playing.loop, -1, mus_playing.baseorder); - S_CreateStream(); - } - catch (const std::runtime_error& err) - { - Printf("Unable to restart music %s: %s\n", mus_playing.name.GetChars(), err.what()); - } +void S_MIDIDeviceChanged(int newdev, bool force) +{ + static int oldmididev = INT_MIN; + + // If a song is playing, move it to the new device. + if (oldmididev != newdev || force) + { + if (mus_playing.handle != nullptr && mus_playing.handle->IsMIDI()) + { + MusInfo* song = mus_playing.handle; + if (song->m_Status == MusInfo::STATE_Playing) + { + if (song->GetDeviceType() == MDEV_FLUIDSYNTH && force) + { + // FluidSynth must reload the song to change the patch set. + auto mi = mus_playing; + S_StopMusic(true); + S_ChangeMusic(mi.name, mi.baseorder, mi.loop); + } + else + { + song->Stop(); + S_StartMusicPlaying(song, song->m_Looping, -1, 0); + } + } + } } + // 'force' + if (!force) oldmididev = newdev; } //========================================================================== diff --git a/src/sound/s_music.h b/src/sound/s_music.h index 35ebc4c3e..b0fcf231a 100644 --- a/src/sound/s_music.h +++ b/src/sound/s_music.h @@ -51,8 +51,7 @@ bool S_ChangeMusic (const char *music_name, int order=0, bool looping=true, bool bool S_ChangeCDMusic (int track, unsigned int id=0, bool looping=true); void S_RestartMusic (); - -void S_MIDIDeviceChanged(); +void S_MIDIDeviceChanged(int newdev, bool force); int S_GetMusic (const char **name); @@ -80,4 +79,16 @@ typedef TMap MidiDeviceMap; extern MusicAliasMap MusicAliases; extern MidiDeviceMap MidiDevices; +class MusInfo; +struct MusPlayingInfo +{ + FString name; + MusInfo* handle; + int baseorder; + bool loop; +}; + +extern float relative_volume, saved_relative_volume; + + #endif