diff --git a/libraries/music_common/fileio.h b/libraries/music_common/fileio.h index 550c2e57a..aa7b5dadd 100644 --- a/libraries/music_common/fileio.h +++ b/libraries/music_common/fileio.h @@ -379,6 +379,7 @@ public: } }; - +MusicIO::SoundFontReaderInterface* ClientOpenSoundFont(const char* name, int type); } + diff --git a/libraries/zmusic/mididevices/music_timidity_mididevice.cpp b/libraries/zmusic/mididevices/music_timidity_mididevice.cpp index b460a74a8..0847d8a0f 100644 --- a/libraries/zmusic/mididevices/music_timidity_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_timidity_mididevice.cpp @@ -267,14 +267,20 @@ bool GUS_SetupConfig(const char* args) if (*args == 0) args = gusConfig.gus_config.c_str(); if (stricmp(gusConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded - MusicIO::SoundFontReaderInterface *reader = nullptr; - if (musicCallbacks.OpenSoundFont) + MusicIO::SoundFontReaderInterface* reader = MusicIO::ClientOpenSoundFont(args, SF_GUS | SF_SF2); + if (!reader && MusicIO::fileExists(args)) { - reader = musicCallbacks.OpenSoundFont(args, SF_GUS | SF_SF2); - } - else if (MusicIO::fileExists(args)) - { - reader = new MusicIO::FileSystemSoundFontReader(args, true); + auto f = MusicIO::utf8_fopen(args, "rb"); + if (f) + { + char test[12] = {}; + fread(test, 1, 12, f); + fclose(f); + // If the passed file is an SF2 sound font we need to use the special reader that fakes a config for it. + if (memcmp(test, "RIFF", 4) == 0 && memcmp(test + 8, "sfbk", 4) == 0) + reader = new MusicIO::SF2Reader(args); + } + if (!reader) reader = new MusicIO::FileSystemSoundFontReader(args, true); } if (reader == nullptr) diff --git a/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp b/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp index 57f45df71..f5f66c3ea 100644 --- a/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_timiditypp_mididevice.cpp @@ -198,14 +198,20 @@ bool Timidity_SetupConfig(const char* args) if (*args == 0) args = timidityConfig.timidity_config.c_str(); if (stricmp(timidityConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded - MusicIO::SoundFontReaderInterface* reader = nullptr; - if (musicCallbacks.OpenSoundFont) + MusicIO::SoundFontReaderInterface* reader = MusicIO::ClientOpenSoundFont(args, SF_GUS | SF_SF2); + if (!reader && MusicIO::fileExists(args)) { - reader = musicCallbacks.OpenSoundFont(args, SF_GUS | SF_SF2); - } - else if (MusicIO::fileExists(args)) - { - reader = new MusicIO::FileSystemSoundFontReader(args, true); + auto f = MusicIO::utf8_fopen(args, "rb"); + if (f) + { + char test[12] = {}; + fread(test, 1, 12, f); + fclose(f); + // If the passed file is an SF2 sound font we need to use the special reader that fakes a config for it. + if (memcmp(test, "RIFF", 4) == 0 && memcmp(test + 8, "sfbk", 4) == 0) + reader = new MusicIO::SF2Reader(args); + } + if (!reader) reader = new MusicIO::FileSystemSoundFontReader(args, true); } if (reader == nullptr) diff --git a/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp b/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp index 1bdd7e738..5af0806ee 100644 --- a/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp +++ b/libraries/zmusic/mididevices/music_wildmidi_mididevice.cpp @@ -244,12 +244,8 @@ bool WildMidi_SetupConfig(const char* args) if (*args == 0) args = wildMidiConfig.config.c_str(); if (stricmp(wildMidiConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded - MusicIO::SoundFontReaderInterface* reader = nullptr; - if (musicCallbacks.OpenSoundFont) - { - reader = musicCallbacks.OpenSoundFont(args, SF_GUS); - } - else if (MusicIO::fileExists(args)) + MusicIO::SoundFontReaderInterface* reader = MusicIO::ClientOpenSoundFont(args, SF_GUS); + if (!reader && MusicIO::fileExists(args)) { reader = new MusicIO::FileSystemSoundFontReader(args, true); } diff --git a/libraries/zmusic/midisources/midisource_hmi.cpp b/libraries/zmusic/midisources/midisource_hmi.cpp index 96fba013e..791954eda 100644 --- a/libraries/zmusic/midisources/midisource_hmi.cpp +++ b/libraries/zmusic/midisources/midisource_hmi.cpp @@ -37,6 +37,7 @@ #include #include #include "midisource.h" +#include "zmusic/zmusic_internal.h" #include "zmusic/m_swap.h" // MACROS ------------------------------------------------------------------ diff --git a/libraries/zmusic/midisources/midisource_smf.cpp b/libraries/zmusic/midisources/midisource_smf.cpp index 0d9f47699..8d223ec60 100644 --- a/libraries/zmusic/midisources/midisource_smf.cpp +++ b/libraries/zmusic/midisources/midisource_smf.cpp @@ -38,6 +38,7 @@ // HEADER FILES ------------------------------------------------------------ #include "midisource.h" +#include "zmusic/zmusic_internal.h" // MACROS ------------------------------------------------------------------ diff --git a/libraries/zmusic/musicformats/music_cd.cpp b/libraries/zmusic/musicformats/music_cd.cpp index 4ddd44c8a..d494c9174 100644 --- a/libraries/zmusic/musicformats/music_cd.cpp +++ b/libraries/zmusic/musicformats/music_cd.cpp @@ -31,7 +31,7 @@ ** */ -#include "zmusic/zmusic.h" +#include "zmusic/zmusic_internal.h" #include "zmusic/musinfo.h" #ifdef _WIN32 diff --git a/libraries/zmusic/musicformats/music_stream.cpp b/libraries/zmusic/musicformats/music_stream.cpp index db59cd604..19807435d 100644 --- a/libraries/zmusic/musicformats/music_stream.cpp +++ b/libraries/zmusic/musicformats/music_stream.cpp @@ -33,6 +33,7 @@ */ #include "zmusic/musinfo.h" +#include "zmusic/zmusic_internal.h" #include "streamsources/streamsource.h" class StreamSong : public MusInfo diff --git a/libraries/zmusic/zmusic/configuration.cpp b/libraries/zmusic/zmusic/configuration.cpp index e093baf80..e95852550 100644 --- a/libraries/zmusic/zmusic/configuration.cpp +++ b/libraries/zmusic/zmusic/configuration.cpp @@ -54,9 +54,56 @@ struct Dummy MiscConfig miscConfig; Callbacks musicCallbacks; +class SoundFontWrapperInterface : public MusicIO::SoundFontReaderInterface +{ + void* handle; + +public: + SoundFontWrapperInterface(void* h) + { + handle = h; + } + + struct MusicIO::FileInterface* open_file(const char* fn) override + { + auto rd = musicCallbacks.SF_OpenFile(handle, fn); + if (rd) + { + auto fr = new CustomFileReader(rd); + if (fr) fr->filename = fn? fn : "timidity.cfg"; + return fr; + } + else return nullptr; + } + void add_search_path(const char* path) override + { + musicCallbacks.SF_AddToSearchPath(handle, path); + } + void close() override + { + musicCallbacks.SF_Close(handle); + delete this; + } +}; + +namespace MusicIO { + SoundFontReaderInterface* ClientOpenSoundFont(const char* name, int type) + { + if (!musicCallbacks.OpenSoundFont) return nullptr; + auto iface = musicCallbacks.OpenSoundFont(name, type); + if (!iface) return nullptr; + return new SoundFontWrapperInterface(iface); + } +} + + DLL_EXPORT void ZMusic_SetCallbacks(const Callbacks* cb) { musicCallbacks = *cb; + // If not all these are set the sound font interface is not usable. + if (!cb->SF_AddToSearchPath || !cb->SF_OpenFile || !cb->SF_Close) + musicCallbacks.OpenSoundFont = nullptr; + } DLL_EXPORT void ZMusic_SetGenMidi(const uint8_t* data) diff --git a/libraries/zmusic/zmusic/mididefs.h b/libraries/zmusic/zmusic/mididefs.h index 29cfcb5a5..29cda0d20 100644 --- a/libraries/zmusic/zmusic/mididefs.h +++ b/libraries/zmusic/zmusic/mididefs.h @@ -10,29 +10,6 @@ enum inline constexpr uint8_t MEVENT_EVENTTYPE(uint32_t x) { return ((uint8_t)((x) >> 24)); } inline constexpr uint32_t MEVENT_EVENTPARM(uint32_t x) { return ((x) & 0xffffff); } -// These constants must match the corresponding values of the Windows headers -// to avoid readjustment in the native Windows device's playback functions -// and should not be changed. -enum EMidiDeviceClass -{ - MIDIDEV_MIDIPORT = 1, - MIDIDEV_SYNTH, - MIDIDEV_SQSYNTH, - MIDIDEV_FMSYNTH, - MIDIDEV_MAPPER, - MIDIDEV_WAVETABLE, - MIDIDEV_SWSYNTH -}; - -enum EMIDIType -{ - MIDI_NOTMIDI, - MIDI_MIDI, - MIDI_HMI, - MIDI_XMI, - MIDI_MUS -}; - enum EMidiEvent : uint8_t { MEVENT_TEMPO = 1, @@ -40,38 +17,6 @@ enum EMidiEvent : uint8_t MEVENT_LONGMSG = 128, }; -enum EMidiDevice -{ - MDEV_DEFAULT = -1, - MDEV_MMAPI = 0, - MDEV_OPL = 1, - MDEV_SNDSYS = 2, - MDEV_TIMIDITY = 3, - MDEV_FLUIDSYNTH = 4, - MDEV_GUS = 5, - MDEV_WILDMIDI = 6, - MDEV_ADL = 7, - MDEV_OPN = 8, - - MDEV_COUNT -}; - -enum ESoundFontTypes -{ - SF_SF2 = 1, - SF_GUS = 2, - SF_WOPL = 4, - SF_WOPN = 8 -}; - - -struct SoundStreamInfo -{ - int mBufferSize; // If mBufferSize is 0, the song doesn't use streaming but plays through a different interface. - int mSampleRate; - int mNumChannels; // If mNumChannels is negative, 16 bit integer format is used instead of floating point. -}; - #ifndef MAKE_ID #ifndef __BIG_ENDIAN__ #define MAKE_ID(a,b,c,d) ((uint32_t)((a)|((b)<<8)|((c)<<16)|((d)<<24))) diff --git a/libraries/zmusic/zmusic/musinfo.h b/libraries/zmusic/zmusic/musinfo.h index 3b934aab4..c892d0141 100644 --- a/libraries/zmusic/zmusic/musinfo.h +++ b/libraries/zmusic/zmusic/musinfo.h @@ -3,6 +3,7 @@ #include #include #include "mididefs.h" +#include "zmusic/zmusic_internal.h" // The base music class. Everything is derived from this -------------------- diff --git a/libraries/zmusic/zmusic/zmusic.cpp b/libraries/zmusic/zmusic/zmusic.cpp index efb5b67b3..2394b1013 100644 --- a/libraries/zmusic/zmusic/zmusic.cpp +++ b/libraries/zmusic/zmusic/zmusic.cpp @@ -319,23 +319,6 @@ DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void* mem, size_t size, E return ZMusic_OpenSongInternal(mr, device, Args); } -struct CustomFileReader : public MusicIO::FileInterface -{ - ZMusicCustomReader* cr; - - CustomFileReader(ZMusicCustomReader* zr) : cr(zr) {} - virtual char* gets(char* buff, int n) { return cr->gets(cr, buff, n); } - virtual long read(void* buff, int32_t size) { return cr->read(cr, buff, size); } - virtual long seek(long offset, int whence) { return cr->seek(cr, offset, whence); } - virtual long tell() { return cr->tell(cr); } - virtual void close() - { - cr->close(cr); - delete this; - } - -}; - DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EMidiDevice device, const char* Args) { if (!reader) diff --git a/libraries/zmusic/zmusic/zmusic.h b/libraries/zmusic/zmusic/zmusic.h index 35a978bcf..9dcedbd53 100644 --- a/libraries/zmusic/zmusic/zmusic.h +++ b/libraries/zmusic/zmusic/zmusic.h @@ -1,7 +1,61 @@ #pragma once -#include "mididefs.h" -#include "../../music_common/fileio.h" +#include +#include + +// These constants must match the corresponding values of the Windows headers +// to avoid readjustment in the native Windows device's playback functions +// and should not be changed. +enum EMidiDeviceClass +{ + MIDIDEV_MIDIPORT = 1, + MIDIDEV_SYNTH, + MIDIDEV_SQSYNTH, + MIDIDEV_FMSYNTH, + MIDIDEV_MAPPER, + MIDIDEV_WAVETABLE, + MIDIDEV_SWSYNTH +}; + +enum EMIDIType +{ + MIDI_NOTMIDI, + MIDI_MIDI, + MIDI_HMI, + MIDI_XMI, + MIDI_MUS +}; + +enum EMidiDevice +{ + MDEV_DEFAULT = -1, + MDEV_MMAPI = 0, + MDEV_OPL = 1, + MDEV_SNDSYS = 2, + MDEV_TIMIDITY = 3, + MDEV_FLUIDSYNTH = 4, + MDEV_GUS = 5, + MDEV_WILDMIDI = 6, + MDEV_ADL = 7, + MDEV_OPN = 8, + + MDEV_COUNT +}; + +enum ESoundFontTypes +{ + SF_SF2 = 1, + SF_GUS = 2, + SF_WOPL = 4, + SF_WOPN = 8 +}; + +struct SoundStreamInfo +{ + int mBufferSize; // If mBufferSize is 0, the song doesn't use streaming but plays through a different interface. + int mSampleRate; + int mNumChannels; // If mNumChannels is negative, 16 bit integer format is used instead of floating point. +}; enum EIntConfigKey { @@ -111,34 +165,51 @@ enum EStringConfigKey NUM_STRING_CONFIGS }; + +struct ZMusicCustomReader +{ + void* handle; + char* (*gets)(struct ZMusicCustomReader* handle, char* buff, int n); + long (*read)(struct ZMusicCustomReader* handle, void* buff, int32_t size); + long (*seek)(struct ZMusicCustomReader* handle, long offset, int whence); + long (*tell)(struct ZMusicCustomReader* handle); + void (*close)(struct ZMusicCustomReader* handle); +}; + struct Callbacks { // Callbacks the client can install to capture messages from the backends // or to provide sound font data. // The message callbacks are optional, without them the output goes to stdout. - void (*WildMidi_MessageFunc)(const char* wmfmt, va_list args) = nullptr; - void (*GUS_MessageFunc)(int type, int verbosity_level, const char* fmt, ...) = nullptr; - void (*Timidity_Messagefunc)(int type, int verbosity_level, const char* fmt, ...) = nullptr; - int (*Fluid_MessageFunc)(const char *fmt, ...) = nullptr; - - // The sound font callbacks are for allowing the client to customize sound font management - // Without them only paths to real files can be used. - const char *(*PathForSoundfont)(const char *name, int type) = nullptr; - MusicIO::SoundFontReaderInterface *(*OpenSoundFont)(const char* name, int type) = nullptr; - - // Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion. - const char *(*NicePath)(const char* path) = nullptr; -}; + void (*WildMidi_MessageFunc)(const char* wmfmt, va_list args); + void (*GUS_MessageFunc)(int type, int verbosity_level, const char* fmt, ...); + void (*Timidity_Messagefunc)(int type, int verbosity_level, const char* fmt, ...); + int (*Fluid_MessageFunc)(const char *fmt, ...); -struct ZMusicCustomReader -{ - void* handle; - char* (*gets)(ZMusicCustomReader*handle, char* buff, int n); - long (*read)(ZMusicCustomReader* handle, void* buff, int32_t size); - long (*seek)(ZMusicCustomReader* handle, long offset, int whence); - long (*tell)(ZMusicCustomReader* handle); - void (*close)(ZMusicCustomReader* handle); + // Retrieves the path to a soundfont identified by an identifier. Only needed if the client virtualizes the sound font names + const char *(*PathForSoundfont)(const char *name, int type); + + // The sound font callbacks are for allowing the client to customize sound font management and they are optional. + // They only need to be defined if the client virtualizes the sound font management and doesn't pass real paths to the music code. + // Without them only paths to real files can be used. If one of these gets set, all must be set. + + // This opens a sound font. Must return a handle with which the sound font's content can be read. + void *(*OpenSoundFont)(const char* name, int type); + + // Opens a file in the sound font. For GUS patch sets this will try to open each patch with this function. + // For other formats only the sound font's actual name can be requested. + // When passed NULL this must open the Timidity config file, if this is requested for an SF2 sound font it should be synthesized. + struct ZMusicCustomReader* (*SF_OpenFile)(void* handle, const char* fn); + + //Adds a path to the list of directories in which files must be looked for. + void (*SF_AddToSearchPath)(void* handle, const char* path); + + // Closes the sound font reader. + void (*SF_Close)(void* handle); + + // Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion. + const char *(*NicePath)(const char* path); }; @@ -168,7 +239,7 @@ extern "C" 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(ZMusicCustomReader* reader, EMidiDevice device, const char* Args); + DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(struct ZMusicCustomReader* reader, EMidiDevice device, const char* Args); DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char *filename, EMidiDevice device, const char* Args); DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void *mem, size_t size, EMidiDevice device, const char* Args); DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid = 0); diff --git a/libraries/zmusic/zmusic/zmusic_internal.h b/libraries/zmusic/zmusic/zmusic_internal.h index 5b7838239..8a73d2ac4 100644 --- a/libraries/zmusic/zmusic/zmusic_internal.h +++ b/libraries/zmusic/zmusic/zmusic_internal.h @@ -7,5 +7,24 @@ typedef class MIDISource *ZMusic_MidiSource; typedef class MusInfo *ZMusic_MusicStream; #include "zmusic.h" +#include "../../music_common/fileio.h" void SetError(const char *text); + +struct CustomFileReader : public MusicIO::FileInterface +{ + ZMusicCustomReader* cr; + + CustomFileReader(ZMusicCustomReader* zr) : cr(zr) {} + virtual char* gets(char* buff, int n) { return cr->gets(cr, buff, n); } + virtual long read(void* buff, int32_t size) { return cr->read(cr, buff, size); } + virtual long seek(long offset, int whence) { return cr->seek(cr, offset, whence); } + virtual long tell() { return cr->tell(cr); } + virtual void close() + { + cr->close(cr); + delete this; + } + +}; + diff --git a/src/sound/backend/i_soundinternal.h b/src/sound/backend/i_soundinternal.h index 823f672b7..da932e223 100644 --- a/src/sound/backend/i_soundinternal.h +++ b/src/sound/backend/i_soundinternal.h @@ -7,7 +7,6 @@ #include "vectors.h" #include "tarray.h" #include "zmusic/sounddecoder.h" -#include "../../libraries/music_common/fileio.h" #include "tflags.h" enum EChanFlag diff --git a/src/sound/music/i_music.cpp b/src/sound/music/i_music.cpp index 9045e9994..4344fa6d0 100644 --- a/src/sound/music/i_music.cpp +++ b/src/sound/music/i_music.cpp @@ -193,11 +193,26 @@ static const char* mus_pathToSoundFont(const char* sfname, int type) return info ? info->mFilename.GetChars() : nullptr; } -static MusicIO::SoundFontReaderInterface* mus_openSoundFont(const char* sfname, int type) +static void* mus_openSoundFont(const char* sfname, int type) { return sfmanager.OpenSoundFont(sfname, type); } +static ZMusicCustomReader* mus_sfopenfile(void* handle, const char* fn) +{ + return reinterpret_cast(handle)->open_interface(fn); +} + +static void mus_sfaddpath(void *handle, const char* path) +{ + reinterpret_cast(handle)->AddPath(path); +} + +static void mus_sfclose(void* handle) +{ + reinterpret_cast(handle)->close(); +} + //========================================================================== // @@ -266,7 +281,7 @@ void I_InitMusic (void) #endif // _WIN32 snd_mididevice.Callback(); - Callbacks callbacks; + Callbacks callbacks{}; callbacks.Fluid_MessageFunc = Printf; callbacks.GUS_MessageFunc = callbacks.Timidity_Messagefunc = tim_printfunc; @@ -274,6 +289,9 @@ void I_InitMusic (void) callbacks.NicePath = mus_NicePath; callbacks.PathForSoundfont = mus_pathToSoundFont; callbacks.OpenSoundFont = mus_openSoundFont; + callbacks.SF_OpenFile = mus_sfopenfile; + callbacks.SF_AddToSearchPath = mus_sfaddpath; + callbacks.SF_Close = mus_sfclose; ZMusic_SetCallbacks(&callbacks); SetupGenMidi(); diff --git a/src/sound/music/i_soundfont.cpp b/src/sound/music/i_soundfont.cpp index f14e53842..f55ee208c 100644 --- a/src/sound/music/i_soundfont.cpp +++ b/src/sound/music/i_soundfont.cpp @@ -135,30 +135,17 @@ FileReader FSoundFontReader::Open(const char *name, std::string& filename) // //========================================================================== -MusicIO::FileInterface* FSoundFontReader::open_interface(const char* name) +ZMusicCustomReader* FSoundFontReader::open_interface(const char* name) { std::string filename; FileReader fr = Open(name, filename); if (!fr.isOpen()) return nullptr; - auto fri = new FileReaderMusicInterface(fr); - fri->filename = std::move(filename); + auto fri = GetMusicReader(fr); return fri; } -//========================================================================== -// -// The file interface for the backend -// -//========================================================================== - -struct MusicIO::FileInterface* FSoundFontReader::open_file(const char* name) -{ - return open_interface(name); -} - - //========================================================================== // // Note that the file type has already been checked diff --git a/src/sound/music/i_soundfont.h b/src/sound/music/i_soundfont.h index 76e20d1b1..c2955620c 100644 --- a/src/sound/music/i_soundfont.h +++ b/src/sound/music/i_soundfont.h @@ -19,8 +19,7 @@ struct FSoundFontInfo // //========================================================================== -class FSoundFontReader : public MusicIO::SoundFontReaderInterface -// Yes, it's 3 copies of essentially the same interface, but since we want to keep the 3 renderers as isolated modules we have to pull in their own implementations here. +class FSoundFontReader { protected: // This is only doable for loose config files that get set as sound fonts. All other cases read from a contained environment where this does not apply. @@ -52,15 +51,12 @@ public: } virtual FileReader Open(const char* name, std::string &filename); + virtual void close() + { + delete this; + } - // Timidity++ interface - struct MusicIO::FileInterface* open_file(const char* name) override; - void add_search_path(const char* name) override - { - return AddPath(name); - } - - MusicIO::FileInterface* open_interface(const char* name); + ZMusicCustomReader* open_interface(const char* name); }; diff --git a/src/utility/filereadermusicinterface.h b/src/utility/filereadermusicinterface.h index 095f8528a..cde43f88e 100644 --- a/src/utility/filereadermusicinterface.h +++ b/src/utility/filereadermusicinterface.h @@ -1,45 +1,9 @@ #pragma once -#include "../libraries/music_common/fileio.h" #include "zmusic/zmusic.h" #include "files.h" -struct FileReaderMusicInterface : public MusicIO::FileInterface -{ - FileReader fr; - - FileReaderMusicInterface(FileReader& fr_in) - { - fr = std::move(fr_in); - } - char* gets(char* buff, int n) override - { - if (!fr.isOpen()) return nullptr; - return fr.Gets(buff, n); - } - long read(void* buff, int32_t size) override - { - if (!fr.isOpen()) return 0; - return (long)fr.Read(buff, size); - } - long seek(long offset, int whence) override - { - if (!fr.isOpen()) return 0; - return (long)fr.Seek(offset, (FileReader::ESeek)whence); - } - long tell() override - { - if (!fr.isOpen()) return 0; - return (long)fr.Tell(); - } - FileReader& getReader() - { - return fr; - } -}; - - inline ZMusicCustomReader *GetMusicReader(FileReader& fr) { auto zcr = new ZMusicCustomReader;