mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- ZMusic interface refactoring.
Use global functions instead of the class interface which exposed too many implementation details.
This commit is contained in:
parent
30f2ac1e89
commit
dc32c2148a
9 changed files with 173 additions and 97 deletions
|
@ -454,8 +454,11 @@ bool ChangeMusicSetting(ZMusic::EIntConfigKey key, MusInfo *currSong, int value,
|
|||
return false;
|
||||
|
||||
case snd_mididevice:
|
||||
{
|
||||
bool change = miscConfig.snd_mididevice != value;
|
||||
miscConfig.snd_mididevice = value;
|
||||
return false;
|
||||
return change;
|
||||
}
|
||||
|
||||
case snd_outputrate:
|
||||
miscConfig.snd_outputrate = value;
|
||||
|
|
|
@ -37,5 +37,4 @@ public:
|
|||
STATE_Paused
|
||||
} m_Status = STATE_Stopped;
|
||||
bool m_Looping = false;
|
||||
bool m_NotStartedYet = false; // Song has been created but not yet played
|
||||
};
|
||||
|
|
|
@ -306,3 +306,102 @@ MusInfo *ZMusic_OpenCDSong (int track, int id)
|
|||
return info;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// streaming callback
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ZMusic_FillStream(MusInfo* stream, void* buff, int len)
|
||||
{
|
||||
if (stream == nullptr) return false;
|
||||
return stream->ServiceStream(buff, len);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// starts playback
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZMusic_Start(MusInfo *song, int subsong, bool loop)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Play(loop, subsong);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Utilities
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZMusic_Pause(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Pause();
|
||||
}
|
||||
|
||||
void ZMusic_Resume(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Resume();
|
||||
}
|
||||
|
||||
void ZMusic_Update(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Update();
|
||||
}
|
||||
|
||||
bool ZMusic_IsPlaying(MusInfo *song)
|
||||
{
|
||||
if (!song) return false;
|
||||
return song->IsPlaying();
|
||||
}
|
||||
|
||||
void ZMusic_Stop(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Stop();
|
||||
}
|
||||
|
||||
bool ZMusic_SetSubsong(MusInfo *song, int subsong)
|
||||
{
|
||||
if (!song) return false;
|
||||
return song->SetSubsong(subsong);
|
||||
}
|
||||
|
||||
bool ZMusic_IsLooping(MusInfo *song)
|
||||
{
|
||||
if (!song) return false;
|
||||
return song->m_Looping;
|
||||
}
|
||||
|
||||
bool ZMusic_IsMIDI(MusInfo *song)
|
||||
{
|
||||
if (!song) return false;
|
||||
return song->IsMIDI();
|
||||
}
|
||||
|
||||
SoundStreamInfo ZMusic_GetStreamInfo(MusInfo *song)
|
||||
{
|
||||
if (!song) return {};
|
||||
return song->GetStreamInfo();
|
||||
}
|
||||
|
||||
void ZMusic_Close(MusInfo *song)
|
||||
{
|
||||
if (song) delete song;
|
||||
}
|
||||
|
||||
void ZMusic_VolumeChanged(MusInfo *song)
|
||||
{
|
||||
if (song) song->MusicVolumeChanged();
|
||||
}
|
||||
|
||||
std::string ZMusic_GetStats(MusInfo *song)
|
||||
{
|
||||
if (!song) return "";
|
||||
return song->GetStats();
|
||||
}
|
||||
|
|
|
@ -159,7 +159,21 @@ void MIDIDumpWave(MIDISource* source, EMidiDevice devtype, const char* devarg, c
|
|||
MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, const char *Args);
|
||||
MusInfo *ZMusic_OpenCDSong (int track, int cdid = 0);
|
||||
|
||||
class MusInfo;
|
||||
bool ZMusic_FillStream(MusInfo* stream, void* buff, int len);
|
||||
void ZMusic_Start(MusInfo *song, int subsong, bool loop);
|
||||
void ZMusic_Pause(MusInfo *song);
|
||||
void ZMusic_Resume(MusInfo *song);
|
||||
void ZMusic_Update(MusInfo *song);
|
||||
bool ZMusic_IsPlaying(MusInfo *song);
|
||||
void ZMusic_Stop(MusInfo *song);
|
||||
void ZMusic_Close(MusInfo *song);
|
||||
bool ZMusic_SetSubsong(MusInfo *song, int subsong);
|
||||
bool ZMusic_IsLooping(MusInfo *song);
|
||||
bool ZMusic_IsMIDI(MusInfo *song);
|
||||
void ZMusic_VolumeChanged(MusInfo *song);
|
||||
SoundStreamInfo ZMusic_GetStreamInfo(MusInfo *song);
|
||||
std::string ZMusic_GetStats(MusInfo *song);
|
||||
|
||||
// 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, MusInfo *song, int value, int *pRealValue = nullptr);
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "s_music.h"
|
||||
#include "doomstat.h"
|
||||
#include "zmusic/zmusic.h"
|
||||
#include "zmusic/musinfo.h"
|
||||
#include "streamsources/streamsource.h"
|
||||
#include "filereadermusicinterface.h"
|
||||
#include "../libraries/zmusic/midisources/midisource.h"
|
||||
|
@ -133,7 +132,7 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
// let them know about the change.
|
||||
if (mus_playing.handle != nullptr)
|
||||
{
|
||||
mus_playing.handle->MusicVolumeChanged();
|
||||
ZMusic_VolumeChanged(mus_playing.handle);
|
||||
}
|
||||
else
|
||||
{ // If the music was stopped because volume was 0, start it now.
|
||||
|
@ -274,6 +273,7 @@ void I_InitMusic (void)
|
|||
#ifdef _WIN32
|
||||
I_InitMusicWin32 ();
|
||||
#endif // _WIN32
|
||||
snd_mididevice.Callback();
|
||||
|
||||
Callbacks callbacks;
|
||||
|
||||
|
@ -342,7 +342,7 @@ ADD_STAT(music)
|
|||
{
|
||||
if (mus_playing.handle != nullptr)
|
||||
{
|
||||
return FString(mus_playing.handle->GetStats().c_str());
|
||||
return FString(ZMusic_GetStats(mus_playing.handle).c_str());
|
||||
}
|
||||
return "No song playing";
|
||||
}
|
||||
|
|
|
@ -50,17 +50,17 @@
|
|||
decltype(*self) newval; \
|
||||
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle, *self, &newval); \
|
||||
self = (decltype(*self))newval; \
|
||||
if (ret) S_MIDIDeviceChanged(-1, true);
|
||||
if (ret) S_MIDIDeviceChanged(-1);
|
||||
|
||||
#define FORWARD_BOOL_CVAR(key) \
|
||||
int newval; \
|
||||
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self, &newval); \
|
||||
self = !!newval; \
|
||||
if (ret) S_MIDIDeviceChanged(-1, true);
|
||||
if (ret) S_MIDIDeviceChanged(-1);
|
||||
|
||||
#define FORWARD_STRING_CVAR(key) \
|
||||
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self); \
|
||||
if (ret) S_MIDIDeviceChanged(-1, true);
|
||||
if (ret) S_MIDIDeviceChanged(-1);
|
||||
|
||||
|
||||
CUSTOM_CVAR(Int, adl_chips_count, 6, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
|
|
|
@ -45,8 +45,10 @@
|
|||
#include "zmusic/zmusic.h"
|
||||
#include "s_music.h"
|
||||
|
||||
#define DEF_MIDIDEV -5
|
||||
|
||||
EXTERN_CVAR(Int, snd_mididevice)
|
||||
static uint32_t nummididevices;
|
||||
static bool nummididevicesset;
|
||||
|
||||
#define NUM_DEF_DEVICES 7
|
||||
|
||||
|
@ -70,39 +72,11 @@ static void AddDefaultMidiDevices(FOptionValues *opt)
|
|||
|
||||
}
|
||||
|
||||
#define DEF_MIDIDEV -5
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (!nummididevicesset)
|
||||
return;
|
||||
|
||||
if ((self >= (signed)nummididevices) || (self < -8))
|
||||
{
|
||||
// Don't do repeated message spam if there is no valid device.
|
||||
if (self != 0)
|
||||
{
|
||||
Printf("ID out of range. Using default device.\n");
|
||||
self = DEF_MIDIDEV;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (self == -1) self = DEF_MIDIDEV;
|
||||
ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self);
|
||||
S_MIDIDeviceChanged(self, false);
|
||||
}
|
||||
|
||||
void I_InitMusicWin32 ()
|
||||
{
|
||||
nummididevices = midiOutGetNumDevs ();
|
||||
nummididevicesset = true;
|
||||
snd_mididevice.Callback ();
|
||||
}
|
||||
|
||||
void I_BuildMIDIMenuList (FOptionValues *opt)
|
||||
|
@ -196,21 +170,6 @@ CCMD (snd_listmididevices)
|
|||
|
||||
#else
|
||||
|
||||
// Everything but Windows uses this code.
|
||||
|
||||
CUSTOM_CVAR(Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (self < -8)
|
||||
self = -8;
|
||||
else if (self > -2)
|
||||
self = -2;
|
||||
else
|
||||
{
|
||||
ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self);
|
||||
S_MIDIDeviceChanged(self, false);
|
||||
}
|
||||
}
|
||||
|
||||
void I_BuildMIDIMenuList (FOptionValues *opt)
|
||||
{
|
||||
AddDefaultMidiDevices(opt);
|
||||
|
@ -227,3 +186,25 @@ CCMD (snd_listmididevices)
|
|||
Printf("%s-2. TiMidity++\n", -2 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if ((self >= (signed)nummididevices) || (self < -8))
|
||||
{
|
||||
// Don't do repeated message spam if there is no valid device.
|
||||
if (self != 0)
|
||||
{
|
||||
Printf("ID out of range. Using default device.\n");
|
||||
}
|
||||
self = DEF_MIDIDEV;
|
||||
return;
|
||||
}
|
||||
else if (self == -1)
|
||||
{
|
||||
self = DEF_MIDIDEV;
|
||||
return;
|
||||
}
|
||||
bool change = ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self);
|
||||
if (change) S_MIDIDeviceChanged(self);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,6 @@
|
|||
#include "g_game.h"
|
||||
#include "s_music.h"
|
||||
#include "filereadermusicinterface.h"
|
||||
#include "zmusic/musinfo.h"
|
||||
#include "zmusic/zmusic.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
@ -126,7 +125,8 @@ static std::unique_ptr<SoundStream> musicStream;
|
|||
|
||||
static bool FillStream(SoundStream* stream, void* buff, int len, void* userdata)
|
||||
{
|
||||
bool written = mus_playing.handle? mus_playing.handle->ServiceStream(buff, len) : 0;
|
||||
bool written = ZMusic_FillStream(mus_playing.handle, buff, len);
|
||||
|
||||
if (!written)
|
||||
{
|
||||
memset((char*)buff, 0, len);
|
||||
|
@ -139,7 +139,7 @@ static bool FillStream(SoundStream* stream, void* buff, int len, void* userdata)
|
|||
void S_CreateStream()
|
||||
{
|
||||
if (!mus_playing.handle) return;
|
||||
auto fmt = mus_playing.handle->GetStreamInfo();
|
||||
auto fmt = ZMusic_GetStreamInfo(mus_playing.handle);
|
||||
if (fmt.mBufferSize > 0)
|
||||
{
|
||||
int flags = fmt.mNumChannels < 0 ? 0 : SoundStream::Float;
|
||||
|
@ -179,9 +179,8 @@ static void S_StartMusicPlaying(MusInfo* song, bool loop, float rel_vol, int sub
|
|||
saved_relative_volume = rel_vol;
|
||||
I_SetRelativeVolume(saved_relative_volume * factor);
|
||||
}
|
||||
song->Stop();
|
||||
song->Play(loop, subsong);
|
||||
song->m_NotStartedYet = false;
|
||||
ZMusic_Stop(song);
|
||||
ZMusic_Start(song, subsong, loop);
|
||||
|
||||
// Notify the sound system of the changed relative volume
|
||||
snd_musicvolume.Callback();
|
||||
|
@ -199,7 +198,7 @@ void S_PauseMusic ()
|
|||
{
|
||||
if (mus_playing.handle && !MusicPaused)
|
||||
{
|
||||
mus_playing.handle->Pause();
|
||||
ZMusic_Pause(mus_playing.handle);
|
||||
S_PauseStream(true);
|
||||
MusicPaused = true;
|
||||
}
|
||||
|
@ -216,7 +215,7 @@ void S_ResumeMusic ()
|
|||
{
|
||||
if (mus_playing.handle && MusicPaused)
|
||||
{
|
||||
mus_playing.handle->Resume();
|
||||
ZMusic_Resume(mus_playing.handle);
|
||||
S_PauseStream(false);
|
||||
MusicPaused = false;
|
||||
}
|
||||
|
@ -232,12 +231,12 @@ void S_UpdateMusic ()
|
|||
{
|
||||
if (mus_playing.handle != nullptr)
|
||||
{
|
||||
mus_playing.handle->Update();
|
||||
ZMusic_Update(mus_playing.handle);
|
||||
|
||||
// [RH] Update music and/or playlist. IsPlaying() must be called
|
||||
// to attempt to reconnect to broken net streams and to advance the
|
||||
// playlist when the current song finishes.
|
||||
if (!mus_playing.handle->IsPlaying())
|
||||
if (!ZMusic_IsPlaying(mus_playing.handle))
|
||||
{
|
||||
if (PlayList.GetNumSongs())
|
||||
{
|
||||
|
@ -408,20 +407,20 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
|||
if (!mus_playing.name.IsEmpty() &&
|
||||
mus_playing.handle != nullptr &&
|
||||
stricmp (mus_playing.name, musicname) == 0 &&
|
||||
mus_playing.handle->m_Looping == looping)
|
||||
ZMusic_IsLooping(mus_playing.handle) == looping)
|
||||
{
|
||||
if (order != mus_playing.baseorder)
|
||||
{
|
||||
if (mus_playing.handle->SetSubsong(order))
|
||||
if (ZMusic_SetSubsong(mus_playing.handle, order))
|
||||
{
|
||||
mus_playing.baseorder = order;
|
||||
}
|
||||
}
|
||||
else if (!mus_playing.handle->IsPlaying())
|
||||
else if (!ZMusic_IsPlaying(mus_playing.handle))
|
||||
{
|
||||
try
|
||||
{
|
||||
mus_playing.handle->Play(looping, order);
|
||||
ZMusic_Start(mus_playing.handle, looping, order);
|
||||
S_CreateStream();
|
||||
}
|
||||
catch (const std::runtime_error& err)
|
||||
|
@ -574,35 +573,16 @@ void S_RestartMusic ()
|
|||
//==========================================================================
|
||||
|
||||
|
||||
void S_MIDIDeviceChanged(int newdev, bool force)
|
||||
void S_MIDIDeviceChanged(int newdev)
|
||||
{
|
||||
static int oldmididev = INT_MIN;
|
||||
|
||||
// If a song is playing, move it to the new device.
|
||||
if (oldmididev != newdev || force)
|
||||
MusInfo* song = mus_playing.handle;
|
||||
if (song != nullptr && ZMusic_IsMIDI(song) && ZMusic_IsPlaying(song))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reload the song to change the device
|
||||
auto mi = mus_playing;
|
||||
S_StopMusic(true);
|
||||
S_ChangeMusic(mi.name, mi.baseorder, mi.loop);
|
||||
}
|
||||
// 'force'
|
||||
if (!force) oldmididev = newdev;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -645,8 +625,8 @@ void S_StopMusic (bool force)
|
|||
{
|
||||
S_ResumeMusic();
|
||||
S_StopStream();
|
||||
mus_playing.handle->Stop();
|
||||
delete mus_playing.handle;
|
||||
ZMusic_Stop(mus_playing.handle);
|
||||
ZMusic_Close(mus_playing.handle);
|
||||
mus_playing.handle = nullptr;
|
||||
}
|
||||
mus_playing.LastSong = std::move(mus_playing.name);
|
||||
|
@ -657,7 +637,7 @@ void S_StopMusic (bool force)
|
|||
//Printf("Unable to stop %s: %s\n", mus_playing.name.GetChars(), err.what());
|
||||
if (mus_playing.handle != nullptr)
|
||||
{
|
||||
delete mus_playing.handle;
|
||||
ZMusic_Close(mus_playing.handle);
|
||||
mus_playing.handle = nullptr;
|
||||
}
|
||||
mus_playing.name = "";
|
||||
|
|
|
@ -50,7 +50,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(int newdev, bool force);
|
||||
void S_MIDIDeviceChanged(int newdev);
|
||||
|
||||
int S_GetMusic (const char **name);
|
||||
|
||||
|
|
Loading…
Reference in a new issue