mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 22:51:39 +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 <stdio.h>
|
||||
#include "zmusic/mpg123_decoder.h"
|
||||
#include "mpg123_decoder.h"
|
||||
#include "i_module.h"
|
||||
|
||||
#ifdef HAVE_MPG123
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef MPG123_DECODER_H
|
||||
#define MPG123_DECODER_H
|
||||
|
||||
#include "sounddecoder.h"
|
||||
#include "zmusic/sounddecoder.h"
|
||||
|
||||
#ifdef HAVE_MPG123
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "zmusic/sndfile_decoder.h"
|
||||
#include "sndfile_decoder.h"
|
||||
#include "i_module.h"
|
||||
|
||||
#ifdef HAVE_SNDFILE
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef SNDFILE_DECODER_H
|
||||
#define SNDFILE_DECODER_H
|
||||
|
||||
#include "sounddecoder.h"
|
||||
#include "zmusic/sounddecoder.h"
|
||||
|
||||
#ifdef HAVE_SNDFILE
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
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_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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
void I_InitMusicWin32 ();
|
||||
|
||||
extern float relative_volume;
|
||||
class MIDISource;
|
||||
class MIDIDevice;
|
||||
class OPLmusicFile;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue