mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 06:41:41 +00:00
- 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:
parent
c24f9b42ba
commit
7923d25cce
11 changed files with 222 additions and 139 deletions
|
@ -57,7 +57,7 @@ void *safe_malloc(size_t count)
|
|||
auto p = malloc(count);
|
||||
if (!p)
|
||||
{
|
||||
std::terminate(); // we must abort, though...
|
||||
abort(); // we must abort, though...
|
||||
}
|
||||
return p;
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
#include "midisource.h"
|
||||
|
||||
|
||||
|
@ -418,7 +418,7 @@ extern int MUSHeaderSearch(const uint8_t *head, int len);
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
EMIDIType IdentifyMIDIType(uint32_t *id, int size)
|
||||
EMIDIType ZMusic_IdentifyMIDIType(uint32_t *id, int size)
|
||||
{
|
||||
// Check for MUS format
|
||||
// Tolerate sloppy wads by searching up to 32 bytes for the header
|
||||
|
@ -467,23 +467,39 @@ EMIDIType IdentifyMIDIType(uint32_t *id, int size)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDISource *CreateMIDISource(const uint8_t *data, size_t length, EMIDIType miditype)
|
||||
DLL_EXPORT ZMusic_MidiSource ZMusic_CreateMIDISource(const uint8_t *data, size_t length, EMIDIType miditype)
|
||||
{
|
||||
try
|
||||
{
|
||||
MIDISource* source;
|
||||
switch (miditype)
|
||||
{
|
||||
case MIDI_MUS:
|
||||
return new MUSSong2(data, length);
|
||||
source = new MUSSong2(data, length);
|
||||
break;
|
||||
|
||||
case MIDI_MIDI:
|
||||
return new MIDISong2(data, length);
|
||||
source = new MIDISong2(data, length);
|
||||
break;
|
||||
|
||||
case MIDI_HMI:
|
||||
return new HMISong(data, length);
|
||||
source = new HMISong(data, length);
|
||||
break;
|
||||
|
||||
case MIDI_XMI:
|
||||
return new XMISong(data, length);
|
||||
source = new XMISong(data, length);
|
||||
break;
|
||||
|
||||
default:
|
||||
SetError("Unable to identify MIDI data");
|
||||
source = nullptr;
|
||||
break;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
catch (const std::exception & ex)
|
||||
{
|
||||
SetError(ex.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
#include "zmusic/musinfo.h"
|
||||
#include "mididevices/mididevice.h"
|
||||
#include "midisources/midisource.h"
|
||||
|
@ -1004,9 +1005,18 @@ MusInfo* CreateMIDIStreamer(MIDISource *source, EMidiDevice devtype, const char*
|
|||
return me;
|
||||
}
|
||||
|
||||
void MIDIDumpWave(MIDISource* source, EMidiDevice devtype, const char *devarg, const char *outname, int subsong, int samplerate)
|
||||
DLL_EXPORT bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char *devarg, const char *outname, int subsong, int samplerate)
|
||||
{
|
||||
try
|
||||
{
|
||||
MIDIStreamer me(devtype, devarg);
|
||||
me.SetMIDISource(source);
|
||||
me.DumpWave(outname, subsong, samplerate);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception & ex)
|
||||
{
|
||||
SetError(ex.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "oplsynth/oplio.h"
|
||||
#include "../../libraries/dumb/include/dumb.h"
|
||||
|
||||
#include "zmusic.h"
|
||||
#include "zmusic_internal.h"
|
||||
#include "musinfo.h"
|
||||
#include "midiconfig.h"
|
||||
|
||||
|
@ -54,25 +54,25 @@ struct Dummy
|
|||
MiscConfig miscConfig;
|
||||
Callbacks musicCallbacks;
|
||||
|
||||
void ZMusic_SetCallbacks(const Callbacks* cb)
|
||||
DLL_EXPORT void ZMusic_SetCallbacks(const Callbacks* cb)
|
||||
{
|
||||
dumb_decode_vorbis = cb->DumbVorbisDecode;
|
||||
musicCallbacks = *cb;
|
||||
}
|
||||
|
||||
void ZMusic_SetGenMidi(const uint8_t* data)
|
||||
DLL_EXPORT void ZMusic_SetGenMidi(const uint8_t* data)
|
||||
{
|
||||
memcpy(oplConfig.OPLinstruments, data, 175 * 36);
|
||||
oplConfig.genmidiset = true;
|
||||
}
|
||||
|
||||
void ZMusic_SetWgOpn(const void* data, unsigned len)
|
||||
DLL_EXPORT void ZMusic_SetWgOpn(const void* data, unsigned len)
|
||||
{
|
||||
opnConfig.default_bank.resize(len);
|
||||
memcpy(opnConfig.default_bank.data(), data, len);
|
||||
}
|
||||
|
||||
void ZMusic_SetDmxGus(const void* data, unsigned len)
|
||||
DLL_EXPORT void ZMusic_SetDmxGus(const void* data, unsigned len)
|
||||
{
|
||||
gusConfig.dmxgus.resize(len);
|
||||
memcpy(gusConfig.dmxgus.data(), data, len);
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <string>
|
||||
#include <zlib.h>
|
||||
#include "m_swap.h"
|
||||
#include "zmusic.h"
|
||||
#include "zmusic_internal.h"
|
||||
#include "midiconfig.h"
|
||||
#include "musinfo.h"
|
||||
#include "streamsources/streamsource.h"
|
||||
|
@ -157,6 +157,7 @@ MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, co
|
|||
|
||||
if(reader->read(id, 32) != 32 || reader->seek(-32, SEEK_CUR) != 0)
|
||||
{
|
||||
SetError("Unable to read header");
|
||||
reader->close();
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -190,16 +191,17 @@ MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, co
|
|||
}
|
||||
}
|
||||
|
||||
EMIDIType miditype = IdentifyMIDIType(id, sizeof(id));
|
||||
EMIDIType miditype = ZMusic_IdentifyMIDIType(id, sizeof(id));
|
||||
if (miditype != MIDI_NOTMIDI)
|
||||
{
|
||||
std::vector<uint8_t> data(reader->filelength());
|
||||
if (reader->read(data.data(), (long)data.size()) != (long)data.size())
|
||||
{
|
||||
SetError("Failed to read MIDI data");
|
||||
reader->close();
|
||||
return nullptr;
|
||||
}
|
||||
auto source = CreateMIDISource(data.data(), data.size(), miditype);
|
||||
auto source = ZMusic_CreateMIDISource(data.data(), data.size(), miditype);
|
||||
if (source == nullptr)
|
||||
{
|
||||
reader->close();
|
||||
|
@ -207,6 +209,7 @@ MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, co
|
|||
}
|
||||
if (!source->isValid())
|
||||
{
|
||||
SetError("Invalid data in MIDI file");
|
||||
delete source;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -268,23 +271,26 @@ MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, co
|
|||
{
|
||||
// File could not be identified as music.
|
||||
if (reader) reader->close();
|
||||
SetError("Unable to identify as music");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (info && !info->IsValid())
|
||||
{
|
||||
delete info;
|
||||
SetError("Unable to identify as music");
|
||||
info = nullptr;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Make sure the reader is closed if this function abnormally terminates
|
||||
if (reader) reader->close();
|
||||
throw;
|
||||
}
|
||||
if (reader) reader->close();
|
||||
return info;
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
// Make sure the reader is closed if this function abnormally terminates
|
||||
if (reader) reader->close();
|
||||
SetError(ex.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -293,7 +299,7 @@ MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, co
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MusInfo *ZMusic_OpenCDSong (int track, int id)
|
||||
DLL_EXPORT MusInfo *ZMusic_OpenCDSong (int track, int id)
|
||||
{
|
||||
MusInfo *info = CD_OpenSong (track, id);
|
||||
|
||||
|
@ -301,6 +307,7 @@ MusInfo *ZMusic_OpenCDSong (int track, int id)
|
|||
{
|
||||
delete info;
|
||||
info = nullptr;
|
||||
SetError("Unable to open CD Audio");
|
||||
}
|
||||
|
||||
return info;
|
||||
|
@ -312,7 +319,7 @@ MusInfo *ZMusic_OpenCDSong (int track, int id)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ZMusic_FillStream(MusInfo* song, void* buff, int len)
|
||||
DLL_EXPORT bool ZMusic_FillStream(MusInfo* song, void* buff, int len)
|
||||
{
|
||||
if (song == nullptr) return false;
|
||||
std::lock_guard<std::mutex> lock(song->CritSec);
|
||||
|
@ -325,10 +332,19 @@ bool ZMusic_FillStream(MusInfo* song, void* buff, int len)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZMusic_Start(MusInfo *song, int subsong, bool loop)
|
||||
DLL_EXPORT bool ZMusic_Start(MusInfo *song, int subsong, bool loop)
|
||||
{
|
||||
if (!song) return;
|
||||
if (!song) return true; // Starting a null song is not an error! It just won't play anything.
|
||||
try
|
||||
{
|
||||
song->Play(loop, subsong);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception & ex)
|
||||
{
|
||||
SetError(ex.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -337,51 +353,51 @@ void ZMusic_Start(MusInfo *song, int subsong, bool loop)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZMusic_Pause(MusInfo *song)
|
||||
DLL_EXPORT void ZMusic_Pause(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Pause();
|
||||
}
|
||||
|
||||
void ZMusic_Resume(MusInfo *song)
|
||||
DLL_EXPORT void ZMusic_Resume(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Resume();
|
||||
}
|
||||
|
||||
void ZMusic_Update(MusInfo *song)
|
||||
DLL_EXPORT void ZMusic_Update(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
song->Update();
|
||||
}
|
||||
|
||||
bool ZMusic_IsPlaying(MusInfo *song)
|
||||
DLL_EXPORT bool ZMusic_IsPlaying(MusInfo *song)
|
||||
{
|
||||
if (!song) return false;
|
||||
return song->IsPlaying();
|
||||
}
|
||||
|
||||
void ZMusic_Stop(MusInfo *song)
|
||||
DLL_EXPORT void ZMusic_Stop(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
std::lock_guard<std::mutex> lock(song->CritSec);
|
||||
song->Stop();
|
||||
}
|
||||
|
||||
bool ZMusic_SetSubsong(MusInfo *song, int subsong)
|
||||
DLL_EXPORT bool ZMusic_SetSubsong(MusInfo *song, int subsong)
|
||||
{
|
||||
if (!song) return false;
|
||||
std::lock_guard<std::mutex> lock(song->CritSec);
|
||||
return song->SetSubsong(subsong);
|
||||
}
|
||||
|
||||
bool ZMusic_IsLooping(MusInfo *song)
|
||||
DLL_EXPORT bool ZMusic_IsLooping(MusInfo *song)
|
||||
{
|
||||
if (!song) return false;
|
||||
return song->m_Looping;
|
||||
}
|
||||
|
||||
bool ZMusic_IsMIDI(MusInfo *song)
|
||||
DLL_EXPORT bool ZMusic_IsMIDI(MusInfo *song)
|
||||
{
|
||||
if (!song) return false;
|
||||
return song->IsMIDI();
|
||||
|
@ -394,13 +410,13 @@ SoundStreamInfo ZMusic_GetStreamInfo(MusInfo *song)
|
|||
return song->GetStreamInfo();
|
||||
}
|
||||
|
||||
void ZMusic_Close(MusInfo *song)
|
||||
DLL_EXPORT void ZMusic_Close(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
delete song;
|
||||
}
|
||||
|
||||
void ZMusic_VolumeChanged(MusInfo *song)
|
||||
DLL_EXPORT void ZMusic_VolumeChanged(MusInfo *song)
|
||||
{
|
||||
if (!song) return;
|
||||
std::lock_guard<std::mutex> lock(song->CritSec);
|
||||
|
@ -413,3 +429,28 @@ std::string ZMusic_GetStats(MusInfo *song)
|
|||
std::lock_guard<std::mutex> lock(song->CritSec);
|
||||
return song->GetStats();
|
||||
}
|
||||
|
||||
static std::string staticErrorMessage;
|
||||
void SetError(const char* msg)
|
||||
{
|
||||
staticErrorMessage = msg;
|
||||
}
|
||||
|
||||
DLL_EXPORT const char* ZMusic_GetLastError()
|
||||
{
|
||||
return staticErrorMessage.c_str();
|
||||
}
|
||||
|
||||
DLL_EXPORT bool ZMusic_WriteSMF(MIDISource* source, const char *fn, int looplimit)
|
||||
{
|
||||
std::vector<uint8_t> midi;
|
||||
bool success;
|
||||
|
||||
if (!source) return false;
|
||||
source->CreateSMF(midi, 1);
|
||||
auto f = MusicIO::utf8_fopen(fn, "wt");
|
||||
if (f == nullptr) return false;
|
||||
success = (fwrite(&midi[0], 1, midi.size(), f) == midi.size());
|
||||
delete f;
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -140,42 +140,63 @@ struct Callbacks
|
|||
|
||||
};
|
||||
|
||||
// Sets callbacks for functionality that the client needs to provide.
|
||||
void ZMusic_SetCallbacks(const Callbacks *callbacks);
|
||||
// Sets GenMidi data for OPL playback. If this isn't provided the OPL synth will not work.
|
||||
void ZMusic_SetGenMidi(const uint8_t* data);
|
||||
// Set default bank for OPN. Without this OPN only works with custom banks.
|
||||
void ZMusic_SetWgOpn(const void* data, unsigned len);
|
||||
// Set DMXGUS data for running the GUS synth in actual GUS mode.
|
||||
void ZMusic_SetDmxGus(const void* data, unsigned len);
|
||||
|
||||
// These exports are needed by the MIDI dumpers which need to remain on the client side.
|
||||
class MIDISource; // abstract for the client
|
||||
#ifndef ZMUSIC_INTERNAL
|
||||
#define DLL_IMPORT // _declspec(dllimport)
|
||||
typedef struct { int zm1; } *ZMusic_MidiSource;
|
||||
typedef struct { int zm2; } *ZMusic_MusicStream;
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
DLL_IMPORT const char* ZMusic_GetLastError();
|
||||
|
||||
// Sets callbacks for functionality that the client needs to provide.
|
||||
DLL_IMPORT void ZMusic_SetCallbacks(const Callbacks* callbacks);
|
||||
// Sets GenMidi data for OPL playback. If this isn't provided the OPL synth will not work.
|
||||
DLL_IMPORT void ZMusic_SetGenMidi(const uint8_t* data);
|
||||
// Set default bank for OPN. Without this OPN only works with custom banks.
|
||||
DLL_IMPORT void ZMusic_SetWgOpn(const void* data, unsigned len);
|
||||
// Set DMXGUS data for running the GUS synth in actual GUS mode.
|
||||
DLL_IMPORT void ZMusic_SetDmxGus(const void* data, unsigned len);
|
||||
|
||||
// These exports are needed by the MIDI dumpers which need to remain on the client side because the need access to the client's file system.
|
||||
DLL_IMPORT EMIDIType ZMusic_IdentifyMIDIType(uint32_t* id, int size);
|
||||
DLL_IMPORT ZMusic_MidiSource ZMusic_CreateMIDISource(const uint8_t* data, size_t length, EMIDIType miditype);
|
||||
DLL_IMPORT bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
|
||||
|
||||
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(MusicIO::FileInterface* reader, EMidiDevice device, const char* Args);
|
||||
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid = 0);
|
||||
|
||||
DLL_IMPORT bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len);
|
||||
DLL_IMPORT bool ZMusic_Start(ZMusic_MusicStream song, int subsong, bool loop);
|
||||
DLL_IMPORT void ZMusic_Pause(ZMusic_MusicStream song);
|
||||
DLL_IMPORT void ZMusic_Resume(ZMusic_MusicStream song);
|
||||
DLL_IMPORT void ZMusic_Update(ZMusic_MusicStream song);
|
||||
DLL_IMPORT bool ZMusic_IsPlaying(ZMusic_MusicStream song);
|
||||
DLL_IMPORT void ZMusic_Stop(ZMusic_MusicStream song);
|
||||
DLL_IMPORT void ZMusic_Close(ZMusic_MusicStream song);
|
||||
DLL_IMPORT bool ZMusic_SetSubsong(ZMusic_MusicStream song, int subsong);
|
||||
DLL_IMPORT bool ZMusic_IsLooping(ZMusic_MusicStream song);
|
||||
DLL_IMPORT bool ZMusic_IsMIDI(ZMusic_MusicStream song);
|
||||
DLL_IMPORT void ZMusic_VolumeChanged(ZMusic_MusicStream song);
|
||||
DLL_IMPORT bool ZMusic_WriteSMF(ZMusic_MidiSource source, const char* fn, int looplimit);
|
||||
SoundStreamInfo ZMusic_GetStreamInfo(ZMusic_MusicStream 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.
|
||||
}
|
||||
|
||||
class MusInfo;
|
||||
EMIDIType IdentifyMIDIType(uint32_t *id, int size);
|
||||
MIDISource *CreateMIDISource(const uint8_t *data, size_t length, EMIDIType miditype);
|
||||
void MIDIDumpWave(MIDISource* source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
|
||||
|
||||
MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, const char *Args);
|
||||
MusInfo *ZMusic_OpenCDSong (int track, int cdid = 0);
|
||||
|
||||
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);
|
||||
bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, MusInfo* song, float value, float *pRealValue = nullptr);
|
||||
bool ChangeMusicSetting(ZMusic::EStringConfigKey key, MusInfo* song, const char *value);
|
||||
#if 0
|
||||
std::string ZMusic_GetStats(ZMusic_MusicStream song);
|
||||
bool ChangeMusicSetting(ZMusic::EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue = nullptr);
|
||||
bool ChangeMusicSetting(ZMusic::EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue = nullptr);
|
||||
bool ChangeMusicSetting(ZMusic::EStringConfigKey key, ZMusic_MusicStream song, const char* value);
|
||||
#else
|
||||
// Cannot be done yet.
|
||||
std::string ZMusic_GetStats(MusInfo* song);
|
||||
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);
|
||||
#endif
|
11
libraries/zmusic/zmusic/zmusic_internal.h
Normal file
11
libraries/zmusic/zmusic/zmusic_internal.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#define ZMUSIC_INTERNAL
|
||||
|
||||
#define DLL_EXPORT // __declspec(dllexport)
|
||||
#define DLL_IMPORT
|
||||
typedef class MIDISource *ZMusic_MidiSource;
|
||||
typedef class MusInfo *ZMusic_MusicStream;
|
||||
|
||||
#include "zmusic.h"
|
||||
|
||||
void SetError(const char *text);
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError());
|
||||
}
|
||||
S_CreateStream();
|
||||
}
|
||||
catch (const std::runtime_error& err)
|
||||
{
|
||||
Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), err.what());
|
||||
}
|
||||
|
||||
}
|
||||
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.
|
||||
|
@ -503,15 +507,12 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
|||
mus_playing.handle = handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
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)
|
||||
if (mus_playing.handle == nullptr)
|
||||
{
|
||||
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);
|
||||
Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError());
|
||||
return false;
|
||||
}
|
||||
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());
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue