mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 16:07:55 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
86797b419f
28 changed files with 518 additions and 1864 deletions
|
@ -978,6 +978,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||||
nodebuild_extract.cpp
|
nodebuild_extract.cpp
|
||||||
nodebuild_gl.cpp
|
nodebuild_gl.cpp
|
||||||
nodebuild_utility.cpp
|
nodebuild_utility.cpp
|
||||||
|
pathexpander.cpp
|
||||||
p_3dfloors.cpp
|
p_3dfloors.cpp
|
||||||
p_3dmidtex.cpp
|
p_3dmidtex.cpp
|
||||||
p_acs.cpp
|
p_acs.cpp
|
||||||
|
@ -1257,7 +1258,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||||
timidity/timidity.cpp
|
timidity/timidity.cpp
|
||||||
wildmidi/file_io.cpp
|
wildmidi/file_io.cpp
|
||||||
wildmidi/gus_pat.cpp
|
wildmidi/gus_pat.cpp
|
||||||
wildmidi/lock.cpp
|
|
||||||
wildmidi/reverb.cpp
|
wildmidi/reverb.cpp
|
||||||
wildmidi/wildmidi_lib.cpp
|
wildmidi/wildmidi_lib.cpp
|
||||||
wildmidi/wm_error.cpp
|
wildmidi/wm_error.cpp
|
||||||
|
|
134
src/pathexpander.cpp
Normal file
134
src/pathexpander.cpp
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
** pathexpander.cpp
|
||||||
|
** Utility class for expanding a given path with a range of directories
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2015 Christoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pathexpander.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
static FString BuildPath(const FString &base, const char *name)
|
||||||
|
{
|
||||||
|
FString current;
|
||||||
|
if (base.IsNotEmpty())
|
||||||
|
{
|
||||||
|
current = base;
|
||||||
|
if (current[current.Len() - 1] != '/') current += '/';
|
||||||
|
}
|
||||||
|
current += name;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// This is meant to find and open files for reading.
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
FileReader *PathExpander::openFileReader(const char *name, int *plumpnum)
|
||||||
|
{
|
||||||
|
FileReader *fp;
|
||||||
|
FString current_filename;
|
||||||
|
|
||||||
|
if (!name || !(*name))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First try the given name */
|
||||||
|
current_filename = name;
|
||||||
|
FixPathSeperator(current_filename);
|
||||||
|
|
||||||
|
|
||||||
|
if (openmode != OM_FILE)
|
||||||
|
{
|
||||||
|
int lumpnum = Wads.CheckNumForFullName(current_filename);
|
||||||
|
if (lumpnum >= 0)
|
||||||
|
{
|
||||||
|
fp = Wads.ReopenLumpNum(lumpnum);
|
||||||
|
if (plumpnum) *plumpnum = lumpnum;
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
if (openmode == OM_LUMP) // search the path list when not loading the main config
|
||||||
|
{
|
||||||
|
for (unsigned int plp = PathList.Size(); plp-- != 0; )
|
||||||
|
{ /* Try along the path then */
|
||||||
|
current_filename = BuildPath(PathList[plp], name);
|
||||||
|
lumpnum = Wads.CheckNumForFullName(current_filename);
|
||||||
|
if (lumpnum >= 0)
|
||||||
|
{
|
||||||
|
fp = Wads.ReopenLumpNum(lumpnum);
|
||||||
|
if (plumpnum) *plumpnum = lumpnum;
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (plumpnum) *plumpnum = -1;
|
||||||
|
|
||||||
|
|
||||||
|
fp = new FileReader;
|
||||||
|
if (fp->Open(current_filename)) return fp;
|
||||||
|
|
||||||
|
if (name[0] != '/')
|
||||||
|
{
|
||||||
|
for (unsigned int plp = PathList.Size(); plp-- != 0; )
|
||||||
|
{ /* Try along the path then */
|
||||||
|
current_filename = BuildPath(PathList[plp], name);
|
||||||
|
if (fp->Open(current_filename)) return fp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete fp;
|
||||||
|
|
||||||
|
/* Nothing could be opened. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This adds a directory to the path list */
|
||||||
|
void PathExpander::addToPathlist(const char *s)
|
||||||
|
{
|
||||||
|
FString copy = s;
|
||||||
|
FixPathSeperator(copy);
|
||||||
|
PathList.Push(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathExpander::clearPathlist()
|
||||||
|
{
|
||||||
|
PathList.Clear();
|
||||||
|
}
|
31
src/pathexpander.h
Normal file
31
src/pathexpander.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __PATHEXPANDER_H
|
||||||
|
#define __PATHEXPANDER_H
|
||||||
|
|
||||||
|
#include "tarray.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
#include "files.h"
|
||||||
|
|
||||||
|
class PathExpander
|
||||||
|
{
|
||||||
|
TArray<FString> PathList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int openmode;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
OM_FILEORLUMP = 0,
|
||||||
|
OM_LUMP,
|
||||||
|
OM_FILE
|
||||||
|
};
|
||||||
|
|
||||||
|
PathExpander(int om = OM_FILEORLUMP)
|
||||||
|
{
|
||||||
|
openmode = om;
|
||||||
|
}
|
||||||
|
void addToPathlist(const char *s);
|
||||||
|
void clearPathlist();
|
||||||
|
FileReader *openFileReader(const char *name, int *plumpnum);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -162,7 +162,7 @@ void I_InitMusic (void)
|
||||||
if (!setatterm)
|
if (!setatterm)
|
||||||
{
|
{
|
||||||
setatterm = true;
|
setatterm = true;
|
||||||
atterm (I_ShutdownMusic);
|
atterm (I_ShutdownMusicExit);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
signal (SIGCHLD, ChildSigHandler);
|
signal (SIGCHLD, ChildSigHandler);
|
||||||
|
@ -178,7 +178,7 @@ void I_InitMusic (void)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void I_ShutdownMusic(void)
|
void I_ShutdownMusic(bool onexit)
|
||||||
{
|
{
|
||||||
if (MusicDown)
|
if (MusicDown)
|
||||||
return;
|
return;
|
||||||
|
@ -189,12 +189,17 @@ void I_ShutdownMusic(void)
|
||||||
assert (currSong == NULL);
|
assert (currSong == NULL);
|
||||||
}
|
}
|
||||||
Timidity::FreeAll();
|
Timidity::FreeAll();
|
||||||
WildMidi_Shutdown();
|
if (onexit) WildMidi_Shutdown();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
I_ShutdownMusicWin32();
|
I_ShutdownMusicWin32();
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I_ShutdownMusicExit()
|
||||||
|
{
|
||||||
|
I_ShutdownMusic(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -281,6 +286,10 @@ void MusInfo::FluidSettingStr(const char *, const char *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MusInfo::WildMidiSetOption(int opt, int set)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
FString MusInfo::GetStats()
|
FString MusInfo::GetStats()
|
||||||
{
|
{
|
||||||
return "No stats available for this song";
|
return "No stats available for this song";
|
||||||
|
|
|
@ -43,7 +43,8 @@ struct FOptionValues;
|
||||||
// MUSIC I/O
|
// MUSIC I/O
|
||||||
//
|
//
|
||||||
void I_InitMusic ();
|
void I_InitMusic ();
|
||||||
void I_ShutdownMusic ();
|
void I_ShutdownMusic (bool onexit = false);
|
||||||
|
void I_ShutdownMusicExit ();
|
||||||
void I_BuildMIDIMenuList (FOptionValues *);
|
void I_BuildMIDIMenuList (FOptionValues *);
|
||||||
void I_UpdateMusic ();
|
void I_UpdateMusic ();
|
||||||
|
|
||||||
|
@ -81,6 +82,7 @@ public:
|
||||||
virtual void FluidSettingInt(const char *setting, int value); // FluidSynth settings
|
virtual void FluidSettingInt(const char *setting, int value); // FluidSynth settings
|
||||||
virtual void FluidSettingNum(const char *setting, double value); // "
|
virtual void FluidSettingNum(const char *setting, double value); // "
|
||||||
virtual void FluidSettingStr(const char *setting, const char *value); // "
|
virtual void FluidSettingStr(const char *setting, const char *value); // "
|
||||||
|
virtual void WildMidiSetOption(int opt, int set);
|
||||||
|
|
||||||
void Start(bool loop, float rel_vol = -1.f, int subsong = 0);
|
void Start(bool loop, float rel_vol = -1.f, int subsong = 0);
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,7 @@ public:
|
||||||
virtual void FluidSettingInt(const char *setting, int value);
|
virtual void FluidSettingInt(const char *setting, int value);
|
||||||
virtual void FluidSettingNum(const char *setting, double value);
|
virtual void FluidSettingNum(const char *setting, double value);
|
||||||
virtual void FluidSettingStr(const char *setting, const char *value);
|
virtual void FluidSettingStr(const char *setting, const char *value);
|
||||||
|
virtual void WildMidiSetOption(int opt, int set);
|
||||||
virtual bool Preprocess(MIDIStreamer *song, bool looping);
|
virtual bool Preprocess(MIDIStreamer *song, bool looping);
|
||||||
virtual FString GetStats();
|
virtual FString GetStats();
|
||||||
};
|
};
|
||||||
|
@ -349,6 +350,7 @@ protected:
|
||||||
void HandleEvent(int status, int parm1, int parm2);
|
void HandleEvent(int status, int parm1, int parm2);
|
||||||
void HandleLongEvent(const BYTE *data, int len);
|
void HandleLongEvent(const BYTE *data, int len);
|
||||||
void ComputeOutput(float *buffer, int len);
|
void ComputeOutput(float *buffer, int len);
|
||||||
|
void WildMidiSetOption(int opt, int set);
|
||||||
};
|
};
|
||||||
|
|
||||||
// FluidSynth implementation of a MIDI device -------------------------------
|
// FluidSynth implementation of a MIDI device -------------------------------
|
||||||
|
@ -447,6 +449,7 @@ public:
|
||||||
void FluidSettingInt(const char *setting, int value);
|
void FluidSettingInt(const char *setting, int value);
|
||||||
void FluidSettingNum(const char *setting, double value);
|
void FluidSettingNum(const char *setting, double value);
|
||||||
void FluidSettingStr(const char *setting, const char *value);
|
void FluidSettingStr(const char *setting, const char *value);
|
||||||
|
void WildMidiSetOption(int opt, int set);
|
||||||
void CreateSMF(TArray<BYTE> &file, int looplimit=0);
|
void CreateSMF(TArray<BYTE> &file, int looplimit=0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -566,7 +569,7 @@ protected:
|
||||||
struct TrackInfo;
|
struct TrackInfo;
|
||||||
|
|
||||||
void ProcessInitialMetaEvents ();
|
void ProcessInitialMetaEvents ();
|
||||||
DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay);
|
DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom);
|
||||||
TrackInfo *FindNextDue ();
|
TrackInfo *FindNextDue ();
|
||||||
|
|
||||||
BYTE *MusHeader;
|
BYTE *MusHeader;
|
||||||
|
|
|
@ -168,6 +168,7 @@ CCMD (snd_listmididevices)
|
||||||
MIDIOUTCAPS caps;
|
MIDIOUTCAPS caps;
|
||||||
MMRESULT res;
|
MMRESULT res;
|
||||||
|
|
||||||
|
PrintMidiDevice (-6, "WildMidi", MOD_SWSYNTH, 0);
|
||||||
#ifdef HAVE_FLUIDSYNTH
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
PrintMidiDevice (-5, "FluidSynth", MOD_SWSYNTH, 0);
|
PrintMidiDevice (-5, "FluidSynth", MOD_SWSYNTH, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -626,6 +626,21 @@ void MIDIStreamer::FluidSettingStr(const char *setting, const char *value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// MIDIDeviceStreamer :: WildMidiSetOption
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void MIDIStreamer::WildMidiSetOption(int opt, int set)
|
||||||
|
{
|
||||||
|
if (MIDI != NULL)
|
||||||
|
{
|
||||||
|
MIDI->WildMidiSetOption(opt, set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// MIDIStreamer :: OutputVolume
|
// MIDIStreamer :: OutputVolume
|
||||||
|
@ -1196,9 +1211,15 @@ void MIDIStreamer::CreateSMF(TArray<BYTE> &file, int looplimit)
|
||||||
len--;
|
len--;
|
||||||
file.Push(MIDI_SYSEX);
|
file.Push(MIDI_SYSEX);
|
||||||
WriteVarLen(file, len);
|
WriteVarLen(file, len);
|
||||||
memcpy(&file[file.Reserve(len - 1)], bytes, len);
|
memcpy(&file[file.Reserve(len)], bytes + 1, len);
|
||||||
running_status = 255;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file.Push(MIDI_SYSEXEND);
|
||||||
|
WriteVarLen(file, len);
|
||||||
|
memcpy(&file[file.Reserve(len)], bytes, len);
|
||||||
|
}
|
||||||
|
running_status = 255;
|
||||||
}
|
}
|
||||||
else if (MEVT_EVENTTYPE(event[2]) == 0)
|
else if (MEVT_EVENTTYPE(event[2]) == 0)
|
||||||
{
|
{
|
||||||
|
@ -1516,6 +1537,16 @@ void MIDIDevice::FluidSettingStr(const char *setting, const char *value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// MIDIDevice :: WildMidiSetOption
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void MIDIDevice::WildMidiSetOption(int opt, int set)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// MIDIDevice :: GetStats
|
// MIDIDevice :: GetStats
|
||||||
|
|
|
@ -322,7 +322,12 @@ DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
|
||||||
// Play all events for this tick.
|
// Play all events for this tick.
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DWORD *new_events = SendCommand(events, TrackDue, time);
|
bool sysex_noroom = false;
|
||||||
|
DWORD *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom);
|
||||||
|
if (sysex_noroom)
|
||||||
|
{
|
||||||
|
return events;
|
||||||
|
}
|
||||||
TrackDue = FindNextDue();
|
TrackDue = FindNextDue();
|
||||||
if (new_events != events)
|
if (new_events != events)
|
||||||
{
|
{
|
||||||
|
@ -366,12 +371,15 @@ void MIDISong2::AdvanceTracks(DWORD time)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
|
DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom)
|
||||||
{
|
{
|
||||||
DWORD len;
|
DWORD len;
|
||||||
BYTE event, data1 = 0, data2 = 0;
|
BYTE event, data1 = 0, data2 = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
sysex_noroom = false;
|
||||||
|
size_t start_p = track->TrackP;
|
||||||
|
|
||||||
CHECK_FINISHED
|
CHECK_FINISHED
|
||||||
event = track->TrackBegin[track->TrackP++];
|
event = track->TrackBegin[track->TrackP++];
|
||||||
CHECK_FINISHED
|
CHECK_FINISHED
|
||||||
|
@ -588,14 +596,45 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Skip SysEx events just because I don't want to bother with them.
|
// SysEx events could potentially not have enough room in the buffer...
|
||||||
// The old MIDI player ignored them too, so this won't break
|
|
||||||
// anything that played before.
|
|
||||||
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
|
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
|
||||||
{
|
{
|
||||||
len = track->ReadVarLen ();
|
len = track->ReadVarLen();
|
||||||
|
if (len >= (MAX_EVENTS-1)*3*4)
|
||||||
|
{ // This message will never fit. Throw it away.
|
||||||
track->TrackP += len;
|
track->TrackP += len;
|
||||||
}
|
}
|
||||||
|
else if (len + 12 >= (size_t)room * 4)
|
||||||
|
{ // Not enough room left in this buffer. Backup and wait for the next one.
|
||||||
|
track->TrackP = start_p;
|
||||||
|
sysex_noroom = true;
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
events[0] = delay;
|
||||||
|
events[1] = 0;
|
||||||
|
BYTE *msg = (BYTE *)&events[3];
|
||||||
|
if (event == MIDI_SYSEX)
|
||||||
|
{ // Need to add the SysEx marker to the message.
|
||||||
|
events[2] = (MEVT_LONGMSG << 24) | (len + 1);
|
||||||
|
*msg++ = MIDI_SYSEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
events[2] = (MEVT_LONGMSG << 24) | len;
|
||||||
|
}
|
||||||
|
memcpy(msg, &track->TrackBegin[track->TrackP], len);
|
||||||
|
msg += len;
|
||||||
|
// Must pad with 0
|
||||||
|
while ((size_t)msg & 3)
|
||||||
|
{
|
||||||
|
*msg++ = 0;
|
||||||
|
}
|
||||||
|
events = (DWORD *)msg;
|
||||||
|
track->TrackP += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (event == MIDI_META)
|
else if (event == MIDI_META)
|
||||||
{
|
{
|
||||||
// It's a meta-event
|
// It's a meta-event
|
||||||
|
|
|
@ -61,6 +61,17 @@ static FString CurrentConfig;
|
||||||
|
|
||||||
CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
CVAR(Int, wildmidi_frequency, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Int, wildmidi_frequency, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||||
|
{
|
||||||
|
if (currSong != NULL)
|
||||||
|
currSong->WildMidiSetOption(WM_MO_REVERB, *self? WM_MO_REVERB:0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||||
|
{
|
||||||
|
if (currSong != NULL)
|
||||||
|
currSong->WildMidiSetOption(WM_MO_ENHANCED_RESAMPLING, *self? WM_MO_ENHANCED_RESAMPLING:0);
|
||||||
|
}
|
||||||
|
|
||||||
// CODE --------------------------------------------------------------------
|
// CODE --------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -90,7 +101,7 @@ WildMIDIDevice::WildMIDIDevice()
|
||||||
WildMidi_Shutdown();
|
WildMidi_Shutdown();
|
||||||
CurrentConfig = "";
|
CurrentConfig = "";
|
||||||
}
|
}
|
||||||
if (!WildMidi_Init(wildmidi_config, SampleRate, WM_MO_ENHANCED_RESAMPLING))
|
if (!WildMidi_Init(wildmidi_config, SampleRate, 0))
|
||||||
{
|
{
|
||||||
CurrentConfig = wildmidi_config;
|
CurrentConfig = wildmidi_config;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +109,10 @@ WildMIDIDevice::WildMIDIDevice()
|
||||||
if (CurrentConfig.IsNotEmpty())
|
if (CurrentConfig.IsNotEmpty())
|
||||||
{
|
{
|
||||||
Renderer = new WildMidi_Renderer();
|
Renderer = new WildMidi_Renderer();
|
||||||
|
int flags = 0;
|
||||||
|
if (wildmidi_enhanced_resampling) flags |= WM_MO_ENHANCED_RESAMPLING;
|
||||||
|
if (wildmidi_reverb) flags |= WM_MO_REVERB;
|
||||||
|
Renderer->SetOption(WM_MO_ENHANCED_RESAMPLING | WM_MO_REVERB, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +193,7 @@ void WildMIDIDevice::HandleEvent(int status, int parm1, int parm2)
|
||||||
|
|
||||||
void WildMIDIDevice::HandleLongEvent(const BYTE *data, int len)
|
void WildMIDIDevice::HandleLongEvent(const BYTE *data, int len)
|
||||||
{
|
{
|
||||||
Renderer->LongEvent((const char *)data, len);
|
Renderer->LongEvent(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -204,3 +219,14 @@ FString WildMIDIDevice::GetStats()
|
||||||
out.Format("%3d voices", Renderer->GetVoiceCount());
|
out.Format("%3d voices", Renderer->GetVoiceCount());
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// WildMIDIDevice :: GetStats
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void WildMIDIDevice::WildMidiSetOption(int opt, int set)
|
||||||
|
{
|
||||||
|
Renderer->SetOption(opt, set);
|
||||||
|
}
|
||||||
|
|
|
@ -35,82 +35,6 @@
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
|
||||||
static TArray<FString> PathList;
|
|
||||||
|
|
||||||
FString BuildPath(FString base, const char *name)
|
|
||||||
{
|
|
||||||
FString current;
|
|
||||||
if (base.IsNotEmpty())
|
|
||||||
{
|
|
||||||
current = base;
|
|
||||||
if (current[current.Len() - 1] != '/') current += '/';
|
|
||||||
}
|
|
||||||
current += name;
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is meant to find and open files for reading. */
|
|
||||||
FileReader *open_filereader(const char *name, int open, int *plumpnum)
|
|
||||||
{
|
|
||||||
FileReader *fp;
|
|
||||||
FString current_filename;
|
|
||||||
|
|
||||||
if (!name || !(*name))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First try the given name */
|
|
||||||
current_filename = name;
|
|
||||||
FixPathSeperator(current_filename);
|
|
||||||
|
|
||||||
int lumpnum = Wads.CheckNumForFullName(current_filename);
|
|
||||||
|
|
||||||
if (open != OM_FILE)
|
|
||||||
{
|
|
||||||
if (lumpnum >= 0)
|
|
||||||
{
|
|
||||||
fp = Wads.ReopenLumpNum(lumpnum);
|
|
||||||
if (plumpnum) *plumpnum = lumpnum;
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
if (open == OM_LUMP) // search the path list when not loading the main config
|
|
||||||
{
|
|
||||||
for (unsigned int plp = PathList.Size(); plp-- != 0; )
|
|
||||||
{ /* Try along the path then */
|
|
||||||
current_filename = BuildPath(PathList[plp], name);
|
|
||||||
lumpnum = Wads.CheckNumForFullName(current_filename);
|
|
||||||
if (lumpnum >= 0)
|
|
||||||
{
|
|
||||||
fp = Wads.ReopenLumpNum(lumpnum);
|
|
||||||
if (plumpnum) *plumpnum = lumpnum;
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (plumpnum) *plumpnum = -1;
|
|
||||||
|
|
||||||
|
|
||||||
fp = new FileReader;
|
|
||||||
if (fp->Open(current_filename)) return fp;
|
|
||||||
|
|
||||||
if (name[0] != '/')
|
|
||||||
{
|
|
||||||
for (unsigned int plp = PathList.Size(); plp-- != 0; )
|
|
||||||
{ /* Try along the path then */
|
|
||||||
current_filename = BuildPath(PathList[plp], name);
|
|
||||||
if (fp->Open(current_filename)) return fp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete fp;
|
|
||||||
|
|
||||||
/* Nothing could be opened. */
|
|
||||||
current_filename = "";
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* This'll allocate memory or die. */
|
/* This'll allocate memory or die. */
|
||||||
|
@ -132,17 +56,5 @@ void *safe_malloc(size_t count)
|
||||||
return 0; // Unreachable.
|
return 0; // Unreachable.
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This adds a directory to the path list */
|
|
||||||
void add_to_pathlist(const char *s)
|
|
||||||
{
|
|
||||||
FString copy = s;
|
|
||||||
FixPathSeperator(copy);
|
|
||||||
PathList.Push(copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_pathlist()
|
|
||||||
{
|
|
||||||
PathList.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ static void reverse_data(sample_t *sp, int ls, int le)
|
||||||
|
|
||||||
TODO: do reverse loops right */
|
TODO: do reverse loops right */
|
||||||
static Instrument *load_instrument(Renderer *song, const char *name, int percussion,
|
static Instrument *load_instrument(Renderer *song, const char *name, int percussion,
|
||||||
int panning, int amp, int note_to_use,
|
int panning, int note_to_use,
|
||||||
int strip_loop, int strip_envelope,
|
int strip_loop, int strip_envelope,
|
||||||
int strip_tail)
|
int strip_tail)
|
||||||
{
|
{
|
||||||
|
@ -159,16 +159,16 @@ static Instrument *load_instrument(Renderer *song, const char *name, int percuss
|
||||||
if (!name) return 0;
|
if (!name) return 0;
|
||||||
|
|
||||||
/* Open patch file */
|
/* Open patch file */
|
||||||
if ((fp = open_filereader(name, openmode, NULL)) == NULL)
|
if ((fp = pathExpander.openFileReader(name, NULL)) == NULL)
|
||||||
{
|
{
|
||||||
/* Try with various extensions */
|
/* Try with various extensions */
|
||||||
FString tmp = name;
|
FString tmp = name;
|
||||||
tmp += ".pat";
|
tmp += ".pat";
|
||||||
if ((fp = open_filereader(tmp, openmode, NULL)) == NULL)
|
if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL)
|
||||||
{
|
{
|
||||||
#ifdef __unix__ // Windows isn't case-sensitive.
|
#ifdef __unix__ // Windows isn't case-sensitive.
|
||||||
tmp.ToUpper();
|
tmp.ToUpper();
|
||||||
if ((fp = open_filereader(tmp, openmode, NULL)) == NULL)
|
if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
noluck = true;
|
noluck = true;
|
||||||
|
@ -372,7 +372,6 @@ fail:
|
||||||
{
|
{
|
||||||
sp->modes &= ~(PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD);
|
sp->modes &= ~(PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD);
|
||||||
}
|
}
|
||||||
sp->modes |= PATCH_T_NO_LOOP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strip_envelope == 1)
|
if (strip_envelope == 1)
|
||||||
|
@ -398,37 +397,6 @@ fail:
|
||||||
patch_data.EnvelopeOffset[k] = patch_data.EnvelopeOffset[0];
|
patch_data.EnvelopeOffset[k] = patch_data.EnvelopeOffset[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sp->modes |= PATCH_T_NO_ENVELOPE;
|
|
||||||
}
|
|
||||||
else if (strip_envelope != 0)
|
|
||||||
{
|
|
||||||
/* Have to make a guess. */
|
|
||||||
if (!(sp->modes & (PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD)))
|
|
||||||
{
|
|
||||||
/* No loop? Then what's there to sustain? No envelope needed either... */
|
|
||||||
sp->modes |= PATCH_T_NO_ENVELOPE;
|
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope\n");
|
|
||||||
}
|
|
||||||
else if (memcmp(patch_data.EnvelopeRate, "??????", 6) == 0 || patch_data.EnvelopeOffset[GF1_RELEASEC] >= 100)
|
|
||||||
{
|
|
||||||
/* Envelope rates all maxed out? Envelope end at a high "offset"?
|
|
||||||
That's a weird envelope. Take it out. */
|
|
||||||
sp->modes |= PATCH_T_NO_ENVELOPE;
|
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope\n");
|
|
||||||
}
|
|
||||||
else if (!(sp->modes & PATCH_SUSTAIN))
|
|
||||||
{
|
|
||||||
/* No sustain? Then no envelope. I don't know if this is
|
|
||||||
justified, but patches without sustain usually don't need the
|
|
||||||
envelope either... at least the Gravis ones. They're mostly
|
|
||||||
drums. I think. */
|
|
||||||
sp->modes |= PATCH_T_NO_ENVELOPE;
|
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!(sp->modes & PATCH_NO_SRELEASE))
|
|
||||||
{ // TiMidity thinks that this is an envelope enable flag.
|
|
||||||
sp->modes |= PATCH_T_NO_ENVELOPE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < 6; j++)
|
for (j = 0; j < 6; j++)
|
||||||
|
@ -470,29 +438,6 @@ fail:
|
||||||
sp->modes |= PATCH_LOOPEN; /* just in case */
|
sp->modes |= PATCH_LOOPEN; /* just in case */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amp != -1)
|
|
||||||
{
|
|
||||||
sp->volume = (amp) / 100.f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Try to determine a volume scaling factor for the sample.
|
|
||||||
This is a very crude adjustment, but things sound more
|
|
||||||
balanced with it. Still, this should be a runtime option.
|
|
||||||
(This is ignored unless midi_timiditylike is turned on.) */
|
|
||||||
int i;
|
|
||||||
sample_t maxamp = 0, a;
|
|
||||||
sample_t *tmp;
|
|
||||||
for (i = sp->data_length, tmp = sp->data; i; --i)
|
|
||||||
{
|
|
||||||
a = fabsf(*tmp++);
|
|
||||||
if (a > maxamp)
|
|
||||||
maxamp = a;
|
|
||||||
}
|
|
||||||
sp->volume = 1 / maxamp;
|
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f\n", sp->volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then fractional samples */
|
/* Then fractional samples */
|
||||||
sp->data_length <<= FRACTION_BITS;
|
sp->data_length <<= FRACTION_BITS;
|
||||||
sp->loop_start <<= FRACTION_BITS;
|
sp->loop_start <<= FRACTION_BITS;
|
||||||
|
@ -653,7 +598,6 @@ static int fill_bank(Renderer *song, int dr, int b)
|
||||||
ip = load_instrument(song, bank->tone[i].name,
|
ip = load_instrument(song, bank->tone[i].name,
|
||||||
(dr) ? 1 : 0,
|
(dr) ? 1 : 0,
|
||||||
bank->tone[i].pan,
|
bank->tone[i].pan,
|
||||||
bank->tone[i].amp,
|
|
||||||
(bank->tone[i].note != -1) ? bank->tone[i].note : ((dr) ? i : -1),
|
(bank->tone[i].note != -1) ? bank->tone[i].note : ((dr) ? i : -1),
|
||||||
(bank->tone[i].strip_loop != -1) ? bank->tone[i].strip_loop : ((dr) ? 1 : -1),
|
(bank->tone[i].strip_loop != -1) ? bank->tone[i].strip_loop : ((dr) ? 1 : -1),
|
||||||
(bank->tone[i].strip_envelope != -1) ? bank->tone[i].strip_envelope : ((dr) ? 1 : -1),
|
(bank->tone[i].strip_envelope != -1) ? bank->tone[i].strip_envelope : ((dr) ? 1 : -1),
|
||||||
|
@ -731,7 +675,7 @@ void free_instruments()
|
||||||
int Renderer::set_default_instrument(const char *name)
|
int Renderer::set_default_instrument(const char *name)
|
||||||
{
|
{
|
||||||
Instrument *ip;
|
Instrument *ip;
|
||||||
if ((ip = load_instrument(this, name, 0, -1, -1, -1, 0, 0, 0)) == NULL)
|
if ((ip = load_instrument(this, name, 0, -1, -1, 0, 0, 0)) == NULL)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1141,7 +1141,6 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins,
|
||||||
sample->loop_start = rgn->wsmp_loop->ulStart / 2;
|
sample->loop_start = rgn->wsmp_loop->ulStart / 2;
|
||||||
sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2);
|
sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2);
|
||||||
}
|
}
|
||||||
sample->volume = 1.0f;
|
|
||||||
|
|
||||||
if (sample->modes & PATCH_SUSTAIN)
|
if (sample->modes & PATCH_SUSTAIN)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,7 +54,7 @@ void font_add(const char *filename, int load_order)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FileReader *fp = open_filereader(filename, openmode, NULL);
|
FileReader *fp = pathExpander.openFileReader(filename, NULL);
|
||||||
|
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1441,7 +1441,6 @@ void SFFile::ApplyGeneratorsToRegion(SFGenComposite *gen, SFSample *sfsamp, Rend
|
||||||
sp->root_freq = note_to_freq(sp->scale_note);
|
sp->root_freq = note_to_freq(sp->scale_note);
|
||||||
sp->sample_rate = sfsamp->SampleRate;
|
sp->sample_rate = sfsamp->SampleRate;
|
||||||
sp->key_group = gen->exclusiveClass;
|
sp->key_group = gen->exclusiveClass;
|
||||||
sp->volume = 1;
|
|
||||||
|
|
||||||
// Set key scaling
|
// Set key scaling
|
||||||
if (gen->keynum >= 0 && gen->keynum <= 127)
|
if (gen->keynum >= 0 && gen->keynum <= 127)
|
||||||
|
@ -1502,7 +1501,7 @@ void SFFile::ApplyGeneratorsToRegion(SFGenComposite *gen, SFSample *sfsamp, Rend
|
||||||
|
|
||||||
void SFFile::LoadSample(SFSample *sample)
|
void SFFile::LoadSample(SFSample *sample)
|
||||||
{
|
{
|
||||||
FileReader *fp = open_filereader(Filename, openmode, NULL);
|
FileReader *fp = pathExpander.openFileReader(Filename, NULL);
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, midi_timiditylike)
|
|
||||||
|
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -78,16 +76,7 @@ void GF1Envelope::Init(Renderer *song, Voice *v)
|
||||||
|
|
||||||
void GF1Envelope::Release(Voice *v)
|
void GF1Envelope::Release(Voice *v)
|
||||||
{
|
{
|
||||||
if (midi_timiditylike)
|
if (!(v->sample->modes & PATCH_NO_SRELEASE) || (v->sample->modes & PATCH_FAST_REL))
|
||||||
{
|
|
||||||
if (!(v->sample->modes & PATCH_T_NO_ENVELOPE))
|
|
||||||
{
|
|
||||||
stage = GF1_RELEASE;
|
|
||||||
Recompute(v);
|
|
||||||
}
|
|
||||||
// else ... loop was already turned off by the caller
|
|
||||||
}
|
|
||||||
else if (!(v->sample->modes & PATCH_NO_SRELEASE) || (v->sample->modes & PATCH_FAST_REL))
|
|
||||||
{
|
{
|
||||||
/* ramp out to minimum volume with rate from final release stage */
|
/* ramp out to minimum volume with rate from final release stage */
|
||||||
stage = GF1_RELEASEC+1;
|
stage = GF1_RELEASEC+1;
|
||||||
|
@ -119,23 +108,11 @@ bool GF1Envelope::Recompute(Voice *v)
|
||||||
bUpdating = false;
|
bUpdating = false;
|
||||||
v->status &= ~(VOICE_SUSTAINING | VOICE_LPE);
|
v->status &= ~(VOICE_SUSTAINING | VOICE_LPE);
|
||||||
v->status |= VOICE_RELEASING;
|
v->status |= VOICE_RELEASING;
|
||||||
if (midi_timiditylike)
|
/* play sampled release */
|
||||||
{ /* kill the voice ... or not */
|
|
||||||
if (volume <= 0)
|
|
||||||
{
|
|
||||||
v->status |= VOICE_STOPPING;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ /* play sampled release */
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newstage == GF1_RELEASE && !(v->status & VOICE_RELEASING) &&
|
if (newstage == GF1_RELEASE && !(v->status & VOICE_RELEASING) && (v->sample->modes & PATCH_SUSTAIN))
|
||||||
((!midi_timiditylike && (v->sample->modes & PATCH_SUSTAIN)) ||
|
|
||||||
(midi_timiditylike && !(v->sample->modes & PATCH_T_NO_ENVELOPE))))
|
|
||||||
{
|
{
|
||||||
v->status |= VOICE_SUSTAINING;
|
v->status |= VOICE_SUSTAINING;
|
||||||
/* Freeze envelope until note turns off. Trumpets want this. */
|
/* Freeze envelope until note turns off. Trumpets want this. */
|
||||||
|
@ -161,10 +138,6 @@ bool GF1Envelope::Recompute(Voice *v)
|
||||||
|
|
||||||
bool GF1Envelope::Update(Voice *v)
|
bool GF1Envelope::Update(Voice *v)
|
||||||
{
|
{
|
||||||
if (midi_timiditylike && (v->sample->modes & PATCH_T_NO_ENVELOPE))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
volume += increment;
|
volume += increment;
|
||||||
if (((increment < 0) && (volume <= target)) || ((increment > 0) && (volume >= target)))
|
if (((increment < 0) && (volume <= target)) || ((increment > 0) && (volume >= target)))
|
||||||
{
|
{
|
||||||
|
@ -182,27 +155,6 @@ void GF1Envelope::ApplyToAmp(Voice *v)
|
||||||
double env_vol = v->attenuation;
|
double env_vol = v->attenuation;
|
||||||
double final_amp;
|
double final_amp;
|
||||||
|
|
||||||
if (midi_timiditylike)
|
|
||||||
{
|
|
||||||
final_amp = v->sample->volume * FINAL_MIX_TIMIDITY_SCALE;
|
|
||||||
if (v->tremolo_phase_increment != 0)
|
|
||||||
{
|
|
||||||
env_vol *= v->tremolo_volume;
|
|
||||||
}
|
|
||||||
if (!(v->sample->modes & PATCH_T_NO_ENVELOPE))
|
|
||||||
{
|
|
||||||
if (stage > GF1_ATTACK)
|
|
||||||
{
|
|
||||||
env_vol *= pow(2.0, volume * (6.0 / (1 << 30)) - 6.0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
env_vol *= volume / float(1 << 30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final_amp = FINAL_MIX_SCALE;
|
final_amp = FINAL_MIX_SCALE;
|
||||||
if (v->tremolo_phase_increment != 0)
|
if (v->tremolo_phase_increment != 0)
|
||||||
{ // [RH] FIXME: This is wrong. Tremolo should offset the
|
{ // [RH] FIXME: This is wrong. Tremolo should offset the
|
||||||
|
@ -211,7 +163,6 @@ void GF1Envelope::ApplyToAmp(Voice *v)
|
||||||
}
|
}
|
||||||
env_vol *= volume / float(1 << 30);
|
env_vol *= volume / float(1 << 30);
|
||||||
env_vol = calc_gf1_amp(env_vol);
|
env_vol = calc_gf1_amp(env_vol);
|
||||||
}
|
|
||||||
env_vol *= final_amp;
|
env_vol *= final_amp;
|
||||||
v->left_mix = float(env_vol * v->left_offset);
|
v->left_mix = float(env_vol * v->left_offset);
|
||||||
v->right_mix = float(env_vol * v->right_offset);
|
v->right_mix = float(env_vol * v->right_offset);
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
#include "timidity.h"
|
#include "timidity.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, midi_timiditylike)
|
|
||||||
|
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -118,7 +116,7 @@ void Renderer::recompute_freq(int v)
|
||||||
voice[v].sample_increment = (int)(a);
|
voice[v].sample_increment = (int)(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BYTE vol_table[] = {
|
static const BYTE vol_table[] = {
|
||||||
000 /* 000 */, 129 /* 001 */, 145 /* 002 */, 155 /* 003 */,
|
000 /* 000 */, 129 /* 001 */, 145 /* 002 */, 155 /* 003 */,
|
||||||
161 /* 004 */, 166 /* 005 */, 171 /* 006 */, 174 /* 007 */,
|
161 /* 004 */, 166 /* 005 */, 171 /* 006 */, 174 /* 007 */,
|
||||||
177 /* 008 */, 180 /* 009 */, 182 /* 010 */, 185 /* 011 */,
|
177 /* 008 */, 180 /* 009 */, 182 /* 010 */, 185 /* 011 */,
|
||||||
|
@ -160,18 +158,9 @@ void Renderer::recompute_amp(Voice *v)
|
||||||
int chanexpr = chan->expression;
|
int chanexpr = chan->expression;
|
||||||
|
|
||||||
if (v->sample->type == INST_GUS)
|
if (v->sample->type == INST_GUS)
|
||||||
{
|
|
||||||
if (midi_timiditylike)
|
|
||||||
{
|
|
||||||
v->attenuation = float(timidityxx_perceived_vol(v->velocity / 127.0) *
|
|
||||||
timidityxx_perceived_vol(chanvol / 127.0) *
|
|
||||||
timidityxx_perceived_vol(chanexpr / 127.0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
v->attenuation = (vol_table[(chanvol * chanexpr) / 127] * vol_table[v->velocity]) * ((127 + 64) / 12419775.f);
|
v->attenuation = (vol_table[(chanvol * chanexpr) / 127] * vol_table[v->velocity]) * ((127 + 64) / 12419775.f);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Implicit modulators from SF2 spec
|
// Implicit modulators from SF2 spec
|
||||||
|
@ -199,7 +188,7 @@ void Renderer::compute_pan(double pan, int type, float &left_offset, float &righ
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (type == INST_GUS && !midi_timiditylike)
|
if (type == INST_GUS)
|
||||||
{
|
{
|
||||||
/* Original amp equation looks like this:
|
/* Original amp equation looks like this:
|
||||||
* calc_gf1_amp(atten + offset)
|
* calc_gf1_amp(atten + offset)
|
||||||
|
@ -218,9 +207,7 @@ void Renderer::compute_pan(double pan, int type, float &left_offset, float &righ
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* I have no idea what equation, if any, will reproduce the sc_pan_table
|
/* Equal Power Panning for SF2/DLS.
|
||||||
* that TiMidity++ uses, so midi_timiditylike gets the same Equal Power
|
|
||||||
* Panning as SF2/DLS.
|
|
||||||
*/
|
*/
|
||||||
left_offset = (float)sqrt(1 - pan);
|
left_offset = (float)sqrt(1 - pan);
|
||||||
right_offset = (float)sqrt(pan);
|
right_offset = (float)sqrt(pan);
|
||||||
|
@ -561,7 +548,7 @@ void Renderer::finish_note(int i)
|
||||||
v->status &= ~VOICE_SUSTAINING;
|
v->status &= ~VOICE_SUSTAINING;
|
||||||
v->status |= VOICE_RELEASING;
|
v->status |= VOICE_RELEASING;
|
||||||
|
|
||||||
if (!(v->sample->modes & PATCH_NO_SRELEASE) || midi_timiditylike)
|
if (!(v->sample->modes & PATCH_NO_SRELEASE))
|
||||||
{
|
{
|
||||||
v->status &= ~VOICE_LPE; /* sampled release */
|
v->status &= ~VOICE_LPE; /* sampled release */
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include "timidity.h"
|
#include "timidity.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, midi_timiditylike)
|
|
||||||
|
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -522,7 +520,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
||||||
|
|
||||||
if (vp->vibrato_control_ratio)
|
if (vp->vibrato_control_ratio)
|
||||||
{
|
{
|
||||||
if (vp->status & VOICE_LPE && !(midi_timiditylike && vp->sample->modes & PATCH_T_NO_LOOP))
|
if (vp->status & VOICE_LPE)
|
||||||
{
|
{
|
||||||
if (modes & PATCH_BIDIR)
|
if (modes & PATCH_BIDIR)
|
||||||
return rs_vib_bidir(song->resample_buffer, song->rate, vp, *countptr);
|
return rs_vib_bidir(song->resample_buffer, song->rate, vp, *countptr);
|
||||||
|
@ -536,7 +534,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vp->status & VOICE_LPE && !(midi_timiditylike && vp->sample->modes & PATCH_T_NO_LOOP))
|
if (vp->status & VOICE_LPE)
|
||||||
{
|
{
|
||||||
if (modes & PATCH_BIDIR)
|
if (modes & PATCH_BIDIR)
|
||||||
return rs_bidir(song->resample_buffer, vp, *countptr);
|
return rs_bidir(song->resample_buffer, vp, *countptr);
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
CVAR(String, midi_config, CONFIG_FILE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(String, midi_config, CONFIG_FILE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Int, midi_voices, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Int, midi_voices, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Bool, midi_timiditylike, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|
||||||
CVAR(String, gus_patchdir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(String, gus_patchdir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Bool, midi_dmxgus, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Bool, midi_dmxgus, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
@ -42,10 +41,10 @@ CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
|
||||||
|
PathExpander pathExpander;
|
||||||
ToneBank *tonebank[MAXBANK], *drumset[MAXBANK];
|
ToneBank *tonebank[MAXBANK], *drumset[MAXBANK];
|
||||||
|
|
||||||
static FString def_instr_name;
|
static FString def_instr_name;
|
||||||
int openmode = OM_FILEORLUMP;
|
|
||||||
|
|
||||||
static int read_config_file(const char *name, bool ismain)
|
static int read_config_file(const char *name, bool ismain)
|
||||||
{
|
{
|
||||||
|
@ -62,21 +61,21 @@ static int read_config_file(const char *name, bool ismain)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ismain) openmode = OM_FILEORLUMP;
|
if (ismain) pathExpander.openmode = PathExpander::OM_FILEORLUMP;
|
||||||
|
|
||||||
if (!(fp = open_filereader(name, openmode, &lumpnum)))
|
if (!(fp = pathExpander.openFileReader(name, &lumpnum)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ismain)
|
if (ismain)
|
||||||
{
|
{
|
||||||
if (lumpnum > 0)
|
if (lumpnum > 0)
|
||||||
{
|
{
|
||||||
openmode = OM_LUMP;
|
pathExpander.openmode = PathExpander::OM_LUMP;
|
||||||
clear_pathlist(); // when reading from a PK3 we won't want to use any external path
|
pathExpander.clearPathlist(); // when reading from a PK3 we don't want to use any external path
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
openmode = OM_FILE;
|
pathExpander.openmode = PathExpander::OM_FILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +287,7 @@ static int read_config_file(const char *name, bool ismain)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
for (i = 1; i < words; i++)
|
for (i = 1; i < words; i++)
|
||||||
add_to_pathlist(w[i]);
|
pathExpander.addToPathlist(w[i]);
|
||||||
}
|
}
|
||||||
else if (!strcmp(w[0], "source"))
|
else if (!strcmp(w[0], "source"))
|
||||||
{
|
{
|
||||||
|
@ -377,7 +376,7 @@ static int read_config_file(const char *name, bool ismain)
|
||||||
delete fp;
|
delete fp;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
bank->tone[i].note = bank->tone[i].amp = bank->tone[i].pan =
|
bank->tone[i].note = bank->tone[i].pan =
|
||||||
bank->tone[i].fontbank = bank->tone[i].fontpreset =
|
bank->tone[i].fontbank = bank->tone[i].fontpreset =
|
||||||
bank->tone[i].fontnote = bank->tone[i].strip_loop =
|
bank->tone[i].fontnote = bank->tone[i].strip_loop =
|
||||||
bank->tone[i].strip_envelope = bank->tone[i].strip_tail = -1;
|
bank->tone[i].strip_envelope = bank->tone[i].strip_tail = -1;
|
||||||
|
@ -415,14 +414,7 @@ static int read_config_file(const char *name, bool ismain)
|
||||||
*cp++ = 0;
|
*cp++ = 0;
|
||||||
if (!strcmp(w[j], "amp"))
|
if (!strcmp(w[j], "amp"))
|
||||||
{
|
{
|
||||||
k = atoi(cp);
|
/* Ignored */
|
||||||
if ((k < 0 || k > MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9'))
|
|
||||||
{
|
|
||||||
Printf("%s: line %d: amplification must be between 0 and %d\n", name, line, MAX_AMPLIFICATION);
|
|
||||||
delete fp;
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
bank->tone[i].amp = k;
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(w[j], "note"))
|
else if (!strcmp(w[j], "note"))
|
||||||
{
|
{
|
||||||
|
@ -532,15 +524,15 @@ int LoadConfig(const char *filename)
|
||||||
* file itself since that file should contain any other directory
|
* file itself since that file should contain any other directory
|
||||||
* that needs to be added to the search path.
|
* that needs to be added to the search path.
|
||||||
*/
|
*/
|
||||||
clear_pathlist();
|
pathExpander.clearPathlist();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
add_to_pathlist("C:\\TIMIDITY");
|
pathExpander.addToPathlist("C:\\TIMIDITY");
|
||||||
add_to_pathlist("\\TIMIDITY");
|
pathExpander.addToPathlist("\\TIMIDITY");
|
||||||
add_to_pathlist(progdir);
|
pathExpander.addToPathlist(progdir);
|
||||||
#else
|
#else
|
||||||
add_to_pathlist("/usr/local/lib/timidity");
|
pathExpander.addToPathlist("/usr/local/lib/timidity");
|
||||||
add_to_pathlist("/etc/timidity");
|
pathExpander.addToPathlist("/etc/timidity");
|
||||||
add_to_pathlist("/etc");
|
pathExpander.addToPathlist("/etc");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some functions get aggravated if not even the standard banks are available. */
|
/* Some functions get aggravated if not even the standard banks are available. */
|
||||||
|
@ -579,10 +571,10 @@ int LoadDMXGUS()
|
||||||
if (ultradir.IsNotEmpty())
|
if (ultradir.IsNotEmpty())
|
||||||
{
|
{
|
||||||
ultradir += "/midi";
|
ultradir += "/midi";
|
||||||
add_to_pathlist(ultradir.GetChars());
|
pathExpander.addToPathlist(ultradir.GetChars());
|
||||||
}
|
}
|
||||||
// Load DMXGUS lump and patches from gus_patchdir
|
// Load DMXGUS lump and patches from gus_patchdir
|
||||||
add_to_pathlist(gus_patchdir);
|
pathExpander.addToPathlist(gus_patchdir);
|
||||||
|
|
||||||
char readbuffer[1024];
|
char readbuffer[1024];
|
||||||
long size = data.GetLength();
|
long size = data.GetLength();
|
||||||
|
@ -676,7 +668,7 @@ int LoadDMXGUS()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int val = k % 128;
|
int val = k % 128;
|
||||||
bank->tone[val].note = bank->tone[val].amp = bank->tone[val].pan =
|
bank->tone[val].note = bank->tone[val].pan =
|
||||||
bank->tone[val].fontbank = bank->tone[val].fontpreset =
|
bank->tone[val].fontbank = bank->tone[val].fontpreset =
|
||||||
bank->tone[val].fontnote = bank->tone[val].strip_loop =
|
bank->tone[val].fontnote = bank->tone[val].strip_loop =
|
||||||
bank->tone[val].strip_envelope = bank->tone[val].strip_tail = -1;
|
bank->tone[val].strip_envelope = bank->tone[val].strip_tail = -1;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define TIMIDITY_H
|
#define TIMIDITY_H
|
||||||
|
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
|
#include "pathexpander.h"
|
||||||
|
|
||||||
class FileReader;
|
class FileReader;
|
||||||
|
|
||||||
|
@ -54,10 +55,6 @@ config.h
|
||||||
volume level of FMOD's built-in MIDI player. */
|
volume level of FMOD's built-in MIDI player. */
|
||||||
#define FINAL_MIX_SCALE 0.5
|
#define FINAL_MIX_SCALE 0.5
|
||||||
|
|
||||||
/* This value is used instead when midi_timiditylike is turned on,
|
|
||||||
because TiMidity++ is louder than a GUS. */
|
|
||||||
#define FINAL_MIX_TIMIDITY_SCALE 0.3
|
|
||||||
|
|
||||||
/* How many bits to use for the fractional part of sample positions.
|
/* How many bits to use for the fractional part of sample positions.
|
||||||
This affects tonal accuracy. The entire position counter must fit
|
This affects tonal accuracy. The entire position counter must fit
|
||||||
in 32 bits, so with FRACTION_BITS equal to 12, the maximum size of
|
in 32 bits, so with FRACTION_BITS equal to 12, the maximum size of
|
||||||
|
@ -172,17 +169,8 @@ extern __inline__ double pow_x87_inline(double x,double y)
|
||||||
common.h
|
common.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define OM_FILEORLUMP 0
|
|
||||||
#define OM_LUMP 1
|
|
||||||
#define OM_FILE 2
|
|
||||||
|
|
||||||
extern void add_to_pathlist(const char *s);
|
|
||||||
extern void clear_pathlist();
|
|
||||||
extern void *safe_malloc(size_t count);
|
extern void *safe_malloc(size_t count);
|
||||||
|
|
||||||
FileReader *open_filereader(const char *name, int open, int *plumpnum);
|
|
||||||
extern int openmode;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
controls.h
|
controls.h
|
||||||
*/
|
*/
|
||||||
|
@ -219,9 +207,6 @@ enum
|
||||||
PATCH_SUSTAIN = (1<<5),
|
PATCH_SUSTAIN = (1<<5),
|
||||||
PATCH_NO_SRELEASE = (1<<6),
|
PATCH_NO_SRELEASE = (1<<6),
|
||||||
PATCH_FAST_REL = (1<<7),
|
PATCH_FAST_REL = (1<<7),
|
||||||
|
|
||||||
PATCH_T_NO_ENVELOPE = (1<<8),
|
|
||||||
PATCH_T_NO_LOOP = (1<<9)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sample
|
struct Sample
|
||||||
|
@ -247,8 +232,6 @@ struct Sample
|
||||||
short release_vol;
|
short release_vol;
|
||||||
} sf2;
|
} sf2;
|
||||||
} envelope;
|
} envelope;
|
||||||
float
|
|
||||||
volume;
|
|
||||||
sample_t *data;
|
sample_t *data;
|
||||||
SDWORD
|
SDWORD
|
||||||
tremolo_sweep_increment, tremolo_phase_increment,
|
tremolo_sweep_increment, tremolo_phase_increment,
|
||||||
|
@ -324,11 +307,12 @@ struct Instrument
|
||||||
struct ToneBankElement
|
struct ToneBankElement
|
||||||
{
|
{
|
||||||
ToneBankElement() :
|
ToneBankElement() :
|
||||||
note(0), amp(0), pan(0), strip_loop(0), strip_envelope(0), strip_tail(0)
|
note(0), pan(0), strip_loop(0), strip_envelope(0), strip_tail(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FString name;
|
FString name;
|
||||||
int note, amp, pan, fontbank, fontpreset, fontnote, strip_loop, strip_envelope, strip_tail;
|
int note, pan, fontbank, fontpreset, fontnote;
|
||||||
|
SBYTE strip_loop, strip_envelope, strip_tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A hack to delay instrument loading until after reading the entire MIDI file. */
|
/* A hack to delay instrument loading until after reading the entire MIDI file. */
|
||||||
|
@ -616,8 +600,6 @@ const double log_of_2 = 0.69314718055994529;
|
||||||
|
|
||||||
#define calc_gf1_amp(x) (pow(2.0,((x)*16.0 - 16.0))) // Actual GUS equation
|
#define calc_gf1_amp(x) (pow(2.0,((x)*16.0 - 16.0))) // Actual GUS equation
|
||||||
#define cb_to_amp(x) (pow(10.0, (x) * (1 / -200.0))) // centibels to amp
|
#define cb_to_amp(x) (pow(10.0, (x) * (1 / -200.0))) // centibels to amp
|
||||||
#define db_to_amp(x) (pow(10.0, (x) * (1 / -20.0))) // decibels to map
|
|
||||||
#define timidityxx_perceived_vol(x) (pow((x), 1.66096404744))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
timidity.h
|
timidity.h
|
||||||
|
@ -627,6 +609,7 @@ int LoadConfig(const char *filename);
|
||||||
int LoadDMXGUS();
|
int LoadDMXGUS();
|
||||||
extern int LoadConfig();
|
extern int LoadConfig();
|
||||||
extern void FreeAll();
|
extern void FreeAll();
|
||||||
|
extern PathExpander pathExpander;
|
||||||
|
|
||||||
extern ToneBank *tonebank[MAXBANK];
|
extern ToneBank *tonebank[MAXBANK];
|
||||||
extern ToneBank *drumset[MAXBANK];
|
extern ToneBank *drumset[MAXBANK];
|
||||||
|
|
|
@ -38,18 +38,56 @@
|
||||||
#include "../files.h"
|
#include "../files.h"
|
||||||
#include "wm_error.h"
|
#include "wm_error.h"
|
||||||
#include "file_io.h"
|
#include "file_io.h"
|
||||||
|
#include "pathexpander.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
|
||||||
unsigned char *_WM_BufferFile(const char *filename, unsigned long int *size)
|
static PathExpander wmPathExpander;
|
||||||
|
|
||||||
|
unsigned char *_WM_BufferFile(const char *filename, unsigned long int *size, bool ismain)
|
||||||
{
|
{
|
||||||
FileReader file;
|
FileReader *fp;
|
||||||
|
int lumpnum;
|
||||||
|
|
||||||
if (!file.Open(filename))
|
if (ismain)
|
||||||
|
{
|
||||||
|
wmPathExpander.openmode = PathExpander::OM_FILEORLUMP;
|
||||||
|
wmPathExpander.clearPathlist();
|
||||||
|
#ifdef _WIN32
|
||||||
|
wmPathExpander.addToPathlist("C:\\TIMIDITY");
|
||||||
|
wmPathExpander.addToPathlist("\\TIMIDITY");
|
||||||
|
wmPathExpander.addToPathlist(progdir);
|
||||||
|
#else
|
||||||
|
wmPathExpander.addToPathlist("/usr/local/lib/timidity");
|
||||||
|
wmPathExpander.addToPathlist("/etc/timidity");
|
||||||
|
wmPathExpander.addToPathlist("/etc");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fp = wmPathExpander.openFileReader(filename, &lumpnum)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (ismain)
|
||||||
|
{
|
||||||
|
if (lumpnum > 0)
|
||||||
|
{
|
||||||
|
wmPathExpander.openmode = PathExpander::OM_LUMP;
|
||||||
|
wmPathExpander.clearPathlist(); // when reading from a PK3 we don't want to use any external path
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wmPathExpander.openmode = PathExpander::OM_FILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
_WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, errno);
|
_WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
long fsize = file.GetLength();
|
long fsize = fp->GetLength();
|
||||||
|
|
||||||
if (fsize > WM_MAXFILESIZE)
|
if (fsize > WM_MAXFILESIZE)
|
||||||
{
|
{
|
||||||
|
@ -66,7 +104,8 @@ unsigned char *_WM_BufferFile(const char *filename, unsigned long int *size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.Read(data, fsize);
|
fp->Read(data, fsize);
|
||||||
|
delete fp;
|
||||||
data[fsize] = 0;
|
data[fsize] = 0;
|
||||||
*size = fsize;
|
*size = fsize;
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -28,6 +28,6 @@
|
||||||
#define __FILE_IO_H
|
#define __FILE_IO_H
|
||||||
|
|
||||||
#define WM_MAXFILESIZE 0x1fffffff
|
#define WM_MAXFILESIZE 0x1fffffff
|
||||||
extern unsigned char *_WM_BufferFile (const char *filename, unsigned long int *size);
|
extern unsigned char *_WM_BufferFile (const char *filename, unsigned long int *size, bool mainfile = false);
|
||||||
|
|
||||||
#endif /* __FILE_IO_H */
|
#endif /* __FILE_IO_H */
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
lock.c - data locking code for lib
|
|
||||||
|
|
||||||
Copyright (C) Chris Ison 2001-2011
|
|
||||||
Copyright (C) Bret Curtis 2013-2014
|
|
||||||
|
|
||||||
This file is part of WildMIDI.
|
|
||||||
|
|
||||||
WildMIDI is free software: you can redistribute and/or modify the player
|
|
||||||
under the terms of the GNU General Public License and you can redistribute
|
|
||||||
and/or modify the library under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation, either version 3 of
|
|
||||||
the licenses, or(at your option) any later version.
|
|
||||||
|
|
||||||
WildMIDI 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 and
|
|
||||||
the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and the
|
|
||||||
GNU Lesser General Public License along with WildMIDI. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//#include "config.h"
|
|
||||||
|
|
||||||
#ifndef __DJGPP__
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "lock.h"
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
_WM_Lock(wmlock)
|
|
||||||
|
|
||||||
wmlock = a pointer to a value
|
|
||||||
|
|
||||||
returns nothing
|
|
||||||
|
|
||||||
Attempts to set a lock on the MDI tree so that
|
|
||||||
only 1 library command may access it at any time.
|
|
||||||
If lock fails the process retries until successful.
|
|
||||||
*/
|
|
||||||
void _WM_Lock(int * wmlock) {
|
|
||||||
LOCK_START:
|
|
||||||
/* Check if lock is clear, if so set it */
|
|
||||||
if (*wmlock == 0) {
|
|
||||||
(*wmlock)++;
|
|
||||||
/* Now that the lock is set, make sure we
|
|
||||||
* don't have a race condition. If so,
|
|
||||||
* decrement the lock by one and retry. */
|
|
||||||
if (*wmlock == 1) {
|
|
||||||
return; /* Lock cleanly set */
|
|
||||||
}
|
|
||||||
(*wmlock)--;
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
Sleep(10);
|
|
||||||
#else
|
|
||||||
usleep(500);
|
|
||||||
#endif
|
|
||||||
goto LOCK_START;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
_WM_Unlock(wmlock)
|
|
||||||
|
|
||||||
wmlock = a pointer to a value
|
|
||||||
|
|
||||||
returns nothing
|
|
||||||
|
|
||||||
Removes a lock previously placed on the MDI tree.
|
|
||||||
*/
|
|
||||||
void _WM_Unlock(int *wmlock) {
|
|
||||||
/* We don't want a -1 lock, so just to make sure */
|
|
||||||
if ((*wmlock) != 0) {
|
|
||||||
(*wmlock)--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __DJGPP__ */
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
lock.h - data locking code for lib
|
|
||||||
|
|
||||||
Copyright (C) Chris Ison 2001-2011
|
|
||||||
Copyright (C) Bret Curtis 2013-2014
|
|
||||||
|
|
||||||
This file is part of WildMIDI.
|
|
||||||
|
|
||||||
WildMIDI is free software: you can redistribute and/or modify the player
|
|
||||||
under the terms of the GNU General Public License and you can redistribute
|
|
||||||
and/or modify the library under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation, either version 3 of
|
|
||||||
the licenses, or(at your option) any later version.
|
|
||||||
|
|
||||||
WildMIDI 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 and
|
|
||||||
the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and the
|
|
||||||
GNU Lesser General Public License along with WildMIDI. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LOCK_H
|
|
||||||
#define __LOCK_H
|
|
||||||
|
|
||||||
extern void _WM_Lock (int * wmlock);
|
|
||||||
extern void _WM_Unlock (int *wmlock);
|
|
||||||
|
|
||||||
#ifdef __DJGPP__
|
|
||||||
#define _WM_Lock(p) do {} while (0)
|
|
||||||
#define _WM_Unlock(p) do {} while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __LOCK_H */
|
|
File diff suppressed because it is too large
Load diff
|
@ -56,12 +56,7 @@ typedef void midi;
|
||||||
WM_SYMBOL const char * WildMidi_GetString (unsigned short int info);
|
WM_SYMBOL const char * WildMidi_GetString (unsigned short int info);
|
||||||
WM_SYMBOL int WildMidi_Init (const char * config_file, unsigned short int rate, unsigned short int options);
|
WM_SYMBOL int WildMidi_Init (const char * config_file, unsigned short int rate, unsigned short int options);
|
||||||
WM_SYMBOL int WildMidi_MasterVolume (unsigned char master_volume);
|
WM_SYMBOL int WildMidi_MasterVolume (unsigned char master_volume);
|
||||||
WM_SYMBOL midi * WildMidi_Open (const char *midifile);
|
|
||||||
WM_SYMBOL midi * WildMidi_OpenBuffer (unsigned char *midibuffer, unsigned long int size);
|
|
||||||
WM_SYMBOL int WildMidi_GetOutput (midi * handle, char * buffer, unsigned long int size);
|
|
||||||
WM_SYMBOL int WildMidi_SetOption (midi * handle, unsigned short int options, unsigned short int setting);
|
WM_SYMBOL int WildMidi_SetOption (midi * handle, unsigned short int options, unsigned short int setting);
|
||||||
WM_SYMBOL struct _WM_Info * WildMidi_GetInfo (midi * handle);
|
|
||||||
WM_SYMBOL int WildMidi_FastSeek (midi * handle, unsigned long int *sample_pos);
|
|
||||||
WM_SYMBOL int WildMidi_Close (midi * handle);
|
WM_SYMBOL int WildMidi_Close (midi * handle);
|
||||||
WM_SYMBOL int WildMidi_Shutdown (void);
|
WM_SYMBOL int WildMidi_Shutdown (void);
|
||||||
WM_SYMBOL int WildMidi_GetSampleRate (void);
|
WM_SYMBOL int WildMidi_GetSampleRate (void);
|
||||||
|
@ -79,10 +74,11 @@ public:
|
||||||
~WildMidi_Renderer();
|
~WildMidi_Renderer();
|
||||||
|
|
||||||
void ShortEvent(int status, int parm1, int parm2);
|
void ShortEvent(int status, int parm1, int parm2);
|
||||||
void LongEvent(const char *data, int len);
|
void LongEvent(const unsigned char *data, int len);
|
||||||
void ComputeOutput(float *buffer, int len);
|
void ComputeOutput(float *buffer, int len);
|
||||||
void LoadInstrument(int bank, int percussion, int instr);
|
void LoadInstrument(int bank, int percussion, int instr);
|
||||||
int GetVoiceCount();
|
int GetVoiceCount();
|
||||||
|
void SetOption(int opt, int set);
|
||||||
private:
|
private:
|
||||||
void *handle;
|
void *handle;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1604,7 +1604,6 @@ OptionMenu AdvSoundOptions
|
||||||
StaticText "GUS Emulation", 1
|
StaticText "GUS Emulation", 1
|
||||||
TextField "GUS config file", "midi_config"
|
TextField "GUS config file", "midi_config"
|
||||||
Slider "MIDI voices", "midi_voices", 16, 256, 4, 0
|
Slider "MIDI voices", "midi_voices", 16, 256, 4, 0
|
||||||
Option "Emulate TiMidity", "midi_timiditylike", "OnOff"
|
|
||||||
Option "Read DMXGUS lumps", "midi_dmxgus", "OnOff"
|
Option "Read DMXGUS lumps", "midi_dmxgus", "OnOff"
|
||||||
Option "GUS memory size", "gus_memsize", "GusMemory"
|
Option "GUS memory size", "gus_memsize", "GusMemory"
|
||||||
StaticText " "
|
StaticText " "
|
||||||
|
@ -1620,6 +1619,10 @@ OptionMenu AdvSoundOptions
|
||||||
Option "Reverb", "timidity_reverb", "OnOff"
|
Option "Reverb", "timidity_reverb", "OnOff"
|
||||||
Option "Chorus", "timidity_chorus", "OnOff"
|
Option "Chorus", "timidity_chorus", "OnOff"
|
||||||
Slider "Relative volume", "timidity_mastervolume", 0, 4, 0.2, 1
|
Slider "Relative volume", "timidity_mastervolume", 0, 4, 0.2, 1
|
||||||
|
StaticText " "
|
||||||
|
StaticText "WildMidi", 1
|
||||||
|
TextField "WildMidi config file", "wildmidi_config"
|
||||||
|
Option "Reverb", "wildmidi_reverb", "OnOff"
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=======================================
|
/*=======================================
|
||||||
|
|
16
zdoom.vcproj
16
zdoom.vcproj
|
@ -942,6 +942,10 @@
|
||||||
RelativePath=".\src\parsecontext.cpp"
|
RelativePath=".\src\parsecontext.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\pathexpander.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\po_man.cpp"
|
RelativePath=".\src\po_man.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1479,6 +1483,10 @@
|
||||||
RelativePath=".\src\parsecontext.h"
|
RelativePath=".\src\parsecontext.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\pathexpander.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\po_man.h"
|
RelativePath=".\src\po_man.h"
|
||||||
>
|
>
|
||||||
|
@ -2811,10 +2819,6 @@
|
||||||
RelativePath=".\src\wildmidi\gus_pat.h"
|
RelativePath=".\src\wildmidi\gus_pat.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\src\wildmidi\lock.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\wildmidi\reverb.h"
|
RelativePath=".\src\wildmidi\reverb.h"
|
||||||
>
|
>
|
||||||
|
@ -2839,10 +2843,6 @@
|
||||||
RelativePath=".\src\wildmidi\gus_pat.cpp"
|
RelativePath=".\src\wildmidi\gus_pat.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\src\wildmidi\lock.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\wildmidi\reverb.cpp"
|
RelativePath=".\src\wildmidi\reverb.cpp"
|
||||||
>
|
>
|
||||||
|
|
Loading…
Reference in a new issue