- made the global interface c compatible. Added an empty C source so that incompatibilities immediately trigger compile errors.

- simplified the message printing interface to a single function.
This commit is contained in:
Christoph Oelckers 2020-01-11 12:47:07 +01:00
parent 463cd4e0c5
commit 17d7942d02
17 changed files with 159 additions and 155 deletions

View file

@ -4,10 +4,14 @@
#include <stdint.h>
#include <stdarg.h>
struct SoundDecoder; // Anonymous to the client.
typedef unsigned char zmusic_bool;
// These constants must match the corresponding values of the Windows headers
// to avoid readjustment in the native Windows device's playback functions
// and should not be changed.
enum EMidiDeviceClass
typedef enum EMidiDeviceClass_
{
MIDIDEV_MIDIPORT = 1,
MIDIDEV_SYNTH,
@ -16,18 +20,18 @@ enum EMidiDeviceClass
MIDIDEV_MAPPER,
MIDIDEV_WAVETABLE,
MIDIDEV_SWSYNTH
};
} EMidiDeviceClass;
enum EMIDIType
typedef enum EMIDIType_
{
MIDI_NOTMIDI,
MIDI_MIDI,
MIDI_HMI,
MIDI_XMI,
MIDI_MUS
};
} EMIDIType;
enum EMidiDevice
typedef enum EMidiDevice_
{
MDEV_DEFAULT = -1,
MDEV_STANDARD = 0,
@ -41,35 +45,36 @@ enum EMidiDevice
MDEV_OPN = 8,
MDEV_COUNT
};
} EMidiDevice;
enum ESoundFontTypes
typedef enum ESoundFontTypes_
{
SF_SF2 = 1,
SF_GUS = 2,
SF_WOPL = 4,
SF_WOPN = 8
};
} ESoundFontTypes;
struct SoundStreamInfo
typedef struct SoundStreamInfo_
{
int mBufferSize; // If mBufferSize is 0, the song doesn't use streaming but plays through a different interface.
int mSampleRate;
int mNumChannels; // If mNumChannels is negative, 16 bit integer format is used instead of floating point.
};
} SoundStreamInfo;
enum SampleType
typedef enum SampleType_
{
SampleType_UInt8,
SampleType_Int16
};
enum ChannelConfig
} SampleType;
typedef enum ChannelConfig_
{
ChannelConfig_Mono,
ChannelConfig_Stereo
};
} ChannelConfig;
enum EIntConfigKey
typedef enum EIntConfigKey_
{
zmusic_adl_chips_count,
zmusic_adl_emulator_id,
@ -136,9 +141,9 @@ enum EIntConfigKey
zmusic_snd_outputrate,
NUM_ZMUSIC_INT_CONFIGS
};
} EIntConfigKey;
enum EFloatConfigKey
typedef enum EFloatConfigKey_
{
zmusic_fluid_gain = 1000,
zmusic_fluid_reverb_roomsize,
@ -161,9 +166,9 @@ enum EFloatConfigKey
zmusic_snd_mastervolume,
NUM_FLOAT_CONFIGS
};
} EFloatConfigKey;
enum EStringConfigKey
typedef enum EStringConfigKey_
{
zmusic_adl_custom_bank = 2000,
zmusic_fluid_lib,
@ -175,36 +180,43 @@ enum EStringConfigKey
zmusic_wildmidi_config,
NUM_STRING_CONFIGS
};
} EStringConfigKey;
struct ZMusicCustomReader
typedef struct ZMusicCustomReader_
{
void* handle;
char* (*gets)(struct ZMusicCustomReader* handle, char* buff, int n);
long (*read)(struct ZMusicCustomReader* handle, void* buff, int32_t size);
long (*seek)(struct ZMusicCustomReader* handle, long offset, int whence);
long (*tell)(struct ZMusicCustomReader* handle);
void (*close)(struct ZMusicCustomReader* handle);
};
char* (*gets)(struct ZMusicCustomReader_* handle, char* buff, int n);
long (*read)(struct ZMusicCustomReader_* handle, void* buff, int32_t size);
long (*seek)(struct ZMusicCustomReader_* handle, long offset, int whence);
long (*tell)(struct ZMusicCustomReader_* handle);
void (*close)(struct ZMusicCustomReader_* handle);
} ZMusicCustomReader;
struct ZMusicMidiOutDevice
typedef struct ZMusicMidiOutDevice_
{
char *Name;
int ID;
int Technology;
};
} ZMusicMidiOutDevice;
struct ZMusicCallbacks
typedef enum EZMusicMessageSeverity_
{
ZMUSIC_MSG_VERBOSE = 1,
ZMUSIC_MSG_DEBUG = 5,
ZMUSIC_MSG_NOTIFY = 10,
ZMUSIC_MSG_WARNING = 50,
ZMUSIC_MSG_ERROR = 100,
ZMUSIC_MSG_FATAL = 666,
} EZMusicMessageSeverity;
typedef struct ZMusicCallbacks_
{
// Callbacks the client can install to capture messages from the backends
// or to provide sound font data.
void (*MessageFunc)(int severity, const char* msg);
// The message callbacks are optional, without them the output goes to stdout.
void (*WildMidi_MessageFunc)(const char* wmfmt, va_list args);
void (*GUS_MessageFunc)(int type, int verbosity_level, const char* fmt, ...);
void (*Timidity_Messagefunc)(int type, int verbosity_level, const char* fmt, ...);
int (*Fluid_MessageFunc)(const char *fmt, ...);
// Retrieves the path to a soundfont identified by an identifier. Only needed if the client virtualizes the sound font names
const char *(*PathForSoundfont)(const char *name, int type);
@ -219,7 +231,7 @@ struct ZMusicCallbacks
// Opens a file in the sound font. For GUS patch sets this will try to open each patch with this function.
// For other formats only the sound font's actual name can be requested.
// When passed NULL this must open the Timidity config file, if this is requested for an SF2 sound font it should be synthesized.
struct ZMusicCustomReader* (*SF_OpenFile)(void* handle, const char* fn);
ZMusicCustomReader* (*SF_OpenFile)(void* handle, const char* fn);
//Adds a path to the list of directories in which files must be looked for.
void (*SF_AddToSearchPath)(void* handle, const char* path);
@ -229,23 +241,24 @@ struct ZMusicCallbacks
// Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion.
const char *(*NicePath)(const char* path);
};
} ZMusicCallbacks;
enum ZMusicVariableType
typedef enum ZMusicVariableType_
{
ZMUSIC_VAR_INT,
ZMUSIC_VAR_BOOL,
ZMUSIC_VAR_FLOAT,
ZMUSIC_VAR_STRING,
};
struct ZMusicConfigurationSetting
} ZMusicVariableType;
typedef struct ZMusicConfigurationSetting_
{
const char* name;
int identifier;
ZMusicVariableType type;
float defaultVal;
const char* defaultString;
};
} ZMusicConfigurationSetting;
#ifndef ZMUSIC_INTERNAL
@ -281,40 +294,40 @@ extern "C"
// These exports are needed by the MIDI dumpers which need to remain on the client side because the need access to the client's file system.
DLL_IMPORT EMIDIType ZMusic_IdentifyMIDIType(uint32_t* id, int size);
DLL_IMPORT ZMusic_MidiSource ZMusic_CreateMIDISource(const uint8_t* data, size_t length, EMIDIType miditype);
DLL_IMPORT bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
DLL_IMPORT zmusic_bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(struct ZMusicCustomReader* reader, EMidiDevice device, const char* Args);
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EMidiDevice device, const char* Args);
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char *filename, EMidiDevice device, const char* Args);
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void *mem, size_t size, EMidiDevice device, const char* Args);
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid = 0);
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid);
DLL_IMPORT bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len);
DLL_IMPORT bool ZMusic_Start(ZMusic_MusicStream song, int subsong, bool loop);
DLL_IMPORT zmusic_bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len);
DLL_IMPORT zmusic_bool ZMusic_Start(ZMusic_MusicStream song, int subsong, zmusic_bool loop);
DLL_IMPORT void ZMusic_Pause(ZMusic_MusicStream song);
DLL_IMPORT void ZMusic_Resume(ZMusic_MusicStream song);
DLL_IMPORT void ZMusic_Update(ZMusic_MusicStream song);
DLL_IMPORT bool ZMusic_IsPlaying(ZMusic_MusicStream song);
DLL_IMPORT zmusic_bool ZMusic_IsPlaying(ZMusic_MusicStream song);
DLL_IMPORT void ZMusic_Stop(ZMusic_MusicStream song);
DLL_IMPORT void ZMusic_Close(ZMusic_MusicStream song);
DLL_IMPORT bool ZMusic_SetSubsong(ZMusic_MusicStream song, int subsong);
DLL_IMPORT bool ZMusic_IsLooping(ZMusic_MusicStream song);
DLL_IMPORT bool ZMusic_IsMIDI(ZMusic_MusicStream song);
DLL_IMPORT zmusic_bool ZMusic_SetSubsong(ZMusic_MusicStream song, int subsong);
DLL_IMPORT zmusic_bool ZMusic_IsLooping(ZMusic_MusicStream song);
DLL_IMPORT zmusic_bool ZMusic_IsMIDI(ZMusic_MusicStream song);
DLL_IMPORT void ZMusic_VolumeChanged(ZMusic_MusicStream song);
DLL_IMPORT bool ZMusic_WriteSMF(ZMusic_MidiSource source, const char* fn, int looplimit);
DLL_IMPORT zmusic_bool ZMusic_WriteSMF(ZMusic_MidiSource source, const char* fn, int looplimit);
DLL_IMPORT void ZMusic_GetStreamInfo(ZMusic_MusicStream song, SoundStreamInfo *info);
// Configuration interface. The return value specifies if a music restart is needed.
// RealValue should be written back to the CVAR or whatever other method the client uses to store configuration state.
DLL_IMPORT bool ChangeMusicSettingInt(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue);
DLL_IMPORT bool ChangeMusicSettingFloat(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue);
DLL_IMPORT bool ChangeMusicSettingString(EStringConfigKey key, ZMusic_MusicStream song, const char* value);
DLL_IMPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue);
DLL_IMPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue);
DLL_IMPORT zmusic_bool ChangeMusicSettingString(EStringConfigKey key, ZMusic_MusicStream song, const char* value);
DLL_IMPORT const char *ZMusic_GetStats(ZMusic_MusicStream song);
DLL_IMPORT struct SoundDecoder* CreateDecoder(const uint8_t* data, size_t size, bool isstatic);
DLL_IMPORT struct SoundDecoder* CreateDecoder(const uint8_t* data, size_t size, zmusic_bool isstatic);
DLL_IMPORT void SoundDecoder_GetInfo(struct SoundDecoder* decoder, int* samplerate, ChannelConfig* chans, SampleType* type);
DLL_IMPORT size_t SoundDecoder_Read(struct SoundDecoder* decoder, void* buffer, size_t length);
DLL_IMPORT void SoundDecoder_Close(struct SoundDecoder* decoder);
DLL_IMPORT void FindLoopTags(const uint8_t* data, size_t size, uint32_t* start, bool* startass, uint32_t* end, bool* endass);
DLL_IMPORT void FindLoopTags(const uint8_t* data, size_t size, uint32_t* start, zmusic_bool* startass, uint32_t* end, zmusic_bool* endass);
// The rest of the decoder interface is only useful for streaming music.
DLL_IMPORT const ZMusicMidiOutDevice *ZMusic_GetMidiDevices(int *pAmount);

View file

@ -85,6 +85,7 @@ file( GLOB HEADER_FILES
decoder/*.h
streamsources/*.h
../thirdparty/*.h
../include/*.h
)
set( all_files
${HEADER_FILES}
@ -118,6 +119,7 @@ set( all_files
zmusic/configuration.cpp
zmusic/zmusic.cpp
zmusic/critsec.cpp
loader/test.c
${PLAT_SOURCES}
)
@ -176,7 +178,8 @@ source_group("MIDI Devices" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/mid
source_group("MIDI Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/midisources/.+")
source_group("Music Formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/musicformats/.+")
source_group("Music Formats\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/musicformats/win32/.+")
source_group("Public Interface" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/zmusic/.+")
source_group("ZMusic Core" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/zmusic/.+")
source_group("Sound Decoding" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/decoder/.+")
source_group("Stream Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/streamsources/.+")
source_group("Third Party" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/.+")
source_group("Public Interface" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/../include/.+")

View file

@ -116,7 +116,7 @@ short* dumb_decode_vorbis(int outlen, const void* oggstream, int sizebytes)
return samples;
}
DLL_EXPORT struct SoundDecoder* CreateDecoder(const uint8_t* data, size_t size, bool isstatic)
DLL_EXPORT struct SoundDecoder* CreateDecoder(const uint8_t* data, size_t size, zmusic_bool isstatic)
{
MusicIO::FileInterface* reader;
if (isstatic) reader = new MusicIO::MemoryReader(data, (long)size);

2
source/loader/test.c Normal file
View file

@ -0,0 +1,2 @@
// This file is only here to have one module that includes the header from a pure C source, so that it immediately errors out when something incompatible is found.
#include "zmusic.h"

View file

@ -41,6 +41,7 @@
#include "mididevice.h"
#include "zmusic/m_swap.h"
#include "zmusic/mus2midi.h"
#include "zmusic_internal.h"
#include "music_alsa_state.h"
#include <alsa/asoundlib.h>
@ -68,7 +69,7 @@ struct EventState {
class AlsaMIDIDevice : public MIDIDevice
{
public:
AlsaMIDIDevice(int dev_id, int (*printfunc_)(const char *, ...));
AlsaMIDIDevice(int dev_id);
~AlsaMIDIDevice();
int Open() override;
void Close() override;
@ -106,7 +107,6 @@ public:
protected:
AlsaSequencer &sequencer;
int (*printfunc)(const char*, ...);
MidiHeader *Events = nullptr;
bool Started = false;
@ -132,7 +132,7 @@ protected:
}
AlsaMIDIDevice::AlsaMIDIDevice(int dev_id, int (*printfunc_)(const char*, ...) = nullptr) : sequencer(AlsaSequencer::Get()), printfunc(printfunc_)
AlsaMIDIDevice::AlsaMIDIDevice(int dev_id) : sequencer(AlsaSequencer::Get())
{
auto & internalDevices = sequencer.GetInternalDevices();
auto & device = internalDevices.at(dev_id);
@ -394,9 +394,7 @@ void AlsaMIDIDevice::PumpEvents() {
continue;
}
if (tick_delta < 0) {
if(printfunc) {
printfunc("Alsa sequencer underrun: %d ticks!\n", tick_delta);
}
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Alsa sequencer underrun: %d ticks!\n", tick_delta);
}
// We found an event worthy of sending to the sequencer
@ -405,12 +403,10 @@ void AlsaMIDIDevice::PumpEvents() {
snd_seq_ev_schedule_tick(&event.data, QueueId, false, buffer_ticks + event.ticks);
int result = snd_seq_event_output(sequencer.handle, &event.data);
if(result < 0) {
if(printfunc) {
printfunc("Alsa sequencer did not accept event: error %d!\n", result);
}
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Alsa sequencer did not accept event: error %d!\n", result);
if(WaitForExit(pump_step, status)) {
break;
}
 }
continue;
}
buffer_ticks += event.ticks;

View file

@ -60,7 +60,7 @@ struct fluid_synth_t;
class FluidSynthMIDIDevice : public SoftSynthMIDIDevice
{
public:
FluidSynthMIDIDevice(int samplerate, std::vector<std::string> &config, int (*printfunc_)(const char *, ...));
FluidSynthMIDIDevice(int samplerate, std::vector<std::string> &config);
~FluidSynthMIDIDevice();
int OpenRenderer() override;
@ -78,7 +78,6 @@ protected:
fluid_settings_t *FluidSettings;
fluid_synth_t *FluidSynth;
int (*printfunc)(const char*, ...);
// Possible results returned by fluid_settings_...() functions
// Initial values are for FluidSynth 2.x
@ -173,12 +172,11 @@ const char *BaseFileSearch(const char *file, const char *ext, bool lookfirstinpr
//
//==========================================================================
FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, std::vector<std::string> &config, int (*printfunc_)(const char*, ...) = nullptr)
FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, std::vector<std::string> &config)
: SoftSynthMIDIDevice(samplerate <= 0? fluidConfig.fluid_samplerate : samplerate, 22050, 96000)
{
StreamBlockSize = 4;
printfunc = printfunc_;
FluidSynth = NULL;
FluidSettings = NULL;
#ifdef DYN_FLUIDSYNTH
@ -358,12 +356,12 @@ int FluidSynthMIDIDevice::LoadPatchSets(const std::vector<std::string> &config)
{
if (FLUID_FAILED != fluid_synth_sfload(FluidSynth, file.c_str(), count == 0))
{
//DPrintf(DMSG_NOTIFY, "Loaded patch set %s.\n", tok);
ZMusic_Printf(ZMUSIC_MSG_DEBUG, "Loaded patch set %s.\n", file.c_str());
count++;
}
else
{
if (printfunc) printfunc("Failed to load patch set %s.\n", file.c_str());
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Failed to load patch set %s.\n", file.c_str());
}
}
return count;
@ -389,19 +387,19 @@ void FluidSynthMIDIDevice::ChangeSettingInt(const char *setting, int value)
{
if (FLUID_OK != fluid_synth_set_interp_method(FluidSynth, -1, value))
{
if (printfunc) printfunc("Setting interpolation method %d failed.\n", value);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Setting interpolation method %d failed.\n", value);
}
}
else if (strcmp(setting, "synth.polyphony") == 0)
{
if (FLUID_OK != fluid_synth_set_polyphony(FluidSynth, value))
{
if (printfunc) printfunc("Setting polyphony to %d failed.\n", value);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Setting polyphony to %d failed.\n", value);
}
}
else if (FluidSettingsResultFailed == fluid_settings_setint(FluidSettings, setting, value))
{
if (printfunc) printfunc("Failed to set %s to %d.\n", setting, value);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Failed to set %s to %d.\n", setting, value);
}
// fluid_settings_setint succeeded; update these settings in the running synth, too
else if (strcmp(setting, "synth.reverb.active") == 0)
@ -440,7 +438,7 @@ void FluidSynthMIDIDevice::ChangeSettingNum(const char *setting, double value)
}
else if (FluidSettingsResultFailed == fluid_settings_setnum(FluidSettings, setting, value))
{
if (printfunc) printfunc("Failed to set %s to %g.\n", setting, value);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Failed to set %s to %g.\n", setting, value);
}
}
@ -463,7 +461,7 @@ void FluidSynthMIDIDevice::ChangeSettingString(const char *setting, const char *
if (FluidSettingsResultFailed == fluid_settings_setstr(FluidSettings, setting, value))
{
if (printfunc) printfunc("Failed to set %s to %s.\n", setting, value);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Failed to set %s to %s.\n", setting, value);
}
}
@ -543,7 +541,7 @@ bool FluidSynthMIDIDevice::LoadFluidSynth(const char *fluid_lib)
if(!FluidSynthModule.Load({fluid_lib}))
{
const char* libname = fluid_lib;
if (printfunc) printfunc("Could not load %s\n", libname);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Could not load %s\n", libname);
}
else
return true;
@ -551,7 +549,7 @@ bool FluidSynthMIDIDevice::LoadFluidSynth(const char *fluid_lib)
if(!FluidSynthModule.Load({FLUIDSYNTHLIB1, FLUIDSYNTHLIB2}))
{
if (printfunc) printfunc("Could not load " FLUIDSYNTHLIB1 " or " FLUIDSYNTHLIB2 "\n");
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Could not load " FLUIDSYNTHLIB1 " or " FLUIDSYNTHLIB2 "\n");
return false;
}
@ -633,8 +631,7 @@ void Fluid_SetupConfig(const char* patches, std::vector<std::string> &patch_path
}
else
{
if (musicCallbacks.Fluid_MessageFunc)
musicCallbacks.Fluid_MessageFunc("Could not find patch set %s.\n", tok);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Could not find patch set %s.\n", tok);
}
tok = strtok(NULL, delim);
}
@ -686,7 +683,7 @@ MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, const char *Args)
std::vector<std::string> fluid_patchset;
Fluid_SetupConfig(Args, fluid_patchset, true);
return new FluidSynthMIDIDevice(samplerate, fluid_patchset, musicCallbacks.Fluid_MessageFunc);
return new FluidSynthMIDIDevice(samplerate, fluid_patchset);
}
#else

View file

@ -348,8 +348,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
lastRequestedDevice = requestedDevice;
lastSelectedDevice = selectedDevice;
if (musicCallbacks.Fluid_MessageFunc)
musicCallbacks.Fluid_MessageFunc("Unable to create %s MIDI device. Falling back to %s\n", devnames[requestedDevice], devnames[selectedDevice]);
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Unable to create %s MIDI device. Falling back to %s\n", devnames[requestedDevice], devnames[selectedDevice]);
}
return dev;
}
@ -1018,7 +1017,7 @@ MusInfo* CreateMIDIStreamer(MIDISource *source, EMidiDevice devtype, const char*
return me;
}
DLL_EXPORT bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char *devarg, const char *outname, int subsong, int samplerate)
DLL_EXPORT zmusic_bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char *devarg, const char *outname, int subsong, int samplerate)
{
try
{

View file

@ -97,7 +97,7 @@ protected:
//
//==========================================================================
bool S_ParseTimeTag(const char* tag, bool* as_samples, unsigned int* time)
bool S_ParseTimeTag(const char* tag, zmusic_bool* as_samples, unsigned int* time)
{
const int time_count = 3;
const char* bit = tag;
@ -183,7 +183,7 @@ bool S_ParseTimeTag(const char* tag, bool* as_samples, unsigned int* time)
//
//==========================================================================
static void ParseVorbisComments(MusicIO::FileInterface *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass)
static void ParseVorbisComments(MusicIO::FileInterface *fr, uint32_t *start, zmusic_bool *startass, uint32_t *end, zmusic_bool *endass)
{
uint8_t vc_data[4];
@ -231,7 +231,7 @@ static void ParseVorbisComments(MusicIO::FileInterface *fr, uint32_t *start, boo
}
}
static void FindFlacComments(MusicIO::FileInterface *fr, uint32_t *loop_start, bool *startass, uint32_t *loop_end, bool *endass)
static void FindFlacComments(MusicIO::FileInterface *fr, uint32_t *loop_start, zmusic_bool *startass, uint32_t *loop_end, zmusic_bool *endass)
{
// Already verified the fLaC marker, so we're 4 bytes into the file
bool lastblock = false;
@ -258,7 +258,7 @@ static void FindFlacComments(MusicIO::FileInterface *fr, uint32_t *loop_start, b
}
}
static void FindOggComments(MusicIO::FileInterface *fr, uint32_t *loop_start, bool *startass, uint32_t *loop_end, bool *endass)
static void FindOggComments(MusicIO::FileInterface *fr, uint32_t *loop_start, zmusic_bool *startass, uint32_t *loop_end, zmusic_bool *endass)
{
uint8_t ogghead[27];
@ -328,7 +328,7 @@ static void FindOggComments(MusicIO::FileInterface *fr, uint32_t *loop_start, bo
}
}
void FindLoopTags(MusicIO::FileInterface *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass)
void FindLoopTags(MusicIO::FileInterface *fr, uint32_t *start, zmusic_bool *startass, uint32_t *end, zmusic_bool *endass)
{
uint8_t signature[4];
@ -339,7 +339,7 @@ void FindLoopTags(MusicIO::FileInterface *fr, uint32_t *start, bool *startass, u
FindOggComments(fr, start, startass, end, endass);
}
DLL_EXPORT void FindLoopTags(const uint8_t* data, size_t size, uint32_t* start, bool* startass, uint32_t* end, bool* endass)
DLL_EXPORT void FindLoopTags(const uint8_t* data, size_t size, uint32_t* start, zmusic_bool* startass, uint32_t* end, zmusic_bool* endass)
{
MusicIO::FileInterface* reader = new MusicIO::MemoryReader(data, (long)size);
FindLoopTags(reader, start, startass, end, endass);
@ -357,7 +357,7 @@ StreamSource *SndFile_OpenSong(MusicIO::FileInterface *fr)
fr->seek(0, SEEK_SET);
uint32_t loop_start = 0, loop_end = ~0u;
bool startass = false, endass = false;
zmusic_bool startass = false, endass = false;
FindLoopTags(fr, &loop_start, &startass, &loop_end, &endass);
fr->seek(0, SEEK_SET);

View file

@ -104,13 +104,31 @@ namespace MusicIO {
}
void ZMusic_Print(int type, const char* msg, va_list args)
{
static char printbuf[4096];
snprintf(printbuf, 4096, msg, args);
if (musicCallbacks.MessageFunc)
{
musicCallbacks.MessageFunc(type, printbuf);
}
else fputs(printbuf, type >= ZMUSIC_MSG_WARNING ? stderr : stdout);
}
void ZMusic_Printf(int type, const char* msg, ...)
{
va_list ap;
va_start(ap, msg);
ZMusic_Print(type, msg, ap);
va_end(ap);
}
DLL_EXPORT void ZMusic_SetCallbacks(const ZMusicCallbacks* cb)
{
musicCallbacks = *cb;
// If not all these are set the sound font interface is not usable.
if (!cb->SF_AddToSearchPath || !cb->SF_OpenFile || !cb->SF_Close)
musicCallbacks.OpenSoundFont = nullptr;
}
DLL_EXPORT void ZMusic_SetGenMidi(const uint8_t* data)
@ -302,7 +320,7 @@ static void TimidityPlus_SetReverb()
//
//==========================================================================
DLL_EXPORT bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSong, int value, int *pRealValue)
DLL_EXPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSong, int value, int *pRealValue)
{
switch (key)
{
@ -633,7 +651,7 @@ DLL_EXPORT bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSong, int
return false;
}
DLL_EXPORT bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* currSong, float value, float *pRealValue)
DLL_EXPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* currSong, float value, float *pRealValue)
{
switch (key)
{
@ -787,7 +805,7 @@ DLL_EXPORT bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* currSong,
return false;
}
DLL_EXPORT bool ChangeMusicSettingString(EStringConfigKey key, MusInfo* currSong, const char *value)
DLL_EXPORT zmusic_bool ChangeMusicSettingString(EStringConfigKey key, MusInfo* currSong, const char *value)
{
switch (key)
{

View file

@ -362,7 +362,7 @@ DLL_EXPORT MusInfo *ZMusic_OpenCDSong (int track, int id)
//
//==========================================================================
DLL_EXPORT bool ZMusic_FillStream(MusInfo* song, void* buff, int len)
DLL_EXPORT zmusic_bool ZMusic_FillStream(MusInfo* song, void* buff, int len)
{
if (song == nullptr) return false;
std::lock_guard<FCriticalSection> lock(song->CritSec);
@ -375,7 +375,7 @@ DLL_EXPORT bool ZMusic_FillStream(MusInfo* song, void* buff, int len)
//
//==========================================================================
DLL_EXPORT bool ZMusic_Start(MusInfo *song, int subsong, bool loop)
DLL_EXPORT zmusic_bool ZMusic_Start(MusInfo *song, int subsong, zmusic_bool loop)
{
if (!song) return true; // Starting a null song is not an error! It just won't play anything.
try
@ -414,7 +414,7 @@ DLL_EXPORT void ZMusic_Update(MusInfo *song)
song->Update();
}
DLL_EXPORT bool ZMusic_IsPlaying(MusInfo *song)
DLL_EXPORT zmusic_bool ZMusic_IsPlaying(MusInfo *song)
{
if (!song) return false;
return song->IsPlaying();
@ -427,20 +427,20 @@ DLL_EXPORT void ZMusic_Stop(MusInfo *song)
song->Stop();
}
DLL_EXPORT bool ZMusic_SetSubsong(MusInfo *song, int subsong)
DLL_EXPORT zmusic_bool ZMusic_SetSubsong(MusInfo *song, int subsong)
{
if (!song) return false;
std::lock_guard<FCriticalSection> lock(song->CritSec);
return song->SetSubsong(subsong);
}
DLL_EXPORT bool ZMusic_IsLooping(MusInfo *song)
DLL_EXPORT zmusic_bool ZMusic_IsLooping(MusInfo *song)
{
if (!song) return false;
return song->m_Looping;
}
DLL_EXPORT bool ZMusic_IsMIDI(MusInfo *song)
DLL_EXPORT zmusic_bool ZMusic_IsMIDI(MusInfo *song)
{
if (!song) return false;
return song->IsMIDI();
@ -487,7 +487,7 @@ DLL_EXPORT const char* ZMusic_GetLastError()
return staticErrorMessage.c_str();
}
DLL_EXPORT bool ZMusic_WriteSMF(MIDISource* source, const char *fn, int looplimit)
DLL_EXPORT zmusic_bool ZMusic_WriteSMF(MIDISource* source, const char *fn, int looplimit)
{
std::vector<uint8_t> midi;
bool success;

View file

@ -47,3 +47,5 @@ struct CustomFileReader : public MusicIO::FileInterface
};
void ZMusic_Printf(int type, const char* msg, ...);

View file

@ -34,6 +34,7 @@
#include "playmidi.h"
void ZMusic_Print(int type, const char* msg, va_list args);
namespace Timidity
{
@ -820,27 +821,15 @@ void Renderer::MarkInstrument(int banknum, int percussion, int instr)
}
}
static void default_cmsg(int type, int verbosity_level, const char* fmt, ...)
{
if (verbosity_level >= VERB_NOISY) return; // Don't waste time on diagnostics.
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;
}
ZMusic_Print(type, fmt, args);
va_end(args);
}
// Allow hosting applications to capture the messages and deal with them themselves.

View file

@ -35,9 +35,9 @@ controls.h
enum
{
CMSG_INFO,
CMSG_WARNING,
CMSG_ERROR
CMSG_INFO = 10,
CMSG_WARNING = 50,
CMSG_ERROR = 100
};
enum

View file

@ -30,6 +30,8 @@
#include "common.h"
#include "controls.h"
void ZMusic_Print(int type, const char* msg, va_list args);
namespace TimidityPlus
{
@ -159,21 +161,8 @@ void default_ctl_cmsg(int type, int verbosity_level, const char* fmt, ...)
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;
}
ZMusic_Print(type, fmt, args);
va_end(args);
}
// Allow hosting applications to capture the messages and deal with them themselves.

View file

@ -4450,7 +4450,7 @@ void Player::update_rpn_map(int ch, int addr, int update_now)
if (channel[ch].drums[note] == NULL)
play_midi_setup_drums(ch, note);
channel[ch].drums[note]->fine = val - 64;
printMessage(CMSG_INFO, VERB_NOISY, "Drum Instrument Pitch Fine (CH:%d NOTE:%d VAL:%d)", ch, note, channel[ch].drums[note]->fine);
//printMessage(CMSG_INFO, VERB_NOISY, "Drum Instrument Pitch Fine (CH:%d NOTE:%d VAL:%d)", ch, note, channel[ch].drums[note]->fine);
channel[ch].pitchfactor = 0;
break;
case NRPN_ADDR_1A00: /* Level of Drum */
@ -4481,7 +4481,7 @@ void Player::update_rpn_map(int ch, int addr, int update_now)
note = channel[ch].lastlrpn;
if (channel[ch].drums[note] == NULL)
play_midi_setup_drums(ch, note);
printMessage(CMSG_INFO, VERB_NOISY, "Reverb Send Level of Drum (CH:%d NOTE:%d VALUE:%d)", ch, note, val);
//printMessage(CMSG_INFO, VERB_NOISY, "Reverb Send Level of Drum (CH:%d NOTE:%d VALUE:%d)", ch, note, val);
if (channel[ch].drums[note]->reverb_level != val) {
channel[ch].drum_effect_flag = 0;
}
@ -4492,7 +4492,7 @@ void Player::update_rpn_map(int ch, int addr, int update_now)
note = channel[ch].lastlrpn;
if (channel[ch].drums[note] == NULL)
play_midi_setup_drums(ch, note);
printMessage(CMSG_INFO, VERB_NOISY, "Chorus Send Level of Drum (CH:%d NOTE:%d VALUE:%d)", ch, note, val);
//printMessage(CMSG_INFO, VERB_NOISY, "Chorus Send Level of Drum (CH:%d NOTE:%d VALUE:%d)", ch, note, val);
if (channel[ch].drums[note]->chorus_level != val) {
channel[ch].drum_effect_flag = 0;
}
@ -4535,22 +4535,22 @@ void Player::update_rpn_map(int ch, int addr, int update_now)
play_midi_setup_drums(ch, note);
break;
case RPN_ADDR_0000: /* Pitch bend sensitivity */
printMessage(CMSG_INFO, VERB_DEBUG, "Pitch Bend Sensitivity (CH:%d VALUE:%d)", ch, val);
//printMessage(CMSG_INFO, VERB_DEBUG, "Pitch Bend Sensitivity (CH:%d VALUE:%d)", ch, val);
/* for mod2mid.c, arpeggio */
if (channel[ch].rpnmap[RPN_ADDR_0000] > 24)
channel[ch].rpnmap[RPN_ADDR_0000] = 24;
channel[ch].pitchfactor = 0;
break;
case RPN_ADDR_0001: /* Master Fine Tuning */
printMessage(CMSG_INFO, VERB_DEBUG, "Master Fine Tuning (CH:%d VALUE:%d)", ch, val);
//printMessage(CMSG_INFO, VERB_DEBUG, "Master Fine Tuning (CH:%d VALUE:%d)", ch, val);
channel[ch].pitchfactor = 0;
break;
case RPN_ADDR_0002: /* Master Coarse Tuning */
printMessage(CMSG_INFO, VERB_DEBUG, "Master Coarse Tuning (CH:%d VALUE:%d)", ch, val);
//printMessage(CMSG_INFO, VERB_DEBUG, "Master Coarse Tuning (CH:%d VALUE:%d)", ch, val);
channel[ch].pitchfactor = 0;
break;
case RPN_ADDR_0003: /* Tuning Program Select */
printMessage(CMSG_INFO, VERB_DEBUG, "Tuning Program Select (CH:%d VALUE:%d)", ch, val);
//printMessage(CMSG_INFO, VERB_DEBUG, "Tuning Program Select (CH:%d VALUE:%d)", ch, val);
for (i = 0; i < upper_voices; i++)
if (voice[i].status != VOICE_FREE) {
voice[i].temper_instant = 1;
@ -4558,7 +4558,7 @@ void Player::update_rpn_map(int ch, int addr, int update_now)
}
break;
case RPN_ADDR_0004: /* Tuning Bank Select */
printMessage(CMSG_INFO, VERB_DEBUG, "Tuning Bank Select (CH:%d VALUE:%d)", ch, val);
//printMessage(CMSG_INFO, VERB_DEBUG, "Tuning Bank Select (CH:%d VALUE:%d)", ch, val);
for (i = 0; i < upper_voices; i++)
if (voice[i].status != VOICE_FREE) {
voice[i].temper_instant = 1;

View file

@ -36,9 +36,9 @@ enum
RC_TUNE_END = 3,
RC_STOP = 4, /* Stop to play */
CMSG_INFO = 0,
CMSG_WARNING = 1,
CMSG_ERROR = 2,
CMSG_INFO = 10,
CMSG_WARNING = 50,
CMSG_ERROR = 100,
VERB_NORMAL = 0,
VERB_VERBOSE = 1,

View file

@ -30,19 +30,15 @@
#include <stdarg.h>
#include "wm_error.h"
void ZMusic_Print(int type, const char* msg, va_list args);
namespace WildMidi
{
static void def_error_func(const char *wmfmt, va_list args)
{
vprintf(wmfmt, args);
}
void (*wm_error_func)(const char *wmfmt, va_list args) = def_error_func;
void _WM_ERROR_NEW(const char * wmfmt, ...) {
va_list args;
va_start(args, wmfmt);
wm_error_func(wmfmt, args);
ZMusic_Print(100, wmfmt, args);
}
void _WM_ERROR(const char * func, unsigned int lne, int wmerno,