diff --git a/src/timidity/instrum_dls.cpp b/src/timidity/instrum_dls.cpp index 286fcb1a3..02b8e59c0 100644 --- a/src/timidity/instrum_dls.cpp +++ b/src/timidity/instrum_dls.cpp @@ -1126,7 +1126,7 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, sample->key_group = (SBYTE)rgn->header->usKeyGroup; sample->low_freq = note_to_freq(rgn->header->RangeKey.usLow); sample->high_freq = note_to_freq(rgn->header->RangeKey.usHigh); - sample->root_freq = note_to_freq(rgn->wsmp->usUnityNote); + sample->root_freq = note_to_freq(rgn->wsmp->usUnityNote + rgn->wsmp->sFineTune * .01f); sample->low_vel = (BYTE)rgn->header->RangeVelocity.usLow; sample->high_vel = (BYTE)rgn->header->RangeVelocity.usHigh; @@ -1137,15 +1137,17 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, convert_sample_data(sample, wave->data); if (rgn->wsmp->cSampleLoops) { - sample->modes |= (PATCH_LOOPEN | PATCH_SUSTAIN); + sample->modes |= (PATCH_LOOPEN | PATCH_SUSTAIN/* | PATCH_NO_SRELEASE*/); sample->loop_start = rgn->wsmp_loop->ulStart / 2; sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2); } + sample->scale_factor = 1024; + sample->scale_note = rgn->wsmp->usUnityNote; if (sample->modes & PATCH_SUSTAIN) { int value; - double attack, hold, decay, release; int sustain; + int attack, hold, decay, release; int sustain; CONNECTIONLIST *art = NULL; CONNECTION *artList = NULL; @@ -1157,16 +1159,11 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, artList = rgn->artList; } - value = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME); - attack = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME); - hold = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME); - decay = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME); - release = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL); - sustain = (int)((1.0 - to_normalized_percent(value)) * 250.0); + attack = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME); + hold = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME); + decay = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME); + release = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME); + sustain = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL); value = load_connection(art->cConnections, artList, CONN_DST_PAN); sample->panning = (int)((0.5 + to_normalized_percent(value)) * 16383.f); @@ -1174,12 +1171,12 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, printf("%d, Rate=%d LV=%d HV=%d Low=%d Hi=%d Root=%d Pan=%d Attack=%f Hold=%f Sustain=%d Decay=%f Release=%f\n", index, sample->sample_rate, rgn->header->RangeVelocity.usLow, rgn->header->RangeVelocity.usHigh, sample->low_freq, sample->high_freq, sample->root_freq, sample->panning, attack, hold, sustain, decay, release); */ - sample->envelope.sf2.decay_vol = 0; - sample->envelope.sf2.attack_vol = (short)attack; - sample->envelope.sf2.hold_vol = (short)hold; - sample->envelope.sf2.decay_vol = (short)decay; - sample->envelope.sf2.release_vol = (short)release; - sample->envelope.sf2.sustain_vol = (short)sustain; + sample->envelope.sf2.delay_vol = -32768; + sample->envelope.sf2.attack_vol = (short)(attack >> 16); + sample->envelope.sf2.hold_vol = (short)(hold >> 16); + sample->envelope.sf2.decay_vol = (short)(decay >> 16); + sample->envelope.sf2.release_vol = (short)(release >> 16); + sample->envelope.sf2.sustain_vol = (short)(sustain >> 16); } sample->data_length <<= FRACTION_BITS; diff --git a/src/timidity/mix.cpp b/src/timidity/mix.cpp index f97710326..beda91e16 100644 --- a/src/timidity/mix.cpp +++ b/src/timidity/mix.cpp @@ -231,6 +231,10 @@ bool SF2Envelope::Update(Voice *v) double sec; double newvolume = 0; + // NOTE! The volume scale is different for different stages of the + // envelope generator: + // Attack stage goes from 0.0 -> 1.0, multiplied directly to the output. + // The following stages go from 0 -> -1000 cB (but recorded positively) switch (stage) { case SF2_DELAY: @@ -333,6 +337,11 @@ bool SF2Envelope::Update(Voice *v) #define FLUID_ATTEN_POWER_FACTOR (-531.509) #define atten2amp(x) pow(10.0, (x) / FLUID_ATTEN_POWER_FACTOR) +static double cb_to_amp(double x) // centibels to amp +{ + return pow(10, x / -200.f); +} + void SF2Envelope::ApplyToAmp(Voice *v) { double amp; @@ -343,13 +352,21 @@ void SF2Envelope::ApplyToAmp(Voice *v) v->right_mix = 0; return; } - else if (stage == SF2_ATTACK) + + amp = v->sample->type == INST_SF2 ? atten2amp(v->attenuation) : cb_to_amp(v->attenuation); + + switch (stage) { - amp = atten2amp(v->attenuation) * volume; - } - else - { - amp = atten2amp(v->attenuation) * cb_to_amp(volume); + case SF2_ATTACK: + amp *= volume; + break; + + case SF2_HOLD: + break; + + default: + amp *= cb_to_amp(volume); + break; } amp *= FINAL_MIX_SCALE * 0.5; v->left_mix = float(amp * v->left_offset); diff --git a/src/timidity/timidity.cpp b/src/timidity/timidity.cpp index 440db9211..267edbb7e 100644 --- a/src/timidity/timidity.cpp +++ b/src/timidity/timidity.cpp @@ -678,6 +678,9 @@ int LoadDMXGUS() return 0; } +DLS_Data *LoadDLS(FILE *src); +void FreeDLS(DLS_Data *data); + Renderer::Renderer(float sample_rate, const char *args) { // 'args' should be used to load a custom config or DMXGUS, but since setup currently requires a snd_reset call, this will need some refactoring first @@ -701,6 +704,11 @@ Renderer::Renderer(float sample_rate, const char *args) voices = MAX(*midi_voices, 16); voice = new Voice[voices]; drumchannels = DEFAULT_DRUMCHANNELS; +#if 0 + FILE *f = fopen("c:\\windows\\system32\\drivers\\gm.dls", "rb"); + patches = LoadDLS(f); + fclose(f); +#endif } Renderer::~Renderer() @@ -713,6 +721,10 @@ Renderer::~Renderer() { delete[] voice; } + if (patches != NULL) + { + FreeDLS(patches); + } } void Renderer::ComputeOutput(float *buffer, int count) diff --git a/src/timidity/timidity.h b/src/timidity/timidity.h index 45e23a9f9..ac423c1e2 100644 --- a/src/timidity/timidity.h +++ b/src/timidity/timidity.h @@ -445,7 +445,7 @@ struct Channel struct MinEnvelope { - int stage; + BYTE stage; BYTE bUpdating; }; @@ -599,7 +599,6 @@ const double log_of_2 = 0.69314718055994529; #define freq_to_note(x) (log((x) / 8175.7989473096690661233836992789) * (12.0 / log_of_2)) #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 /* timidity.h