From 9b1ec8f995d5a8e9199806f82ba5608881193952 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 5 Nov 2021 19:01:16 -0700 Subject: [PATCH] Add a new ZMusic_GetStreamInfoEx function This provides cleaner info about the stream format --- include/zmusic.h | 11 +++++++++++ source/mididevices/mididevice.h | 2 ++ source/mididevices/music_base_mididevice.cpp | 11 +++++++++++ .../music_softsynth_mididevice.cpp | 19 ++++++++++++++++++- source/musicformats/music_midi.cpp | 7 +++++++ source/musicformats/music_stream.cpp | 1 + source/streamsources/music_dumb.cpp | 12 ++++++++++++ source/streamsources/music_gme.cpp | 6 ++++++ source/streamsources/music_libsndfile.cpp | 11 +++++++++++ source/streamsources/music_opl.cpp | 14 ++++++++++++++ source/streamsources/music_xa.cpp | 7 +++++++ source/streamsources/streamsource.h | 1 + source/zmusic/musinfo.h | 1 + source/zmusic/zmusic.cpp | 8 ++++++++ 14 files changed, 110 insertions(+), 1 deletion(-) diff --git a/include/zmusic.h b/include/zmusic.h index d3782c3..985b42b 100644 --- a/include/zmusic.h +++ b/include/zmusic.h @@ -77,6 +77,15 @@ typedef enum ChannelConfig_ ChannelConfig_Stereo } ChannelConfig; +typedef struct SoundStreamInfoEx_ +{ + int mBufferSize; // If mBufferSize is 0, the song doesn't use streaming but plays through a different interface. + int mSampleRate; + SampleType mSampleType; + ChannelConfig mChannelConfig; +} SoundStreamInfoEx; + + typedef enum EIntConfigKey_ { zmusic_adl_chips_count, @@ -320,6 +329,7 @@ extern "C" DLL_IMPORT void ZMusic_VolumeChanged(ZMusic_MusicStream song); DLL_IMPORT zmusic_bool ZMusic_WriteSMF(ZMusic_MidiSource source, const char* fn, int looplimit); DLL_IMPORT void ZMusic_GetStreamInfo(ZMusic_MusicStream song, SoundStreamInfo *info); + DLL_IMPORT void ZMusic_GetStreamInfoEx(ZMusic_MusicStream song, SoundStreamInfoEx *info); // 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. DLL_IMPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue); @@ -407,6 +417,7 @@ typedef zmusic_bool (*pfn_ZMusic_IsMIDI)(ZMusic_MusicStream song); typedef void (*pfn_ZMusic_VolumeChanged)(ZMusic_MusicStream song); typedef zmusic_bool (*pfn_ZMusic_WriteSMF)(ZMusic_MidiSource source, const char* fn, int looplimit); typedef void (*pfn_ZMusic_GetStreamInfo)(ZMusic_MusicStream song, SoundStreamInfo *info); +typedef void (*pfn_ZMusic_GetStreamInfoEx)(ZMusic_MusicStream song, SoundStreamInfoEx *info); typedef zmusic_bool (*pfn_ChangeMusicSettingInt)(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue); typedef zmusic_bool (*pfn_ChangeMusicSettingFloat)(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue); typedef zmusic_bool (*pfn_ChangeMusicSettingString)(EStringConfigKey key, ZMusic_MusicStream song, const char* value); diff --git a/source/mididevices/mididevice.h b/source/mididevices/mididevice.h index 128d710..9bb53bd 100644 --- a/source/mididevices/mididevice.h +++ b/source/mididevices/mididevice.h @@ -52,6 +52,7 @@ public: virtual int GetDeviceType() const { return MDEV_DEFAULT; } virtual bool CanHandleSysex() const { return true; } virtual SoundStreamInfo GetStreamInfo() const; + virtual SoundStreamInfoEx GetStreamInfoEx() const; protected: MidiCallback Callback; @@ -82,6 +83,7 @@ public: virtual bool ServiceStream(void* buff, int numbytes); int GetSampleRate() const { return SampleRate; } SoundStreamInfo GetStreamInfo() const override; + SoundStreamInfoEx GetStreamInfoEx() const override; protected: double Tempo; diff --git a/source/mididevices/music_base_mididevice.cpp b/source/mididevices/music_base_mididevice.cpp index fa6f9df..389d51c 100644 --- a/source/mididevices/music_base_mididevice.cpp +++ b/source/mididevices/music_base_mididevice.cpp @@ -180,3 +180,14 @@ SoundStreamInfo MIDIDevice::GetStreamInfo() const { return { 0, 0, 0 }; // i.e. do not use streaming. } + +//========================================================================== +// +// MIDIDevice :: GetStreamInfoEx +// +//========================================================================== + +SoundStreamInfoEx MIDIDevice::GetStreamInfoEx() const +{ + return {}; // i.e. do not use streaming. +} diff --git a/source/mididevices/music_softsynth_mididevice.cpp b/source/mididevices/music_softsynth_mididevice.cpp index 8b7ea1f..169d952 100644 --- a/source/mididevices/music_softsynth_mididevice.cpp +++ b/source/mididevices/music_softsynth_mididevice.cpp @@ -88,7 +88,7 @@ SoftSynthMIDIDevice::~SoftSynthMIDIDevice() //========================================================================== // -// SoftSynthMIDIDevice :: GwrStreamInfo +// SoftSynthMIDIDevice :: GetStreamInfo // //========================================================================== @@ -102,6 +102,23 @@ SoundStreamInfo SoftSynthMIDIDevice::GetStreamInfo() const return { chunksize, SampleRate, isMono? 1:2 }; } +//========================================================================== +// +// SoftSynthMIDIDevice :: GetStreamInfoEx +// +//========================================================================== + +SoundStreamInfoEx SoftSynthMIDIDevice::GetStreamInfoEx() const +{ + int chunksize = (SampleRate / StreamBlockSize) * 4; + if (!isMono) + { + chunksize *= 2; + } + return { chunksize, SampleRate, SampleType_Float32, + isMono ? ChannelConfig_Mono : ChannelConfig_Stereo }; +} + //========================================================================== // // SoftSynthMIDIDevice :: Open diff --git a/source/musicformats/music_midi.cpp b/source/musicformats/music_midi.cpp index 039a56b..5a6231f 100644 --- a/source/musicformats/music_midi.cpp +++ b/source/musicformats/music_midi.cpp @@ -88,6 +88,7 @@ public: void SetMIDISource(MIDISource* _source); bool ServiceStream(void* buff, int len) override; SoundStreamInfo GetStreamInfo() const override; + SoundStreamInfoEx GetStreamInfoEx() const override; int GetDeviceType() const override; @@ -452,6 +453,12 @@ SoundStreamInfo MIDIStreamer::GetStreamInfo() const else return { 0, 0, 0 }; } +SoundStreamInfoEx MIDIStreamer::GetStreamInfoEx() const +{ + if (MIDI) return MIDI->GetStreamInfoEx(); + else return {}; +} + //========================================================================== // // MIDIStreamer :: StartPlayback diff --git a/source/musicformats/music_stream.cpp b/source/musicformats/music_stream.cpp index 7bb5c12..9bb9a11 100644 --- a/source/musicformats/music_stream.cpp +++ b/source/musicformats/music_stream.cpp @@ -55,6 +55,7 @@ public: void ChangeSettingString(const char *name, const char *value) override { if(m_Source) m_Source->ChangeSettingString(name, value); } bool ServiceStream(void* buff, int len) override; SoundStreamInfo GetStreamInfo() const override { return m_Source->GetFormat(); } + SoundStreamInfoEx GetStreamInfoEx() const override { return m_Source->GetFormatEx(); } protected: diff --git a/source/streamsources/music_dumb.cpp b/source/streamsources/music_dumb.cpp index 7e4f10a..a658dc2 100644 --- a/source/streamsources/music_dumb.cpp +++ b/source/streamsources/music_dumb.cpp @@ -65,6 +65,7 @@ public: bool SetSubsong(int subsong) override; bool Start() override; SoundStreamInfo GetFormat() override; + SoundStreamInfoEx GetFormatEx() override; void ChangeSettingNum(const char* setting, double val) override; std::string GetStats() override; @@ -1039,6 +1040,17 @@ SoundStreamInfo DumbSong::GetFormat() return { 32*1024, srate, 2 }; } +//========================================================================== +// +// DumbSong GetFormatEx +// +//========================================================================== + +SoundStreamInfoEx DumbSong::GetFormatEx() +{ + return { 32*1024, srate, SampleType_Float32, ChannelConfig_Stereo }; +} + //========================================================================== // // DumbSong :: Play diff --git a/source/streamsources/music_gme.cpp b/source/streamsources/music_gme.cpp index f44eb88..ca6e1bf 100644 --- a/source/streamsources/music_gme.cpp +++ b/source/streamsources/music_gme.cpp @@ -58,6 +58,7 @@ public: std::string GetStats() override; bool GetData(void *buffer, size_t len) override; SoundStreamInfo GetFormat() override; + SoundStreamInfoEx GetFormatEx() override; protected: Music_Emu *Emu; @@ -172,6 +173,11 @@ SoundStreamInfo GMESong::GetFormat() return { 32*1024, SampleRate, -2 }; } +SoundStreamInfoEx GMESong::GetFormatEx() +{ + return { 32*1024, SampleRate, SampleType_Int16, ChannelConfig_Stereo }; +} + //========================================================================== // // GMESong - Destructor diff --git a/source/streamsources/music_libsndfile.cpp b/source/streamsources/music_libsndfile.cpp index dea2b12..1f812ca 100644 --- a/source/streamsources/music_libsndfile.cpp +++ b/source/streamsources/music_libsndfile.cpp @@ -51,6 +51,7 @@ public: ~SndFileSong(); std::string GetStats() override; SoundStreamInfo GetFormat() override; + SoundStreamInfoEx GetFormatEx() override; bool GetData(void *buffer, size_t len) override; protected: @@ -455,6 +456,16 @@ SoundStreamInfo SndFileSong::GetFormat() return { 64/*snd_streambuffersize*/ * 1024, SampleRate, -Channels }; } +SoundStreamInfoEx SndFileSong::GetFormatEx() +{ + ChannelConfig chans; + SampleType stype; + int srate; + + Decoder->getInfo(&srate, &chans, &stype); + return { 64/*snd_streambuffersize*/ * 1024, srate, stype, chans }; +} + //========================================================================== // // SndFileSong - Destructor diff --git a/source/streamsources/music_opl.cpp b/source/streamsources/music_opl.cpp index 384c902..2a4b49b 100644 --- a/source/streamsources/music_opl.cpp +++ b/source/streamsources/music_opl.cpp @@ -55,6 +55,7 @@ public: bool Start() override; void ChangeSettingInt(const char *name, int value) override; SoundStreamInfo GetFormat() override; + SoundStreamInfoEx GetFormatEx() override; protected: bool GetData(void *buffer, size_t len) override; @@ -105,6 +106,19 @@ SoundStreamInfo OPLMUSSong::GetFormat() // //========================================================================== +SoundStreamInfoEx OPLMUSSong::GetFormatEx() +{ + int samples = int(OPL_SAMPLE_RATE / 14); + return { samples * 4, int(OPL_SAMPLE_RATE), SampleType_Float32, + current_opl_core == 0? ChannelConfig_Mono:ChannelConfig_Stereo }; +} + +//========================================================================== +// +// +// +//========================================================================== + OPLMUSSong::~OPLMUSSong () { if (Music != NULL) diff --git a/source/streamsources/music_xa.cpp b/source/streamsources/music_xa.cpp index befa91e..8b66e03 100644 --- a/source/streamsources/music_xa.cpp +++ b/source/streamsources/music_xa.cpp @@ -236,6 +236,7 @@ class XASong : public StreamSource public: XASong(MusicIO::FileInterface *readr); SoundStreamInfo GetFormat() override; + SoundStreamInfoEx GetFormatEx() override; bool Start() override; bool GetData(void *buffer, size_t len) override; @@ -266,6 +267,12 @@ SoundStreamInfo XASong::GetFormat() return { 64*1024, SampleRate, 2}; } +SoundStreamInfoEx XASong::GetFormatEx() +{ + auto SampleRate = xad.blockIs18K? 18900 : 37800; + return { 64*1024, SampleRate, SampleType_Float32, ChannelConfig_Stereo }; +} + //========================================================================== // // XASong :: Play diff --git a/source/streamsources/streamsource.h b/source/streamsources/streamsource.h index 48b1810..b41e307 100644 --- a/source/streamsources/streamsource.h +++ b/source/streamsources/streamsource.h @@ -22,6 +22,7 @@ public: virtual bool SetSubsong(int subsong) { return false; } virtual bool GetData(void *buffer, size_t len) = 0; virtual SoundStreamInfo GetFormat() { return {65536, m_OutputRate, 2 }; } // Default format is: System's output sample rate, 32 bit float, stereo + virtual SoundStreamInfoEx GetFormatEx() = 0; virtual std::string GetStats() { return ""; } virtual void ChangeSettingInt(const char *name, int value) { } virtual void ChangeSettingNum(const char *name, double value) { } diff --git a/source/zmusic/musinfo.h b/source/zmusic/musinfo.h index 99d8f38..1bda6b9 100644 --- a/source/zmusic/musinfo.h +++ b/source/zmusic/musinfo.h @@ -32,6 +32,7 @@ public: 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 }; } + virtual SoundStreamInfoEx GetStreamInfoEx() const = 0; enum EState { diff --git a/source/zmusic/zmusic.cpp b/source/zmusic/zmusic.cpp index c8a8553..1b76bab 100644 --- a/source/zmusic/zmusic.cpp +++ b/source/zmusic/zmusic.cpp @@ -460,6 +460,14 @@ DLL_EXPORT void ZMusic_GetStreamInfo(MusInfo *song, SoundStreamInfo *fmt) *fmt = song->GetStreamInfo(); } +DLL_EXPORT void ZMusic_GetStreamInfoEx(MusInfo *song, SoundStreamInfoEx *fmt) +{ + if (!fmt) return; + if (!song) *fmt = {}; + std::lock_guard lock(song->CritSec); + *fmt = song->GetStreamInfoEx(); +} + DLL_EXPORT void ZMusic_Close(MusInfo *song) { if (!song) return;