- something can be heard.

This doesn't pipe the audio through OpenAL yet but the fundamentals for further progress are done.
This commit is contained in:
Christoph Oelckers 2018-02-20 20:50:01 +01:00
parent 5ce3b00b90
commit a8283ffdd6
8 changed files with 73 additions and 64 deletions

View file

@ -44,11 +44,15 @@
#include "version.h"
#include "tmpfileplus.h"
#include "m_misc.h"
#include "v_text.h"
#include "timiditypp/timidity.h"
#include "timiditypp/instrum.h"
class TimidityPPMIDIDevice : public SoftSynthMIDIDevice
{
TArray<uint8_t> midi;
FString CurrentConfig;
static TimidityPlus::Instruments *instruments;
public:
TimidityPPMIDIDevice(const char *args);
~TimidityPPMIDIDevice();
@ -67,9 +71,10 @@ protected:
void HandleLongEvent(const uint8_t *data, int len);
void ComputeOutput(float *buffer, int len);
};
TimidityPlus::Instruments *TimidityPPMIDIDevice::instruments;
// Config file to use
CVAR(String, timidity_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(String, timidity_config, "timidity.cfg", CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
// added because Timidity's output is rather loud.
CUSTOM_CVAR (Float, timidity_mastervolume, 1.0f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -101,14 +106,19 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
{
if (args == NULL || *args == 0) args = timidity_config;
if (CurrentConfig.CompareNoCase(args) != 0)
if (instruments != nullptr && !instruments->checkConfig(args))
{
// reload instruments
// if (!reload_inst()) CurrentConfig = "";
delete instruments;
}
if (CurrentConfig.IsNotEmpty())
instruments = new TimidityPlus::Instruments;
if (!instruments->load(args))
{
//Renderer = new TimidityPlus::Player(timidity_frequency, args);
delete instruments;
instruments = nullptr;
}
if (instruments != nullptr)
{
//Renderer = new TimidityPlus::Player(timidity_frequency, instruments);
}
}
@ -136,11 +146,19 @@ TimidityPPMIDIDevice::~TimidityPPMIDIDevice ()
//
//==========================================================================
namespace TimidityPlus
{
int load_midi_file(FileReader *fr, TimidityPlus::Instruments *inst);
void run_midi(int samples);
void timidity_close();
}
bool TimidityPPMIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
{
// Write MIDI song to temporary file
song->CreateSMF(midi, looping ? 0 : 1);
return midi.Size() > 0;
MemoryReader fr((char*)&midi[0], midi.Size());
return !TimidityPlus::load_midi_file(&fr, instruments);
}
//==========================================================================
@ -148,21 +166,16 @@ bool TimidityPPMIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
// TimidityPPMIDIDevice :: Open
//
//==========================================================================
namespace TimidityPlus
{
int load_midi_file(FileReader *fr);
void run_midi(int samples);
void timidity_close();
}
int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata)
{
// No instruments loaded means we cannot play...
if (instruments == nullptr) return 0;
int ret = OpenStream(2, 0, callback, userdata);
if (ret == 0)
{
//Renderer->Reset();
MemoryReader fr((char*)&midi[0], midi.Size());
return !TimidityPlus::load_midi_file(&fr);
}
return ret;
}
@ -217,8 +230,10 @@ void TimidityPPMIDIDevice::HandleLongEvent(const uint8_t *data, int len)
void TimidityPPMIDIDevice::ComputeOutput(float *buffer, int len)
{
Printf("Committing slice\n");
TimidityPlus::run_midi(len / 8); // bytes to samples
memset(buffer, len, 0); // to do
Printf("Done\n");
//Renderer->ComputeOutput(buffer, len);
}
@ -242,3 +257,30 @@ MIDIDevice *CreateTimidityPPMIDIDevice(const char *args)
{
return new TimidityPPMIDIDevice(args);
}
void TimidityPlus::ctl_cmsg(int type, int verbosity_level, const char *fmt, ...)
{
if (verbosity_level >= VERB_DEBUG) return; // Don't waste time on diagnostics.
va_list args;
va_start(args, fmt);
FString msg;
msg.VFormat(fmt, args);
va_end(args);
switch (type)
{
case CMSG_ERROR:
Printf(TEXTCOLOR_RED "%s\n", msg.GetChars());
break;
case CMSG_WARNING:
Printf(TEXTCOLOR_YELLOW "%s\n", msg.GetChars());
break;
case CMSG_INFO:
DPrintf(DMSG_SPAMMY, "%s\n", msg.GetChars());
break;
}
}

View file

@ -134,7 +134,6 @@ double flt_rand()
PathList::PathList()
{
paths.push_back("./");
}
/* This adds a directory to the path list */
@ -234,9 +233,11 @@ std::pair<FileReader *, std::string> PathList::openFile(const char *name, bool i
s += '/';
}
s += name;
auto fr = tryOpenPath(name, ismainfile);
auto fr = tryOpenPath(s.c_str(), ismainfile);
if (fr!= nullptr) return std::make_pair(fr, s);
}
auto fr = tryOpenPath(name, ismainfile);
if (fr != nullptr) return std::make_pair(fr, name);
}
else
{
@ -254,13 +255,11 @@ std::pair<FileReader *, std::string> PathList::openFile(const char *name, bool i
int PathList::isAbsPath(const char *name)
{
if (name[0] == '/')
return 1;
if (name[0] == '/') return 1;
#ifdef _WIN32
/* [A-Za-z]: (for Windows) */
if (isalpha(name[0]) && name[1] == ':')
return 1;
if (isalpha(name[0]) && name[1] == ':') return 1;
#endif /* _WIN32 */
return 0;
}

View file

@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "common.h"
#include "instrum.h"
#include "quantity.h"
#include "cmdlib.h"
@ -646,6 +647,7 @@ int Instruments::read_config_file(const char *name, int self, int allow_missing_
if (!self)
{
basedir = strdup_mblock(&varbuf, tf->filename.c_str());
FixPathSeperator((char*)basedir);
sep = (char*)strrchr(basedir, '/');
}
else

View file

@ -51,27 +51,8 @@ inline bool RC_IS_SKIP_FILE(int rc)
return ((rc) == RC_QUIT || (rc) == RC_ERROR || (rc) == RC_STOP || (rc) == RC_TUNE_END);
}
inline void ctl_cmsg(int type, int verbosity_level, const char *fmt, ...)
{
/* todo:
CMSG_ERROR: I_Error(...)
CMSG_WARNING, VERB_NORMAL: Printf(TEXTCOLOR_YELLOW
CMSG_WARNING, VERB_VERBOSE: DPrintf(DMSG_SPAMMY
CMSG_INFO, VERB_DEBUG/VERB_NOISY: ignore
/*
#ifdef _WIN32
char buf[1024];
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
I_DebugPrint(buf);
#endif
*/
}
void ctl_cmsg(int type, int verbosity_level, const char *fmt, ...);
}

View file

@ -54,7 +54,7 @@ Instruments::Instruments()
bool Instruments::load(const char *config)
{
if (read_config_file(config, 0, 0, true))
if (read_config_file(config, 0, 0, true) == RC_OK)
{
init_load_soundfont();
set_default_instrument();
@ -617,13 +617,10 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr,
}
/* Open patch file */
if (!(tf = open_file(name, false, pathlist))) {
#ifdef PATCH_EXT_LIST
int name_len, ext_len;
static const char *patch_ext[] = PATCH_EXT_LIST;
#endif
static const char *patch_ext[] = { ".pat", 0 };
noluck = 1;
#ifdef PATCH_EXT_LIST
name_len = (int)strlen(name);
/* Try with various extensions */
for (i = 0; patch_ext[i]; i++) {
@ -641,7 +638,6 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr,
}
}
}
#endif
}
if (noluck) {
ctl_cmsg(CMSG_ERROR, VERB_NORMAL,

View file

@ -1855,6 +1855,7 @@ void Player::finish_note(int i)
void Player::set_envelope_time(int ch, int val, int stage)
{
val = val & 0x7F;
#if 0
switch(stage) {
case EG_ATTACK: /* Attack */
//ctl_cmsg(CMSG_INFO,VERB_NOISY,"Attack Time (CH:%d VALUE:%d)", ch, val);
@ -1868,6 +1869,7 @@ void Player::set_envelope_time(int ch, int val, int stage)
default:
//ctl_cmsg(CMSG_INFO,VERB_NOISY,"? Time (CH:%d VALUE:%d)", ch, val);
}
#endif
channel[ch].envelope_rate[stage] = val;
}
@ -3382,8 +3384,8 @@ void Player::process_sysex_event(int ev, int ch, int val, int b)
case 0x23: /* Insertion Effect ON/OFF */
if(!opt_insertion_effect) {break;}
if(channel[ch].insertion_effect != val) {
if(val) {//ctl_cmsg(CMSG_INFO,VERB_NOISY,"EFX ON (CH:%d)",ch);}
else {//ctl_cmsg(CMSG_INFO,VERB_NOISY,"EFX OFF (CH:%d)",ch);}
//if(val) {//ctl_cmsg(CMSG_INFO,VERB_NOISY,"EFX ON (CH:%d)",ch);}
//else {//ctl_cmsg(CMSG_INFO,VERB_NOISY,"EFX OFF (CH:%d)",ch);}
}
channel[ch].insertion_effect = val;
break;

View file

@ -1562,7 +1562,7 @@ int load_midi_file(FileReader *fr, TimidityPlus::Instruments *inst)
void Player::run_midi(int samples)
{
auto time = current_event->time + samples;
while (current_event->time < samples)
while (current_event->time < time)
{
if (play_event(current_event) != RC_OK)
return;

View file

@ -71,19 +71,6 @@ typedef struct _ChannelBitMask
# define TIM_FSCALENEG(a,b) ((a) * (1.0 / (double)(1<<(b))))
#ifdef _WIN32
#undef PATCH_EXT_LIST
#define PATCH_EXT_LIST { ".pat", 0 }
#endif
#define PATH_SEP '/'
#define PATH_STRING "/"
#define IS_PATH_SEP(c) ((c) == PATH_SEP)
#define NLS "\n"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif /* M_PI */