- made the ZMusic interface more DLL friendly: Reworked all functions not to throw exceptions across the library boundary and made a few definitions internal.

Not complete yet.
This commit is contained in:
Christoph Oelckers 2020-01-01 20:01:38 +01:00
commit 7923d25cce
11 changed files with 223 additions and 140 deletions

View file

@ -39,6 +39,7 @@
#include <zlib.h>
#include "zmusic/zmusic.h"
#include "m_argv.h"
#include "w_wad.h"
#include "c_dispatch.h"
@ -52,7 +53,6 @@
#include "i_soundfont.h"
#include "s_music.h"
#include "doomstat.h"
#include "zmusic/zmusic.h"
#include "streamsources/streamsource.h"
#include "filereadermusicinterface.h"
#include "../libraries/zmusic/midisources/midisource.h"
@ -342,7 +342,7 @@ ADD_STAT(music)
{
if (mus_playing.handle != nullptr)
{
return FString(ZMusic_GetStats(mus_playing.handle).c_str());
return FString(ZMusic_GetStats((MusInfo*)mus_playing.handle).c_str());
}
return "No song playing";
}
@ -353,7 +353,7 @@ ADD_STAT(music)
//
//==========================================================================
static MIDISource *GetMIDISource(const char *fn)
static ZMusic_MidiSource GetMIDISource(const char *fn)
{
FString src = fn;
if (src.Compare("*") == 0) src = mus_playing.name;
@ -375,7 +375,7 @@ static MIDISource *GetMIDISource(const char *fn)
Printf("Unable to read lump %s\n", src.GetChars());
return nullptr;
}
auto type = IdentifyMIDIType(id, 32);
auto type = ZMusic_IdentifyMIDIType(id, 32);
if (type == MIDI_NOTMIDI)
{
Printf("%s is not MIDI-based.\n", src.GetChars());
@ -383,11 +383,11 @@ static MIDISource *GetMIDISource(const char *fn)
}
auto data = wlump.Read();
auto source = CreateMIDISource(data.Data(), data.Size(), type);
auto source = ZMusic_CreateMIDISource(data.Data(), data.Size(), type);
if (source == nullptr)
{
Printf("%s is not MIDI-based.\n", src.GetChars());
Printf("Unable to open %s: %s\n", src.GetChars(), ZMusic_GetLastError());
return nullptr;
}
return source;
@ -431,13 +431,9 @@ UNSAFE_CCMD (writewave)
auto savedsong = mus_playing;
S_StopMusic(true);
if (dev == MDEV_DEFAULT && snd_mididevice >= 0) dev = MDEV_FLUIDSYNTH; // The Windows system synth cannot dump a wave.
try
if (!ZMusic_MIDIDumpWave(source, dev, argv.argc() < 6 ? nullptr : argv[6], argv[2], argv.argc() < 4 ? 0 : (int)strtol(argv[3], nullptr, 10), argv.argc() < 5 ? 0 : (int)strtol(argv[4], nullptr, 10)))
{
MIDIDumpWave(source, dev, argv.argc() < 6 ? nullptr : argv[6], argv[2], argv.argc() < 4 ? 0 : (int)strtol(argv[3], nullptr, 10), argv.argc() < 5 ? 0 : (int)strtol(argv[4], nullptr, 10));
}
catch (const std::runtime_error& err)
{
Printf("MIDI dump failed: %s\n", err.what());
Printf("MIDI dump of %s failed: %s\n",argv[1], ZMusic_GetLastError());
}
S_ChangeMusic(savedsong.name, savedsong.baseorder, savedsong.loop, true);
@ -467,23 +463,13 @@ UNSAFE_CCMD(writemidi)
return;
}
auto source = GetMIDISource(argv[1]);
if (source == nullptr) return;
std::vector<uint8_t> midi;
bool success;
source->CreateSMF(midi, 1);
auto f = FileWriter::Open(argv[2]);
if (f == nullptr)
if (source == nullptr)
{
Printf("Could not open %s.\n", argv[2]);
Printf("Unable to open %s: %s\n", argv[1], ZMusic_GetLastError());
return;
}
success = (f->Write(&midi[0], midi.size()) == midi.size());
delete f;
if (!success)
if (!ZMusic_WriteSMF(source, argv[1], 1))
{
Printf("Could not write to music file %s.\n", argv[2]);
Printf("Unable to write %s\n", argv[1]);
}
}

View file

@ -48,18 +48,18 @@
#define FORWARD_CVAR(key) \
decltype(*self) newval; \
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle, *self, &newval); \
auto ret = ChangeMusicSetting(ZMusic::key, (MusInfo*)mus_playing.handle, *self, &newval); \
self = (decltype(*self))newval; \
if (ret) S_MIDIDeviceChanged(-1);
#define FORWARD_BOOL_CVAR(key) \
int newval; \
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self, &newval); \
auto ret = ChangeMusicSetting(ZMusic::key, (MusInfo*)mus_playing.handle,*self, &newval); \
self = !!newval; \
if (ret) S_MIDIDeviceChanged(-1);
#define FORWARD_STRING_CVAR(key) \
auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self); \
auto ret = ChangeMusicSetting(ZMusic::key, (MusInfo*)mus_playing.handle,*self); \
if (ret) S_MIDIDeviceChanged(-1);

View file

@ -171,7 +171,7 @@ void S_StopStream()
//
//==========================================================================
static void S_StartMusicPlaying(MusInfo* song, bool loop, float rel_vol, int subsong)
static bool S_StartMusicPlaying(ZMusic_MusicStream song, bool loop, float rel_vol, int subsong)
{
if (rel_vol > 0.f)
{
@ -180,10 +180,14 @@ static void S_StartMusicPlaying(MusInfo* song, bool loop, float rel_vol, int sub
I_SetRelativeVolume(saved_relative_volume * factor);
}
ZMusic_Stop(song);
ZMusic_Start(song, subsong, loop);
if (!ZMusic_Start(song, subsong, loop))
{
return false;
}
// Notify the sound system of the changed relative volume
snd_musicvolume.Callback();
return true;
}
@ -418,15 +422,11 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
}
else if (!ZMusic_IsPlaying(mus_playing.handle))
{
try
if (!ZMusic_Start(mus_playing.handle, looping, order))
{
ZMusic_Start(mus_playing.handle, looping, order);
S_CreateStream();
}
catch (const std::runtime_error& err)
{
Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), err.what());
Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError());
}
S_CreateStream();
}
return true;
@ -444,12 +444,16 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
}
S_StopMusic (true);
mus_playing.handle = ZMusic_OpenCDSong (track, id);
if (mus_playing.handle == nullptr)
{
Printf("Unable to start CD Audio for track #%d, ID %d\n", track, id);
}
}
else
{
int lumpnum = -1;
int length = 0;
MusInfo *handle = nullptr;
ZMusic_MusicStream handle = nullptr;
MidiDeviceSetting *devp = MidiDevices.CheckKey(musicname);
// Strip off any leading file:// component.
@ -504,14 +508,11 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
}
else
{
try
auto mreader = new FileReaderMusicInterface(reader);
mus_playing.handle = ZMusic_OpenSong(mreader, devp? (EMidiDevice)devp->device : MDEV_DEFAULT, devp? devp->args.GetChars() : "");
if (mus_playing.handle == nullptr)
{
auto mreader = new FileReaderMusicInterface(reader);
mus_playing.handle = ZMusic_OpenSong(mreader, devp? (EMidiDevice)devp->device : MDEV_DEFAULT, devp? devp->args.GetChars() : "");
}
catch (const std::runtime_error& err)
{
Printf("Unable to load %s: %s\n", mus_playing.name.GetChars(), err.what());
Printf("Unable to load %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError());
}
}
}
@ -523,16 +524,13 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
if (mus_playing.handle != 0)
{ // play it
try
if (!S_StartMusicPlaying(mus_playing.handle, looping, S_GetMusicVolume(musicname), order))
{
S_StartMusicPlaying(mus_playing.handle, looping, S_GetMusicVolume(musicname), order);
S_CreateStream();
mus_playing.baseorder = order;
}
catch (const std::runtime_error& err)
{
Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), err.what());
Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError());
return false;
}
S_CreateStream();
mus_playing.baseorder = order;
return true;
}
return false;
@ -575,7 +573,7 @@ void S_RestartMusic ()
void S_MIDIDeviceChanged(int newdev)
{
MusInfo* song = mus_playing.handle;
auto song = mus_playing.handle;
if (song != nullptr && ZMusic_IsMIDI(song) && ZMusic_IsPlaying(song))
{
// Reload the song to change the device

View file

@ -28,6 +28,7 @@
#ifndef __S_MUSIC__
#define __S_MUSIC__
#include "zmusic/zmusic.h"
#include "doomtype.h"
#include "i_soundinternal.h"
@ -78,11 +79,10 @@ typedef TMap<FName, MidiDeviceSetting> MidiDeviceMap;
extern MusicAliasMap MusicAliases;
extern MidiDeviceMap MidiDevices;
class MusInfo;
struct MusPlayingInfo
{
FString name;
MusInfo* handle;
ZMusic_MusicStream handle;
int baseorder;
bool loop;
FString LastSong; // last music that was played