mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
- moved all configuration code to zmusic project.
The CVARs are now just getting forwarded without any own logic.
This commit is contained in:
parent
b7b57b904d
commit
44a6b6e87c
18 changed files with 441 additions and 612 deletions
|
@ -148,11 +148,11 @@ protected:
|
|||
|
||||
MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, const char *Args);
|
||||
MIDIDevice *CreateADLMIDIDevice(const char* args);
|
||||
MIDIDevice *CreateOPNMIDIDevice(const OpnConfig *args);
|
||||
MIDIDevice *CreateOplMIDIDevice(const OPLConfig* config);
|
||||
MIDIDevice *CreateTimidityMIDIDevice(GUSConfig *config, int samplerate);
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(TimidityConfig *config, int samplerate);
|
||||
MIDIDevice *CreateWildMIDIDevice(WildMidiConfig *config, int samplerate);
|
||||
MIDIDevice *CreateOPNMIDIDevice(const char *args);
|
||||
MIDIDevice *CreateOplMIDIDevice(const char* Args);
|
||||
MIDIDevice *CreateTimidityMIDIDevice(const char* Args, int samplerate);
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(const char *Args, int samplerate);
|
||||
MIDIDevice *CreateWildMIDIDevice(const char *Args, int samplerate);
|
||||
|
||||
#ifdef _WIN32
|
||||
MIDIDevice* CreateWinMIDIDevice(int mididevice);
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "mididevice.h"
|
||||
#include "adlmidi.h"
|
||||
|
||||
ADLConfig adlConfig;
|
||||
|
||||
class ADLMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
struct ADL_MIDIPlayer *Renderer;
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
|
||||
// FluidSynth implementation of a MIDI device -------------------------------
|
||||
|
||||
FluidConfig fluidConfig;
|
||||
|
||||
#if !defined DYN_FLUIDSYNTH
|
||||
#include <fluidsynth.h>
|
||||
#else
|
||||
|
|
|
@ -52,12 +52,14 @@
|
|||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
OPLConfig oplConfig;
|
||||
|
||||
// OPL implementation of a MIDI output device -------------------------------
|
||||
|
||||
class OPLMIDIDevice : public SoftSynthMIDIDevice, protected OPLmusicBlock
|
||||
{
|
||||
public:
|
||||
OPLMIDIDevice(const OPLConfig *config);
|
||||
OPLMIDIDevice(int core);
|
||||
int OpenRenderer();
|
||||
void Close();
|
||||
int GetTechnology() const;
|
||||
|
@ -84,11 +86,11 @@ protected:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
OPLMIDIDevice::OPLMIDIDevice(const OPLConfig *config)
|
||||
: SoftSynthMIDIDevice((int)OPL_SAMPLE_RATE), OPLmusicBlock(config->core, config->numchips)
|
||||
OPLMIDIDevice::OPLMIDIDevice(int core)
|
||||
: SoftSynthMIDIDevice((int)OPL_SAMPLE_RATE), OPLmusicBlock(core, oplConfig.numchips)
|
||||
{
|
||||
FullPan = config->fullpan;
|
||||
memcpy(OPLinstruments, config->OPLinstruments, sizeof(OPLinstruments));
|
||||
FullPan = oplConfig.fullpan;
|
||||
memcpy(OPLinstruments, oplConfig.OPLinstruments, sizeof(OPLinstruments));
|
||||
StreamBlockSize = 14;
|
||||
}
|
||||
|
||||
|
@ -314,7 +316,11 @@ std::string OPLMIDIDevice::GetStats()
|
|||
return out;
|
||||
}
|
||||
|
||||
MIDIDevice* CreateOplMIDIDevice(const OPLConfig* config)
|
||||
|
||||
MIDIDevice* CreateOplMIDIDevice(const char *Args)
|
||||
{
|
||||
return new OPLMIDIDevice(config);
|
||||
if (!oplConfig.genmidiset) throw std::runtime_error("Cannot play OPL without GENMIDI data");
|
||||
int core = oplConfig.core;
|
||||
if (Args != NULL && *Args >= '0' && *Args < '4') core = *Args - '0';
|
||||
return new OPLMIDIDevice(core);
|
||||
}
|
||||
|
|
|
@ -37,11 +37,13 @@
|
|||
#include "mididevice.h"
|
||||
#include "opnmidi.h"
|
||||
|
||||
OpnConfig opnConfig;
|
||||
|
||||
class OPNMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
struct OPN2_MIDIPlayer *Renderer;
|
||||
public:
|
||||
OPNMIDIDevice(const OpnConfig *config);
|
||||
OPNMIDIDevice(const char *bank);
|
||||
~OPNMIDIDevice();
|
||||
|
||||
|
||||
|
@ -76,26 +78,26 @@ enum
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
OPNMIDIDevice::OPNMIDIDevice(const OpnConfig *config)
|
||||
OPNMIDIDevice::OPNMIDIDevice(const char *bank)
|
||||
:SoftSynthMIDIDevice(44100)
|
||||
{
|
||||
Renderer = opn2_init(44100); // todo: make it configurable
|
||||
if (Renderer != nullptr)
|
||||
{
|
||||
if (!LoadCustomBank(config->opn_custom_bank.c_str()))
|
||||
if (!opnConfig.opn_use_custom_bank || !LoadCustomBank(opnConfig.opn_custom_bank.c_str()))
|
||||
{
|
||||
if(config->default_bank.size() == 0)
|
||||
if(opnConfig.default_bank.size() == 0)
|
||||
{
|
||||
opn2_close(Renderer);
|
||||
throw std::runtime_error("No OPN bank found");
|
||||
}
|
||||
opn2_openBankData(Renderer, config->default_bank.data(), (long)config->default_bank.size());
|
||||
opn2_openBankData(Renderer, opnConfig.default_bank.data(), (long)opnConfig.default_bank.size());
|
||||
}
|
||||
|
||||
opn2_switchEmulator(Renderer, (int)config->opn_emulator_id);
|
||||
opn2_setRunAtPcmRate(Renderer, (int)config->opn_run_at_pcm_rate);
|
||||
opn2_setNumChips(Renderer, config->opn_chips_count);
|
||||
opn2_setSoftPanEnabled(Renderer, (int)config->opn_fullpan);
|
||||
opn2_switchEmulator(Renderer, (int)opnConfig.opn_emulator_id);
|
||||
opn2_setRunAtPcmRate(Renderer, (int)opnConfig.opn_run_at_pcm_rate);
|
||||
opn2_setNumChips(Renderer, opnConfig.opn_chips_count);
|
||||
opn2_setSoftPanEnabled(Renderer, (int)opnConfig.opn_fullpan);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -228,9 +230,19 @@ void OPNMIDIDevice::ComputeOutput(float *buffer, int len)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDIDevice *CreateOPNMIDIDevice(const OpnConfig *config)
|
||||
MIDIDevice *CreateOPNMIDIDevice(const char *Args)
|
||||
{
|
||||
return new OPNMIDIDevice(config);
|
||||
const char* bank = Args && *Args ? Args : opnConfig.opn_use_custom_bank ? opnConfig.opn_custom_bank.c_str() : nullptr;
|
||||
if (bank && *bank)
|
||||
{
|
||||
if (musicCallbacks.PathForSoundfont)
|
||||
{
|
||||
auto info = musicCallbacks.PathForSoundfont(bank, SF_WOPN);
|
||||
if (info != nullptr) bank = info;
|
||||
}
|
||||
}
|
||||
|
||||
return new OPNMIDIDevice(bank);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
GUSConfig gusConfig;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -65,9 +66,9 @@ namespace Timidity { struct Renderer; }
|
|||
|
||||
class TimidityMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
void LoadInstruments(GUSConfig *config);
|
||||
void LoadInstruments();
|
||||
public:
|
||||
TimidityMIDIDevice(GUSConfig *config, int samplerate);
|
||||
TimidityMIDIDevice(int samplerate);
|
||||
~TimidityMIDIDevice();
|
||||
|
||||
int OpenRenderer();
|
||||
|
@ -76,7 +77,6 @@ public:
|
|||
|
||||
protected:
|
||||
Timidity::Renderer *Renderer;
|
||||
std::shared_ptr<Timidity::Instruments> instruments; // The device needs to hold a reference to this while the renderer is in use.
|
||||
|
||||
void HandleEvent(int status, int parm1, int parm2);
|
||||
void HandleLongEvent(const uint8_t *data, int len);
|
||||
|
@ -87,13 +87,13 @@ protected:
|
|||
// CODE --------------------------------------------------------------------
|
||||
|
||||
|
||||
void TimidityMIDIDevice::LoadInstruments(GUSConfig *config)
|
||||
void TimidityMIDIDevice::LoadInstruments()
|
||||
{
|
||||
if (config->dmxgus.size())
|
||||
if (gusConfig.dmxgus.size())
|
||||
{
|
||||
// Check if we got some GUS data before using it.
|
||||
std::string ultradir = getenv("ULTRADIR");
|
||||
if (ultradir.length() || config->gus_patchdir.length() != 0)
|
||||
if (ultradir.length() || gusConfig.gus_patchdir.length() != 0)
|
||||
{
|
||||
auto psreader = new MusicIO::FileSystemSoundFontReader("");
|
||||
|
||||
|
@ -104,42 +104,41 @@ void TimidityMIDIDevice::LoadInstruments(GUSConfig *config)
|
|||
psreader->add_search_path(ultradir.c_str());
|
||||
}
|
||||
// Load DMXGUS lump and patches from gus_patchdir
|
||||
if (config->gus_patchdir.length() != 0) psreader->add_search_path(config->gus_patchdir.c_str());
|
||||
if (gusConfig.gus_patchdir.length() != 0) psreader->add_search_path(gusConfig.gus_patchdir.c_str());
|
||||
|
||||
config->instruments.reset(new Timidity::Instruments(psreader));
|
||||
bool success = config->instruments->LoadDMXGUS(config->gus_memsize, (const char*)config->dmxgus.data(), config->dmxgus.size()) >= 0;
|
||||
gusConfig.instruments.reset(new Timidity::Instruments(psreader));
|
||||
bool success = gusConfig.instruments->LoadDMXGUS(gusConfig.gus_memsize, (const char*)gusConfig.dmxgus.data(), gusConfig.dmxgus.size()) >= 0;
|
||||
|
||||
config->dmxgus.clear();
|
||||
gusConfig.dmxgus.clear();
|
||||
|
||||
if (success)
|
||||
{
|
||||
config->loadedConfig = "DMXGUS";
|
||||
gusConfig.loadedConfig = "DMXGUS";
|
||||
return;
|
||||
}
|
||||
}
|
||||
config->loadedConfig = "";
|
||||
config->instruments.reset();
|
||||
gusConfig.loadedConfig = "";
|
||||
gusConfig.instruments.reset();
|
||||
throw std::runtime_error("Unable to initialize DMXGUS for GUS MIDI device");
|
||||
}
|
||||
else if (config->reader)
|
||||
else if (gusConfig.reader)
|
||||
{
|
||||
config->loadedConfig = config->readerName;
|
||||
config->instruments.reset(new Timidity::Instruments(config->reader));
|
||||
bool err = config->instruments->LoadConfig() < 0;
|
||||
config->reader = nullptr;
|
||||
gusConfig.loadedConfig = gusConfig.readerName;
|
||||
gusConfig.instruments.reset(new Timidity::Instruments(gusConfig.reader));
|
||||
bool err = gusConfig.instruments->LoadConfig() < 0;
|
||||
gusConfig.reader = nullptr;
|
||||
|
||||
if (err)
|
||||
{
|
||||
config->instruments.reset();
|
||||
config->loadedConfig = "";
|
||||
gusConfig.instruments.reset();
|
||||
gusConfig.loadedConfig = "";
|
||||
throw std::runtime_error("Unable to initialize instruments for GUS MIDI device");
|
||||
}
|
||||
}
|
||||
else if (config->instruments == nullptr)
|
||||
else if (gusConfig.instruments == nullptr)
|
||||
{
|
||||
throw std::runtime_error("No instruments set for GUS device");
|
||||
}
|
||||
instruments = config->instruments;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -148,11 +147,11 @@ void TimidityMIDIDevice::LoadInstruments(GUSConfig *config)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
TimidityMIDIDevice::TimidityMIDIDevice(GUSConfig *config, int samplerate)
|
||||
TimidityMIDIDevice::TimidityMIDIDevice(int samplerate)
|
||||
: SoftSynthMIDIDevice(samplerate, 11025, 65535)
|
||||
{
|
||||
LoadInstruments(config);
|
||||
Renderer = new Timidity::Renderer((float)SampleRate, config->midi_voices, instruments.get());
|
||||
LoadInstruments();
|
||||
Renderer = new Timidity::Renderer((float)SampleRate, gusConfig.midi_voices, gusConfig.instruments.get());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -244,7 +243,53 @@ void TimidityMIDIDevice::ComputeOutput(float *buffer, int len)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDIDevice *CreateTimidityMIDIDevice(GUSConfig *config, int samplerate)
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the date to load the instruments for the GUS device.
|
||||
// The actual instrument loader is part of the device.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool GUS_SetupConfig(const char* args)
|
||||
{
|
||||
return new TimidityMIDIDevice(config, samplerate);
|
||||
gusConfig.reader = nullptr;
|
||||
if ((gusConfig.gus_dmxgus && *args == 0) || !stricmp(args, "DMXGUS"))
|
||||
{
|
||||
if (stricmp(gusConfig.loadedConfig.c_str(), "DMXGUS") == 0) return false; // aleady loaded
|
||||
if (gusConfig.dmxgus.size() > 0)
|
||||
{
|
||||
gusConfig.readerName = "DMXGUS";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (*args == 0) args = gusConfig.gus_config.c_str();
|
||||
if (stricmp(gusConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
MusicIO::SoundFontReaderInterface *reader;
|
||||
if (musicCallbacks.OpenSoundFont)
|
||||
{
|
||||
reader = musicCallbacks.OpenSoundFont(args, SF_GUS | SF_SF2);
|
||||
}
|
||||
else if (MusicIO::fileExists(args))
|
||||
{
|
||||
reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
||||
}
|
||||
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "GUS: %s: Unable to load sound font\n", args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
gusConfig.reader = reader;
|
||||
gusConfig.readerName = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MIDIDevice *CreateTimidityMIDIDevice(const char *Args, int samplerate)
|
||||
{
|
||||
GUS_SetupConfig(Args);
|
||||
return new TimidityMIDIDevice(samplerate);
|
||||
}
|
||||
|
|
|
@ -39,13 +39,13 @@
|
|||
#include "timiditypp/playmidi.h"
|
||||
|
||||
|
||||
|
||||
TimidityConfig timidityConfig;
|
||||
|
||||
class TimidityPPMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
std::shared_ptr<TimidityPlus::Instruments> instruments;
|
||||
public:
|
||||
TimidityPPMIDIDevice(TimidityConfig *config, int samplerate);
|
||||
TimidityPPMIDIDevice(int samplerate);
|
||||
~TimidityPPMIDIDevice();
|
||||
|
||||
int OpenRenderer();
|
||||
|
@ -61,7 +61,7 @@ protected:
|
|||
void HandleEvent(int status, int parm1, int parm2);
|
||||
void HandleLongEvent(const uint8_t *data, int len);
|
||||
void ComputeOutput(float *buffer, int len);
|
||||
void LoadInstruments(TimidityConfig* config);
|
||||
void LoadInstruments();
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -70,27 +70,27 @@ protected:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void TimidityPPMIDIDevice::LoadInstruments(TimidityConfig* config)
|
||||
void TimidityPPMIDIDevice::LoadInstruments()
|
||||
{
|
||||
if (config->reader)
|
||||
if (timidityConfig.reader)
|
||||
{
|
||||
config->loadedConfig = config->readerName;
|
||||
config->instruments.reset(new TimidityPlus::Instruments());
|
||||
bool success = config->instruments->load(config->reader);
|
||||
config->reader = nullptr;
|
||||
timidityConfig.loadedConfig = timidityConfig.readerName;
|
||||
timidityConfig.instruments.reset(new TimidityPlus::Instruments());
|
||||
bool success = timidityConfig.instruments->load(timidityConfig.reader);
|
||||
timidityConfig.reader = nullptr;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
config->instruments.reset();
|
||||
config->loadedConfig = "";
|
||||
timidityConfig.instruments.reset();
|
||||
timidityConfig.loadedConfig = "";
|
||||
throw std::runtime_error("Unable to initialize instruments for Timidity++ MIDI device");
|
||||
}
|
||||
}
|
||||
else if (config->instruments == nullptr)
|
||||
else if (timidityConfig.instruments == nullptr)
|
||||
{
|
||||
throw std::runtime_error("No instruments set for Timidity++ device");
|
||||
}
|
||||
instruments = config->instruments;
|
||||
instruments = timidityConfig.instruments;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -99,11 +99,11 @@ void TimidityPPMIDIDevice::LoadInstruments(TimidityConfig* config)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice(TimidityConfig *config, int samplerate)
|
||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice(int samplerate)
|
||||
:SoftSynthMIDIDevice(samplerate, 4000, 65000)
|
||||
{
|
||||
TimidityPlus::set_playback_rate(SampleRate);
|
||||
LoadInstruments(config);
|
||||
LoadInstruments();
|
||||
Renderer = new TimidityPlus::Player(instruments.get());
|
||||
}
|
||||
|
||||
|
@ -193,9 +193,36 @@ void TimidityPPMIDIDevice::ComputeOutput(float *buffer, int len)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(TimidityConfig* config, int samplerate)
|
||||
bool Timidity_SetupConfig(const char* args)
|
||||
{
|
||||
return new TimidityPPMIDIDevice(config, samplerate);
|
||||
if (*args == 0) args = timidityConfig.timidity_config.c_str();
|
||||
if (stricmp(timidityConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
MusicIO::SoundFontReaderInterface* reader;
|
||||
if (musicCallbacks.OpenSoundFont)
|
||||
{
|
||||
reader = musicCallbacks.OpenSoundFont(args, SF_GUS | SF_SF2);
|
||||
}
|
||||
else if (MusicIO::fileExists(args))
|
||||
{
|
||||
reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
||||
}
|
||||
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "Timidity++: %s: Unable to load sound font\n", args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
timidityConfig.reader = reader;
|
||||
timidityConfig.readerName = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(const char *Args, int samplerate)
|
||||
{
|
||||
Timidity_SetupConfig(Args);
|
||||
return new TimidityPPMIDIDevice(samplerate);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,12 +41,14 @@
|
|||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
WildMidiConfig wildMidiConfig;
|
||||
|
||||
// WildMidi implementation of a MIDI device ---------------------------------
|
||||
|
||||
class WildMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
public:
|
||||
WildMIDIDevice(WildMidiConfig* config, int samplerate);
|
||||
WildMIDIDevice(int samplerate);
|
||||
~WildMIDIDevice();
|
||||
|
||||
int OpenRenderer();
|
||||
|
@ -62,7 +64,7 @@ protected:
|
|||
void HandleLongEvent(const uint8_t *data, int len);
|
||||
void ComputeOutput(float *buffer, int len);
|
||||
void ChangeSettingInt(const char *opt, int set);
|
||||
void LoadInstruments(WildMidiConfig* config);
|
||||
void LoadInstruments();
|
||||
|
||||
};
|
||||
|
||||
|
@ -75,27 +77,27 @@ protected:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void WildMIDIDevice::LoadInstruments(WildMidiConfig* config)
|
||||
void WildMIDIDevice::LoadInstruments()
|
||||
{
|
||||
if (config->reader)
|
||||
if (wildMidiConfig.reader)
|
||||
{
|
||||
config->loadedConfig = config->readerName;
|
||||
config->instruments.reset(new WildMidi::Instruments(config->reader, SampleRate));
|
||||
bool success = config->instruments->LoadConfig(config->readerName.c_str());
|
||||
config->reader = nullptr;
|
||||
wildMidiConfig.loadedConfig = wildMidiConfig.readerName;
|
||||
wildMidiConfig.instruments.reset(new WildMidi::Instruments(wildMidiConfig.reader, SampleRate));
|
||||
bool success = wildMidiConfig.instruments->LoadConfig(wildMidiConfig.readerName.c_str());
|
||||
wildMidiConfig.reader = nullptr;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
config->instruments.reset();
|
||||
config->loadedConfig = "";
|
||||
wildMidiConfig.instruments.reset();
|
||||
wildMidiConfig.loadedConfig = "";
|
||||
throw std::runtime_error("Unable to initialize instruments for WildMidi device");
|
||||
}
|
||||
}
|
||||
else if (config->instruments == nullptr)
|
||||
else if (wildMidiConfig.instruments == nullptr)
|
||||
{
|
||||
throw std::runtime_error("No instruments set for WildMidi device");
|
||||
}
|
||||
instruments = config->instruments;
|
||||
instruments = wildMidiConfig.instruments;
|
||||
if (instruments->LoadConfig(nullptr) < 0)
|
||||
{
|
||||
throw std::runtime_error("Unable to load instruments set for WildMidi device");
|
||||
|
@ -108,16 +110,16 @@ void WildMIDIDevice::LoadInstruments(WildMidiConfig* config)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
WildMIDIDevice::WildMIDIDevice(WildMidiConfig *config, int samplerate)
|
||||
WildMIDIDevice::WildMIDIDevice(int samplerate)
|
||||
:SoftSynthMIDIDevice(samplerate, 11025, 65535)
|
||||
{
|
||||
Renderer = NULL;
|
||||
LoadInstruments(config);
|
||||
LoadInstruments();
|
||||
|
||||
Renderer = new WildMidi::Renderer(instruments.get());
|
||||
int flags = 0;
|
||||
if (config->enhanced_resampling) flags |= WildMidi::WM_MO_ENHANCED_RESAMPLING;
|
||||
if (config->reverb) flags |= WildMidi::WM_MO_REVERB;
|
||||
if (wildMidiConfig.enhanced_resampling) flags |= WildMidi::WM_MO_ENHANCED_RESAMPLING;
|
||||
if (wildMidiConfig.reverb) flags |= WildMidi::WM_MO_REVERB;
|
||||
Renderer->SetOption(WildMidi::WM_MO_ENHANCED_RESAMPLING | WildMidi::WM_MO_REVERB, flags);
|
||||
}
|
||||
|
||||
|
@ -237,8 +239,43 @@ void WildMIDIDevice::ChangeSettingInt(const char *opt, int set)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDIDevice *CreateWildMIDIDevice(WildMidiConfig *config, int samplerate)
|
||||
bool WildMidi_SetupConfig(const char* args)
|
||||
{
|
||||
return new WildMIDIDevice(config, samplerate);
|
||||
if (*args == 0) args = wildMidiConfig.config.c_str();
|
||||
if (stricmp(wildMidiConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
MusicIO::SoundFontReaderInterface* reader;
|
||||
if (musicCallbacks.OpenSoundFont)
|
||||
{
|
||||
reader = musicCallbacks.OpenSoundFont(args, SF_GUS);
|
||||
}
|
||||
else if (MusicIO::fileExists(args))
|
||||
{
|
||||
reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
||||
}
|
||||
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "WildMidi: %s: Unable to load sound font\n", args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
|
||||
wildMidiConfig.reader = reader;
|
||||
wildMidiConfig.readerName = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDIDevice *CreateWildMIDIDevice(const char *Args, int samplerate)
|
||||
{
|
||||
WildMidi_SetupConfig(Args);
|
||||
return new WildMIDIDevice(samplerate);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,10 +54,12 @@
|
|||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
DumbConfig dumbConfig;
|
||||
|
||||
class DumbSong : public StreamSource
|
||||
{
|
||||
public:
|
||||
DumbSong(DUH *myduh, DumbConfig *config, int samplerate);
|
||||
DumbSong(DUH *myduh, int samplerate);
|
||||
~DumbSong();
|
||||
//bool SetPosition(int ms);
|
||||
bool SetSubsong(int subsong) override;
|
||||
|
@ -582,12 +584,12 @@ DUMBFILE *dumb_read_allfile(dumbfile_mem_status *filestate, uint8_t *start, Musi
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void MOD_SetAutoChip(DUH *duh, DumbConfig *config)
|
||||
static void MOD_SetAutoChip(DUH *duh)
|
||||
{
|
||||
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;
|
||||
int size_force = dumbConfig.mod_autochip_size_force;
|
||||
int size_scan = dumbConfig.mod_autochip_size_scan;
|
||||
int scan_threshold_8 = ((dumbConfig.mod_autochip_scan_threshold * 0x100) + 50) / 100;
|
||||
int scan_threshold_16 = ((dumbConfig.mod_autochip_scan_threshold * 0x10000) + 50) / 100;
|
||||
DUMB_IT_SIGDATA * itsd = duh_get_it_sigdata(duh);
|
||||
|
||||
if (itsd)
|
||||
|
@ -768,7 +770,7 @@ static void MOD_SetAutoChip(DUH *duh, DumbConfig *config)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, DumbConfig* config, int samplerate)
|
||||
StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, int samplerate)
|
||||
{
|
||||
DUH *duh = 0;
|
||||
int headsize;
|
||||
|
@ -925,11 +927,11 @@ StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, DumbConfig* config, i
|
|||
}
|
||||
if ( duh )
|
||||
{
|
||||
if (config->mod_autochip)
|
||||
if (dumbConfig.mod_autochip)
|
||||
{
|
||||
MOD_SetAutoChip(duh, config);
|
||||
MOD_SetAutoChip(duh);
|
||||
}
|
||||
state = new DumbSong(duh, config, samplerate);
|
||||
state = new DumbSong(duh, samplerate);
|
||||
|
||||
if (is_it) ReadIT(filestate.ptr, size, state, false);
|
||||
else ReadDUH(duh, state, false, is_dos);
|
||||
|
@ -1005,20 +1007,20 @@ void DumbSong::ChangeSettingNum(const char* setting, double val)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
DumbSong::DumbSong(DUH* myduh, DumbConfig* config, int samplerate)
|
||||
DumbSong::DumbSong(DUH* myduh, int samplerate)
|
||||
{
|
||||
duh = myduh;
|
||||
sr = NULL;
|
||||
eof = false;
|
||||
interp = config->mod_interp;
|
||||
volramp = config->mod_volramp;
|
||||
interp = dumbConfig.mod_interp;
|
||||
volramp = dumbConfig.mod_volramp;
|
||||
written = 0;
|
||||
length = 0;
|
||||
start_order = 0;
|
||||
MasterVolume = (float)config->mod_dumb_mastervolume;
|
||||
if (config->mod_samplerate != 0)
|
||||
MasterVolume = (float)dumbConfig.mod_dumb_mastervolume;
|
||||
if (dumbConfig.mod_samplerate != 0)
|
||||
{
|
||||
srate = config->mod_samplerate;
|
||||
srate = dumbConfig.mod_samplerate;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -105,7 +105,7 @@ const char *GME_CheckFormat(uint32_t id)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
StreamSource *GME_OpenSong(MusicIO::FileInterface *reader, const char *fmt, float stereo_depth, int sample_rate)
|
||||
StreamSource *GME_OpenSong(MusicIO::FileInterface *reader, const char *fmt, int sample_rate)
|
||||
{
|
||||
gme_type_t type;
|
||||
gme_err_t err;
|
||||
|
@ -143,7 +143,7 @@ StreamSource *GME_OpenSong(MusicIO::FileInterface *reader, const char *fmt, floa
|
|||
gme_delete(emu);
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
gme_set_stereo_depth(emu, std::min(std::max(stereo_depth, 0.f), 1.f));
|
||||
gme_set_stereo_depth(emu, std::min(std::max(miscConfig.gme_stereodepth, 0.f), 1.f));
|
||||
gme_set_fade(emu, -1); // Enable infinite loop
|
||||
return new GMESong(emu, sample_rate);
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
StreamSource *MOD_OpenSong(MusicIO::FileInterface* reader, DumbConfig* config, int samplerate);
|
||||
StreamSource* GME_OpenSong(MusicIO::FileInterface* reader, const char* fmt, float stereo_depth, int sample_rate);
|
||||
StreamSource *MOD_OpenSong(MusicIO::FileInterface* reader, int samplerate);
|
||||
StreamSource* GME_OpenSong(MusicIO::FileInterface* reader, const char* fmt, int sample_rate);
|
||||
StreamSource *SndFile_OpenSong(MusicIO::FileInterface* fr);
|
||||
StreamSource* XA_OpenSong(MusicIO::FileInterface* reader);
|
||||
StreamSource* OPL_OpenSong(MusicIO::FileInterface* reader, OPLConfig *config);
|
||||
|
|
|
@ -54,23 +54,33 @@ int devType()
|
|||
else*/ return MDEV_DEFAULT;
|
||||
}
|
||||
|
||||
// Ordered by configurable device.
|
||||
ADLConfig adlConfig;
|
||||
FluidConfig fluidConfig;
|
||||
OPLConfig oplConfig;
|
||||
OpnConfig opnConfig;
|
||||
GUSConfig gusConfig;
|
||||
TimidityConfig timidityConfig;
|
||||
WildMidiConfig wildMidiConfig;
|
||||
DumbConfig dumbConfig;
|
||||
MiscConfig miscConfig;
|
||||
Callbacks musicCallbacks;
|
||||
|
||||
void SetCallbacks(const Callbacks* cb)
|
||||
{
|
||||
dumb_decode_vorbis = cb->DumbVorbisDecode;
|
||||
musicCallbacks = *cb;
|
||||
}
|
||||
|
||||
void SetGenMidi(const uint8_t* data)
|
||||
{
|
||||
memcpy(oplConfig.OPLinstruments, data, 175 * 36);
|
||||
oplConfig.genmidiset = true;
|
||||
}
|
||||
|
||||
void SetWgOpn(const void* data, unsigned len)
|
||||
{
|
||||
opnConfig.default_bank.resize(len);
|
||||
memcpy(opnConfig.default_bank.data(), data, len);
|
||||
}
|
||||
|
||||
void SetDmxGus(const void* data, unsigned len)
|
||||
{
|
||||
gusConfig.dmxgus.resize(len);
|
||||
memcpy(gusConfig.dmxgus.data(), data, len);
|
||||
}
|
||||
|
||||
template<class valtype>
|
||||
void ChangeAndReturn(valtype &variable, valtype value, valtype *realv)
|
||||
{
|
||||
|
@ -268,6 +278,8 @@ bool ChangeMusicSetting(ZMusic::EIntConfigKey key, int value, int *pRealValue)
|
|||
return false;
|
||||
|
||||
case opl_core:
|
||||
if (value < 0) value = 0;
|
||||
else if (value > 3) value = 3;
|
||||
ChangeAndReturn(oplConfig.core, value, pRealValue);
|
||||
return devType() == MDEV_OPL;
|
||||
|
||||
|
@ -620,138 +632,3 @@ bool ChangeMusicSetting(ZMusic::EStringConfigKey key, const char *value)
|
|||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi)
|
||||
{
|
||||
// This needs to be done only once.
|
||||
if (!config->genmidiset && midi)
|
||||
{
|
||||
// The OPL renderer should not care about where this comes from.
|
||||
// Note: No I_Error here - this needs to be consistent with the rest of the music code.
|
||||
auto lump = Wads.CheckNumForName("GENMIDI", ns_global);
|
||||
if (lump < 0) throw std::runtime_error("No GENMIDI lump found");
|
||||
auto data = Wads.OpenLumpReader(lump);
|
||||
|
||||
uint8_t filehdr[8];
|
||||
data.Read(filehdr, 8);
|
||||
if (memcmp(filehdr, "#OPL_II#", 8)) throw std::runtime_error("Corrupt GENMIDI lump");
|
||||
data.Read(oplConfig.OPLinstruments, 175 * 36);
|
||||
config->genmidiset = true;
|
||||
}
|
||||
|
||||
config->core = opl_core;
|
||||
if (args != NULL && *args >= '0' && *args < '4') config->core = *args - '0';
|
||||
}
|
||||
|
||||
|
||||
void OPN_SetupConfig(OpnConfig *config, const char *Args)
|
||||
{
|
||||
//Resolve the path here, so that the renderer does not have to do the work itself and only needs to process final names.
|
||||
const char *bank = Args && *Args? Args : opn_use_custom_bank? *opn_custom_bank : nullptr;
|
||||
if (bank && *bank)
|
||||
{
|
||||
auto info = sfmanager.FindSoundFont(bank, SF_WOPN);
|
||||
if (info == nullptr)
|
||||
{
|
||||
config->opn_custom_bank = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
config->opn_custom_bank = info->mFilename;
|
||||
}
|
||||
}
|
||||
|
||||
int lump = Wads.CheckNumForFullName("xg.wopn");
|
||||
if (lump < 0)
|
||||
{
|
||||
config->default_bank.resize(0);
|
||||
return;
|
||||
}
|
||||
FMemLump data = Wads.ReadLump(lump);
|
||||
config->default_bank.resize(data.GetSize());
|
||||
memcpy(config->default_bank.data(), data.GetMem(), data.GetSize());
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the date to load the instruments for the GUS device.
|
||||
// The actual instrument loader is part of the device.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool GUS_SetupConfig(GUSConfig *config, const char *args)
|
||||
{
|
||||
config->errorfunc = gus_printfunc;
|
||||
if ((midi_dmxgus && *args == 0) || !stricmp(args, "DMXGUS"))
|
||||
{
|
||||
if (stricmp(config->loadedConfig.c_str(), "DMXGUS") == 0) return false; // aleady loaded
|
||||
int lump = Wads.CheckNumForName("DMXGUS");
|
||||
if (lump == -1) lump = Wads.CheckNumForName("DMXGUSC");
|
||||
if (lump >= 0)
|
||||
{
|
||||
auto data = Wads.OpenLumpReader(lump);
|
||||
if (data.GetLength() > 0)
|
||||
{
|
||||
config->dmxgus.resize(data.GetLength());
|
||||
data.Read(config->dmxgus.data(), data.GetLength());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*args == 0) args = midi_config;
|
||||
if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2);
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "GUS: %s: Unable to load sound font\n",args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
config->reader = reader;
|
||||
config->readerName = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Timidity_SetupConfig(TimidityConfig* config, const char* args)
|
||||
{
|
||||
config->errorfunc = gus_printfunc;
|
||||
if (*args == 0) args = timidity_config;
|
||||
if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2);
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "Timidity++: %s: Unable to load sound font\n", args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
config->reader = reader;
|
||||
config->readerName = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WildMidi_SetupConfig(WildMidiConfig* config, const char* args)
|
||||
{
|
||||
config->errorfunc = wm_printfunc;
|
||||
if (*args == 0) args = wildmidi_config;
|
||||
if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
auto reader = sfmanager.OpenSoundFont(args, SF_GUS);
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "WildMidi: %s: Unable to load sound font\n", args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
config->reader = reader;
|
||||
config->readerName = args;
|
||||
config->reverb = wildmidi_reverb;
|
||||
config->enhanced_resampling = wildmidi_enhanced_resampling;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -81,7 +81,7 @@ struct GUSConfig
|
|||
MusicIO::SoundFontReaderInterface *reader;
|
||||
std::string readerName;
|
||||
std::string loadedConfig;
|
||||
std::shared_ptr<Timidity::Instruments> instruments; // this is held both by the config and the device
|
||||
std::unique_ptr<Timidity::Instruments> instruments;
|
||||
};
|
||||
|
||||
namespace TimidityPlus
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "mididefs.h"
|
||||
#include "../../music_common/fileio.h"
|
||||
|
||||
namespace ZMusic // Namespaced because these conflict with the same-named CVARs
|
||||
{
|
||||
|
@ -122,12 +123,24 @@ struct Callbacks
|
|||
// 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.
|
||||
std::string (*NicePath)(const char *path) = nullptr;
|
||||
|
||||
// For playing modules with compressed samples.
|
||||
short* (*DumbVorbisDecode)(int outlen, const void* oggstream, int sizebytes);
|
||||
|
||||
};
|
||||
|
||||
// Sets callbacks for functionality that the client needs to provide.
|
||||
void SetCallbacks(const Callbacks *callbacks);
|
||||
// Sets GenMidi data for OPL playback. If this isn't provided the OPL synth will not work.
|
||||
void SetGenMidi(const uint8_t* data);
|
||||
// Set default bank for OPN. Without this OPN only works with custom banks.
|
||||
void SetWgOpn(const void* data, unsigned len);
|
||||
// Set DMXGUS data for running the GUS synth in actual GUS mode.
|
||||
void SetDmxGus(const void* data, unsigned len);
|
||||
|
||||
// These exports is needed by the MIDI dumpers which need to remain on the client side.
|
||||
class MIDISource; // abstract for the client
|
||||
|
|
|
@ -56,9 +56,6 @@
|
|||
#include "../libraries/zmusic/midisources/midisource.h"
|
||||
#include "../libraries/dumb/include/dumb.h"
|
||||
|
||||
EXTERN_CVAR(Float, gme_stereodepth)
|
||||
|
||||
|
||||
#define GZIP_ID1 31
|
||||
#define GZIP_ID2 139
|
||||
#define GZIP_CM 8
|
||||
|
@ -86,17 +83,6 @@ 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
|
||||
|
@ -168,6 +154,17 @@ static void wm_printfunc(const char* wmfmt, va_list args)
|
|||
VPrintf(PRINT_HIGH, wmfmt, args);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// other callbacks
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static short* dumb_decode_vorbis_(int outlen, const void* oggstream, int sizebytes)
|
||||
{
|
||||
return GSnd->DecodeSample(outlen, oggstream, sizebytes, CODEC_Vorbis);
|
||||
}
|
||||
|
||||
static std::string mus_NicePath(const char* str)
|
||||
{
|
||||
FString strv = NicePath(str);
|
||||
|
@ -180,6 +177,56 @@ 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)
|
||||
{
|
||||
return sfmanager.OpenSoundFont(sfname, type);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Pass some basic working data to the music backend
|
||||
// We do this once at startup for everything available.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void SetupGenMidi()
|
||||
{
|
||||
// The OPL renderer should not care about where this comes from.
|
||||
// Note: No I_Error here - this needs to be consistent with the rest of the music code.
|
||||
auto lump = Wads.CheckNumForName("GENMIDI", ns_global);
|
||||
if (lump < 0) Printf("No GENMIDI lump found. OPL playback not available.");
|
||||
auto data = Wads.OpenLumpReader(lump);
|
||||
|
||||
auto genmidi = data.Read();
|
||||
if (genmidi.Size() < 8 + 175 * 36 || memcmp(genmidi.Data(), "#OPL_II#", 8)) return;
|
||||
SetGenMidi(genmidi.Data()+8);
|
||||
}
|
||||
|
||||
static void SetupWgOpn()
|
||||
{
|
||||
int lump = Wads.CheckNumForFullName("xg.wopn");
|
||||
if (lump < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
FMemLump data = Wads.ReadLump(lump);
|
||||
SetWgOpn(data.GetMem(), (uint32_t)data.GetSize());
|
||||
}
|
||||
|
||||
static void SetupDMXGUS()
|
||||
{
|
||||
int lump = Wads.CheckNumForFullName("DMXGUS");
|
||||
if (lump < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
FMemLump data = Wads.ReadLump(lump);
|
||||
SetDmxGus(data.GetMem(), (uint32_t)data.GetSize());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -199,7 +246,6 @@ void I_InitMusic (void)
|
|||
#endif // _WIN32
|
||||
|
||||
MusicDown = false;
|
||||
dumb_decode_vorbis = dumb_decode_vorbis_;
|
||||
|
||||
Callbacks callbacks;
|
||||
|
||||
|
@ -208,7 +254,12 @@ void I_InitMusic (void)
|
|||
callbacks.WildMidi_MessageFunc = wm_printfunc;
|
||||
callbacks.NicePath = mus_NicePath;
|
||||
callbacks.PathForSoundfont = mus_pathToSoundFont;
|
||||
callbacks.OpenSoundFont = mus_openSoundFont;
|
||||
callbacks.DumbVorbisDecode = dumb_decode_vorbis_;
|
||||
|
||||
SetCallbacks(&callbacks);
|
||||
SetupGenMidi();
|
||||
SetupDMXGUS();
|
||||
}
|
||||
|
||||
|
||||
|
@ -460,7 +511,6 @@ MusInfo *I_RegisterSong (MusicIO::FileInterface *reader, MidiDeviceSetting *devi
|
|||
(id[0] == MAKE_ID('D', 'B', 'R', 'A') && id[1] == MAKE_ID('W', 'O', 'P', 'L')) || // DosBox Raw OPL
|
||||
(id[0] == MAKE_ID('A', 'D', 'L', 'I') && *((uint8_t*)id + 4) == 'B')) // Martin Fernandez's modified IMF
|
||||
{
|
||||
OPL_SetupConfig(&oplConfig, device->args.GetChars(), false);
|
||||
streamsource = OPL_OpenSong(reader, &oplConfig);
|
||||
}
|
||||
else if ((id[0] == MAKE_ID('R', 'I', 'F', 'F') && id[2] == MAKE_ID('C', 'D', 'X', 'A')))
|
||||
|
@ -471,13 +521,12 @@ MusInfo *I_RegisterSong (MusicIO::FileInterface *reader, MidiDeviceSetting *devi
|
|||
// Check for game music
|
||||
else if ((fmt = GME_CheckFormat(id[0])) != nullptr && fmt[0] != '\0')
|
||||
{
|
||||
streamsource = GME_OpenSong(reader, fmt, gme_stereodepth, (int)GSnd->GetOutputRate());
|
||||
streamsource = GME_OpenSong(reader, fmt, (int)GSnd->GetOutputRate());
|
||||
}
|
||||
// Check for module formats
|
||||
else
|
||||
{
|
||||
Dumb_SetupConfig(&dumbConfig);
|
||||
streamsource = MOD_OpenSong(reader, &dumbConfig, (int)GSnd->GetOutputRate());
|
||||
streamsource = MOD_OpenSong(reader, (int)GSnd->GetOutputRate());
|
||||
}
|
||||
if (streamsource == nullptr)
|
||||
{
|
||||
|
|
|
@ -138,15 +138,6 @@ public:
|
|||
|
||||
// Data interface
|
||||
|
||||
void Fluid_SetupConfig(FluidConfig *config, const char* patches, bool systemfallback);
|
||||
void ADL_SetupConfig(ADLConfig *config, const char *Args);
|
||||
void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi = true);
|
||||
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 -----------------------------------------------
|
||||
|
||||
class StreamSource;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
** music_config.cpp
|
||||
** This forwards all CVAR changes to the music system which
|
||||
** was designed for any kind of configuration system.
|
||||
** This forwards all CVAR changes to the music system.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1999-2016 Randy Heit
|
||||
|
@ -33,32 +32,11 @@
|
|||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "i_musicinterns.h"
|
||||
#include "i_soundfont.h"
|
||||
#include "cmdlib.h"
|
||||
#include "doomerrors.h"
|
||||
#include "v_text.h"
|
||||
#include "c_console.h"
|
||||
#include "c_cvars.h"
|
||||
#include "zmusic/zmusic.h"
|
||||
|
||||
#include "zmusic/midiconfig.h"
|
||||
#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
|
||||
extern "C" unsigned __stdcall GetSystemDirectoryA(char* lpBuffer, unsigned uSize);
|
||||
#endif // _WIN32
|
||||
|
||||
static void CheckRestart(int devtype)
|
||||
{
|
||||
if (currSong != nullptr && currSong->GetDeviceType() == devtype)
|
||||
{
|
||||
MIDIDeviceChanged(-1, true);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -229,55 +207,19 @@ CUSTOM_CVAR(Int, fluid_chorus_type, 0/*FLUID_CHORUS_DEFAULT_TYPE*/, CVAR_ARCHIVE
|
|||
|
||||
CUSTOM_CVAR(Int, opl_numchips, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (*self <= 0)
|
||||
{
|
||||
self = 1;
|
||||
}
|
||||
else if (*self > MAXOPL2CHIPS)
|
||||
{
|
||||
self = MAXOPL2CHIPS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currSong != NULL)
|
||||
currSong->ChangeSettingInt("opl.numchips", self);
|
||||
oplConfig.numchips = self;
|
||||
}
|
||||
FORWARD_CVAR(opl_numchips);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, opl_core, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
CheckRestart(MDEV_OPL);
|
||||
FORWARD_CVAR(opl_core);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, opl_fullpan, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
oplConfig.fullpan = self;
|
||||
FORWARD_BOOL_CVAR(opl_fullpan);
|
||||
}
|
||||
|
||||
void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi)
|
||||
{
|
||||
// This needs to be done only once.
|
||||
if (!config->genmidiset && midi)
|
||||
{
|
||||
// The OPL renderer should not care about where this comes from.
|
||||
// Note: No I_Error here - this needs to be consistent with the rest of the music code.
|
||||
auto lump = Wads.CheckNumForName("GENMIDI", ns_global);
|
||||
if (lump < 0) throw std::runtime_error("No GENMIDI lump found");
|
||||
auto data = Wads.OpenLumpReader(lump);
|
||||
|
||||
uint8_t filehdr[8];
|
||||
data.Read(filehdr, 8);
|
||||
if (memcmp(filehdr, "#OPL_II#", 8)) throw std::runtime_error("Corrupt GENMIDI lump");
|
||||
data.Read(oplConfig.OPLinstruments, 175 * 36);
|
||||
config->genmidiset = true;
|
||||
}
|
||||
|
||||
config->core = opl_core;
|
||||
if (args != NULL && *args >= '0' && *args < '4') config->core = *args - '0';
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OPN MIDI device
|
||||
|
@ -287,74 +229,34 @@ void OPL_SetupConfig(OPLConfig *config, const char *args, bool midi)
|
|||
|
||||
CUSTOM_CVAR(Int, opn_chips_count, 8, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
opnConfig.opn_chips_count = self;
|
||||
CheckRestart(MDEV_OPN);
|
||||
FORWARD_CVAR(opn_chips_count);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, opn_emulator_id, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
opnConfig.opn_emulator_id = self;
|
||||
CheckRestart(MDEV_OPN);
|
||||
|
||||
FORWARD_CVAR(opn_emulator_id);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, opn_run_at_pcm_rate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
opnConfig.opn_run_at_pcm_rate = self;
|
||||
CheckRestart(MDEV_OPN);
|
||||
|
||||
FORWARD_BOOL_CVAR(opn_run_at_pcm_rate);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, opn_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
opnConfig.opn_fullpan = self;
|
||||
CheckRestart(MDEV_OPN);
|
||||
|
||||
FORWARD_BOOL_CVAR(opn_fullpan);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, opn_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
CheckRestart(MDEV_OPN);
|
||||
|
||||
FORWARD_BOOL_CVAR(opn_use_custom_bank);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (opn_use_custom_bank)
|
||||
{
|
||||
CheckRestart(MDEV_OPN);
|
||||
}
|
||||
FORWARD_STRING_CVAR(opn_custom_bank);
|
||||
}
|
||||
|
||||
void OPN_SetupConfig(OpnConfig *config, const char *Args)
|
||||
{
|
||||
//Resolve the path here, so that the renderer does not have to do the work itself and only needs to process final names.
|
||||
const char *bank = Args && *Args? Args : opn_use_custom_bank? *opn_custom_bank : nullptr;
|
||||
if (bank && *bank)
|
||||
{
|
||||
auto info = sfmanager.FindSoundFont(bank, SF_WOPN);
|
||||
if (info == nullptr)
|
||||
{
|
||||
config->opn_custom_bank = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
config->opn_custom_bank = info->mFilename;
|
||||
}
|
||||
}
|
||||
|
||||
int lump = Wads.CheckNumForFullName("xg.wopn");
|
||||
if (lump < 0)
|
||||
{
|
||||
config->default_bank.resize(0);
|
||||
return;
|
||||
}
|
||||
FMemLump data = Wads.ReadLump(lump);
|
||||
config->default_bank.resize(data.GetSize());
|
||||
memcpy(config->default_bank.data(), data.GetMem(), data.GetSize());
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GUS MIDI device
|
||||
|
@ -364,240 +266,123 @@ void OPN_SetupConfig(OpnConfig *config, const char *Args)
|
|||
|
||||
CUSTOM_CVAR(String, midi_config, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
CheckRestart(MDEV_GUS);
|
||||
FORWARD_STRING_CVAR(gus_config);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, midi_dmxgus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) // This was 'true' but since it requires special setup that's not such a good idea.
|
||||
{
|
||||
CheckRestart(MDEV_GUS);
|
||||
FORWARD_BOOL_CVAR(gus_dmxgus);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(String, gus_patchdir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
gusConfig.gus_patchdir = self;
|
||||
CheckRestart(MDEV_GUS);
|
||||
FORWARD_STRING_CVAR(gus_patchdir);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, midi_voices, 32, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
gusConfig.midi_voices = self;
|
||||
CheckRestart(MDEV_GUS);
|
||||
FORWARD_CVAR(gus_midi_voices);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
gusConfig.gus_memsize = self;
|
||||
CheckRestart(MDEV_GUS);
|
||||
FORWARD_CVAR(gus_memsize);
|
||||
}
|
||||
|
||||
|
||||
// make sure we can use the above function for the Timidity++ device as well.
|
||||
static_assert(Timidity::CMSG_ERROR == TimidityPlus::CMSG_ERROR, "Timidity constant mismatch");
|
||||
static_assert(Timidity::CMSG_WARNING == TimidityPlus::CMSG_WARNING, "Timidity constant mismatch");
|
||||
static_assert(Timidity::CMSG_INFO == TimidityPlus::CMSG_INFO, "Timidity constant mismatch");
|
||||
static_assert(Timidity::VERB_DEBUG == TimidityPlus::VERB_DEBUG, "Timidity constant mismatch");
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the date to load the instruments for the GUS device.
|
||||
// The actual instrument loader is part of the device.
|
||||
// Timidity++ device
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool GUS_SetupConfig(GUSConfig *config, const char *args)
|
||||
{
|
||||
if ((midi_dmxgus && *args == 0) || !stricmp(args, "DMXGUS"))
|
||||
{
|
||||
if (stricmp(config->loadedConfig.c_str(), "DMXGUS") == 0) return false; // aleady loaded
|
||||
int lump = Wads.CheckNumForName("DMXGUS");
|
||||
if (lump == -1) lump = Wads.CheckNumForName("DMXGUSC");
|
||||
if (lump >= 0)
|
||||
{
|
||||
auto data = Wads.OpenLumpReader(lump);
|
||||
if (data.GetLength() > 0)
|
||||
{
|
||||
config->dmxgus.resize(data.GetLength());
|
||||
data.Read(config->dmxgus.data(), data.GetLength());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*args == 0) args = midi_config;
|
||||
if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2);
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "GUS: %s: Unable to load sound font\n",args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
config->reader = reader;
|
||||
config->readerName = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CVar interface to configurable parameters
|
||||
//
|
||||
// Timidity++ uses a static global set of configuration variables
|
||||
// THese can be changed while the synth is playing but need synchronization.
|
||||
//
|
||||
// Currently the synth is not fully reentrant due to this and a handful
|
||||
// of other global variables.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
template<class T> void ChangeVarSync(T& var, T value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(TimidityPlus::ConfigMutex);
|
||||
var = value;
|
||||
}
|
||||
*/
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_modulation_wheel, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
////ChangeVarSync(TimidityPlus::timidity_modulation_wheel, *self);
|
||||
FORWARD_BOOL_CVAR(timidity_modulation_wheel);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_portamento, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
////ChangeVarSync(TimidityPlus::timidity_portamento, *self);
|
||||
}
|
||||
/*
|
||||
* reverb=0 no reverb 0
|
||||
* reverb=1 old reverb 1
|
||||
* reverb=1,n set reverb level to n (-1 to -127)
|
||||
* reverb=2 "global" old reverb 2
|
||||
* reverb=2,n set reverb level to n (-1 to -127) - 128
|
||||
* reverb=3 new reverb 3
|
||||
* reverb=3,n set reverb level to n (-1 to -127) - 256
|
||||
* reverb=4 "global" new reverb 4
|
||||
* reverb=4,n set reverb level to n (-1 to -127) - 384
|
||||
*/
|
||||
EXTERN_CVAR(Int, timidity_reverb_level)
|
||||
EXTERN_CVAR(Int, timidity_reverb)
|
||||
|
||||
static void SetReverb()
|
||||
{
|
||||
int value = 0;
|
||||
int mode = timidity_reverb;
|
||||
int level = timidity_reverb_level;
|
||||
|
||||
if (mode == 0 || level == 0) value = mode;
|
||||
else value = (mode - 1) * -128 - level;
|
||||
//ChangeVarSync(TimidityPlus::timidity_reverb, value);
|
||||
FORWARD_BOOL_CVAR(timidity_portamento);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, timidity_reverb, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (self < 0 || self > 4) self = 0;
|
||||
else SetReverb();
|
||||
FORWARD_CVAR(timidity_reverb);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, timidity_reverb_level, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (self < 0 || self > 127) self = 0;
|
||||
else SetReverb();
|
||||
FORWARD_CVAR(timidity_reverb_level);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, timidity_chorus, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_chorus, *self);
|
||||
FORWARD_CVAR(timidity_chorus);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_surround_chorus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_surround_chorus, *self);
|
||||
CheckRestart(MDEV_TIMIDITY);
|
||||
FORWARD_BOOL_CVAR(timidity_surround_chorus);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_channel_pressure, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_channel_pressure, *self);
|
||||
FORWARD_BOOL_CVAR(timidity_channel_pressure);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, timidity_lpf_def, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_lpf_def, *self);
|
||||
FORWARD_CVAR(timidity_lpf_def);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_temper_control, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_temper_control, *self);
|
||||
FORWARD_BOOL_CVAR(timidity_temper_control);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_modulation_envelope, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_modulation_envelope, *self);
|
||||
CheckRestart(MDEV_TIMIDITY);
|
||||
FORWARD_BOOL_CVAR(timidity_modulation_envelope);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_overlap_voice_allow, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_overlap_voice_allow, *self);
|
||||
FORWARD_BOOL_CVAR(timidity_overlap_voice_allow);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_drum_effect, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_drum_effect, *self);
|
||||
FORWARD_BOOL_CVAR(timidity_drum_effect);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, timidity_pan_delay, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
//ChangeVarSync(TimidityPlus::timidity_pan_delay, *self);
|
||||
FORWARD_BOOL_CVAR(timidity_pan_delay);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, timidity_drum_power, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) /* coef. of drum amplitude */
|
||||
{
|
||||
if (self < 0) self = 0;
|
||||
else if (self > MAX_AMPLIFICATION / 100.f) self = MAX_AMPLIFICATION / 100.f;
|
||||
//ChangeVarSync(TimidityPlus::timidity_drum_power, *self);
|
||||
FORWARD_CVAR(timidity_drum_power);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, timidity_key_adjust, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (self < -24) self = -24;
|
||||
else if (self > 24) self = 24;
|
||||
//ChangeVarSync(TimidityPlus::timidity_key_adjust, *self);
|
||||
FORWARD_CVAR(timidity_key_adjust);
|
||||
}
|
||||
// For testing mainly.
|
||||
|
||||
CUSTOM_CVAR(Float, timidity_tempo_adjust, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (self < 0.25) self = 0.25;
|
||||
else if (self > 10) self = 10;
|
||||
//ChangeVarSync(TimidityPlus::timidity_tempo_adjust, *self);
|
||||
FORWARD_CVAR(timidity_tempo_adjust);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, min_sustain_time, 5000, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (self < 0) self = 0;
|
||||
//ChangeVarSync(TimidityPlus::min_sustain_time, *self);
|
||||
FORWARD_CVAR(min_sustain_time);
|
||||
}
|
||||
|
||||
// Config file to use
|
||||
CUSTOM_CVAR(String, timidity_config, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
CheckRestart(MDEV_TIMIDITY);
|
||||
}
|
||||
|
||||
bool Timidity_SetupConfig(TimidityConfig* config, const char* args)
|
||||
{
|
||||
if (*args == 0) args = timidity_config;
|
||||
if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
auto reader = sfmanager.OpenSoundFont(args, SF_GUS | SF_SF2);
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "Timidity++: %s: Unable to load sound font\n", args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
config->reader = reader;
|
||||
config->readerName = args;
|
||||
return true;
|
||||
FORWARD_STRING_CVAR(timidity_config);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -608,50 +393,30 @@ bool Timidity_SetupConfig(TimidityConfig* config, const char* args)
|
|||
|
||||
CUSTOM_CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
CheckRestart(MDEV_WILDMIDI);
|
||||
FORWARD_STRING_CVAR(wildmidi_config);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL | CVAR_NOINITCALL)
|
||||
CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (currSong != NULL)
|
||||
currSong->ChangeSettingInt("wildmidi.reverb", *self);
|
||||
wildMidiConfig.reverb = self;
|
||||
FORWARD_BOOL_CVAR(wildmidi_reverb);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL | CVAR_NOINITCALL)
|
||||
CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (currSong != NULL)
|
||||
currSong->ChangeSettingInt("wildmidi.resampling", *self);
|
||||
wildMidiConfig.enhanced_resampling = self;
|
||||
FORWARD_BOOL_CVAR(wildmidi_enhanced_resampling);
|
||||
}
|
||||
|
||||
|
||||
bool WildMidi_SetupConfig(WildMidiConfig* config, const char* args)
|
||||
{
|
||||
if (*args == 0) args = wildmidi_config;
|
||||
if (stricmp(config->loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
auto reader = sfmanager.OpenSoundFont(args, SF_GUS);
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
snprintf(error, 80, "WildMidi: %s: Unable to load sound font\n", args);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
config->reader = reader;
|
||||
config->readerName = args;
|
||||
config->reverb = wildmidi_reverb;
|
||||
config->enhanced_resampling = wildmidi_enhanced_resampling;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This one is for Win32 MMAPI.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CUSTOM_CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_BOOL_CVAR(snd_midiprecache);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -661,40 +426,7 @@ CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRT
|
|||
|
||||
CUSTOM_CVAR(Float, gme_stereodepth, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (currSong != nullptr)
|
||||
currSong->ChangeSettingNum("GME.stereodepth", *self);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Dumb
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CVAR(Int, mod_samplerate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CVAR(Int, mod_volramp, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CVAR(Int, mod_interp, DUMB_LQ_CUBIC, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CVAR(Bool, mod_autochip, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CVAR(Int, mod_autochip_size_force, 100, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CVAR(Int, mod_autochip_size_scan, 500, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CVAR(Int, mod_autochip_scan_threshold, 12, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL);
|
||||
CUSTOM_CVAR(Float, mod_dumb_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
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;
|
||||
FORWARD_CVAR(gme_stereodepth);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -705,13 +437,52 @@ void Dumb_SetupConfig(DumbConfig* config)
|
|||
|
||||
CUSTOM_CVAR(Int, snd_streambuffersize, 64, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
if (self < 16)
|
||||
{
|
||||
self = 16;
|
||||
}
|
||||
else if (self > 1024)
|
||||
{
|
||||
self = 1024;
|
||||
}
|
||||
FORWARD_CVAR(snd_streambuffersize);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Dumb
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CUSTOM_CVAR(Int, mod_samplerate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_CVAR(mod_samplerate);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, mod_volramp, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_CVAR(mod_volramp);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, mod_interp, 2/*DUMB_LQ_CUBIC*/, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_CVAR(mod_interp);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, mod_autochip, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_BOOL_CVAR(mod_autochip);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, mod_autochip_size_force, 100, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_CVAR(mod_autochip_size_force);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, mod_autochip_size_scan, 500, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_CVAR(mod_autochip_size_scan);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, mod_autochip_scan_threshold, 12, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_CVAR(mod_autochip_scan_threshold);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, mod_dumb_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
||||
{
|
||||
FORWARD_CVAR(mod_dumb_mastervolume);
|
||||
}
|
||||
|
||||
|
|
|
@ -193,8 +193,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
|
|||
switch (devtype)
|
||||
{
|
||||
case MDEV_GUS:
|
||||
GUS_SetupConfig(&gusConfig, Args);
|
||||
dev = CreateTimidityMIDIDevice(&gusConfig, samplerate);
|
||||
dev = CreateTimidityMIDIDevice(Args, samplerate);
|
||||
break;
|
||||
|
||||
case MDEV_ADL:
|
||||
|
@ -202,8 +201,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
|
|||
break;
|
||||
|
||||
case MDEV_OPN:
|
||||
OPN_SetupConfig(&opnConfig, Args);
|
||||
dev = CreateOPNMIDIDevice(&opnConfig);
|
||||
dev = CreateOPNMIDIDevice(Args);
|
||||
break;
|
||||
|
||||
case MDEV_MMAPI:
|
||||
|
@ -219,18 +217,15 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
|
|||
break;
|
||||
|
||||
case MDEV_OPL:
|
||||
OPL_SetupConfig(&oplConfig, Args);
|
||||
dev = CreateOplMIDIDevice(&oplConfig);
|
||||
dev = CreateOplMIDIDevice(Args);
|
||||
break;
|
||||
|
||||
case MDEV_TIMIDITY:
|
||||
Timidity_SetupConfig(&timidityConfig, Args);
|
||||
dev = CreateTimidityPPMIDIDevice(&timidityConfig, samplerate);
|
||||
dev = CreateTimidityPPMIDIDevice(Args, samplerate);
|
||||
break;
|
||||
|
||||
case MDEV_WILDMIDI:
|
||||
WildMidi_SetupConfig(&wildMidiConfig, Args);
|
||||
dev = CreateWildMIDIDevice(&wildMidiConfig, samplerate);
|
||||
dev = CreateWildMIDIDevice(Args, samplerate);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue