- handled the final piece where Timidity++ had a direct dependency on GZDoom - the error logging function.

This is npw a function pointer so that a simple stdout printout can be used as default, but allows to override it.
Also added the missing timidity_file.h header.
This commit is contained in:
Christoph Oelckers 2019-09-23 14:14:32 +02:00
parent 98329311b4
commit 56e4c8f213
5 changed files with 200 additions and 29 deletions

View file

@ -44,6 +44,43 @@
#include "timiditypp/playmidi.h"
//==========================================================================
//
// Error printing override to redirect to the internal console instead of stdout.
//
//==========================================================================
static void gzdoom_ctl_cmsg(int type, int verbosity_level, const char* fmt, ...)
{
if (verbosity_level >= TimidityPlus::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 TimidityPlus::CMSG_ERROR:
Printf(TEXTCOLOR_RED "%s\n", msg.GetChars());
break;
case TimidityPlus::CMSG_WARNING:
Printf(TEXTCOLOR_YELLOW "%s\n", msg.GetChars());
break;
case TimidityPlus::CMSG_INFO:
DPrintf(DMSG_SPAMMY, "%s\n", msg.GetChars());
break;
}
}
//==========================================================================
//
// CVar interface to configurable parameters
//
//==========================================================================
template<class T> void ChangeVarSync(T& var, T value)
{
@ -237,11 +274,11 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args, int samplerate)
delete instruments;
instruments = nullptr;
}
TimidityPlus::ctl_cmsg = gzdoom_ctl_cmsg;
TimidityPlus::set_playback_rate(SampleRate);
if (instruments == nullptr)
{
auto sfreader = sfmanager.OpenSoundFont(args, SF_SF2 | SF_GUS);
if (sfreader != nullptr)
{
@ -367,30 +404,3 @@ void TimidityPP_Shutdown()
TimidityPlus::free_gauss_table();
TimidityPlus::free_global_mblock();
}
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

@ -27,6 +27,7 @@
#include <string.h>
#include <ctype.h>
#include "common.h"
#include "controls.h"
namespace TimidityPlus
{
@ -151,5 +152,31 @@ int tf_getc(struct timidity_file *tf)
return read == 0 ? EOF : c;
}
void default_ctl_cmsg(int type, int verbosity_level, const char* fmt, ...)
{
if (verbosity_level >= VERB_DEBUG) return; // Don't waste time on diagnostics.
char buffer[2048];
va_list args;
va_start(args, fmt);
switch (type)
{
case CMSG_ERROR:
vprintf("Error: %s\n", args);
break;
case CMSG_WARNING:
vprintf("Warning: %s\n", args);
break;
case CMSG_INFO:
vprintf("Info: %s\n", args);
break;
}
}
// Allow hosting applications to capture the messages and deal with them themselves.
void (*ctl_cmsg)(int type, int verbosity_level, const char* fmt, ...) = default_ctl_cmsg;
}

View file

@ -52,7 +52,7 @@ inline bool RC_IS_SKIP_FILE(int rc)
}
void ctl_cmsg(int type, int verbosity_level, const char *fmt, ...);
extern void (*ctl_cmsg)(int type, int verbosity_level, const char* fmt, ...);
}

View file

@ -174,5 +174,6 @@ const int max_voices = DEFAULT_VOICES;
const int temper_type_mute = 0;
const int opt_preserve_silence = 0;
const int opt_init_keysig = 8;
}
#endif /* TIMIDITY_H_INCLUDED */

View file

@ -0,0 +1,133 @@
/*
TiMidity++ -- File interface for the pure sequencer.
Copyright (C) 2019 Christoph Oelckers
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include <stdio.h>
#include <vector>
#include <string>
namespace TimidityPlus
{
struct timidity_file
{
std::string filename;
virtual ~timidity_file() {}
virtual char* gets(char* buff, int n) = 0;
virtual long read(void* buff, int32_t size, int32_t nitems) = 0;
virtual long seek(long offset, int whence) = 0;
virtual long tell() = 0;
};
class SoundFontReaderInterface
{
public:
virtual struct timidity_file* open_timidityplus_file(const char* fn) = 0;
virtual void timidityplus_add_path(const char* path) = 0;
};
// A minimalistic sound font reader interface. Normally this should be replaced with something better tied into the host application.
#ifdef USE_BASE_INTERFACE
// Base version of timidity_file using stdio's FILE.
struct timidity_file_FILE : public timidity_file
{
FILE* f = nullptr;
~timidity_file_FILE()
{
if (f) fclose(f);
}
char* gets(char* buff, int n) override
{
if (!f) return nullptr;
return fgets(buff, n, f);
}
long read(void* buff, int32_t size, int32_t nitems) override
{
if (!f) return 0;
return (long)fread(buff, size, nitems, f);
}
long seek(long offset, int whence) override
{
if (!f) return 0;
return fseek(f, offset, whence);
}
long tell() override
{
if (!f) return 0;
return ftell(f);
}
};
class BaseSoundFontReader : public SoundFontReaderInterface
{
std::vector<std::string> paths;
bool IsAbsPath(const char *name)
{
if (name[0] == '/' || name[0] == '\\') return true;
#ifdef _WIN32
/* [A-Za-z]: (for Windows) */
if (isalpha(name[0]) && name[1] == ':') return true;
#endif /* _WIN32 */
return 0;
}
struct timidity_file* open_timidityplus_file(const char* fn)
{
FILE *f = nullptr;
std::string fullname;
if (!fn)
{
f = fopen("timidity.cfg", "rt");
fullname = "timidity.cfg";
}
else
{
if (!IsAbsPath(fn))
{
for(int i = (int)paths.size()-1; i>=0; i--)
{
fullname = paths[i] + fn;
f = fopen(fullname.c_str(), "rt");
break;
}
}
if (!f) f = fopen(fn, "rt");
}
if (!f) return nullptr;
auto tf = new timidity_file_FILE;
tf->f = f;
tf->filename = fullname;
return tf;
}
void timidityplus_add_path(const char* path)
{
std::string p = path;
if (p.back() != '/' && p.back() != '\\') p += '/'; // always let it end with a slash.
paths.push_back(p);
}
};
#endif
}