📄 instrum.c
字号:
/* TiMidity -- Experimental MIDI to WAVE converter Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. instrum.c Code to load and unload GUS-compatible instrument patches.*/#include <stdio.h>#include <string.h>#include <stdlib.h>#include "config.h"#include "common.h"#include "instrum.h"#include "playmidi.h"#include "output.h"#include "ctrlmode.h"#include "resample.h"#include "tables.h"#include "filter.h"/* Some functions get aggravated if not even the standard banks are available. */static ToneBank standard_tonebank, standard_drumset;ToneBank *tonebank[MAXBANK]={&standard_tonebank}, *drumset[MAXBANK]={&standard_drumset};/* This is a special instrument, used for all melodic programs */InstrumentLayer *default_instrument=0;/* This is only used for tracks that don't specify a program */int default_program=DEFAULT_PROGRAM;int antialiasing_allowed=0;#ifdef FAST_DECAYint fast_decay=1;#elseint fast_decay=0;#endifint current_tune_number = 0;int last_tune_purged = 0;int current_patch_memory = 0;int max_patch_memory = 60000000;static void purge_as_required(void);static void free_instrument(Instrument *ip){ Sample *sp; int i; if (!ip) return; if (!ip->contents) for (i=0; i<ip->samples; i++) { sp=&(ip->sample[i]); if (sp->data) free(sp->data); } free(ip->sample); if (!ip->contents) for (i=0; i<ip->right_samples; i++) { sp=&(ip->right_sample[i]); if (sp->data) free(sp->data); } if (ip->right_sample) free(ip->right_sample); free(ip);}static void free_layer(InstrumentLayer *lp){ InstrumentLayer *next; current_patch_memory -= lp->size; for (; lp; lp = next) { next = lp->next; free_instrument(lp->instrument); free(lp); }}static void free_bank(int dr, int b){ int i; ToneBank *bank=((dr) ? drumset[b] : tonebank[b]); for (i=0; i<MAXPROG; i++) { if (bank->tone[i].layer) { /* Not that this could ever happen, of course */ if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT) { free_layer(bank->tone[i].layer); bank->tone[i].layer=NULL; bank->tone[i].last_used=-1; } } if (bank->tone[i].name) { free(bank->tone[i].name); bank->tone[i].name = NULL; } }}static void free_old_bank(int dr, int b, int how_old){ int i; ToneBank *bank=((dr) ? drumset[b] : tonebank[b]); for (i=0; i<MAXPROG; i++) if (bank->tone[i].layer && bank->tone[i].last_used < how_old) { if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT) { ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Unloading %s %s[%d,%d] - last used %d.", (dr)? "drum" : "inst", bank->tone[i].name, i, b, bank->tone[i].last_used); free_layer(bank->tone[i].layer); bank->tone[i].layer=NULL; bank->tone[i].last_used=-1; } }}int32 convert_envelope_rate_attack(uint8 rate, uint8 fastness){ int32 r; r=3-((rate>>6) & 0x3); r*=3; r = (int32)(rate & 0x3f) << r; /* 6.9 fixed point */ /* 15.15 fixed point. */ return (((r * 44100) / play_mode->rate) * control_ratio) << 10;}int32 convert_envelope_rate(uint8 rate){ int32 r; r=3-((rate>>6) & 0x3); r*=3; r = (int32)(rate & 0x3f) << r; /* 6.9 fixed point */ /* 15.15 fixed point. */ return (((r * 44100) / play_mode->rate) * control_ratio) << ((fast_decay) ? 10 : 9);}int32 convert_envelope_offset(uint8 offset){ /* This is not too good... Can anyone tell me what these values mean? Are they GUS-style "exponential" volumes? And what does that mean? */ /* 15.15 fixed point */ return offset << (7+15);}int32 convert_tremolo_sweep(uint8 sweep){ if (!sweep) return 0; return ((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) / (play_mode->rate * sweep);}int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio){ if (!sweep) return 0; return (int32) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT) / (double)(play_mode->rate * sweep)); /* this was overflowing with seashore.pat ((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) / (play_mode->rate * sweep); */}int32 convert_tremolo_rate(uint8 rate){ return ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) / (TREMOLO_RATE_TUNING * play_mode->rate);}int32 convert_vibrato_rate(uint8 rate){ /* Return a suitable vibrato_control_ratio value */ return (VIBRATO_RATE_TUNING * play_mode->rate) / (rate * 2 * VIBRATO_SAMPLE_INCREMENTS);}static void reverse_data(int16 *sp, int32 ls, int32 le){ int16 s, *ep=sp+le; sp+=ls; le-=ls; le/=2; while (le--) { s=*sp; *sp++=*ep; *ep--=s; }}/* If panning or note_to_use != -1, it will be used for all samples, instead of the sample-specific values in the instrument file. For note_to_use, any value <0 or >127 will be forced to 0. For other parameters, 1 means yes, 0 means no, other values are undefined. TODO: do reverse loops right */static InstrumentLayer *load_instrument(char *name, int font_type, int percussion, int panning, int amp, int cfg_tuning, int note_to_use, int strip_loop, int strip_envelope, int strip_tail, int bank, int gm_num, int sf_ix){ InstrumentLayer *lp, *lastlp, *headlp; Instrument *ip; FILE *fp; uint8 tmp[1024]; int i,j,noluck=0;#ifdef PATCH_EXT_LIST static char *patch_ext[] = PATCH_EXT_LIST;#endif int sf2flag = 0; int right_samples = 0; int stereo_channels = 1, stereo_layer; int vlayer_list[19][4], vlayer, vlayer_count; if (!name) return 0; /* Open patch file */ if ((fp=open_file(name, 1, OF_NORMAL)) == NULL) { noluck=1;#ifdef PATCH_EXT_LIST /* Try with various extensions */ for (i=0; patch_ext[i]; i++) { if (strlen(name)+strlen(patch_ext[i])<1024) { char path[1024]; strcpy(path, name); strcat(path, patch_ext[i]); if ((fp=open_file(path, 1, OF_NORMAL)) != NULL) { noluck=0; break; } } }#endif } if (noluck) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.", name); return 0; } /*ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);*/ /* Read some headers and do cursory sanity checks. There are loads of magic offsets. This could be rewritten... */ if ((239 != fread(tmp, 1, 239, fp)) || (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the differences are */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name); return 0; }/* patch layout: * bytes: info: starts at offset: * 22 id (see above) 0 * 60 copyright 22 * 1 instruments 82 * 1 voices 83 * 1 channels 84 * 2 number of waveforms 85 * 2 master volume 87 * 4 datasize 89 * 36 reserved, but now: 93 * 7 "SF2EXT\0" id 93 * 1 right samples 100 * 28 reserved 101 * 2 instrument number 129 * 16 instrument name 131 * 4 instrument size 147 * 1 number of layers 151 * 40 reserved 152 * 1 layer duplicate 192 * 1 layer number 193 * 4 layer size 194 * 1 number of samples 198 * 40 reserved 199 * 239 * THEN, for each sample, see below */ if (!memcmp(tmp + 93, "SF2EXT", 6)) { sf2flag = 1; vlayer_count = tmp[152]; } if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 0 means 1 */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments", tmp[82]); return 0; } if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers", tmp[151]); return 0; } if (sf2flag && vlayer_count > 0) { for (i = 0; i < 9; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = tmp[153+i*4+j]; for (i = 9; i < 19; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = tmp[199+(i-9)*4+j]; } else { for (i = 0; i < 19; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = 0; vlayer_list[0][0] = 0; vlayer_list[0][1] = 127; vlayer_list[0][2] = tmp[198]; vlayer_list[0][3] = 0; vlayer_count = 1; } lastlp = 0; for (vlayer = 0; vlayer < vlayer_count; vlayer++) { lp=(InstrumentLayer *)safe_malloc(sizeof(InstrumentLayer)); lp->size = sizeof(InstrumentLayer); lp->lo = vlayer_list[vlayer][0]; lp->hi = vlayer_list[vlayer][1]; ip=(Instrument *)safe_malloc(sizeof(Instrument)); lp->size += sizeof(Instrument); lp->instrument = ip; lp->next = 0; if (lastlp) lastlp->next = lp; else headlp = lp; lastlp = lp; if (sf2flag) ip->type = INST_SF2; else ip->type = INST_GUS; ip->samples = vlayer_list[vlayer][2]; ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples); lp->size += sizeof(Sample) * ip->samples; ip->left_samples = ip->samples; ip->left_sample = ip->sample; right_samples = vlayer_list[vlayer][3]; ip->right_samples = right_samples; if (right_samples) { ip->right_sample = (Sample *)safe_malloc(sizeof(Sample) * right_samples); lp->size += sizeof(Sample) * right_samples; stereo_channels = 2; } else ip->right_sample = 0; ip->contents = 0; ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s%s[%d,%d] %s(%d-%d layer %d of %d)", (percussion)? " ":"", name, (percussion)? note_to_use : gm_num, bank, (right_samples)? "(2) " : "", lp->lo, lp->hi, vlayer+1, vlayer_count); for (stereo_layer = 0; stereo_layer < stereo_channels; stereo_layer++) { int sample_count; if (stereo_layer == 0) sample_count = ip->left_samples; else if (stereo_layer == 1) sample_count = ip->right_samples; for (i=0; i < sample_count; i++) { uint8 fractions; int32 tmplong; uint16 tmpshort; uint16 sample_volume; uint8 tmpchar; Sample *sp; uint8 sf2delay;#define READ_CHAR(thing) \ if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \ thing = tmpchar;#define READ_SHORT(thing) \ if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \ thing = LE_SHORT(tmpshort);#define READ_LONG(thing) \ if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \ thing = LE_LONG(tmplong);/* * 7 sample name * 1 fractions * 4 length * 4 loop start * 4 loop end * 2 sample rate * 4 low frequency * 4 high frequency * 2 finetune * 1 panning * 6 envelope rates | * 6 envelope offsets | 18 bytes * 3 tremolo sweep, rate, depth | * 3 vibrato sweep, rate, depth | * 1 sample mode * 2 scale frequency * 2 scale factor * 2 sample volume (??) * 34 reserved * Now: 1 delay * 33 reserved */ skip(fp, 7); /* Skip the wave name */ if (1 != fread(&fractions, 1, 1, fp)) { fail: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i); if (stereo_layer == 1) { for (j=0; j<i; j++) free(ip->right_sample[j].data); free(ip->right_sample); i = ip->left_samples; } for (j=0; j<i; j++) free(ip->left_sample[j].data); free(ip->left_sample); free(ip); free(lp); return 0; } if (stereo_layer == 0) sp=&(ip->left_sample[i]); else if (stereo_layer == 1) sp=&(ip->right_sample[i]); READ_LONG(sp->data_length); READ_LONG(sp->loop_start); READ_LONG(sp->loop_end); READ_SHORT(sp->sample_rate); READ_LONG(sp->low_freq); READ_LONG(sp->high_freq); READ_LONG(sp->root_freq); skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */ READ_CHAR(tmp[0]); if (panning==-1) sp->panning = (tmp[0] * 8 + 4) & 0x7f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -