⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instrum.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    instrum.c    Code to load and unload GUS-compatible instrument patches.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#include <math.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include "timidity.h"#include "common.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.h"#include "output.h"#include "controls.h"#include "resample.h"#include "tables.h"#include "filter.h"#include "quantity.h"#include "freq.h"#define INSTRUMENT_HASH_SIZE 128struct InstrumentCache{    char *name;    int panning, amp, note_to_use, strip_loop, strip_envelope, strip_tail;    Instrument *ip;    struct InstrumentCache *next;};static struct InstrumentCache *instrument_cache[INSTRUMENT_HASH_SIZE];/* Some functions get aggravated if not even the standard banks are   available. */static ToneBank standard_tonebank, standard_drumset;ToneBank  *tonebank[128 + MAP_BANK_COUNT] = {&standard_tonebank},  *drumset[128 + MAP_BANK_COUNT] = {&standard_drumset};/* bank mapping (mapped bank) */struct bank_map_elem {	int16 used, mapid;	int bankno;};static struct bank_map_elem map_bank[MAP_BANK_COUNT], map_drumset[MAP_BANK_COUNT];static int map_bank_counter;/* This is a special instrument, used for all melodic programs */Instrument *default_instrument=0;SpecialPatch *special_patch[NSPECIAL_PATCH];int progbase = 0;struct inst_map_elem{    int set, elem, mapped;};static struct inst_map_elem *inst_map_table[NUM_INST_MAP][128];/* This is only used for tracks that don't specify a program */int default_program[MAX_CHANNELS];char *default_instrument_name = NULL;int antialiasing_allowed=0;#ifdef FAST_DECAYint fast_decay=1;#elseint fast_decay=0;#endif/*Pseudo Reverb*/int32 modify_release;/** below three functinos are imported from sndfont.c **//* convert from 8bit value to fractional offset (15.15) */static int32 to_offset(int offset){	return (int32)offset << (7+15);}/* calculate ramp rate in fractional unit; * diff = 8bit, time = msec */static int32 calc_rate(int diff, double msec){    double rate;    if(msec < 6)	msec = 6;    if(diff == 0)	diff = 255;    diff <<= (7+15);    rate = ((double)diff / play_mode->rate) * control_ratio * 1000.0 / msec;    if(fast_decay)	rate *= 2;    return (int32)rate;}/*End of Pseudo Reverb*/void free_instrument(Instrument *ip){  Sample *sp;  int i;  if (!ip) return;  for (i=0; i<ip->samples; i++)    {      sp=&(ip->sample[i]);      if(sp->data_alloced)	  free(sp->data);    }  free(ip->sample);  free(ip);}void clear_magic_instruments(void){    int i, j;    for(j = 0; j < 128 + map_bank_counter; j++)    {	if(tonebank[j])	{	    ToneBank *bank = tonebank[j];	    for(i = 0; i < 128; i++)		if(IS_MAGIC_INSTRUMENT(bank->tone[i].instrument))		    bank->tone[i].instrument = NULL;	}	if(drumset[j])	{	    ToneBank *bank = drumset[j];	    for(i = 0; i < 128; i++)		if(IS_MAGIC_INSTRUMENT(bank->tone[i].instrument))		    bank->tone[i].instrument = NULL;	}    }}#define GUS_ENVRATE_MAX (int32)(0x3FFFFFFF >> 9)static 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. */  r = r * 44100 / play_mode->rate * control_ratio * (1 << fast_decay);  if(r > GUS_ENVRATE_MAX) {r = GUS_ENVRATE_MAX;}  return (r << 9);}static 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);}static int32 convert_tremolo_sweep(uint8 sweep){  if (!sweep)    return 0;  return    ((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /      (play_mode->rate * sweep);}static int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio){  if (!sweep)    return 0;  return (int32)(TIM_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); */}static int32 convert_tremolo_rate(uint8 rate){  return    ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /      (TREMOLO_RATE_TUNING * play_mode->rate);}static 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;  int32 i;  sp+=ls;  le-=ls;  le/=2;  for(i = 0; i < le; i++)  {      s=*sp;      *sp++=*ep;      *ep--=s;  }}static int name_hash(char *name){    unsigned int addr = 0;    while(*name)	addr += *name++;    return addr % INSTRUMENT_HASH_SIZE;}static Instrument *search_instrument_cache(char *name,				int panning, int amp, int note_to_use,				int strip_loop, int strip_envelope,				int strip_tail){    struct InstrumentCache *p;    for(p = instrument_cache[name_hash(name)]; p != NULL; p = p->next)    {	if(strcmp(p->name, name) != 0)	    return NULL;	if(p->panning == panning &&	   p->amp == amp &&	   p->note_to_use == note_to_use &&	   p->strip_loop == strip_loop &&	   p->strip_envelope == strip_envelope &&	   p->strip_tail == strip_tail)	    return p->ip;    }    return NULL;}static void store_instrument_cache(Instrument *ip,				   char *name,				   int panning, int amp, int note_to_use,				   int strip_loop, int strip_envelope,				   int strip_tail){    struct InstrumentCache *p;    int addr;    addr = name_hash(name);    p = (struct InstrumentCache *)safe_malloc(sizeof(struct InstrumentCache));    p->next = instrument_cache[addr];    instrument_cache[addr] = p;    p->name = name;    p->panning = panning;    p->amp = amp;    p->note_to_use = note_to_use;    p->strip_loop = strip_loop;    p->strip_envelope = strip_envelope;    p->strip_tail = strip_tail;    p->ip = ip;}static int32 adjust_tune_freq(int32 val, float tune){	if (! tune)		return val;	return val / pow(2.0, tune / 12.0);}static int16 adjust_scale_tune(int16 val){	return 1024 * (double) val / 100 + 0.5;}static int16 adjust_fc(int16 val){	if (val < 0 || val > play_mode->rate / 2) {		return 0;	} else {		return val;	}}static int16 adjust_reso(int16 val){	if (val < 0 || val > 960) {		return 0;	} else {		return val;	}}static int32 to_rate(int rate){	return (rate) ? (int32) (0x200 * pow(2.0, rate / 17.0)			* 44100 / play_mode->rate * control_ratio) << fast_decay : 0;}#if 0static int32 to_control(int control){	return (int32) (0x2000 / pow(2.0, control / 31.0));}#endifstatic void apply_bank_parameter(Instrument *ip, ToneBankElement *tone){	int i, j;	Sample *sp;		if (tone->tunenum)		for (i = 0; i < ip->samples; i++) {			sp = &ip->sample[i];			if (tone->tunenum == 1) {				sp->low_freq = adjust_tune_freq(sp->low_freq, tone->tune[0]);				sp->high_freq = adjust_tune_freq(sp->high_freq, tone->tune[0]);				sp->root_freq = adjust_tune_freq(sp->root_freq, tone->tune[0]);			} else if (i < tone->tunenum) {				sp->low_freq = adjust_tune_freq(sp->low_freq, tone->tune[i]);				sp->high_freq = adjust_tune_freq(sp->high_freq, tone->tune[i]);				sp->root_freq = adjust_tune_freq(sp->root_freq, tone->tune[i]);			}		}	if (tone->envratenum)		for (i = 0; i < ip->samples; i++) {			sp = &ip->sample[i];			if (tone->envratenum == 1) {				for (j = 0; j < 6; j++)					if (tone->envrate[0][j] >= 0)						sp->envelope_rate[j] = to_rate(tone->envrate[0][j]);			} else if (i < tone->envratenum) {				for (j = 0; j < 6; j++)					if (tone->envrate[i][j] >= 0)						sp->envelope_rate[j] = to_rate(tone->envrate[i][j]);			}		}	if (tone->envofsnum)		for (i = 0; i < ip->samples; i++) {			sp = &ip->sample[i];			if (tone->envofsnum == 1) {				for (j = 0; j < 6; j++)					if (tone->envofs[0][j] >= 0)						sp->envelope_offset[j] = to_offset(tone->envofs[0][j]);			} else if (i < tone->envofsnum) {				for (j = 0; j < 6; j++)					if (tone->envofs[i][j] >= 0)						sp->envelope_offset[j] = to_offset(tone->envofs[i][j]);			}		}	if (tone->tremnum)		for (i = 0; i < ip->samples; i++) {			sp = &ip->sample[i];			if (tone->tremnum == 1) {				if (IS_QUANTITY_DEFINED(tone->trem[0][0]))					sp->tremolo_sweep_increment =							quantity_to_int(&tone->trem[0][0], 0);				if (IS_QUANTITY_DEFINED(tone->trem[0][1]))					sp->tremolo_phase_increment =							quantity_to_int(&tone->trem[0][1], 0);				if (IS_QUANTITY_DEFINED(tone->trem[0][2]))					sp->tremolo_depth =							quantity_to_int(&tone->trem[0][2], 0) << 1;			} else if (i < tone->tremnum) {				if (IS_QUANTITY_DEFINED(tone->trem[i][0]))					sp->tremolo_sweep_increment =							quantity_to_int(&tone->trem[i][0], 0);				if (IS_QUANTITY_DEFINED(tone->trem[i][1]))					sp->tremolo_phase_increment =							quantity_to_int(&tone->trem[i][1], 0);				if (IS_QUANTITY_DEFINED(tone->trem[i][2]))					sp->tremolo_depth =							quantity_to_int(&tone->trem[i][2], 0) << 1;			}		}	if (tone->vibnum)		for (i = 0; i < ip->samples; i++) {			sp = &ip->sample[i];			if (tone->vibnum == 1) {				if (IS_QUANTITY_DEFINED(tone->vib[0][1]))					sp->vibrato_control_ratio =							quantity_to_int(&tone->vib[0][1], 0);				if (IS_QUANTITY_DEFINED(tone->vib[0][0]))					sp->vibrato_sweep_increment =							quantity_to_int(&tone->vib[0][0],							sp->vibrato_control_ratio);				if (IS_QUANTITY_DEFINED(tone->vib[0][2]))					sp->vibrato_depth = quantity_to_int(&tone->vib[0][2], 0);			} else if (i < tone->vibnum) {				if (IS_QUANTITY_DEFINED(tone->vib[i][1]))					sp->vibrato_control_ratio =							quantity_to_int(&tone->vib[i][1], 0);				if (IS_QUANTITY_DEFINED(tone->vib[i][0]))					sp->vibrato_sweep_increment =							quantity_to_int(&tone->vib[i][0],							sp->vibrato_control_ratio);				if (IS_QUANTITY_DEFINED(tone->vib[i][2]))					sp->vibrato_depth = quantity_to_int(&tone->vib[i][2], 0);			}		}	if (tone->sclnotenum)		for (i = 0; i < ip->samples; i++) {			sp = &ip->sample[i];			if (tone->sclnotenum == 1)				sp->scale_freq = tone->sclnote[0];			else if (i < tone->sclnotenum)				sp->scale_freq = tone->sclnote[i];		}	if (tone->scltunenum)		for (i = 0; i < ip->samples; i++) {			sp = &ip->sample[i];			if (tone->scltunenum == 1)				sp->scale_factor = adjust_scale_tune(tone->scltune[0]);			else if (i < tone->scltunenum)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -