Update gus_pat.cpp's envelope fudging to current git version

This commit is contained in:
Randy Heit 2016-01-11 17:31:23 -06:00
parent 0c3b468e42
commit a74d352490
2 changed files with 138 additions and 50 deletions

View File

@ -27,14 +27,14 @@
#ifndef __COMMON_H #ifndef __COMMON_H
#define __COMMON_H #define __COMMON_H
#define SAMPLE_16BIT 0x01 #define SAMPLE_16BIT 0x01
#define SAMPLE_UNSIGNED 0x02 #define SAMPLE_UNSIGNED 0x02
#define SAMPLE_LOOP 0x04 #define SAMPLE_LOOP 0x04
#define SAMPLE_PINGPONG 0x08 #define SAMPLE_PINGPONG 0x08
#define SAMPLE_REVERSE 0x10 #define SAMPLE_REVERSE 0x10
#define SAMPLE_SUSTAIN 0x20 #define SAMPLE_SUSTAIN 0x20
#define SAMPLE_ENVELOPE 0x40 #define SAMPLE_ENVELOPE 0x40
#define SAMPLE_CLAMPED 0x80 #define SAMPLE_CLAMPED 0x80
#ifdef DEBUG_SAMPLES #ifdef DEBUG_SAMPLES
#define SAMPLE_CONVERT_DEBUG(dx) printf("\r%s\n",dx) #define SAMPLE_CONVERT_DEBUG(dx) printf("\r%s\n",dx)
@ -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 {

View File

@ -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);