mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
Update gus_pat.cpp's envelope fudging to current git version
This commit is contained in:
parent
0c3b468e42
commit
a74d352490
2 changed files with 138 additions and 50 deletions
|
@ -45,21 +45,23 @@
|
||||||
extern unsigned short int _WM_SampleRate;
|
extern unsigned short int _WM_SampleRate;
|
||||||
|
|
||||||
struct _sample {
|
struct _sample {
|
||||||
unsigned long int data_length;
|
unsigned int data_length;
|
||||||
unsigned long int loop_start;
|
unsigned int loop_start;
|
||||||
unsigned long int loop_end;
|
unsigned int loop_end;
|
||||||
unsigned long int loop_size;
|
unsigned int loop_size;
|
||||||
unsigned char loop_fraction;
|
unsigned char loop_fraction;
|
||||||
unsigned short int rate;
|
unsigned short rate;
|
||||||
unsigned long int freq_low;
|
unsigned int freq_low;
|
||||||
unsigned long int freq_high;
|
unsigned int freq_high;
|
||||||
unsigned long int freq_root;
|
unsigned int freq_root;
|
||||||
unsigned char modes;
|
unsigned char modes;
|
||||||
signed long int env_rate[7];
|
signed int env_rate[7];
|
||||||
signed long int env_target[7];
|
signed int env_target[7];
|
||||||
unsigned long int inc_div;
|
unsigned int inc_div;
|
||||||
signed short *data;
|
signed short *data;
|
||||||
struct _sample *next;
|
struct _sample *next;
|
||||||
|
|
||||||
|
unsigned int note_off_decay;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _env {
|
struct _env {
|
||||||
|
|
|
@ -1,31 +1,26 @@
|
||||||
/*
|
/*
|
||||||
gus_pat.c
|
* gus_pat.c -- Midi Wavetable Processing library
|
||||||
|
*
|
||||||
Midi Wavetable Processing library
|
* Copyright (C) WildMIDI Developers 2001-2015
|
||||||
|
*
|
||||||
Copyright (C) Chris Ison 2001-2011
|
* This file is part of WildMIDI.
|
||||||
Copyright (C) Bret Curtis 2013-2014
|
*
|
||||||
|
* WildMIDI is free software: you can redistribute and/or modify the player
|
||||||
This file is part of WildMIDI.
|
* 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
|
||||||
WildMIDI is free software: you can redistribute and/or modify the player
|
* License as published by the Free Software Foundation, either version 3 of
|
||||||
under the terms of the GNU General Public License and you can redistribute
|
* the licenses, or(at your option) any later version.
|
||||||
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
|
* WildMIDI is distributed in the hope that it will be useful, but WITHOUT
|
||||||
the licenses, or(at your option) any later version.
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License and
|
||||||
WildMIDI is distributed in the hope that it will be useful, but WITHOUT
|
* the GNU Lesser General Public License for more details.
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
*
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License and
|
* You should have received a copy of the GNU General Public License and the
|
||||||
the GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License along with WildMIDI. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
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"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -737,6 +732,8 @@ struct _sample * _WM_load_gus_pat(const char *filename, int fix_release) {
|
||||||
};
|
};
|
||||||
unsigned long int tmp_loop;
|
unsigned long int tmp_loop;
|
||||||
|
|
||||||
|
/*unused*/fix_release;
|
||||||
|
|
||||||
SAMPLE_CONVERT_DEBUG(__FUNCTION__); SAMPLE_CONVERT_DEBUG(filename);
|
SAMPLE_CONVERT_DEBUG(__FUNCTION__); SAMPLE_CONVERT_DEBUG(filename);
|
||||||
|
|
||||||
if ((gus_patch = _WM_BufferFile(filename, &gus_size)) == NULL) {
|
if ((gus_patch = _WM_BufferFile(filename, &gus_size)) == NULL) {
|
||||||
|
@ -839,17 +836,80 @@ struct _sample * _WM_load_gus_pat(const char *filename, int fix_release) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FIXME: Experimental Hacky Fix
|
FIXME: Experimental Hacky Fix
|
||||||
|
|
||||||
|
This looks for "dodgy" release envelope settings that faulty editors
|
||||||
|
may have set and attempts to corrects it.
|
||||||
|
if (fix_release)
|
||||||
|
Lets make this automatic ...
|
||||||
*/
|
*/
|
||||||
if (fix_release) {
|
{
|
||||||
if (env_time_table[gus_patch[gus_ptr + 40]]
|
/*
|
||||||
< env_time_table[gus_patch[gus_ptr + 41]]) {
|
After studying faulty gus_pats this way may work better
|
||||||
unsigned char tmp_hack_rate = gus_patch[gus_ptr + 41];
|
Testing to determine if any further adjustments are required
|
||||||
gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 40];
|
*/
|
||||||
gus_patch[gus_ptr + 40] = tmp_hack_rate;
|
if (env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 41]]) {
|
||||||
|
unsigned char tmp_hack_rate = 0;
|
||||||
|
|
||||||
|
if (env_time_table[gus_patch[gus_ptr + 41]] < env_time_table[gus_patch[gus_ptr + 42]]) {
|
||||||
|
// 1 2 3
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 40];
|
||||||
|
gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 42];
|
||||||
|
gus_patch[gus_ptr + 42] = tmp_hack_rate;
|
||||||
|
} else if (env_time_table[gus_patch[gus_ptr + 41]] == env_time_table[gus_patch[gus_ptr + 42]]) {
|
||||||
|
// 1 2 2
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 40];
|
||||||
|
gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 42];
|
||||||
|
gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 42];
|
||||||
|
gus_patch[gus_ptr + 42] = tmp_hack_rate;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 42]]) {
|
||||||
|
// 1 3 2
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 40];
|
||||||
|
gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 41];
|
||||||
|
gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 42];
|
||||||
|
gus_patch[gus_ptr + 42] = tmp_hack_rate;
|
||||||
|
} else {
|
||||||
|
// 2 3 1 or 1 2 1
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 40];
|
||||||
|
gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 41];
|
||||||
|
gus_patch[gus_ptr + 41] = tmp_hack_rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (env_time_table[gus_patch[gus_ptr + 41]] < env_time_table[gus_patch[gus_ptr + 42]]) {
|
||||||
|
unsigned char tmp_hack_rate = 0;
|
||||||
|
|
||||||
|
if (env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 42]]) {
|
||||||
|
// 2 1 3
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 40];
|
||||||
|
gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 42];
|
||||||
|
gus_patch[gus_ptr + 42] = gus_patch[gus_ptr + 41];
|
||||||
|
gus_patch[gus_ptr + 41] = tmp_hack_rate;
|
||||||
|
} else {
|
||||||
|
// 3 1 2
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 41];
|
||||||
|
gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 42];
|
||||||
|
gus_patch[gus_ptr + 42] = tmp_hack_rate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if ((env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 41]]) && (env_time_table[gus_patch[gus_ptr + 41]] == env_time_table[gus_patch[gus_ptr + 42]])) {
|
||||||
|
uint8_t tmp_hack_rate = 0;
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 41];
|
||||||
|
gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 40];
|
||||||
|
gus_patch[gus_ptr + 42] = gus_patch[gus_ptr + 40];
|
||||||
|
gus_patch[gus_ptr + 40] = tmp_hack_rate;
|
||||||
|
tmp_hack_rate = gus_patch[gus_ptr + 47];
|
||||||
|
gus_patch[gus_ptr + 47] = gus_patch[gus_ptr + 46];
|
||||||
|
gus_patch[gus_ptr + 48] = gus_patch[gus_ptr + 46];
|
||||||
|
gus_patch[gus_ptr + 46] = tmp_hack_rate;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
|
GUSPAT_INT_DEBUG("Envelope #",i);
|
||||||
if (gus_sample->modes & SAMPLE_ENVELOPE) {
|
if (gus_sample->modes & SAMPLE_ENVELOPE) {
|
||||||
unsigned char env_rate = gus_patch[gus_ptr + 37 + i];
|
unsigned char env_rate = gus_patch[gus_ptr + 37 + i];
|
||||||
gus_sample->env_target[i] = 16448 * gus_patch[gus_ptr + 43 + i];
|
gus_sample->env_target[i] = 16448 * gus_patch[gus_ptr + 43 + i];
|
||||||
|
@ -886,6 +946,32 @@ struct _sample * _WM_load_gus_pat(const char *filename, int fix_release) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test and set decay expected decay time after a note off
|
||||||
|
NOTE: This sets samples for full range decay
|
||||||
|
*/
|
||||||
|
if (gus_sample->modes & SAMPLE_ENVELOPE) {
|
||||||
|
double samples_f = 0.0;
|
||||||
|
|
||||||
|
if (gus_sample->modes & SAMPLE_CLAMPED) {
|
||||||
|
samples_f = (4194301.0 - (float)gus_sample->env_target[5]) / gus_sample->env_rate[5];
|
||||||
|
} else {
|
||||||
|
if (gus_sample->modes & SAMPLE_SUSTAIN) {
|
||||||
|
samples_f = (4194301.0 - (float)gus_sample->env_target[3]) / gus_sample->env_rate[3];
|
||||||
|
samples_f += (float)(gus_sample->env_target[3] - gus_sample->env_target[4]) / gus_sample->env_rate[4];
|
||||||
|
} else {
|
||||||
|
samples_f = (4194301.0 - (float)gus_sample->env_target[4]) / gus_sample->env_rate[4];
|
||||||
|
}
|
||||||
|
samples_f += (float)(gus_sample->env_target[4] - gus_sample->env_target[5]) / gus_sample->env_rate[5];
|
||||||
|
}
|
||||||
|
samples_f += (float)gus_sample->env_target[5] / gus_sample->env_rate[6];
|
||||||
|
|
||||||
|
gus_sample->note_off_decay = (unsigned)samples_f;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
gus_sample->note_off_decay = gus_sample->data_length * _WM_SampleRate / gus_sample->rate;
|
||||||
|
}
|
||||||
|
|
||||||
gus_ptr += tmp_cnt;
|
gus_ptr += tmp_cnt;
|
||||||
gus_sample->loop_start = (gus_sample->loop_start << 10)
|
gus_sample->loop_start = (gus_sample->loop_start << 10)
|
||||||
| (((gus_sample->loop_fraction & 0x0f) << 10) / 16);
|
| (((gus_sample->loop_fraction & 0x0f) << 10) / 16);
|
||||||
|
|
Loading…
Reference in a new issue