mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-06-01 09:22:17 +00:00
- 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:
parent
7c27cd0c57
commit
2c33e47988
21 changed files with 228 additions and 283 deletions
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "zmusic/mpg123_decoder.h"
|
#include "mpg123_decoder.h"
|
||||||
#include "i_module.h"
|
#include "i_module.h"
|
||||||
|
|
||||||
#ifdef HAVE_MPG123
|
#ifdef HAVE_MPG123
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef MPG123_DECODER_H
|
#ifndef MPG123_DECODER_H
|
||||||
#define MPG123_DECODER_H
|
#define MPG123_DECODER_H
|
||||||
|
|
||||||
#include "sounddecoder.h"
|
#include "zmusic/sounddecoder.h"
|
||||||
|
|
||||||
#ifdef HAVE_MPG123
|
#ifdef HAVE_MPG123
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "zmusic/sndfile_decoder.h"
|
#include "sndfile_decoder.h"
|
||||||
#include "i_module.h"
|
#include "i_module.h"
|
||||||
|
|
||||||
#ifdef HAVE_SNDFILE
|
#ifdef HAVE_SNDFILE
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef SNDFILE_DECODER_H
|
#ifndef SNDFILE_DECODER_H
|
||||||
#define SNDFILE_DECODER_H
|
#define SNDFILE_DECODER_H
|
||||||
|
|
||||||
#include "sounddecoder.h"
|
#include "zmusic/sounddecoder.h"
|
||||||
|
|
||||||
#ifdef HAVE_SNDFILE
|
#ifdef HAVE_SNDFILE
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "zmusic/sndfile_decoder.h"
|
#include "sndfile_decoder.h"
|
||||||
#include "zmusic/mpg123_decoder.h"
|
#include "mpg123_decoder.h"
|
||||||
|
|
||||||
SoundDecoder *SoundDecoder::CreateDecoder(MusicIO::FileInterface *reader)
|
SoundDecoder *SoundDecoder::CreateDecoder(MusicIO::FileInterface *reader)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "../../libraries/dumb/include/dumb.h"
|
#include "../../libraries/dumb/include/dumb.h"
|
||||||
|
|
||||||
#include "zmusic.h"
|
#include "zmusic.h"
|
||||||
|
#include "musinfo.h"
|
||||||
#include "midiconfig.h"
|
#include "midiconfig.h"
|
||||||
|
|
||||||
struct Dummy
|
struct Dummy
|
||||||
|
@ -46,13 +47,9 @@ struct Dummy
|
||||||
void ChangeSettingNum(const char*, double) {}
|
void ChangeSettingNum(const char*, double) {}
|
||||||
void ChangeSettingString(const char*, const char*) {}
|
void ChangeSettingString(const char*, const char*) {}
|
||||||
};
|
};
|
||||||
static Dummy* currSong;
|
|
||||||
//extern MusInfo *CurrSong;
|
#define devType() ((currSong)? (currSong)->GetDeviceType() : MDEV_DEFAULT)
|
||||||
int devType()
|
|
||||||
{
|
|
||||||
/*if (CurrSong) return CurrSong->GetDeviceType();
|
|
||||||
else*/ return MDEV_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MiscConfig miscConfig;
|
MiscConfig miscConfig;
|
||||||
Callbacks musicCallbacks;
|
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)
|
switch (key)
|
||||||
{
|
{
|
||||||
|
@ -452,11 +449,20 @@ bool ChangeMusicSetting(ZMusic::EIntConfigKey key, int value, int *pRealValue)
|
||||||
case mod_autochip_scan_threshold:
|
case mod_autochip_scan_threshold:
|
||||||
ChangeAndReturn(dumbConfig.mod_autochip_scan_threshold, value, pRealValue);
|
ChangeAndReturn(dumbConfig.mod_autochip_scan_threshold, value, pRealValue);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case snd_mididevice:
|
||||||
|
miscConfig.snd_mididevice = value;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case snd_outputrate:
|
||||||
|
miscConfig.snd_outputrate = value;
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
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)
|
switch (key)
|
||||||
{
|
{
|
||||||
|
@ -588,11 +594,24 @@ bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, float value, float *pRealVa
|
||||||
if (value < 0) value = 0;
|
if (value < 0) value = 0;
|
||||||
ChangeAndReturn(dumbConfig.mod_dumb_mastervolume, value, pRealValue);
|
ChangeAndReturn(dumbConfig.mod_dumb_mastervolume, value, pRealValue);
|
||||||
return false;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChangeMusicSetting(ZMusic::EStringConfigKey key, const char *value)
|
bool ChangeMusicSetting(ZMusic::EStringConfigKey key, MusInfo* currSong, const char *value)
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
|
|
|
@ -138,7 +138,12 @@ struct MiscConfig
|
||||||
{
|
{
|
||||||
int snd_midiprecache;
|
int snd_midiprecache;
|
||||||
float gme_stereodepth;
|
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;
|
extern ADLConfig adlConfig;
|
||||||
|
|
40
libraries/zmusic/zmusic/musinfo.h
Normal file
40
libraries/zmusic/zmusic/musinfo.h
Normal 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
|
||||||
|
};
|
|
@ -69,6 +69,9 @@ enum EIntConfigKey
|
||||||
|
|
||||||
snd_streambuffersize,
|
snd_streambuffersize,
|
||||||
|
|
||||||
|
snd_mididevice,
|
||||||
|
snd_outputrate,
|
||||||
|
|
||||||
NUM_INT_CONFIGS
|
NUM_INT_CONFIGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,6 +93,10 @@ enum EFloatConfigKey
|
||||||
gme_stereodepth,
|
gme_stereodepth,
|
||||||
mod_dumb_mastervolume,
|
mod_dumb_mastervolume,
|
||||||
|
|
||||||
|
snd_musicvolume,
|
||||||
|
relative_volume,
|
||||||
|
snd_mastervolume,
|
||||||
|
|
||||||
NUM_FLOAT_CONFIGS
|
NUM_FLOAT_CONFIGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,8 +154,9 @@ class MIDISource; // abstract for the client
|
||||||
EMIDIType IdentifyMIDIType(uint32_t *id, int size);
|
EMIDIType IdentifyMIDIType(uint32_t *id, int size);
|
||||||
MIDISource *CreateMIDISource(const uint8_t *data, size_t length, EMIDIType miditype);
|
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.
|
// 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.
|
// 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::EIntConfigKey key, MusInfo *song, int value, int *pRealValue = nullptr);
|
||||||
bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, float value, float *pRealValue = nullptr);
|
bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, MusInfo* song, float value, float *pRealValue = nullptr);
|
||||||
bool ChangeMusicSetting(ZMusic::EStringConfigKey key, const char *value);
|
bool ChangeMusicSetting(ZMusic::EStringConfigKey key, MusInfo* song, const char *value);
|
||||||
|
|
|
@ -41,8 +41,7 @@
|
||||||
|
|
||||||
#include "i_module.h"
|
#include "i_module.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "zmusic/mpg123_decoder.h"
|
#include "zmusic/sounddecoder.h"
|
||||||
#include "zmusic/sndfile_decoder.h"
|
|
||||||
|
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "i_music.h"
|
#include "i_music.h"
|
||||||
|
@ -51,6 +50,7 @@
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
#include "s_music.h"
|
#include "s_music.h"
|
||||||
|
#include "zmusic/zmusic.h"
|
||||||
|
|
||||||
EXTERN_CVAR (Float, snd_sfxvolume)
|
EXTERN_CVAR (Float, snd_sfxvolume)
|
||||||
EXTERN_CVAR (Float, snd_musicvolume)
|
EXTERN_CVAR (Float, snd_musicvolume)
|
||||||
|
@ -93,6 +93,8 @@ CUSTOM_CVAR(Float, snd_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVA
|
||||||
self = 0.f;
|
self = 0.f;
|
||||||
else if (self > 1.f)
|
else if (self > 1.f)
|
||||||
self = 1.f;
|
self = 1.f;
|
||||||
|
|
||||||
|
ChangeMusicSetting(ZMusic::snd_mastervolume, nullptr, self);
|
||||||
snd_sfxvolume.Callback();
|
snd_sfxvolume.Callback();
|
||||||
snd_musicvolume.Callback();
|
snd_musicvolume.Callback();
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,16 +119,7 @@ void FindLoopTags(MusicIO::FileInterface *fr, uint32_t *start, bool *startass, u
|
||||||
|
|
||||||
const char *GetSampleTypeName(enum SampleType type);
|
const char *GetSampleTypeName(enum SampleType type);
|
||||||
const char *GetChannelConfigName(enum ChannelConfig chan);
|
const char *GetChannelConfigName(enum ChannelConfig chan);
|
||||||
|
|
||||||
class MusInfo;
|
|
||||||
class SoundStream;
|
class SoundStream;
|
||||||
struct MusPlayingInfo
|
|
||||||
{
|
|
||||||
FString name;
|
|
||||||
MusInfo *handle;
|
|
||||||
int baseorder;
|
|
||||||
bool loop;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "i_soundfont.h"
|
#include "i_soundfont.h"
|
||||||
#include "s_music.h"
|
#include "s_music.h"
|
||||||
#include "zmusic/zmusic.h"
|
#include "zmusic/zmusic.h"
|
||||||
|
#include "zmusic/musinfo.h"
|
||||||
#include "streamsources/streamsource.h"
|
#include "streamsources/streamsource.h"
|
||||||
#include "filereadermusicinterface.h"
|
#include "filereadermusicinterface.h"
|
||||||
#include "../libraries/zmusic/midisources/midisource.h"
|
#include "../libraries/zmusic/midisources/midisource.h"
|
||||||
|
@ -70,6 +71,7 @@
|
||||||
extern int MUSHeaderSearch(const uint8_t *head, int len);
|
extern int MUSHeaderSearch(const uint8_t *head, int len);
|
||||||
void I_InitSoundFonts();
|
void I_InitSoundFonts();
|
||||||
extern "C" void dumb_exit();
|
extern "C" void dumb_exit();
|
||||||
|
extern MusPlayingInfo mus_playing;
|
||||||
|
|
||||||
EXTERN_CVAR (Int, snd_samplerate)
|
EXTERN_CVAR (Int, snd_samplerate)
|
||||||
EXTERN_CVAR (Int, snd_mididevice)
|
EXTERN_CVAR (Int, snd_mididevice)
|
||||||
|
@ -80,8 +82,6 @@ static bool ungzip(uint8_t *data, int size, std::vector<uint8_t> &newdata);
|
||||||
|
|
||||||
MusInfo *currSong;
|
MusInfo *currSong;
|
||||||
int nomusic = 0;
|
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
|
else
|
||||||
{
|
{
|
||||||
// Set general music volume.
|
// Set general music volume.
|
||||||
|
ChangeMusicSetting(ZMusic::snd_musicvolume, nullptr, self);
|
||||||
if (GSnd != nullptr)
|
if (GSnd != nullptr)
|
||||||
{
|
{
|
||||||
GSnd->SetMusicVolume(clamp<float>(self * relative_volume * snd_mastervolume, 0, 1));
|
GSnd->SetMusicVolume(clamp<float>(self * relative_volume * snd_mastervolume, 0, 1));
|
||||||
}
|
}
|
||||||
// For music not implemented through the digital sound system,
|
// For music not implemented through the digital sound system,
|
||||||
// let them know about the change.
|
// let them know about the change.
|
||||||
if (currSong != nullptr)
|
if (mus_playing.handle != nullptr)
|
||||||
{
|
{
|
||||||
currSong->MusicVolumeChanged();
|
mus_playing.handle->MusicVolumeChanged();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // If the music was stopped because volume was 0, start it now.
|
{ // 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
|
// 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
|
// Sets relative music volume. Takes $musicvolume in SNDINFO into consideration
|
||||||
|
@ -657,8 +570,7 @@ void I_UpdateMusic()
|
||||||
void I_SetMusicVolume (double factor)
|
void I_SetMusicVolume (double factor)
|
||||||
{
|
{
|
||||||
factor = clamp(factor, 0., 2.0);
|
factor = clamp(factor, 0., 2.0);
|
||||||
relative_volume = saved_relative_volume * float(factor);
|
I_SetRelativeVolume(factor);
|
||||||
snd_musicvolume.Callback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -671,8 +583,7 @@ CCMD(testmusicvol)
|
||||||
{
|
{
|
||||||
if (argv.argc() > 1)
|
if (argv.argc() > 1)
|
||||||
{
|
{
|
||||||
relative_volume = (float)strtod(argv[1], nullptr);
|
I_SetRelativeVolume((float)strtod(argv[1], nullptr));
|
||||||
snd_musicvolume.Callback();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Printf("Current relative volume is %1.2f\n", relative_volume);
|
Printf("Current relative volume is %1.2f\n", relative_volume);
|
||||||
|
@ -686,9 +597,9 @@ CCMD(testmusicvol)
|
||||||
|
|
||||||
ADD_STAT(music)
|
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";
|
return "No song playing";
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ void I_BuildMIDIMenuList (FOptionValues *);
|
||||||
void I_UpdateMusic ();
|
void I_UpdateMusic ();
|
||||||
|
|
||||||
// Volume.
|
// Volume.
|
||||||
|
void I_SetRelativeVolume(float);
|
||||||
void I_SetMusicVolume (double volume);
|
void I_SetMusicVolume (double volume);
|
||||||
|
|
||||||
// Registers a song handle to song data.
|
// Registers a song handle to song data.
|
||||||
|
@ -58,44 +59,6 @@ struct MidiDeviceSetting;
|
||||||
MusInfo *I_RegisterSong (MusicIO::FileInterface *reader, MidiDeviceSetting *device);
|
MusInfo *I_RegisterSong (MusicIO::FileInterface *reader, MidiDeviceSetting *device);
|
||||||
MusInfo *I_RegisterCDSong (int track, int cdid = 0);
|
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;
|
extern int nomusic;
|
||||||
|
|
||||||
#endif //__I_MUSIC_H__
|
#endif //__I_MUSIC_H__
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
void I_InitMusicWin32 ();
|
void I_InitMusicWin32 ();
|
||||||
|
|
||||||
extern float relative_volume;
|
|
||||||
class MIDISource;
|
class MIDISource;
|
||||||
class MIDIDevice;
|
class MIDIDevice;
|
||||||
class OPLmusicFile;
|
class OPLmusicFile;
|
||||||
|
|
|
@ -35,8 +35,10 @@
|
||||||
|
|
||||||
#include "i_musicinterns.h"
|
#include "i_musicinterns.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
|
#include "s_music.h"
|
||||||
#include "zmusic/zmusic.h"
|
#include "zmusic/zmusic.h"
|
||||||
|
|
||||||
|
extern MusPlayingInfo mus_playing;
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -46,19 +48,19 @@
|
||||||
|
|
||||||
#define FORWARD_CVAR(key) \
|
#define FORWARD_CVAR(key) \
|
||||||
decltype(*self) newval; \
|
decltype(*self) newval; \
|
||||||
auto ret = ChangeMusicSetting(ZMusic::key, *self, &newval); \
|
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle, *self, &newval); \
|
||||||
self = (decltype(*self))newval; \
|
self = (decltype(*self))newval; \
|
||||||
if (ret) MIDIDeviceChanged(-1, true);
|
if (ret) S_MIDIDeviceChanged(-1, true);
|
||||||
|
|
||||||
#define FORWARD_BOOL_CVAR(key) \
|
#define FORWARD_BOOL_CVAR(key) \
|
||||||
int newval; \
|
int newval; \
|
||||||
auto ret = ChangeMusicSetting(ZMusic::key, *self, &newval); \
|
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self, &newval); \
|
||||||
self = !!newval; \
|
self = !!newval; \
|
||||||
if (ret) MIDIDeviceChanged(-1, true);
|
if (ret) S_MIDIDeviceChanged(-1, true);
|
||||||
|
|
||||||
#define FORWARD_STRING_CVAR(key) \
|
#define FORWARD_STRING_CVAR(key) \
|
||||||
auto ret = ChangeMusicSetting(ZMusic::key, *self); \
|
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self); \
|
||||||
if (ret) MIDIDeviceChanged(-1, true);
|
if (ret) S_MIDIDeviceChanged(-1, true);
|
||||||
|
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, adl_chips_count, 6, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
CUSTOM_CVAR(Int, adl_chips_count, 6, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
|
#include "zmusic/zmusic.h"
|
||||||
#include "s_music.h"
|
#include "s_music.h"
|
||||||
|
|
||||||
static uint32_t nummididevices;
|
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
|
#define DEF_MIDIDEV -5
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -115,8 +79,6 @@ void MIDIDeviceChanged(int newdev, bool force)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
|
||||||
unsigned mididevice;
|
|
||||||
|
|
||||||
CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
{
|
{
|
||||||
if (!nummididevicesset)
|
if (!nummididevicesset)
|
||||||
|
@ -133,8 +95,8 @@ CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (self == -1) self = DEF_MIDIDEV;
|
else if (self == -1) self = DEF_MIDIDEV;
|
||||||
mididevice = MAX<int>(0, self);
|
ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self);
|
||||||
MIDIDeviceChanged(self);
|
S_MIDIDeviceChanged(self, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_InitMusicWin32 ()
|
void I_InitMusicWin32 ()
|
||||||
|
@ -244,7 +206,10 @@ CUSTOM_CVAR(Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
else if (self > -2)
|
else if (self > -2)
|
||||||
self = -2;
|
self = -2;
|
||||||
else
|
else
|
||||||
MIDIDeviceChanged(self);
|
{
|
||||||
|
ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self);
|
||||||
|
S_MIDIDeviceChanged(self, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_BuildMIDIMenuList (FOptionValues *opt)
|
void I_BuildMIDIMenuList (FOptionValues *opt)
|
||||||
|
|
|
@ -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"
|
#include "i_cd.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,36 +35,20 @@
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
#include "i_musicinterns.h"
|
#include "zmusic/musinfo.h"
|
||||||
#include "templates.h"
|
|
||||||
#include "doomerrors.h"
|
|
||||||
#include "v_text.h"
|
|
||||||
|
|
||||||
#include "mididevices/mididevice.h"
|
#include "mididevices/mididevice.h"
|
||||||
#include "midisources/midisource.h"
|
#include "midisources/midisource.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
#define MAX_TIME (1000000/10) // Send out 1/10 of a sec of events at a time.
|
enum
|
||||||
|
{
|
||||||
|
MAX_TIME = (1000000/10) // Send out 1/10 of a sec of events at a time.
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
};
|
||||||
|
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||||
|
|
||||||
static void WriteVarLen (TArray<uint8_t> &file, uint32_t value);
|
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// 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 ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
|
@ -86,7 +70,7 @@ public:
|
||||||
bool IsValid() const override;
|
bool IsValid() const override;
|
||||||
bool SetSubsong(int subsong) override;
|
bool SetSubsong(int subsong) override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
FString GetStats() override;
|
std::string GetStats() override;
|
||||||
void ChangeSettingInt(const char* setting, int value) override;
|
void ChangeSettingInt(const char* setting, int value) override;
|
||||||
void ChangeSettingNum(const char* setting, double value) override;
|
void ChangeSettingNum(const char* setting, double value) override;
|
||||||
void ChangeSettingString(const char* setting, const char* value) override;
|
void ChangeSettingString(const char* setting, const char* value) override;
|
||||||
|
@ -229,7 +213,7 @@ EMidiDevice MIDIStreamer::SelectMIDIDevice(EMidiDevice device)
|
||||||
{
|
{
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
switch (snd_mididevice)
|
switch (miscConfig.snd_mididevice)
|
||||||
{
|
{
|
||||||
case -1: return MDEV_SNDSYS;
|
case -1: return MDEV_SNDSYS;
|
||||||
case -2: return MDEV_TIMIDITY;
|
case -2: return MDEV_TIMIDITY;
|
||||||
|
@ -285,7 +269,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
|
||||||
case MDEV_MMAPI:
|
case MDEV_MMAPI:
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
dev = CreateWinMIDIDevice(mididevice);
|
dev = CreateWinMIDIDevice(std::max(0, miscConfig.snd_mididevice));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
// Intentional fall-through for non-Windows systems.
|
// Intentional fall-through for non-Windows systems.
|
||||||
|
@ -312,7 +296,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
|
||||||
}
|
}
|
||||||
catch (std::runtime_error &err)
|
catch (std::runtime_error &err)
|
||||||
{
|
{
|
||||||
DPrintf(DMSG_WARNING, "%s\n", err.what());
|
//DPrintf(DMSG_WARNING, "%s\n", err.what());
|
||||||
checked[devtype] = true;
|
checked[devtype] = true;
|
||||||
devtype = MDEV_DEFAULT;
|
devtype = MDEV_DEFAULT;
|
||||||
// Opening the requested device did not work out so choose another one.
|
// 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)
|
if (devtype == MDEV_DEFAULT)
|
||||||
{
|
{
|
||||||
Printf("Failed to play music: Unable to open any MIDI Device.\n");
|
std::string message = std::string(err.what()) + "\n\nFailed to play music: Unable to open any MIDI Device.";
|
||||||
return nullptr;
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,7 +330,8 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
|
||||||
|
|
||||||
lastRequestedDevice = requestedDevice;
|
lastRequestedDevice = requestedDevice;
|
||||||
lastSelectedDevice = selectedDevice;
|
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;
|
return dev;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +352,7 @@ void MIDIStreamer::Play(bool looping, int subsong)
|
||||||
m_Looping = looping;
|
m_Looping = looping;
|
||||||
source->SetMIDISubsong(subsong);
|
source->SetMIDISubsong(subsong);
|
||||||
devtype = SelectMIDIDevice(DeviceType);
|
devtype = SelectMIDIDevice(DeviceType);
|
||||||
MIDI.reset(CreateMIDIDevice(devtype, (int)GSnd->GetOutputRate()));
|
MIDI.reset(CreateMIDIDevice(devtype, miscConfig.snd_outputrate));
|
||||||
InitPlayback();
|
InitPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,8 +588,9 @@ void MIDIStreamer::MusicVolumeChanged()
|
||||||
{
|
{
|
||||||
if (MIDI != NULL && MIDI->FakeVolume())
|
if (MIDI != NULL && MIDI->FakeVolume())
|
||||||
{
|
{
|
||||||
float realvolume = clamp<float>(snd_musicvolume * relative_volume * snd_mastervolume, 0.f, 1.f);
|
float realvolume = miscConfig.snd_musicvolume * miscConfig.relative_volume * miscConfig.snd_mastervolume;
|
||||||
Volume = clamp<uint32_t>((uint32_t)(realvolume * 65535.f), 0, 65535);
|
if (realvolume < 0 || realvolume > 1) realvolume = 1;
|
||||||
|
Volume = (uint32_t)(realvolume * 65535.f);
|
||||||
}
|
}
|
||||||
else
|
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
|
// Be more responsive when unpausing by only playing each buffer
|
||||||
// for a third of the maximum time.
|
// 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[1] = 0;
|
||||||
events[2] = MEVENT_NOP << 24;
|
events[2] = MEVENT_NOP << 24;
|
||||||
events += 3;
|
events += 3;
|
||||||
|
@ -956,14 +942,13 @@ int MIDIStreamer::GetDeviceType() const
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FString MIDIStreamer::GetStats()
|
std::string MIDIStreamer::GetStats()
|
||||||
{
|
{
|
||||||
if (MIDI == NULL)
|
if (MIDI == NULL)
|
||||||
{
|
{
|
||||||
return "No MIDI device in use.";
|
return "No MIDI device in use.";
|
||||||
}
|
}
|
||||||
auto s = MIDI->GetStats();
|
return MIDI->GetStats();
|
||||||
return s.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
**---------------------------------------------------------------------------
|
**---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "i_musicinterns.h"
|
#include "zmusic/musinfo.h"
|
||||||
#include "streamsources/streamsource.h"
|
#include "streamsources/streamsource.h"
|
||||||
|
|
||||||
class StreamSong : public MusInfo
|
class StreamSong : public MusInfo
|
||||||
|
@ -48,7 +48,7 @@ public:
|
||||||
bool IsValid () const override { return m_Source != nullptr; }
|
bool IsValid () const override { return m_Source != nullptr; }
|
||||||
bool SetPosition (unsigned int pos) override;
|
bool SetPosition (unsigned int pos) override;
|
||||||
bool SetSubsong (int subsong) 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 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 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); }
|
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);
|
return m_Source->SetSubsong(subsong);
|
||||||
}
|
}
|
||||||
|
|
||||||
FString StreamSong::GetStats()
|
std::string StreamSong::GetStats()
|
||||||
{
|
{
|
||||||
FString s1, s2;
|
std::string s1, s2;
|
||||||
if (m_Source != NULL)
|
if (m_Source != NULL)
|
||||||
{
|
{
|
||||||
auto stat = m_Source->GetStats();
|
auto stat = m_Source->GetStats();
|
||||||
s2 = stat.c_str();
|
s2 = stat.c_str();
|
||||||
}
|
}
|
||||||
if (s1.IsEmpty() && s2.IsEmpty()) return "No song loaded\n";
|
if (s1.empty() && s2.empty()) return "No song loaded\n";
|
||||||
if (s1.IsEmpty()) return s2;
|
if (s1.empty()) return s2;
|
||||||
if (s2.IsEmpty()) return s1;
|
if (s2.empty()) return s1;
|
||||||
return FStringf("%s\n%s", s1.GetChars(), s2.GetChars());
|
return s1 + "\n" + s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StreamSong::ServiceStream (void *buff, int len)
|
bool StreamSong::ServiceStream (void *buff, int len)
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
#include "atterm.h"
|
#include "atterm.h"
|
||||||
#include "s_music.h"
|
#include "s_music.h"
|
||||||
#include "filereadermusicinterface.h"
|
#include "filereadermusicinterface.h"
|
||||||
|
#include "zmusic/musinfo.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -102,6 +103,8 @@ static bool MusicPaused; // whether music is paused
|
||||||
MusPlayingInfo mus_playing; // music currently being played
|
MusPlayingInfo mus_playing; // music currently being played
|
||||||
static FString LastSong; // last music that was played
|
static FString LastSong; // last music that was played
|
||||||
static FPlayList *PlayList;
|
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_GLOBAL_NAMED(mus_playing, musplaying);
|
||||||
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, name);
|
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
|
// S_PauseSound
|
||||||
|
@ -530,7 +557,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
||||||
{ // play it
|
{ // play it
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mus_playing.handle->Start(looping, S_GetMusicVolume(musicname), order);
|
S_StartMusicPlaying(mus_playing.handle, looping, S_GetMusicVolume(musicname), order);
|
||||||
S_CreateStream();
|
S_CreateStream();
|
||||||
mus_playing.baseorder = order;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -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);
|
bool S_ChangeCDMusic (int track, unsigned int id=0, bool looping=true);
|
||||||
|
|
||||||
void S_RestartMusic ();
|
void S_RestartMusic ();
|
||||||
|
void S_MIDIDeviceChanged(int newdev, bool force);
|
||||||
void S_MIDIDeviceChanged();
|
|
||||||
|
|
||||||
int S_GetMusic (const char **name);
|
int S_GetMusic (const char **name);
|
||||||
|
|
||||||
|
@ -80,4 +79,16 @@ typedef TMap<FName, MidiDeviceSetting> MidiDeviceMap;
|
||||||
extern MusicAliasMap MusicAliases;
|
extern MusicAliasMap MusicAliases;
|
||||||
extern MidiDeviceMap MidiDevices;
|
extern MidiDeviceMap MidiDevices;
|
||||||
|
|
||||||
|
class MusInfo;
|
||||||
|
struct MusPlayingInfo
|
||||||
|
{
|
||||||
|
FString name;
|
||||||
|
MusInfo* handle;
|
||||||
|
int baseorder;
|
||||||
|
bool loop;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern float relative_volume, saved_relative_volume;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue