mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
- Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of
GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. SVN r959 (trunk)
This commit is contained in:
parent
e64586d86f
commit
d4563767ee
7 changed files with 156 additions and 64 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
May 9, 2008
|
||||||
|
- Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of
|
||||||
|
GUS patch flags, envelopes, and volume levels, while trying to be closer
|
||||||
|
to TiMidity++ than original TiMidity.
|
||||||
|
- Renamed timidity_config and timidity_voices to midi_config and midi_voices
|
||||||
|
respectively.
|
||||||
|
|
||||||
May 8, 2008
|
May 8, 2008
|
||||||
- Reduced volume, expression, and panning controllers back to 7 bits.
|
- Reduced volume, expression, and panning controllers back to 7 bits.
|
||||||
- Added very basic Soundfont support to the internal TiMidity. Things missing:
|
- Added very basic Soundfont support to the internal TiMidity. Things missing:
|
||||||
|
|
|
@ -362,53 +362,58 @@ fail:
|
||||||
if (header.Description[j] != 0)
|
if (header.Description[j] != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j == DESC_SIZE)
|
/* Strip any loops and envelopes we're permitted to */
|
||||||
|
/* [RH] (But PATCH_BACKWARD isn't a loop flag at all!) */
|
||||||
|
if ((strip_loop == 1) &&
|
||||||
|
(sp->modes & (PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD)))
|
||||||
{
|
{
|
||||||
/* Strip any loops and envelopes we're permitted to */
|
cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain\n");
|
||||||
/* [RH] (But PATCH_BACKWARD isn't a loop flag at all!) */
|
if (j == DESC_SIZE)
|
||||||
if ((strip_loop == 1) &&
|
|
||||||
(sp->modes & (PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD)))
|
|
||||||
{
|
{
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain\n");
|
|
||||||
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)
|
||||||
|
{
|
||||||
|
cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope\n");
|
||||||
|
/* [RH] The envelope isn't really removed, but this is the way the standard
|
||||||
|
* Gravis patches get that effect: All rates at maximum, and all offsets at
|
||||||
|
* a constant level.
|
||||||
|
*/
|
||||||
|
if (j == DESC_SIZE)
|
||||||
{
|
{
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope\n");
|
int k;
|
||||||
/* [RH] The envelope isn't really removed, but this is the way the standard
|
for (k = 1; k < ENVELOPES; ++k)
|
||||||
* Gravis patches get that effect: All rates at maximum, and all offsets at
|
|
||||||
* a constant level.
|
|
||||||
*/
|
|
||||||
for (j = 1; j < ENVELOPES; ++j)
|
|
||||||
{ /* Find highest offset. */
|
{ /* Find highest offset. */
|
||||||
if (patch_data.EnvelopeOffset[j] > patch_data.EnvelopeOffset[0])
|
if (patch_data.EnvelopeOffset[k] > patch_data.EnvelopeOffset[0])
|
||||||
{
|
{
|
||||||
patch_data.EnvelopeOffset[0] = patch_data.EnvelopeOffset[j];
|
patch_data.EnvelopeOffset[0] = patch_data.EnvelopeOffset[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (j = 0; j < ENVELOPES; ++j)
|
for (k = 0; k < ENVELOPES; ++k)
|
||||||
{
|
{
|
||||||
patch_data.EnvelopeRate[j] = 63;
|
patch_data.EnvelopeRate[k] = 63;
|
||||||
patch_data.EnvelopeOffset[j] = patch_data.EnvelopeOffset[0];
|
patch_data.EnvelopeOffset[k] = patch_data.EnvelopeOffset[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sp->modes |= PATCH_T_NO_ENVELOPE;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
else if (strip_envelope != 0)
|
else if (strip_envelope != 0)
|
||||||
{
|
{
|
||||||
/* Have to make a guess. */
|
/* Have to make a guess. */
|
||||||
if (!(sp->modes & (PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD)))
|
if (!(sp->modes & (PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD)))
|
||||||
{
|
{
|
||||||
/* No loop? Then what's there to sustain? No envelope needed either... */
|
/* No loop? Then what's there to sustain? No envelope needed either... */
|
||||||
sp->modes &= ~(PATCH_SUSTAIN | PATCH_NO_SRELEASE);
|
sp->modes |= PATCH_T_NO_ENVELOPE;
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope\n");
|
cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope\n");
|
||||||
}
|
}
|
||||||
else if (memcmp(patch_data.EnvelopeRate, "??????", 6) == 0 || patch_data.EnvelopeOffset[RELEASEC] >= 100)
|
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"?
|
/* Envelope rates all maxed out? Envelope end at a high "offset"?
|
||||||
That's a weird envelope. Take it out. */
|
That's a weird envelope. Take it out. */
|
||||||
sp->modes &= ~PATCH_NO_SRELEASE;
|
sp->modes |= PATCH_T_NO_ENVELOPE;
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope\n");
|
cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope\n");
|
||||||
}
|
}
|
||||||
else if (!(sp->modes & PATCH_SUSTAIN))
|
else if (!(sp->modes & PATCH_SUSTAIN))
|
||||||
|
@ -417,11 +422,14 @@ fail:
|
||||||
justified, but patches without sustain usually don't need the
|
justified, but patches without sustain usually don't need the
|
||||||
envelope either... at least the Gravis ones. They're mostly
|
envelope either... at least the Gravis ones. They're mostly
|
||||||
drums. I think. */
|
drums. I think. */
|
||||||
sp->modes &= ~PATCH_NO_SRELEASE;
|
sp->modes |= PATCH_T_NO_ENVELOPE;
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope\n");
|
cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
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++)
|
||||||
{
|
{
|
||||||
|
@ -468,10 +476,10 @@ fail:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(ADJUST_SAMPLE_VOLUMES)
|
|
||||||
/* Try to determine a volume scaling factor for the sample.
|
/* Try to determine a volume scaling factor for the sample.
|
||||||
This is a very crude adjustment, but things sound more
|
This is a very crude adjustment, but things sound more
|
||||||
balanced with it. Still, this should be a runtime option. */
|
balanced with it. Still, this should be a runtime option.
|
||||||
|
(This is ignored unless midi_timiditylike is turned on.) */
|
||||||
int i;
|
int i;
|
||||||
sample_t maxamp = 0, a;
|
sample_t maxamp = 0, a;
|
||||||
sample_t *tmp;
|
sample_t *tmp;
|
||||||
|
@ -483,9 +491,6 @@ fail:
|
||||||
}
|
}
|
||||||
sp->volume = 1 / maxamp;
|
sp->volume = 1 / maxamp;
|
||||||
cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f\n", sp->volume);
|
cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f\n", sp->volume);
|
||||||
#else
|
|
||||||
sp->volume = 1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then fractional samples */
|
/* Then fractional samples */
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
|
|
||||||
#include "timidity.h"
|
#include "timidity.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, midi_timiditylike)
|
||||||
|
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
@ -75,7 +78,16 @@ void GF1Envelope::Init(Renderer *song, Voice *v)
|
||||||
|
|
||||||
void GF1Envelope::Release(Voice *v)
|
void GF1Envelope::Release(Voice *v)
|
||||||
{
|
{
|
||||||
if (!(v->sample->modes & PATCH_NO_SRELEASE) || (v->sample->modes & PATCH_FAST_REL))
|
if (midi_timiditylike)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
@ -96,22 +108,31 @@ void GF1Envelope::Release(Voice *v)
|
||||||
/* Returns 1 if envelope runs out */
|
/* Returns 1 if envelope runs out */
|
||||||
bool GF1Envelope::Recompute(Voice *v)
|
bool GF1Envelope::Recompute(Voice *v)
|
||||||
{
|
{
|
||||||
int oldstage;
|
int newstage;
|
||||||
|
|
||||||
oldstage = stage;
|
newstage = stage;
|
||||||
|
|
||||||
if (oldstage > GF1_RELEASEC)
|
if (newstage > GF1_RELEASEC)
|
||||||
{
|
{
|
||||||
/* Envelope ran out. */
|
/* Envelope ran out. */
|
||||||
/* play sampled release */
|
|
||||||
v->status &= ~(VOICE_SUSTAINING | VOICE_LPE);
|
|
||||||
v->status |= VOICE_RELEASING;
|
|
||||||
increment = 0;
|
increment = 0;
|
||||||
bUpdating = false;
|
bUpdating = false;
|
||||||
|
v->status &= ~(VOICE_SUSTAINING | VOICE_LPE);
|
||||||
|
v->status |= VOICE_RELEASING;
|
||||||
|
if (midi_timiditylike)
|
||||||
|
{ /* kill the voice */
|
||||||
|
v->status |= VOICE_STOPPING;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* play sampled release */
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldstage == GF1_RELEASE && !(v->status & VOICE_RELEASING) && (v->sample->modes & PATCH_SUSTAIN))
|
if (newstage == GF1_RELEASE && !(v->status & VOICE_RELEASING) &&
|
||||||
|
((!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. */
|
||||||
|
@ -120,14 +141,14 @@ bool GF1Envelope::Recompute(Voice *v)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stage = oldstage + 1;
|
stage = newstage + 1;
|
||||||
|
|
||||||
if (volume == offset[oldstage])
|
if (volume == offset[newstage])
|
||||||
{
|
{
|
||||||
return Recompute(v);
|
return Recompute(v);
|
||||||
}
|
}
|
||||||
target = offset[oldstage];
|
target = offset[newstage];
|
||||||
increment = rate[oldstage];
|
increment = rate[newstage];
|
||||||
if (target < volume)
|
if (target < volume)
|
||||||
increment = -increment;
|
increment = -increment;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +158,10 @@ 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)))
|
||||||
{
|
{
|
||||||
|
@ -152,14 +177,39 @@ bool GF1Envelope::Update(Voice *v)
|
||||||
void GF1Envelope::ApplyToAmp(Voice *v)
|
void GF1Envelope::ApplyToAmp(Voice *v)
|
||||||
{
|
{
|
||||||
double env_vol = v->attenuation;
|
double env_vol = v->attenuation;
|
||||||
double final_amp = v->sample->volume * FINAL_MIX_SCALE;
|
double final_amp;
|
||||||
if (v->tremolo_phase_increment != 0)
|
|
||||||
{ // [RH] FIXME: This is wrong. Tremolo should offset the
|
if (midi_timiditylike)
|
||||||
// envelope volume, not scale it.
|
{
|
||||||
env_vol *= v->tremolo_volume;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
env_vol *= volume / float(1 << 30);
|
else
|
||||||
env_vol = calc_gf1_amp(env_vol) * final_amp;
|
{
|
||||||
|
final_amp = FINAL_MIX_SCALE;
|
||||||
|
if (v->tremolo_phase_increment != 0)
|
||||||
|
{ // [RH] FIXME: This is wrong. Tremolo should offset the
|
||||||
|
// envelope volume, not scale it.
|
||||||
|
env_vol *= v->tremolo_volume;
|
||||||
|
}
|
||||||
|
env_vol *= volume / float(1 << 30);
|
||||||
|
env_vol = calc_gf1_amp(env_vol);
|
||||||
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "timidity.h"
|
#include "timidity.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, midi_timiditylike)
|
||||||
|
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
@ -161,7 +164,16 @@ void Renderer::recompute_amp(Voice *v)
|
||||||
|
|
||||||
if (v->sample->type == INST_GUS)
|
if (v->sample->type == INST_GUS)
|
||||||
{
|
{
|
||||||
v->attenuation = (vol_table[(chanvol * chanexpr) / 127] * vol_table[v->velocity]) * ((127 + 64) / 12419775.f);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -190,7 +202,7 @@ void Renderer::compute_pan(double pan, int type, float &left_offset, float &righ
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (type == INST_GUS)
|
if (type == INST_GUS && !midi_timiditylike)
|
||||||
{
|
{
|
||||||
/* Original amp equation looks like this:
|
/* Original amp equation looks like this:
|
||||||
* calc_gf1_amp(atten + offset)
|
* calc_gf1_amp(atten + offset)
|
||||||
|
@ -209,8 +221,12 @@ void Renderer::compute_pan(double pan, int type, float &left_offset, float &righ
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
left_offset = (float)db_to_amp(-20 * log10(sqrt(1 - pan)));
|
/* I have no idea what equation, if any, will reproduce the sc_pan_table
|
||||||
right_offset = (float)db_to_amp(-20 * log10(sqrt(pan)));
|
* that TiMidity++ uses, so midi_timiditylike gets the same Equal Power
|
||||||
|
* Panning as SF2/DLS.
|
||||||
|
*/
|
||||||
|
left_offset = (float)sqrt(1 - pan);
|
||||||
|
right_offset = (float)sqrt(pan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,7 +564,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))
|
if (!(v->sample->modes & PATCH_NO_SRELEASE) || midi_timiditylike)
|
||||||
{
|
{
|
||||||
v->status &= ~VOICE_LPE; /* sampled release */
|
v->status &= ~VOICE_LPE; /* sampled release */
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "timidity.h"
|
#include "timidity.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, midi_timiditylike)
|
||||||
|
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
@ -484,7 +487,7 @@ static sample_t *rs_vib_bidir(sample_t *resample_buffer, float rate, Voice *vp,
|
||||||
sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
||||||
{
|
{
|
||||||
int ofs;
|
int ofs;
|
||||||
BYTE modes;
|
WORD modes;
|
||||||
|
|
||||||
if (vp->sample->sample_rate == 0)
|
if (vp->sample->sample_rate == 0)
|
||||||
{
|
{
|
||||||
|
@ -519,7 +522,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)
|
if (vp->status & VOICE_LPE && !(midi_timiditylike && vp->sample->modes & PATCH_T_NO_LOOP))
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
@ -533,7 +536,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vp->status & VOICE_LPE)
|
if (vp->status & VOICE_LPE && !(midi_timiditylike && vp->sample->modes & PATCH_T_NO_LOOP))
|
||||||
{
|
{
|
||||||
if (modes & PATCH_BIDIR)
|
if (modes & PATCH_BIDIR)
|
||||||
return rs_bidir(song->resample_buffer, vp, *countptr);
|
return rs_bidir(song->resample_buffer, vp, *countptr);
|
||||||
|
|
|
@ -32,8 +32,9 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
|
||||||
CVAR(String, timidity_config, CONFIG_FILE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(String, midi_config, CONFIG_FILE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Int, timidity_voices, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Int, midi_voices, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
CVAR(Bool, midi_timiditylike, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
namespace Timidity
|
namespace Timidity
|
||||||
{
|
{
|
||||||
|
@ -551,7 +552,7 @@ int LoadConfig(const char *filename)
|
||||||
|
|
||||||
int LoadConfig()
|
int LoadConfig()
|
||||||
{
|
{
|
||||||
return LoadConfig(timidity_config);
|
return LoadConfig(midi_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::Renderer(float sample_rate)
|
Renderer::Renderer(float sample_rate)
|
||||||
|
@ -573,7 +574,7 @@ Renderer::Renderer(float sample_rate)
|
||||||
if (def_instr_name.IsNotEmpty())
|
if (def_instr_name.IsNotEmpty())
|
||||||
set_default_instrument(def_instr_name);
|
set_default_instrument(def_instr_name);
|
||||||
|
|
||||||
voices = clamp<int>(timidity_voices, 16, 256);
|
voices = clamp<int>(midi_voices, 16, 256);
|
||||||
voice = new Voice[voices];
|
voice = new Voice[voices];
|
||||||
drumchannels = DEFAULT_DRUMCHANNELS;
|
drumchannels = DEFAULT_DRUMCHANNELS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,11 @@ config.h
|
||||||
|
|
||||||
/* A scalar applied to the final mix to try and approximate the
|
/* A scalar applied to the final mix to try and approximate the
|
||||||
volume level of FMOD's built-in MIDI player. */
|
volume level of FMOD's built-in MIDI player. */
|
||||||
#define FINAL_MIX_SCALE 0.5f
|
#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
|
||||||
|
@ -214,7 +218,10 @@ enum
|
||||||
PATCH_BACKWARD = (1<<4),
|
PATCH_BACKWARD = (1<<4),
|
||||||
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
|
||||||
|
@ -249,7 +256,9 @@ struct Sample
|
||||||
BYTE
|
BYTE
|
||||||
tremolo_depth, vibrato_depth,
|
tremolo_depth, vibrato_depth,
|
||||||
low_vel, high_vel,
|
low_vel, high_vel,
|
||||||
modes, type;
|
type;
|
||||||
|
WORD
|
||||||
|
modes;
|
||||||
SWORD
|
SWORD
|
||||||
panning;
|
panning;
|
||||||
WORD
|
WORD
|
||||||
|
@ -608,6 +617,7 @@ 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 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
|
||||||
|
|
Loading…
Reference in a new issue