diff --git a/libraries/zmusic/midisources/midisource_xmi.cpp b/libraries/zmusic/midisources/midisource_xmi.cpp index bbb254f88..2e1e51214 100644 --- a/libraries/zmusic/midisources/midisource_xmi.cpp +++ b/libraries/zmusic/midisources/midisource_xmi.cpp @@ -35,6 +35,7 @@ // HEADER FILES ------------------------------------------------------------ #include "midisource.h" +#include "zmusic/mididefs.h" #include "zmusic/m_swap.h" // MACROS ------------------------------------------------------------------ @@ -51,14 +52,6 @@ return events; \ } -#ifndef MAKE_ID -#ifndef __BIG_ENDIAN__ -#define MAKE_ID(a,b,c,d) ((uint32_t)((a)|((b)<<8)|((c)<<16)|((d)<<24))) -#else -#define MAKE_ID(a,b,c,d) ((uint32_t)((d)|((c)<<8)|((b)<<16)|((a)<<24))) -#endif -#endif - // TYPES ------------------------------------------------------------------- struct LoopInfo diff --git a/libraries/zmusic/zmusic/midiconfig.h b/libraries/zmusic/zmusic/midiconfig.h index b49dbac0a..edb3d125f 100644 --- a/libraries/zmusic/zmusic/midiconfig.h +++ b/libraries/zmusic/zmusic/midiconfig.h @@ -126,3 +126,14 @@ struct WildMidiConfig }; +struct DumbConfig +{ + int mod_samplerate; + int mod_volramp; + int mod_interp; + bool mod_autochip; + int mod_autochip_size_force; + int mod_autochip_size_scan; + int mod_autochip_scan_threshold; + float mod_dumb_mastervolume; +}; diff --git a/libraries/zmusic/zmusic/mididefs.h b/libraries/zmusic/zmusic/mididefs.h index 97bdc8a76..67c4f1d09 100644 --- a/libraries/zmusic/zmusic/mididefs.h +++ b/libraries/zmusic/zmusic/mididefs.h @@ -53,3 +53,11 @@ struct SoundStreamInfo int mNumChannels; }; +#ifndef MAKE_ID +#ifndef __BIG_ENDIAN__ +#define MAKE_ID(a,b,c,d) ((uint32_t)((a)|((b)<<8)|((c)<<16)|((d)<<24))) +#else +#define MAKE_ID(a,b,c,d) ((uint32_t)((d)|((c)<<8)|((b)<<16)|((a)<<24))) +#endif +#endif + diff --git a/src/sound/backend/i_sound.h b/src/sound/backend/i_sound.h index f45a6f925..bc18f9cda 100644 --- a/src/sound/backend/i_sound.h +++ b/src/sound/backend/i_sound.h @@ -40,12 +40,6 @@ class FileReader; struct FSoundChan; -enum ECodecType -{ - CODEC_Unknown, - CODEC_Vorbis, -}; - enum EStartSoundFlags { SNDF_LOOP=1, @@ -55,6 +49,13 @@ enum EStartSoundFlags SNDF_NOREVERB=16, }; +enum ECodecType +{ + CODEC_Unknown, + CODEC_Vorbis, +}; + + class SoundStream { public: diff --git a/src/sound/music/i_music.cpp b/src/sound/music/i_music.cpp index 9abe79901..828fa7cf5 100644 --- a/src/sound/music/i_music.cpp +++ b/src/sound/music/i_music.cpp @@ -47,7 +47,9 @@ #include "stats.h" #include "vm.h" #include "s_music.h" +#include "i_soundfont.h" #include "../libraries/zmusic/midisources/midisource.h" +#include "../libraries/dumb/include/dumb.h" EXTERN_CVAR(Float, gme_stereodepth) @@ -88,6 +90,17 @@ int nomusic = 0; float relative_volume = 1.f; float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function +//========================================================================== +// +// dumb_decode_vorbis +// +//========================================================================== + +static short* dumb_decode_vorbis_(int outlen, const void* oggstream, int sizebytes) +{ + return GSnd->DecodeSample(outlen, oggstream, sizebytes, CODEC_Vorbis); +} + //========================================================================== // // CVAR snd_musicvolume @@ -140,6 +153,7 @@ void I_InitMusic (void) #endif // _WIN32 MusicDown = false; + dumb_decode_vorbis = dumb_decode_vorbis_; } @@ -457,15 +471,25 @@ MusInfo *I_RegisterSong (FileReader &reader, MidiDeviceSetting *device) // Check for module formats else { - streamsource = MOD_OpenSong(reader); + auto mreader = new FileReaderMusicInterface(reader); + Dumb_SetupConfig(&dumbConfig); + streamsource = MOD_OpenSong(mreader, &dumbConfig, (int)GSnd->GetOutputRate()); + delete mreader; } if (info == nullptr && streamsource == nullptr) { streamsource = SndFile_OpenSong(reader); } - if (streamsource) info = OpenStreamSong(streamsource); - + if (streamsource) + { + info = OpenStreamSong(streamsource); + if (!info) + { + // If this fails we have no more valid data - but it couldn't be a CDDA file anyway. + return nullptr; + } + } if (info == nullptr) { // Check for CDDA "format" diff --git a/src/sound/music/i_musicinterns.h b/src/sound/music/i_musicinterns.h index c0c36d3ec..2767e4092 100644 --- a/src/sound/music/i_musicinterns.h +++ b/src/sound/music/i_musicinterns.h @@ -26,11 +26,11 @@ extern OpnConfig opnConfig; extern GUSConfig gusConfig; extern TimidityConfig timidityConfig; extern WildMidiConfig wildMidiConfig; +extern DumbConfig dumbConfig; class MIDIStreamer; - // Base class for streaming MUS and MIDI files ------------------------------ class MIDIStreamer : public MusInfo @@ -108,34 +108,6 @@ protected: std::unique_ptr<SoundStream> Stream; }; -// Anything supported by the sound system out of the box -------------------- - -class StreamSource -{ -protected: - bool m_Looping = true; - int m_OutputRate; - -public: - - StreamSource (int outputRate) { m_OutputRate = outputRate; } - virtual ~StreamSource () {} - virtual void SetPlayMode(bool looping) { m_Looping = looping; } - virtual bool Start() { return true; } - virtual bool SetPosition(unsigned position) { return false; } - 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 FString GetStats() { return ""; } - virtual void ChangeSettingInt(const char *name, int value) { } - virtual void ChangeSettingNum(const char *name, double value) { } - virtual void ChangeSettingString(const char *name, const char *value) { } - -protected: - StreamSource() = default; -}; - - // CD track/disk played through the multimedia system ----------------------- class CDSong : public MusInfo @@ -174,10 +146,13 @@ void OPN_SetupConfig(OpnConfig *config, const char *Args); bool GUS_SetupConfig(GUSConfig *config, const char *args); bool Timidity_SetupConfig(TimidityConfig* config, const char* args); bool WildMidi_SetupConfig(WildMidiConfig* config, const char* args); +void Dumb_SetupConfig(DumbConfig* config); // Module played via foo_dumb ----------------------------------------------- -StreamSource *MOD_OpenSong(FileReader &reader); +class StreamSource; + +StreamSource *MOD_OpenSong(MusicIO::FileInterface* reader, DumbConfig* config, int samplerate); StreamSource *GME_OpenSong(FileReader &reader, const char *fmt, float depth); StreamSource *SndFile_OpenSong(FileReader &fr); StreamSource* XA_OpenSong(FileReader& reader); diff --git a/src/sound/music/midi_cvars.cpp b/src/sound/music/midi_cvars.cpp index d90765085..8aafe9fee 100644 --- a/src/sound/music/midi_cvars.cpp +++ b/src/sound/music/midi_cvars.cpp @@ -43,6 +43,7 @@ #include "../libraries/timidity/timidity/timidity.h" #include "../libraries/timidityplus/timiditypp/timidity.h" #include "../libraries/oplsynth/oplsynth/oplio.h" +#include "../libraries/dumb/include/dumb.h" #ifdef _WIN32 // do this without including windows.h for this one single prototype @@ -64,6 +65,7 @@ OpnConfig opnConfig; GUSConfig gusConfig; TimidityConfig timidityConfig; WildMidiConfig wildMidiConfig; +DumbConfig dumbConfig; //========================================================================== // @@ -912,14 +914,54 @@ bool WildMidi_SetupConfig(WildMidiConfig* config, const char* args) return true; } +//========================================================================== +// // This one is for Win32 MMAPI. +// +//========================================================================== CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); +//========================================================================== +// // GME +// +//========================================================================== CUSTOM_CVAR(Float, gme_stereodepth, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { if (currSong != nullptr) currSong->ChangeSettingNum("GME.stereodepth", *self); } + +//========================================================================== +// +// Dumb +// +//========================================================================== + +CVAR(Int, mod_samplerate, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Int, mod_volramp, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Int, mod_interp, DUMB_LQ_CUBIC, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Bool, mod_autochip, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Int, mod_autochip_size_force, 100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Int, mod_autochip_size_scan, 500, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Int, mod_autochip_scan_threshold, 12, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CUSTOM_CVAR(Float, mod_dumb_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 0.5f) self = 0.5f; + else if (self > 16.f) self = 16.f; +} + + +void Dumb_SetupConfig(DumbConfig* config) +{ + config->mod_samplerate = mod_samplerate; + config->mod_volramp = mod_volramp; + config->mod_interp = mod_interp; + config->mod_autochip = mod_autochip; + config->mod_autochip_size_force = mod_autochip_size_force; + config->mod_autochip_size_scan = mod_autochip_size_scan; + config->mod_autochip_scan_threshold = mod_autochip_scan_threshold; + config->mod_dumb_mastervolume = mod_dumb_mastervolume; +} diff --git a/src/sound/musicformats/music_dumb.cpp b/src/sound/musicformats/music_dumb.cpp index bad3471b5..4161ebf1d 100644 --- a/src/sound/musicformats/music_dumb.cpp +++ b/src/sound/musicformats/music_dumb.cpp @@ -37,23 +37,18 @@ #include <math.h> #include <mutex> -#include "i_musicinterns.h" +#include <string> +#include <stdint.h> +#include "streamsource.h" #undef CDECL // w32api's windef.h defines this #include "../dumb/include/dumb.h" #include "../dumb/include/internal/it.h" - -//========================================================================== -// -// dumb_decode_vorbis -// -//========================================================================== - -static short *DUMBCALLBACK dumb_decode_vorbis_(int outlen, const void *oggstream, int sizebytes) -{ - return GSnd->DecodeSample(outlen, oggstream, sizebytes, CODEC_Vorbis); -} +#include "m_swap.h" +#include "zmusic/mididefs.h" +#include "zmusic/midiconfig.h" +#include "../..//libraries/music_common/fileio.h" // MACROS ------------------------------------------------------------------ @@ -62,20 +57,22 @@ static short *DUMBCALLBACK dumb_decode_vorbis_(int outlen, const void *oggstream class DumbSong : public StreamSource { public: - DumbSong(DUH *myduh); + DumbSong(DUH *myduh, DumbConfig *config, int samplerate); ~DumbSong(); //bool SetPosition(int ms); bool SetSubsong(int subsong) override; bool Start() override; SoundStreamInfo GetFormat() override; - FString GetStats() override; + void ChangeSettingNum(const char* setting, double val) override; + std::string GetStats() override; - FString Codec; - FString TrackerVersion; - FString FormatVersion; + std::string Codec; + std::string TrackerVersion; + std::string FormatVersion; int NumChannels; int NumPatterns; int NumOrders; + float MasterVolume; protected: int srate, interp, volramp; @@ -98,6 +95,12 @@ protected: #pragma pack(1) +#if defined(__GNUC__) +#define FORCE_PACKED __attribute__((__packed__)) +#else +#define FORCE_PACKED +#endif + typedef struct tagITFILEHEADER { uint32_t id; // 0x4D504D49 @@ -143,19 +146,6 @@ typedef struct MODMIDICFG // PUBLIC DATA DEFINITIONS ------------------------------------------------- -CVAR(Int, mod_samplerate, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Int, mod_volramp, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Int, mod_interp, DUMB_LQ_CUBIC, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Bool, mod_autochip, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Int, mod_autochip_size_force, 100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Int, mod_autochip_size_scan, 500, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Int, mod_autochip_scan_threshold, 12, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CUSTOM_CVAR(Float, mod_dumb_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (self < 0.5f) self = 0.5f; - else if (self > 16.f) self = 16.f; -} - // PRIVATE DATA DEFINITIONS ------------------------------------------------ // CODE -------------------------------------------------------------------- @@ -205,12 +195,17 @@ static void ReadDUH(DUH * duh, DumbSong *info, bool meta, bool dos) } } - info->Codec = duh_get_tag(duh, "FORMAT"); - info->TrackerVersion = duh_get_tag(duh, "TRACKERVERSION"); - info->FormatVersion = duh_get_tag(duh, "FORMATVERSION"); + // std::string does not like nullptr assignments. Was this really necessary? :( + auto a = duh_get_tag(duh, "FORMAT"); + if (a) info->Codec = a; + a = duh_get_tag(duh, "TRACKERVERSION"); + if (a) info->TrackerVersion = a; + a = duh_get_tag(duh, "FORMATVERSION"); + if (a) info->FormatVersion = a; + #if 0 - FString name; + std::string name; if (itsd->n_samples) { @@ -276,12 +271,12 @@ static bool ReadIT(const uint8_t * ptr, unsigned size, DumbSong *info, bool meta LittleShort(pifh->smpnum)*4 + LittleShort(pifh->patnum)*4 > size) return false; - FString ver; + char ver[40]; - ver.Format("IT v%u.%02x", LittleShort(pifh->cmwt) >> 8, LittleShort(pifh->cmwt) & 255); + snprintf(ver, 40, "IT v%u.%02x", LittleShort(pifh->cmwt) >> 8, LittleShort(pifh->cmwt) & 255); info->Codec = ver; - ver.Format("%u.%02x", LittleShort(pifh->cwtv) >> 8, LittleShort(pifh->cwtv) & 255); + snprintf(ver, 40, "%u.%02x", LittleShort(pifh->cwtv) >> 8, LittleShort(pifh->cwtv) & 255); info->TrackerVersion = ver; //if ( pifh->smpnum ) info.info_set_int( field_samples, LittleShort(pifh->smpnum) ); @@ -296,7 +291,7 @@ static bool ReadIT(const uint8_t * ptr, unsigned size, DumbSong *info, bool meta unsigned msgend = msgoffset + LittleShort(pifh->msglength); uint32_t * offset; -// FString name; +// std::string name; if (meta) { @@ -466,7 +461,7 @@ static bool ReadIT(const uint8_t * ptr, unsigned size, DumbSong *info, bool meta if ( meta && ( LittleShort(pifh->special) & 1 ) && ( msgend - msgoffset ) && ( msgend < size ) ) { const char * str = (const char *) ptr + msgoffset; - FString msg(str); + std::string msg(str); //info.meta_add( field_comment, string_utf8_from_it_multiline( msg ) ); } @@ -558,7 +553,7 @@ static DUMBFILE_SYSTEM mem_dfs = { // //========================================================================== -DUMBFILE *dumb_read_allfile(dumbfile_mem_status *filestate, uint8_t *start, FileReader &reader, int lenhave, int lenfull) +DUMBFILE *dumb_read_allfile(dumbfile_mem_status *filestate, uint8_t *start, MusicIO::FileInterface *reader, int lenhave, int lenfull) { filestate->size = lenfull; filestate->offset = 0; @@ -568,7 +563,7 @@ DUMBFILE *dumb_read_allfile(dumbfile_mem_status *filestate, uint8_t *start, File { uint8_t *mem = new uint8_t[lenfull]; memcpy(mem, start, lenhave); - if (reader.Read(mem + lenhave, lenfull - lenhave) != (lenfull - lenhave)) + if (reader->read(mem + lenhave, lenfull - lenhave) != (lenfull - lenhave)) { delete[] mem; return NULL; @@ -587,12 +582,12 @@ DUMBFILE *dumb_read_allfile(dumbfile_mem_status *filestate, uint8_t *start, File // //========================================================================== -static void MOD_SetAutoChip(DUH *duh) +static void MOD_SetAutoChip(DUH *duh, DumbConfig *config) { - int size_force = mod_autochip_size_force; - int size_scan = mod_autochip_size_scan; - int scan_threshold_8 = ((mod_autochip_scan_threshold * 0x100) + 50) / 100; - int scan_threshold_16 = ((mod_autochip_scan_threshold * 0x10000) + 50) / 100; + int size_force = config->mod_autochip_size_force; + int size_scan = config->mod_autochip_size_scan; + int scan_threshold_8 = ((config->mod_autochip_scan_threshold * 0x100) + 50) / 100; + int scan_threshold_16 = ((config->mod_autochip_scan_threshold * 0x10000) + 50) / 100; DUMB_IT_SIGDATA * itsd = duh_get_it_sigdata(duh); if (itsd) @@ -773,7 +768,7 @@ static void MOD_SetAutoChip(DUH *duh) // //========================================================================== -StreamSource *MOD_OpenSong(FileReader &reader) +StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, DumbConfig* config, int samplerate) { DUH *duh = 0; int headsize; @@ -789,14 +784,16 @@ StreamSource *MOD_OpenSong(FileReader &reader) bool is_it = false; bool is_dos = true; - int size = (int)reader.GetLength(); - auto fpos = reader.Tell(); + auto fpos = reader->tell(); + reader->seek(0, SEEK_END); + int size = (int)reader->tell(); + reader->seek(fpos, SEEK_SET); filestate.ptr = start; filestate.offset = 0; headsize = MIN((int)sizeof(start), size); - if (headsize != reader.Read(start, headsize)) + if (headsize != reader->read(start, headsize)) { return NULL; } @@ -908,7 +905,7 @@ StreamSource *MOD_OpenSong(FileReader &reader) { if (!(f = dumb_read_allfile(&filestate, start, reader, headsize, size))) { - reader.Seek(fpos, FileReader::SeekSet); + reader->seek(fpos, SEEK_SET); return NULL; } } @@ -930,11 +927,11 @@ StreamSource *MOD_OpenSong(FileReader &reader) } if ( duh ) { - if (mod_autochip) + if (config->mod_autochip) { - MOD_SetAutoChip(duh); + MOD_SetAutoChip(duh, config); } - state = new DumbSong(duh); + state = new DumbSong(duh, config, samplerate); if (is_it) ReadIT(filestate.ptr, size, state, false); else ReadDUH(duh, state, false, is_dos); @@ -942,7 +939,7 @@ StreamSource *MOD_OpenSong(FileReader &reader) else { // Reposition file pointer for other codecs to do their checks. - reader.Seek(fpos, FileReader::SeekSet); + reader->seek(fpos, SEEK_SET); } if (filestate.ptr != (uint8_t *)start) { @@ -983,7 +980,7 @@ bool DumbSong::GetData(void *buffer, size_t sizebytes) // Convert to float for (int i = 0; i < written * 2; ++i) { - ((float *)buffer)[i] = (((int *)buffer)[i] / (float)(1 << 24)) * mod_dumb_mastervolume; + ((float *)buffer)[i] = (((int *)buffer)[i] / (float)(1 << 24)) * MasterVolume; } } buffer = (uint8_t *)buffer + written * 8; @@ -992,30 +989,42 @@ bool DumbSong::GetData(void *buffer, size_t sizebytes) return true; } +//========================================================================== +// +// ChangeSetting +// +//========================================================================== + +void DumbSong::ChangeSettingNum(const char* setting, double val) +{ + if (!stricmp(setting, "dumb.mastervolume")) + MasterVolume = (float)val; +} + //========================================================================== // // DumbSong constructor // //========================================================================== -DumbSong::DumbSong(DUH *myduh) +DumbSong::DumbSong(DUH* myduh, DumbConfig* config, int samplerate) { - dumb_decode_vorbis = dumb_decode_vorbis_; duh = myduh; sr = NULL; eof = false; - interp = mod_interp; - volramp = mod_volramp; + interp = config->mod_interp; + volramp = config->mod_volramp; written = 0; length = 0; start_order = 0; - if (mod_samplerate != 0) + MasterVolume = (float)config->mod_dumb_mastervolume; + if (config->mod_samplerate != 0) { - srate = mod_samplerate; + srate = config->mod_samplerate; } else { - srate = (int)GSnd->GetOutputRate(); + srate = samplerate; } delta = 65536.0 / srate; } @@ -1186,12 +1195,11 @@ retry: // //========================================================================== -FString DumbSong::GetStats() +std::string DumbSong::GetStats() { //return StreamSong::GetStats(); DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); DUMB_IT_SIGDATA *itsd = duh_get_it_sigdata(duh); - FString out; int channels = 0; for (int i = 0; i < DUMB_IT_N_CHANNELS; i++) @@ -1206,12 +1214,13 @@ FString DumbSong::GetStats() if (itsr == NULL || itsd == NULL) { - out = "Problem getting stats"; + return "Problem getting stats"; } else { - out.Format("%s, Order:%3d/%d Patt:%2d/%d Row:%2d/%2d Chan:%2d/%2d Speed:%2d Tempo:%3d", - Codec.GetChars(), + char out[120]; + snprintf(out, 120, "%s, Order:%3d/%d Patt:%2d/%d Row:%2d/%2d Chan:%2d/%2d Speed:%2d Tempo:%3d", + Codec.c_str(), itsr->order, NumOrders, (itsd->order && itsr->order < itsd->n_orders ? itsd->order[itsr->order] : 0), NumPatterns, itsr->row, itsr->n_rows, @@ -1219,7 +1228,7 @@ FString DumbSong::GetStats() itsr->speed, itsr->tempo ); + return out; } - return out; } diff --git a/src/sound/musicformats/music_gme.cpp b/src/sound/musicformats/music_gme.cpp index 4f87b1c90..23b61d293 100644 --- a/src/sound/musicformats/music_gme.cpp +++ b/src/sound/musicformats/music_gme.cpp @@ -43,6 +43,7 @@ #include <mutex> #include "v_text.h" #include "templates.h" +#include "streamsource.h" // MACROS ------------------------------------------------------------------ @@ -56,7 +57,7 @@ public: bool SetSubsong(int subsong) override; bool Start() override; void ChangeSettingNum(const char *name, double val) override; - FString GetStats() override; + std::string GetStats() override; bool GetData(void *buffer, size_t len) override; SoundStreamInfo GetFormat() override; @@ -276,17 +277,15 @@ bool GMESong::StartTrack(int track, bool getcritsec) // //========================================================================== -FString GMESong::GetStats() +std::string GMESong::GetStats() { - FString out; + char out[80]; if (TrackInfo != NULL) { int time = gme_tell(Emu); - out.Format( - "Track: " TEXTCOLOR_YELLOW "%d" TEXTCOLOR_NORMAL - " Time:" TEXTCOLOR_YELLOW "%3d:%02d:%03d" TEXTCOLOR_NORMAL - " System: " TEXTCOLOR_YELLOW "%s" TEXTCOLOR_NORMAL, + snprintf(out, 80, + "Track: %d Time: %3d:%02d:%03d System: %s", CurrTrack, time/60000, (time/1000) % 60, diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index 7c1e3588b..7c7f505ad 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -39,6 +39,7 @@ #include "v_text.h" #include "templates.h" #include "m_fixed.h" +#include "streamsource.h" // MACROS ------------------------------------------------------------------ @@ -49,7 +50,7 @@ class SndFileSong : public StreamSource public: SndFileSong(FileReader &reader, SoundDecoder *decoder, uint32_t loop_start, uint32_t loop_end, bool startass, bool endass); ~SndFileSong(); - FString GetStats() override; + std::string GetStats() override; SoundStreamInfo GetFormat() override; bool GetData(void *buffer, size_t len) override; @@ -328,18 +329,17 @@ SndFileSong::~SndFileSong() // //========================================================================== -FString SndFileSong::GetStats() +std::string SndFileSong::GetStats() { - FString out; + char out[80]; size_t SamplePos; SamplePos = Decoder->getSampleOffset(); int time = int (SamplePos / SampleRate); - out.Format( - "Track: " TEXTCOLOR_YELLOW "%s, %dHz" TEXTCOLOR_NORMAL - " Time:" TEXTCOLOR_YELLOW "%02d:%02d" TEXTCOLOR_NORMAL, + snprintf(out, 80, + "Track: %s, %dHz Time: %02d:%02d", Channels == 2? "Stereo" : "Mono", SampleRate, time/60, time % 60); diff --git a/src/sound/musicformats/music_opl.cpp b/src/sound/musicformats/music_opl.cpp index 93327d7d1..35aa878fa 100644 --- a/src/sound/musicformats/music_opl.cpp +++ b/src/sound/musicformats/music_opl.cpp @@ -32,6 +32,7 @@ */ #include "i_musicinterns.h" +#include "streamsource.h" #include "../libraries/oplsynth/oplsynth/opl.h" #include "../libraries/oplsynth/oplsynth/opl_mus_player.h" diff --git a/src/sound/musicformats/music_stream.cpp b/src/sound/musicformats/music_stream.cpp index ccf24700d..fdfaa52b2 100644 --- a/src/sound/musicformats/music_stream.cpp +++ b/src/sound/musicformats/music_stream.cpp @@ -33,6 +33,7 @@ */ #include "i_musicinterns.h" +#include "streamsource.h" class StreamSong : public MusInfo { @@ -185,7 +186,8 @@ FString StreamSong::GetStats() } if (m_Source != NULL) { - s2 = m_Source->GetStats(); + auto stat = m_Source->GetStats(); + s2 = stat.c_str(); } if (s1.IsEmpty() && s2.IsEmpty()) return "No song loaded\n"; if (s1.IsEmpty()) return s2; diff --git a/src/sound/musicformats/music_xa.cpp b/src/sound/musicformats/music_xa.cpp index ada0abe31..5c06d3369 100644 --- a/src/sound/musicformats/music_xa.cpp +++ b/src/sound/musicformats/music_xa.cpp @@ -1,4 +1,5 @@ #include "i_musicinterns.h" +#include "streamsource.h" /** * PlayStation XA (ADPCM) source support for MultiVoc * Adapted and remixed from superxa2wav