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

📄 instrum.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef LITTLE_ENDIAN		else {	/* convert to machine byte order */			int32 i;			int16 *tmp = (int16 *) sp->data, s;						for (i = 0; i < sp->data_length / 2; i++)				s = LE_SHORT(tmp[i]), tmp[i] = s;		}#endif		if (sp->modes & MODES_UNSIGNED) {	/* convert to signed data */			int32 i = sp->data_length / 2;			int16 *tmp = (int16 *) sp->data;						while (i--)				*tmp++ ^= 0x8000;		}		/* Reverse loops and pass them off as normal loops */		if (sp->modes & MODES_REVERSE) {			/* The GUS apparently plays reverse loops by reversing the			 * whole sample.  We do the same because the GUS does not SUCK.			 */			int32 t;						reverse_data((int16 *) sp->data, 0, sp->data_length / 2);			t = sp->loop_start;			sp->loop_start = sp->data_length - sp->loop_end;			sp->loop_end = sp->data_length - t;			sp->modes &= ~MODES_REVERSE;			sp->modes |= MODES_LOOPING;	/* just in case */			ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name);		}		/* If necessary do some anti-aliasing filtering */		if (antialiasing_allowed)			antialiasing((int16 *) sp->data, sp->data_length / 2,					sp->sample_rate, play_mode->rate);#ifdef ADJUST_SAMPLE_VOLUMES		if (amp != -1)			sp->volume = (double) amp / 100;		else {			/* Try to determine a volume scaling factor for the sample.			 * This is a very crude adjustment, but things sound more			 * balanced with it.  Still, this should be a runtime option.			 */			int32 i, a, maxamp = 0;			int16 *tmp = (int16 *) sp->data;						for (i = 0; i < sp->data_length / 2; i++)				if ((a = abs(tmp[i])) > maxamp)					maxamp = a;			sp->volume = 32768 / (double) maxamp;			ctl->cmsg(CMSG_INFO, VERB_DEBUG,					" * volume comp: %f", sp->volume);		}#else		sp->volume = (amp != -1) ? (double) amp / 100 : 1.0;#endif		/* These are in bytes.  Convert into samples. */		sp->data_length /= 2;		sp->loop_start /= 2;		sp->loop_end /= 2;		/* The sample must be padded out by 2 extra sample, so that		 * round off errors in the offsets used in interpolation will not		 * cause a "pop" by reading random data beyond data_length		 */		sp->data[sp->data_length] = sp->data[sp->data_length + 1] = 0;		/* Remove abnormal loops which cause pop noise		 * in long sustain stage		 */		if (! (sp->modes & MODES_LOOPING)) {			sp->loop_start = sp->data_length - 1;			sp->loop_end = sp->data_length;			sp->data[sp->data_length - 1] = 0;		}		/* Then fractional samples */		sp->data_length <<= FRACTION_BITS;		sp->loop_start <<= FRACTION_BITS;		sp->loop_end <<= FRACTION_BITS;		/* Adjust for fractional loop points. This is a guess.  Does anyone		 * know what "fractions" really stands for?		 */		sp->loop_start |= (fractions & 0x0f) << (FRACTION_BITS - 4);		sp->loop_end |= ((fractions >> 4) & 0x0f) << (FRACTION_BITS - 4);		/* If this instrument will always be played on the same note,		 * and it's not looped, we can resample it now.		 */		if (sp->note_to_use && ! (sp->modes & MODES_LOOPING))			pre_resample(sp);		/* do pitch detection on drums if surround chorus is used */		if (dr && opt_surround_chorus)		{		    sp->chord = -1;		    sp->root_freq_detected = freq_fourier(sp, &(sp->chord));		    sp->transpose_detected =			assign_pitch_to_freq(sp->root_freq_detected) -			assign_pitch_to_freq(sp->root_freq / 1024.0);		}#ifdef LOOKUP_HACK		squash_sample_16to8(sp);#endif		if (strip_tail == 1) {			/* Let's not really, just say we did. */			sp->data_length = sp->loop_end;			ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail");		}	}	close_file(tf);	store_instrument_cache(ip, name, panning, amp, note_to_use,			strip_loop, strip_envelope, strip_tail);	return ip;}#ifdef LOOKUP_HACK/*! Squash the 16-bit data into 8 bits. */void squash_sample_16to8(Sample *sp){	uint8 *gulp, *ulp;	int16 *swp;	int l = sp->data_length >> FRACTION_BITS;	gulp = ulp = (uint8 *)safe_malloc(l + 1);	swp = (int16 *)sp->data;	while (l--)		*ulp++ = (*swp++ >> 8) & 0xff;	free(sp->data);	sp->data = (sample_t *)gulp;}#endifInstrument *load_instrument(int dr, int b, int prog){	ToneBank *bank = ((dr) ? drumset[b] : tonebank[b]);	Instrument *ip;	int i, font_bank, font_preset, font_keynote;	extern Instrument *extract_sample_file(char *);	FLOAT_T volume_max;	int pan, panning;	char infomsg[256];	#ifndef CFG_FOR_SF	if (play_system_mode == GS_SYSTEM_MODE && (b == 64 || b == 65))		if (! dr)	/* User Instrument */			recompute_userinst(b, prog);		else		/* User Drumset */			recompute_userdrum(b, prog);#endif	if (bank->tone[prog].instype == 1 || bank->tone[prog].instype == 2) {		if (bank->tone[prog].instype == 1) {	/* Font extention */			font_bank = bank->tone[prog].font_bank;			font_preset = bank->tone[prog].font_preset;			font_keynote = bank->tone[prog].font_keynote;			ip = extract_soundfont(bank->tone[prog].name,					font_bank, font_preset, font_keynote);		} else	/* Sample extension */			ip = extract_sample_file(bank->tone[prog].name);		/* amp tuning */		if (ip != NULL && bank->tone[prog].amp != -1) {			for (i = 0, volume_max = 0; i < ip->samples; i++)				if (volume_max < ip->sample[i].volume)					volume_max = ip->sample[i].volume;			if (volume_max != 0)				for (i = 0; i < ip->samples; i++)					ip->sample[i].volume *= bank->tone[prog].amp							/ 100.0 / volume_max;		}		/* panning */		if (ip != NULL && bank->tone[prog].pan != -1) {			pan = ((int) bank->tone[prog].pan & 0x7f) - 64;			for (i = 0; i < ip->samples; i++) {				panning = (int) ip->sample[i].panning + pan;				panning = (panning < 0) ? 0						: ((panning > 127) ? 127 : panning);				ip->sample[i].panning = panning;			}		}		/* note to use */		if (ip != NULL && bank->tone[prog].note != -1)			for (i = 0; i < ip->samples; i++)				ip->sample[i].root_freq =						freq_table[bank->tone[prog].note & 0x7f];		/* filter key-follow */		if (ip != NULL && bank->tone[prog].key_to_fc != 0)			for (i = 0; i < ip->samples; i++)				ip->sample[i].key_to_fc = bank->tone[prog].key_to_fc;		/* filter velocity-follow */		if (ip != NULL && bank->tone[prog].vel_to_fc != 0)			for (i = 0; i < ip->samples; i++)				ip->sample[i].key_to_fc = bank->tone[prog].vel_to_fc;		/* resonance velocity-follow */		if (ip != NULL && bank->tone[prog].vel_to_resonance != 0)			for (i = 0; i < ip->samples; i++)				ip->sample[i].vel_to_resonance =						bank->tone[prog].vel_to_resonance;		/* strip tail */		if (ip != NULL && bank->tone[prog].strip_tail == 1)			for (i = 0; i < ip->samples; i++)				ip->sample[i].data_length = ip->sample[i].loop_end;		if (ip != NULL) {			i = (dr) ? 0 : prog;			if (bank->tone[i].comment)				free(bank->tone[i].comment);			bank->tone[i].comment = safe_strdup(ip->instname);			apply_bank_parameter(ip, &bank->tone[prog]);		}		return ip;	}	if (! dr) {		font_bank = b;		font_preset = prog;		font_keynote = -1;	} else {		font_bank = 128;		font_preset = b;		font_keynote = prog;	}	/* preload soundfont */	ip = load_soundfont_inst(0, font_bank, font_preset, font_keynote);	if (ip != NULL) {		if (bank->tone[prog].comment)			free(bank->tone[prog].comment);		bank->tone[prog].comment = safe_strdup(ip->instname);	}	if (ip == NULL) {	/* load GUS/patch file */		if (! dr)			sprintf(infomsg, "Tonebank %d %d", b, prog + progbase);		else			sprintf(infomsg, "Drumset %d %d(%s)",					b + progbase, prog, note_name[prog % 12]);		ip = load_gus_instrument(bank->tone[prog].name,				bank, dr, prog, infomsg);		if (ip == NULL) {	/* no patch; search soundfont again */			ip = load_soundfont_inst(1, font_bank, font_preset, font_keynote);			if (ip != NULL) {				if (bank->tone[0].comment)					free(bank->tone[0].comment);				bank->tone[0].comment = safe_strdup(ip->instname);			}		}	}	if (ip != NULL)		apply_bank_parameter(ip, &bank->tone[prog]);	return ip;}static int fill_bank(int dr, int b, int *rc){    int i, errors = 0;    ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);    if(rc != NULL)	*rc = RC_NONE;    for(i = 0; i < 128; i++)    {	if(bank->tone[i].instrument == MAGIC_LOAD_INSTRUMENT)	{	    if(!(bank->tone[i].name))	    {		bank->tone[i].instrument = load_instrument(dr, b, i);		if(bank->tone[i].instrument == NULL)		{		    ctl->cmsg(CMSG_WARNING,			      (b != 0) ? VERB_VERBOSE : VERB_NORMAL,			      "No instrument mapped to %s %d, program %d%s",			      dr ? "drum set" : "tone bank",			      dr ? b+progbase : b,			      dr ? i : i+progbase,			      (b != 0) ? "" :			      " - this instrument will not be heard");		    if(b != 0)		    {			/* Mark the corresponding instrument in the default			   bank / drumset for loading (if it isn't already) */			if(!dr)			{			    if(!(standard_tonebank.tone[i].instrument))				standard_tonebank.tone[i].instrument =				    MAGIC_LOAD_INSTRUMENT;			}			else			{			    if(!(standard_drumset.tone[i].instrument))				standard_drumset.tone[i].instrument =				    MAGIC_LOAD_INSTRUMENT;			}			bank->tone[i].instrument = 0;		    }		    else			bank->tone[i].instrument = MAGIC_ERROR_INSTRUMENT;		    errors++;		}	    }	    else	    {		if(rc != NULL)		{		    *rc = check_apply_control();		    if(RC_IS_SKIP_FILE(*rc))			return errors;		}		bank->tone[i].instrument = load_instrument(dr, b, i);		if(!bank->tone[i].instrument)		{		    ctl->cmsg(CMSG_ERROR, VERB_NORMAL,			      "Couldn't load instrument %s "			      "(%s %d, program %d)", bank->tone[i].name,			      dr ? "drum set" : "tone bank",			      dr ? b+progbase : b,			      dr ? i : i+progbase);		    errors++;		}	    }	}    }    return errors;}int load_missing_instruments(int *rc){  int i = 128 + map_bank_counter, errors = 0;  if(rc != NULL)      *rc = RC_NONE;  while (i--)    {      if (tonebank[i])	errors+=fill_bank(0,i,rc);      if(rc != NULL && RC_IS_SKIP_FILE(*rc))	  return errors;      if (drumset[i])	errors+=fill_bank(1,i,rc);      if(rc != NULL && RC_IS_SKIP_FILE(*rc))	  return errors;    }  return errors;}static void *safe_memdup(void *s, size_t size){	return memcpy(safe_malloc(size), s, size);}/*! Copy ToneBankElement src to elm. The original elm is released. */void copy_tone_bank_element(ToneBankElement *elm, const ToneBankElement *src){	int i;		free_tone_bank_element(elm);	memcpy(elm, src, sizeof(ToneBankElement));	if (elm->name)		elm->name = safe_strdup(elm->name);	if (elm->tunenum)		elm->tune = (float *) safe_memdup(elm->tune,				elm->tunenum * sizeof(float));	if (elm->envratenum) {		elm->envrate = (int **) safe_memdup(elm->envrate,				elm->envratenum * sizeof(int *));		for (i = 0; i < elm->envratenum; i++)			elm->envrate[i] = (int *) safe_memdup(elm->envrate[i],					6 * sizeof(int));	}	if (elm->envofsnum) {		elm->envofs = (int **) safe_memdup(elm->envofs,				elm->envofsnum * sizeof(int *));		for (i = 0; i < elm->envofsnum; i++)			elm->envofs[i] = (int *) safe_memdup(elm->envofs[i],					6 * sizeof(int));	}	if (elm->tremnum) {		elm->trem = (Quantity **) safe_memdup(elm->trem,				elm->tremnum * sizeof(Quantity *));		for (i = 0; i < elm->tremnum; i++)			elm->trem[i] = (Quantity *) safe_memdup(elm->trem[i],					3 * sizeof(Quantity));	}	if (elm->vibnum) {		elm->vib = (Quantity **) safe_memdup(elm->vib,				elm->vibnum * sizeof(Quantity *));		for (i = 0; i < elm->vibnum; i++)			elm->vib[i] = (Quantity *) safe_memdup(elm->vib[i],					3 * sizeof(Quantity));	}	if (elm->sclnotenum)		elm->sclnote = (int16 *) safe_memdup(elm->sclnote,				elm->sclnotenum * sizeof(int16));	if (elm->scltunenum)		elm->scltune = (int16 *) safe_memdup(elm->scltune,				elm->scltunenum * sizeof(int16));	if (elm->comment)		elm->comment = safe_strdup(elm->comment);	if (elm->modenvratenum) {		elm->modenvrate = (int **) safe_memdup(elm->modenvrate,				elm->modenvratenum * sizeof(int *));		for (i = 0; i < elm->modenvratenum; i++)			elm->modenvrate[i] = (int *) safe_memdup(elm->modenvrate[i],					6 * sizeof(int));	}	if (elm->modenvofsnum) {		elm->modenvofs = (int **) safe_memdup(elm->modenvofs,				elm->modenvofsnum * sizeof(int *));		for (i = 0; i < elm->modenvofsnum; i++)			elm->modenvofs[i] = (int *) safe_memdup(elm->modenvofs[i],					6 * sizeof(int));	}	if (elm->envkeyfnum) {		elm->envkeyf = (int **) safe_memdup(elm->envkeyf,				elm->envkeyfnum * sizeof(int *));		for (i = 0; i < elm->envkeyfnum; i++)			elm->envkeyf[i] = (int *) safe_memdup(elm->envkeyf[i],					6 * sizeof(int));	}	if (elm->envvelfnum) {		elm->envvelf = (int **) safe_memdup(elm->envvelf,				elm->envvelfnum * sizeof(int *));		for (i = 0; i < elm->envvelfnum; i++)			elm->envvelf[i] = (int *) safe_memdup(elm->envvelf[i],					6 * sizeof(int));	}	if (elm->modenvkeyfnum) {		elm->modenvkeyf = (int **) safe_memdup(elm->modenvkeyf,				elm->modenvkeyfnum * sizeof(int *));		for (i = 0; i < elm->modenvkeyfnum; i++)			elm->modenvkeyf[i] = (int *) safe_memdup(elm->modenvkeyf[i],					6 * sizeof(int));	}	if (elm->modenvvelfnum) {		elm->modenvvelf = (int **) safe_memdup(elm->modenvvelf,				elm->modenvvelfnum * sizeof(int *));		for (i = 0; i < elm->modenvvelfnum; i++)			elm->modenvvelf[i] = (int *) safe_memdup(elm->modenvvelf[i],					6 * sizeof(int));	}	if (elm->trempitchnum)		elm->trempitch = (int16 *) safe_memdup(elm->trempitch,				elm->trempitchnum * sizeof(int16));	if (elm->tremfcnum)		elm->tremfc = (int16 *) safe_memdup(elm->tremfc,				elm->tremfcnum * sizeof(int16));	if (elm->modpitchnum)		elm->modpitch = (int16 *) safe_memdup(elm->modpitch,				elm->modpitchnum * sizeof(int16));	if (elm->modfcnum)		elm->modfc = (int16 *) safe_memdup(elm->modfc,				elm->modfcnum * sizeof(int16));	if (elm->fcnum)		elm->fc = (int16 *) safe_memdup(elm->fc,				elm->fcnum * sizeof(int16));	if (elm->resonum)		elm->reso = (int16 *) safe_memdup(elm->reso,				elm->resonum * sizeof(int16));

⌨️ 快捷键说明

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