- dependency cleanup in music_dumb.cpp.

This commit is contained in:
Christoph Oelckers 2019-09-29 00:41:13 +02:00
parent 7468c0f36d
commit 5eed3dab59
13 changed files with 196 additions and 130 deletions

View file

@ -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

View file

@ -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;
};

View file

@ -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

View file

@ -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:

View file

@ -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"

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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,

View file

@ -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);

View file

@ -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"

View file

@ -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;

View file

@ -1,4 +1,5 @@
#include "i_musicinterns.h"
#include "streamsource.h"
/**
* PlayStation XA (ADPCM) source support for MultiVoc
* Adapted and remixed from superxa2wav