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

📄 sndfont.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 4 页
字号:
    if(fast_decay) {rate *= 2;}	if(rate > SF_ENVRATE_MAX) {rate = SF_ENVRATE_MAX;}	else if(rate < SF_ENVRATE_MIN) {rate = SF_ENVRATE_MIN;}    return (int32)rate;}/* * convert timecents to sec */static double to_msec(int timecent){    return timecent == -12000 ? 0 : 1000.0 * pow(2.0, (double)timecent / 1200.0);}/* * Sustain level * sf: centibels * parm: 0x7f - sustain_level(dB) * 0.75 */static int32 calc_sustain(int sust_cB){	if(sust_cB <= 0) {return 65533;}	else if(sust_cB >= 1000) {return 0;}	else {return (1000 - sust_cB) * 65533 / 1000;}}static Instrument *load_from_file(SFInsts *rec, InstList *ip){	SampleList *sp;	Instrument *inst;	int i;	int32 len;	if(ip->pat.bank == 128)	    ctl->cmsg(CMSG_INFO, VERB_NOISY,		      "Loading SF Drumset %d %d: %s",		      ip->pat.preset + progbase, ip->pat.keynote,		      rec->inst_namebuf[ip->pr_idx]);	else	    ctl->cmsg(CMSG_INFO, VERB_NOISY,		      "Loading SF Tonebank %d %d: %s",		      ip->pat.bank, ip->pat.preset + progbase,		      rec->inst_namebuf[ip->pr_idx]);	inst = (Instrument *)safe_malloc(sizeof(Instrument));	inst->instname = rec->inst_namebuf[ip->pr_idx];	inst->type = INST_SF2;	inst->samples = ip->samples;	inst->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples);	memset(inst->sample, 0, sizeof(Sample) * ip->samples);	for (i = 0, sp = ip->slist; i < ip->samples && sp; i++, sp = sp->next) {		Sample *sample = inst->sample + i;		int32 j;#ifndef LITTLE_ENDIAN		int32 k;		int16 *tmp, s;#endif		ctl->cmsg(CMSG_INFO, VERB_DEBUG,			  "[%d] Rate=%d LV=%d HV=%d "			  "Low=%d Hi=%d Root=%d Pan=%d",			  sp->start, sp->v.sample_rate, 			  sp->v.low_vel, sp->v.high_vel, 			  sp->v.low_freq, sp->v.high_freq, sp->v.root_freq,			  sp->v.panning);		memcpy(sample, &sp->v, sizeof(Sample));		sample->data = NULL;		sample->data_alloced = 0;		if(i > 0 && (!sample->note_to_use ||			     (sample->modes & MODES_LOOPING)))		{		    SampleList *sps;		    Sample *found, *s;		    found = NULL;		    for(j = 0, sps = ip->slist, s = inst->sample; j < i && sps;			j++, sps = sps->next, s++)		    {			if(s->data == NULL)			    break;			if(sp->start == sps->start)			{			    if(antialiasing_allowed)			    {				 if(sample->data_length != s->data_length ||				    sample->sample_rate != s->sample_rate)				     continue;			    }			    if(s->note_to_use && !(s->modes & MODES_LOOPING))				continue;			    found = s;			    break;			}		    }		    if(found)		    {			sample->data = found->data;			sample->data_alloced = 0;			ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * Cached");			continue;		    }		}		sample->data = (sample_t *)safe_large_malloc(sp->len + 2 * 3);		sample->data_alloced = 1;		tf_seek(rec->tf, sp->start, SEEK_SET);		tf_read(sample->data, sp->len, 1, rec->tf);#ifndef LITTLE_ENDIAN		tmp = (int16*)sample->data;		k = sp->len / 2;		for (j = 0; j < k; j++) {			s = LE_SHORT(*tmp);			*tmp++ = s;		}#endif		/* set a small blank loop at the tail for avoiding abnormal loop. */		len = sp->len / 2;		sample->data[len] = sample->data[len + 1] = sample->data[len + 2] = 0;		if (antialiasing_allowed)		    antialiasing((int16 *)sample->data,				 sample->data_length >> FRACTION_BITS,				 sample->sample_rate,				 play_mode->rate);		/* resample it if possible */		if (sample->note_to_use && !(sample->modes & MODES_LOOPING))			pre_resample(sample);		/* do pitch detection on drums if surround chorus is used */		if (ip->pat.bank == 128 && opt_surround_chorus)		{		    sample->chord = -1;		    sample->root_freq_detected =		    	freq_fourier(sample, &(sample->chord));		    sample->transpose_detected =			assign_pitch_to_freq(sample->root_freq_detected) -			assign_pitch_to_freq(sample->root_freq / 1024.0);		}#ifdef LOOKUP_HACK		squash_sample_16to8(sample);#endif	}	return inst;}/*---------------------------------------------------------------- * excluded samples *----------------------------------------------------------------*/int exclude_soundfont(int bank, int preset, int keynote){	SFExclude *exc;	if(current_sfrec == NULL)	    return 1;	exc = (SFExclude*)SFMalloc(current_sfrec , sizeof(SFExclude));	exc->pat.bank = bank;	exc->pat.preset = preset;	exc->pat.keynote = keynote;	exc->next = current_sfrec->sfexclude;	current_sfrec->sfexclude = exc;	return 0;}/* check the instrument is specified to be excluded */static int is_excluded(SFInsts *rec, int bank, int preset, int keynote){	SFExclude *p;	for (p = rec->sfexclude; p; p = p->next) {		if (p->pat.bank == bank &&		    (p->pat.preset < 0 || p->pat.preset == preset) &&		    (p->pat.keynote < 0 || p->pat.keynote == keynote))			return 1;	}	return 0;}/*---------------------------------------------------------------- * ordered samples *----------------------------------------------------------------*/int order_soundfont(int bank, int preset, int keynote, int order){	SFOrder *p;	if(current_sfrec == NULL)	    return 1;	p = (SFOrder*)SFMalloc(current_sfrec, sizeof(SFOrder));	p->pat.bank = bank;	p->pat.preset = preset;	p->pat.keynote = keynote;	p->order = order;	p->next = current_sfrec->sforder;	current_sfrec->sforder = p;	return 0;}/* check the instrument is specified to be ordered */static int is_ordered(SFInsts *rec, int bank, int preset, int keynote){	SFOrder *p;	for (p = rec->sforder; p; p = p->next) {		if (p->pat.bank == bank &&		    (p->pat.preset < 0 || p->pat.preset == preset) &&		    (p->pat.keynote < 0 || p->pat.keynote == keynote))			return p->order;	}	return -1;}/*----------------------------------------------------------------*/static int load_font(SFInfo *sf, int pridx){	SFPresetHdr *preset = &sf->preset[pridx];	int rc, j, nlayers;	SFGenLayer *layp, *globalp;	/* if layer is empty, skip it */	if ((nlayers = preset->hdr.nlayers) <= 0 ||	    (layp = preset->hdr.layer) == NULL)		return AWE_RET_SKIP;	/* check global layer */	globalp = NULL;	if (is_global(layp)) {		globalp = layp;		layp++;		nlayers--;	}	/* parse for each preset layer */	for (j = 0; j < nlayers; j++, layp++) {		LayerTable tbl;		/* set up table */		clear_table(&tbl);		if (globalp)			set_to_table(sf, &tbl, globalp, P_GLOBAL);		set_to_table(sf, &tbl, layp, P_LAYER);				/* parse the instrument */		rc = parse_layer(sf, pridx, &tbl, 0);		if(rc == AWE_RET_ERR || rc == AWE_RET_NOMEM)			return rc;	}	return AWE_RET_OK;}/*----------------------------------------------------------------*//* parse a preset layer and convert it to the patch structure */static int parse_layer(SFInfo *sf, int pridx, LayerTable *tbl, int level){	SFInstHdr *inst;	int rc, i, nlayers;	SFGenLayer *lay, *globalp;#if 0	SFPresetHdr *preset = &sf->preset[pridx];#endif	if (level >= 2) {		fprintf(stderr, "parse_layer: too deep instrument level\n");		return AWE_RET_ERR;	}	/* instrument must be defined */	if (!tbl->set[SF_instrument])		return AWE_RET_SKIP;	inst = &sf->inst[tbl->val[SF_instrument]];	/* Here, TiMidity makes the reference of the data.  The real data	 * is loaded after.  So, duplicated data is allowed */#if 0	/* if non-standard drumset includes standard drum instruments,	   skip it to avoid duplicate the data */	if (def_drum_inst >= 0 && preset->bank == 128 && preset->preset != 0 &&	    tbl->val[SF_instrument] == def_drum_inst)			return AWE_RET_SKIP;#endif	/* if layer is empty, skip it */	if ((nlayers = inst->hdr.nlayers) <= 0 ||	    (lay = inst->hdr.layer) == NULL)		return AWE_RET_SKIP;	/* check global layer */	globalp = NULL;	if (is_global(lay)) {		globalp = lay;		lay++;		nlayers--;	}	/* parse for each layer */	for (i = 0; i < nlayers; i++, lay++) {		LayerTable ctbl;		clear_table(&ctbl);		if (globalp)			set_to_table(sf, &ctbl, globalp, P_GLOBAL);		set_to_table(sf, &ctbl, lay, P_LAYER);		if (!ctbl.set[SF_sampleId]) {			/* recursive loading */			merge_table(sf, &ctbl, tbl);			if (! sanity_range(&ctbl))				continue;			rc = parse_layer(sf, pridx, &ctbl, level+1);			if (rc != AWE_RET_OK && rc != AWE_RET_SKIP)				return rc;		} else {			init_and_merge_table(sf, &ctbl, tbl);			if (! sanity_range(&ctbl))				continue;			/* load the info data */			if ((rc = make_patch(sf, pridx, &ctbl)) == AWE_RET_ERR)				return rc;		}	}	return AWE_RET_OK;}static int is_global(SFGenLayer *layer){	int i;	for (i = 0; i < layer->nlists; i++) {		if (layer->list[i].oper == SF_instrument ||		    layer->list[i].oper == SF_sampleId)			return 0;	}	return 1;}/*---------------------------------------------------------------- * layer table handlers *----------------------------------------------------------------*//* initialize layer table */static void clear_table(LayerTable *tbl){	memset(tbl->val, 0, sizeof(tbl->val));	memset(tbl->set, 0, sizeof(tbl->set));}/* set items in a layer to the table */static void set_to_table(SFInfo *sf, LayerTable *tbl, SFGenLayer *lay, int level){	int i;	for (i = 0; i < lay->nlists; i++) {		SFGenRec *gen = &lay->list[i];		/* copy the value regardless of its copy policy */		tbl->val[gen->oper] = gen->amount;		tbl->set[gen->oper] = level;	}}/* add an item to the table */static void add_item_to_table(LayerTable *tbl, int oper, int amount, int level){	LayerItem *item = &layer_items[oper];	int o_lo, o_hi, lo, hi;	switch (item->copy) {	case L_INHRT:		tbl->val[oper] += amount;		break;	case L_OVWRT:		tbl->val[oper] = amount;		break;	case L_PRSET:	case L_INSTR:		/* do not overwrite */		if (!tbl->set[oper])			tbl->val[oper] = amount;		break;	case L_RANGE:		if (!tbl->set[oper]) {			tbl->val[oper] = amount;		} else {			o_lo = LOWNUM(tbl->val[oper]);			o_hi = HIGHNUM(tbl->val[oper]);			lo = LOWNUM(amount);			hi = HIGHNUM(amount);			if (lo < o_lo) lo = o_lo;			if (hi > o_hi) hi = o_hi;			tbl->val[oper] = RANGE(lo, hi);		}		break;	}}/* merge two tables */static void merge_table(SFInfo *sf, LayerTable *dst, LayerTable *src){	int i;	for (i = 0; i < SF_EOF; i++) {		if (src->set[i]) {			if (sf->version == 1) {				if (!dst->set[i] ||				    i == SF_keyRange || i == SF_velRange)					/* just copy it */					dst->val[i] = src->val[i];			}			else				add_item_to_table(dst, i, src->val[i], P_GLOBAL);			dst->set[i] = P_GLOBAL;		}	}}/* merge and set default values */static void init_and_merge_table(SFInfo *sf, LayerTable *dst, LayerTable *src){	int i;	/* default value is not zero */	if (sf->version == 1) {		layer_items[SF_sustainEnv1].defv = 1000;		layer_items[SF_sustainEnv2].defv = 1000;		layer_items[SF_freqLfo1].defv = -725;		layer_items[SF_freqLfo2].defv = -15600;	} else {		layer_items[SF_sustainEnv1].defv = 0;		layer_items[SF_sustainEnv2].defv = 0;		layer_items[SF_freqLfo1].defv = 0;		layer_items[SF_freqLfo2].defv = 0;	}	/* set default */	for (i = 0; i < SF_EOF; i++) {		if (!dst->set[i])			dst->val[i] = layer_items[i].defv;	}	merge_table(sf, dst, src);	/* convert from SBK to SF2 */	if (sf->version == 1) {		for (i = 0; i < SF_EOF; i++) {			if (dst->set[i])				dst->val[i] = sbk_to_sf2(i, dst->val[i]);		}	}}/*---------------------------------------------------------------- * check key and velocity range *----------------------------------------------------------------*/static int sanity_range(LayerTable *tbl){	int lo, hi;	lo = LOWNUM(tbl->val[SF_keyRange]);	hi = HIGHNUM(tbl->val[SF_keyRange]);	if (lo < 0 || lo > 127 || hi < 0 || hi > 127 || hi < lo)		return 0;	lo = LOWNUM(tbl->val[SF_velRange]);	hi = HIGHNUM(tbl->val[SF_velRange]);	if (lo < 0 || lo > 127 || hi < 0 || hi > 127 || hi < lo)		return 0;	return 1;}/*---------------------------------------------------------------- * create patch record from the stored data table *----------------------------------------------------------------*/#ifdef CFG_FOR_SFint opt_reverb_control;	/* to avoid warning. */static int cfg_for_sf_scan(char *name, int x_bank, int x_preset, int x_keynote_from, int x_keynote_to, int romflag);#endifstatic int make_patch(SFInfo *sf, int pridx, LayerTable *tbl){    int bank, preset, keynote;    int keynote_from, keynote_to, done;    int addr, order;    InstList *ip;    SFSampleInfo *sample;    SampleList *sp;    sample = &sf->sample[tbl->val[SF_sampleId]];#ifdef CFG_FOR_SF	cfg_for_sf_scan(sample->name,sf->preset[pridx].bank,sf->preset[pridx].preset,LOWNUM(tbl->val[SF_keyRange]),		HIGHNUM(tbl->val[SF_keyRange]),sample->sampletype & SF_SAMPLETYPE_ROM);#endif    if(sample->sampletype & SF_SAMPLETYPE_ROM) /* is ROM sample? */    {	ctl->cmsg(CMSG_INFO, VERB_DEBUG, "preset %d is ROM sample: 0x%x",		  pridx, sample->sampletype);	return AWE_RET_SKIP;    }    bank = sf->preset[pridx].bank;    preset = sf->preset[pridx].preset;    if(bank == 128){		keynote_from = LOWNUM(tbl->val[SF_keyRange]);		keynote_to = HIGHNUM(tbl->val[SF_keyRange]);    } else	keynote_from = keynote_to = -1;	done = 0;	for(keynote=keynote_from;keynote<=keynote_to;keynote++){    ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,	      "SF make inst pridx=%d bank=%d preset=%d keynote=%d",	      pridx, bank, preset, keynote);    if(is_excluded(current_sfrec, bank, preset, keynote))    {	ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY, " * Excluded");	continue;    } else	done++;    order = is_ordered(current_sfrec, bank, preset, keynote);    if(order < 0)	order = current_sfrec->def_order;    addr = INSTHASH(bank, preset, keynote);    for(ip = current_sfrec->instlist[addr]; ip; ip = ip->next)    {	if(ip->pat.bank == bank && ip->pat.preset == preset &&

⌨️ 快捷键说明

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