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

📄 playmidi.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 5 页
字号:
							(bend_fine[-tmp >> 5 & 0xff]							* bend_coarse[-tmp >> 13 & 0x7f]);			}			voice[v].frequency =					voice[v].orig_frequency * channel[ch].pitchfactor;			if (voice[v].frequency != voice[v].orig_frequency)				voice[v].cache = NULL;		}	} else {	/* Portamento */		pb -= 0x2000;		tmp = pb * channel[ch].rpnmap[RPN_ADDR_0000]				+ (voice[v].porta_pb << 5) + tuning;		if (tmp >= 0)			pf = bend_fine[tmp >> 5 & 0xff]					* bend_coarse[tmp >> 13 & 0x7f];		else			pf = 1.0 / (bend_fine[-tmp >> 5 & 0xff]					* bend_coarse[-tmp >> 13 & 0x7f]);		voice[v].frequency = voice[v].orig_frequency * pf;		voice[v].cache = NULL;	}	root_freq = voice[v].sample->root_freq;	a = TIM_FSCALE(((double) voice[v].sample->sample_rate			* ((double)voice[v].frequency + channel[ch].pitch_offset_fine))			/ (root_freq * play_mode->rate), FRACTION_BITS) + 0.5;	/* need to preserve the loop direction */	voice[v].sample_increment = (voice[v].sample_increment >= 0) ? a : -a;#ifdef ABORT_AT_FATAL	if (voice[v].sample_increment == 0) {		fprintf(stderr, "Invalid sample increment a=%e %ld %ld %ld %ld%s\n",				(double)a, (long) voice[v].sample->sample_rate,				(long) voice[v].frequency, (long) voice[v].sample->root_freq,				(long) play_mode->rate, (voice[v].cache) ? " (Cached)" : "");		abort();	}#endif	/* ABORT_AT_FATAL */}static int32 calc_velocity(int32 ch,int32 vel){	int32 velocity;	velocity = channel[ch].velocity_sense_depth * vel / 64 + (channel[ch].velocity_sense_offset - 64) * 2;	if(velocity > 127) {velocity = 127;}	return velocity;}static void recompute_voice_tremolo(int v){	Voice *vp = &(voice[v]);	int ch = vp->channel;	int32 depth = vp->sample->tremolo_depth;	depth += get_midi_controller_amp_depth(&(channel[ch].mod))		+ get_midi_controller_amp_depth(&(channel[ch].bend))		+ get_midi_controller_amp_depth(&(channel[ch].caf))		+ get_midi_controller_amp_depth(&(channel[ch].paf))		+ get_midi_controller_amp_depth(&(channel[ch].cc1))		+ get_midi_controller_amp_depth(&(channel[ch].cc2));	if(depth > 256) {depth = 256;}	vp->tremolo_depth = depth;}static void recompute_amp(int v){	FLOAT_T tempamp;	int ch = voice[v].channel;	/* master_volume and sample->volume are percentages, used to scale	 *  amplitude directly, NOT perceived volume	 *	 * all other MIDI volumes are linear in perceived volume, 0-127	 * use a lookup table for the non-linear scalings	 */	if (opt_user_volume_curve) {	tempamp = master_volume *		   voice[v].sample->volume *		   user_vol_table[calc_velocity(ch, voice[v].velocity)] *		   user_vol_table[channel[ch].volume] *		   user_vol_table[channel[ch].expression]; /* 21 bits */	} else if (play_system_mode == GM2_SYSTEM_MODE) {	tempamp = master_volume *		  voice[v].sample->volume *		  gm2_vol_table[calc_velocity(ch, voice[v].velocity)] *	/* velocity: not in GM2 standard */		  gm2_vol_table[channel[ch].volume] *		  gm2_vol_table[channel[ch].expression]; /* 21 bits */	} else if(play_system_mode == GS_SYSTEM_MODE) {	/* use measured curve */ 	tempamp = master_volume *		   voice[v].sample->volume *		   sc_vel_table[calc_velocity(ch, voice[v].velocity)] *		   sc_vol_table[channel[ch].volume] *		   sc_vol_table[channel[ch].expression]; /* 21 bits */	} else if (IS_CURRENT_MOD_FILE) {	/* use linear curve */	tempamp = master_volume *		  voice[v].sample->volume *		  calc_velocity(ch, voice[v].velocity) *		  channel[ch].volume *		  channel[ch].expression; /* 21 bits */	} else {	/* use generic exponential curve */	tempamp = master_volume *		  voice[v].sample->volume *		  perceived_vol_table[calc_velocity(ch, voice[v].velocity)] *		  perceived_vol_table[channel[ch].volume] *		  perceived_vol_table[channel[ch].expression]; /* 21 bits */	}	/* every digital effect increases amplitude,	 * so that it must be reduced in advance.	 */	if (! (play_mode->encoding & PE_MONO)	    && (opt_reverb_control || opt_chorus_control || opt_delay_control		|| (opt_eq_control && (eq_status_gs.low_gain != 0x40				       || eq_status_gs.high_gain != 0x40))		|| opt_insertion_effect))		tempamp *= 1.35f * 0.55f;	else		tempamp *= 1.35f;	/* NRPN - drum instrument tva level */	if(ISDRUMCHANNEL(ch)) {		if(channel[ch].drums[voice[v].note] != NULL) {			tempamp *= channel[ch].drums[voice[v].note]->drum_level;		}		tempamp *= (double)opt_drum_power * 0.01f;	/* global drum power */	}	/* MIDI controllers amplitude control */	if(opt_channel_pressure) {		tempamp *= get_midi_controller_amp(&(channel[ch].mod))			* get_midi_controller_amp(&(channel[ch].bend))			* get_midi_controller_amp(&(channel[ch].caf))			* get_midi_controller_amp(&(channel[ch].paf))			* get_midi_controller_amp(&(channel[ch].cc1))			* get_midi_controller_amp(&(channel[ch].cc2));		recompute_voice_tremolo(v);	}	if (voice[v].fc.type != 0) {		tempamp *= voice[v].fc.gain;	/* filter gain */	}	/* applying panning to amplitude */	if(!(play_mode->encoding & PE_MONO))    	{		if(voice[v].panning == 64)		{			voice[v].panned = PANNED_CENTER;			voice[v].left_amp = voice[v].right_amp = TIM_FSCALENEG(tempamp * pan_table[64], 27);		}		else if (voice[v].panning < 2)		{			voice[v].panned = PANNED_LEFT;			voice[v].left_amp = TIM_FSCALENEG(tempamp, 20);			voice[v].right_amp = 0;		}		else if(voice[v].panning == 127)		{#ifdef SMOOTH_MIXING			if(voice[v].panned == PANNED_MYSTERY) {				voice[v].old_left_mix = voice[v].old_right_mix;				voice[v].old_right_mix = 0;			}#endif			voice[v].panned = PANNED_RIGHT;			voice[v].left_amp =  TIM_FSCALENEG(tempamp, 20);			voice[v].right_amp = 0;		}		else		{#ifdef SMOOTH_MIXING			if(voice[v].panned == PANNED_RIGHT) {				voice[v].old_right_mix = voice[v].old_left_mix;				voice[v].old_left_mix = 0;			}#endif			voice[v].panned = PANNED_MYSTERY;			voice[v].left_amp = TIM_FSCALENEG(tempamp * pan_table[128 - voice[v].panning], 27);			voice[v].right_amp = TIM_FSCALENEG(tempamp * pan_table[voice[v].panning], 27);		}    	}    	else    	{		voice[v].panned = PANNED_CENTER;		voice[v].left_amp = TIM_FSCALENEG(tempamp, 21);    	}}#define RESONANCE_COEFF 0.2393void recompute_channel_filter(int ch, int note){	double coef = 1.0f, reso = 0;	if(channel[ch].special_sample > 0) {return;}	/* Soft Pedal */	if(channel[ch].soft_pedal != 0) {		if(note > 49) {	/* tre corde */			coef *= 1.0 - 0.20 * ((double)channel[ch].soft_pedal) / 127.0f;		} else {	/* una corda (due corde) */			coef *= 1.0 - 0.25 * ((double)channel[ch].soft_pedal) / 127.0f;		}	}	if(!ISDRUMCHANNEL(ch)) {		/* NRPN Filter Cutoff */		coef *= pow(1.26, (double)(channel[ch].param_cutoff_freq) / 8.0f);		/* NRPN Resonance */		reso = (double)channel[ch].param_resonance * RESONANCE_COEFF;	}	channel[ch].cutoff_freq_coef = coef;	channel[ch].resonance_dB = reso;}void init_voice_filter(int i){  memset(&(voice[i].fc), 0, sizeof(FilterCoefficients));  if(opt_lpf_def && voice[i].sample->cutoff_freq) {	  voice[i].fc.orig_freq = voice[i].sample->cutoff_freq;	  voice[i].fc.orig_reso_dB = (double)voice[i].sample->resonance / 10.0f - 3.01f;	  if (voice[i].fc.orig_reso_dB < 0.0f) {voice[i].fc.orig_reso_dB = 0.0f;}	  if (opt_lpf_def == 2) {		  voice[i].fc.gain = 1.0;		  voice[i].fc.type = 2;	  } else if(opt_lpf_def == 1) {		  voice[i].fc.gain = pow(10.0f, -voice[i].fc.orig_reso_dB / 2.0f / 20.0f);		  voice[i].fc.type = 1;	  }	  voice[i].fc.start_flag = 0;  } else {	  voice[i].fc.type = 0;  }}#define CHAMBERLIN_RESONANCE_MAX 24.0void recompute_voice_filter(int v){	int ch = voice[v].channel, note = voice[v].note;	double coef = 1.0, reso = 0, cent = 0, depth_cent = 0, freq;	FilterCoefficients *fc = &(voice[v].fc);	Sample *sp = (Sample *) &voice[v].sample;	if(fc->type == 0) {return;}	coef = channel[ch].cutoff_freq_coef;	if(ISDRUMCHANNEL(ch) && channel[ch].drums[note] != NULL) {		/* NRPN Drum Instrument Filter Cutoff */		coef *= pow(1.26, (double)(channel[ch].drums[note]->drum_cutoff_freq) / 8.0f);		/* NRPN Drum Instrument Filter Resonance */		reso += (double)channel[ch].drums[note]->drum_resonance * RESONANCE_COEFF;	}	/* MIDI controllers filter cutoff control and LFO filter depth */	if(opt_channel_pressure) {		cent += get_midi_controller_filter_cutoff(&(channel[ch].mod))			+ get_midi_controller_filter_cutoff(&(channel[ch].bend))			+ get_midi_controller_filter_cutoff(&(channel[ch].caf))			+ get_midi_controller_filter_cutoff(&(channel[ch].paf))			+ get_midi_controller_filter_cutoff(&(channel[ch].cc1))			+ get_midi_controller_filter_cutoff(&(channel[ch].cc2));		depth_cent += get_midi_controller_filter_depth(&(channel[ch].mod))			+ get_midi_controller_filter_depth(&(channel[ch].bend))			+ get_midi_controller_filter_depth(&(channel[ch].caf))			+ get_midi_controller_filter_depth(&(channel[ch].paf))			+ get_midi_controller_filter_depth(&(channel[ch].cc1))			+ get_midi_controller_filter_depth(&(channel[ch].cc2));	}	if(sp->vel_to_fc) {	/* velocity to filter cutoff frequency */		if(voice[v].velocity > sp->vel_to_fc_threshold)			cent += sp->vel_to_fc * (double)(127 - voice[v].velocity) / 127.0f;		else			coef += sp->vel_to_fc * (double)(127 - sp->vel_to_fc_threshold) / 127.0f;	}	if(sp->vel_to_resonance) {	/* velocity to filter resonance */		reso += (double)voice[v].velocity * sp->vel_to_resonance / 127.0f / 10.0f;	}	if(sp->key_to_fc) {	/* filter cutoff key-follow */		cent += sp->key_to_fc * (double)(voice[v].note - sp->key_to_fc_bpo);	}	if(opt_modulation_envelope) {		if(voice[v].sample->tremolo_to_fc + (int16)depth_cent) {			cent += ((double)voice[v].sample->tremolo_to_fc + depth_cent) * lookup_triangular(voice[v].tremolo_phase >> RATE_SHIFT);		}		if(voice[v].sample->modenv_to_fc) {			cent += (double)voice[v].sample->modenv_to_fc * voice[v].last_modenv_volume;		}	}	if(cent != 0) {coef *= pow(2.0, cent / 1200.0f);}	freq = (double)fc->orig_freq * coef;	if (freq > play_mode->rate / 2) {freq = play_mode->rate / 2;}	else if(freq < 5) {freq = 5;}	else if(freq > 20000) {freq = 20000;}	fc->freq = (int32)freq;	fc->reso_dB = fc->orig_reso_dB + channel[ch].resonance_dB + reso;	if(fc->reso_dB < 0.0f) {fc->reso_dB = 0.0f;}	else if(fc->reso_dB > 96.0f) {fc->reso_dB = 96.0f;}	if(fc->type == 1) {	/* Chamberlin filter */		if(fc->freq > play_mode->rate / 6) {			if (fc->start_flag == 0) {fc->type = 0;}	/* turn off. */ 			else {fc->freq = play_mode->rate / 6;}		}		if(fc->reso_dB > CHAMBERLIN_RESONANCE_MAX) {fc->reso_dB = CHAMBERLIN_RESONANCE_MAX;}	} else if(fc->type == 2) {	/* Moog VCF */		if(fc->reso_dB > fc->orig_reso_dB / 2) {			fc->gain = pow(10.0f, (fc->reso_dB - fc->orig_reso_dB / 2) / 20.0f);		}	}	fc->start_flag = 1;	/* filter is started. */}float calc_drum_tva_level(int ch, int note, int level){	int def_level, nbank, nprog;	ToneBank *bank;	if(channel[ch].special_sample > 0) {return 1.0;}	nbank = channel[ch].bank;	nprog = note;	instrument_map(channel[ch].mapID, &nbank, &nprog);	if(ISDRUMCHANNEL(ch)) {		bank = drumset[nbank];		if(bank == NULL) {bank = drumset[0];}	} else {		return 1.0;	}	def_level = bank->tone[nprog].tva_level;	if(def_level == -1 || def_level == 0) {def_level = 127;}	else if(def_level > 127) {def_level = 127;}	return (sc_drum_level_table[level] / sc_drum_level_table[def_level]);}static int32 calc_random_delay(int ch, int note){	int nbank, nprog;	ToneBank *bank;	if(channel[ch].special_sample > 0) {return 0;}	nbank = channel[ch].bank;	if(ISDRUMCHANNEL(ch)) {		nprog = note;		instrument_map(channel[ch].mapID, &nbank, &nprog);		bank = drumset[nbank];		if (bank == NULL) {bank = drumset[0];}	} else {		nprog = channel[ch].program;		if(nprog == SPECIAL_PROGRAM) {return 0;}		instrument_map(channel[ch].mapID, &nbank, &nprog);		bank = tonebank[nbank];		if(bank == NULL) {bank = tonebank[0];}	}	if (bank->tone[nprog].rnddelay == 0) {return 0;}	else {return (int32)((double)bank->tone[nprog].rnddelay * play_mode->rate / 1000.0		* (get_pink_noise_light(&global_pink_noise_light) + 1.0f) * 0.5);}}void recompute_bank_parameter(int ch, int note){	int nbank, nprog;	ToneBank *bank;	struct DrumParts *drum;	if(channel[ch].special_sample > 0) {return;}	nbank = channel[ch].bank;	if(ISDRUMCHANNEL(ch)) {		nprog = note;		instrument_map(channel[ch].mapID, &nbank, &nprog);		bank = drumset[nbank];		if (bank == NULL) {bank = drumset[0];}		if (channel[ch].drums[note] == NULL)				play_midi_setup_drums(ch, note);		drum = channel[ch].drums[note];		if (drum->reverb_level == -1 && bank->tone[nprog].reverb_send != -1) {			drum->reverb_level = bank->tone[nprog].reverb_send;		}		if (drum->chorus_level == -1 && bank->tone[nprog].chorus_send != -1) {			drum->chorus_level = bank->tone[nprog].chorus_send;		}		if (drum->delay_level == -1 && bank->tone[nprog].delay_send != -1) {			drum->delay_level = bank->tone[nprog].delay_send;		}	} else {		nprog = channel[ch].program;		if (nprog == SPECIAL_PROGRAM) {return;}		instrument_map(channel[ch].mapID, &nbank, &nprog);		bank = tonebank[nbank];		if (bank == NULL) {bank = tonebank[0];}		channel[ch].legato = bank->tone[nprog].legato;		channel[ch].damper_mode = bank->tone[nprog].damper_mode;		channel[ch].loop_timeout = bank->tone[nprog].loop_timeout;	}}Instrument *play_midi_load_instrument(int dr, int bk, int prog){	ToneBank **bank = (dr) ? drumset : tonebank;	Instrument *ip;	int load_success = 0;	if (bank[bk] == NULL)		alloc_instrument_bank(dr, bk);	if (bank[bk]->tone[prog].name) {		/* Instrument is found. */		if ((ip = bank[bk]->tone[prog].instrument) == MAGIC_LOAD_INSTRUMENT#ifndef SUPPRESS_CHANNEL_LAYER			|| ip == NULL	/* see also readmidi.c: groom_list(). */#endif		) {ip = bank[bk]->tone[prog].instrument = load_instrument(dr, bk, prog);}		if (ip == NULL || IS_MAGIC_INSTRUMENT(ip)) {			bank[bk]->tone[prog].instrument = MAGIC_ERROR_INSTRUMENT;		} else {			load_success = 1;		}	} else {		/* Instrument is not found.		   Try to load the instrument from bank 0 */		if ((ip = bank[0]->tone[prog].instrument) == NULL			|| ip == MAGIC_LOAD_INSTRUMENT)			ip = bank[0]->tone[prog].instrument = load_instrument(dr, 0, prog);		if (ip == NULL || IS_MAGIC_INSTRUMENT(ip)) {			bank[0]->tone[prog].instrument = MAGIC_ERROR_INSTRUMENT;		} else {			copy_tone_bank_element(&bank[bk]->tone[prog], &bank[0]->tone[prog]);			bank[bk]->tone[prog].instrument = ip;			load_success = 1;		}	}	if (load_success)		aq_add(NULL, 0);	/* Update software buffer */	if (ip == MAGIC_ERROR_INSTRUMENT)

⌨️ 快捷键说明

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