- hooked up a few more CVARs and other values the music backend needs to know about and moved the MusInfo base class into zmusic.

This commit is contained in:
Christoph Oelckers 2019-09-30 01:34:16 +02:00
parent 7c27cd0c57
commit 2c33e47988
21 changed files with 228 additions and 283 deletions

View file

@ -33,7 +33,7 @@
#include <algorithm>
#include <stdio.h>
#include "zmusic/mpg123_decoder.h"
#include "mpg123_decoder.h"
#include "i_module.h"
#ifdef HAVE_MPG123

View file

@ -1,7 +1,7 @@
#ifndef MPG123_DECODER_H
#define MPG123_DECODER_H
#include "sounddecoder.h"
#include "zmusic/sounddecoder.h"
#ifdef HAVE_MPG123

View file

@ -32,7 +32,7 @@
*/
#include <algorithm>
#include "zmusic/sndfile_decoder.h"
#include "sndfile_decoder.h"
#include "i_module.h"
#ifdef HAVE_SNDFILE

View file

@ -1,7 +1,7 @@
#ifndef SNDFILE_DECODER_H
#define SNDFILE_DECODER_H
#include "sounddecoder.h"
#include "zmusic/sounddecoder.h"
#ifdef HAVE_SNDFILE

View file

@ -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)
{

View file

@ -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)
{

View file

@ -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;

View file

@ -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
};

View file

@ -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);

View file

@ -41,8 +41,7 @@
#include "i_module.h"
#include "cmdlib.h"
#include "zmusic/mpg123_decoder.h"
#include "zmusic/sndfile_decoder.h"
#include "zmusic/sounddecoder.h"
#include "c_dispatch.h"
#include "i_music.h"
@ -51,6 +50,7 @@
#include "c_cvars.h"
#include "stats.h"
#include "s_music.h"
#include "zmusic/zmusic.h"
EXTERN_CVAR (Float, snd_sfxvolume)
EXTERN_CVAR (Float, snd_musicvolume)
@ -93,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();
}

View file

@ -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;
};

View file

@ -51,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"
@ -70,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)
@ -80,8 +82,6 @@ static bool ungzip(uint8_t *data, int size, std::vector<uint8_t> &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
//==========================================================================
//
@ -99,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<float>(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.
@ -287,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
@ -648,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
@ -657,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);
}
//==========================================================================
@ -671,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);
@ -686,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";
}

View file

@ -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__

View file

@ -13,7 +13,6 @@
void I_InitMusicWin32 ();
extern float relative_volume;
class MIDISource;
class MIDIDevice;
class OPLmusicFile;

View file

@ -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)

View file

@ -43,6 +43,7 @@
#include "v_text.h"
#include "menu/menu.h"
#include "zmusic/zmusic.h"
#include "s_music.h"
static uint32_t nummididevices;
@ -70,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
@ -115,8 +79,6 @@ void MIDIDeviceChanged(int newdev, bool force)
#include <windows.h>
#include <mmsystem.h>
unsigned mididevice;
CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
if (!nummididevicesset)
@ -133,8 +95,8 @@ CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
return;
}
else if (self == -1) self = DEF_MIDIDEV;
mididevice = MAX<int>(0, self);
MIDIDeviceChanged(self);
ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self);
S_MIDIDeviceChanged(self, false);
}
void I_InitMusicWin32 ()
@ -244,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)

View file

@ -31,7 +31,9 @@
**
*/
#include "i_musicinterns.h"
#include "zmusic/musinfo.h"
#include "zmusic/zmusic.h"
#include "zmusic/m_swap.h"
#include "i_cd.h"

View file

@ -35,36 +35,20 @@
// HEADER FILES ------------------------------------------------------------
#include "i_musicinterns.h"
#include "templates.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<uint8_t> &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 ------------------------------------------------
@ -86,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;
@ -229,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;
@ -285,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.
@ -312,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.
@ -327,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);
}
}
}
@ -346,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;
}
@ -367,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();
}
@ -603,8 +588,9 @@ void MIDIStreamer::MusicVolumeChanged()
{
if (MIDI != NULL && MIDI->FakeVolume())
{
float realvolume = clamp<float>(snd_musicvolume * relative_volume * snd_mastervolume, 0.f, 1.f);
Volume = clamp<uint32_t>((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
{
@ -843,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<uint32_t>(1, (max_time / 3) * source->getDivision() / source->getTempo());
events[0] = std::max<uint32_t>(1, (max_time / 3) * source->getDivision() / source->getTempo());
events[1] = 0;
events[2] = MEVENT_NOP << 24;
events += 3;
@ -956,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();
}
//==========================================================================

View file

@ -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)

View file

@ -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;
}
//==========================================================================

View file

@ -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<FName, MidiDeviceSetting> 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