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

📄 m2m.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 3 页
字号:
		  "Couldn't open mod cfg file!  Proceeding without it.");}/* Fill the delta time byte array used in the mod->midi output routine */int set_dt_array(unsigned char *dt_array, int32 delta_time){    int num_dt_bytes = 0, i = 0;    int32 dt_byte;    if (delta_time < 0)    {	ctl->cmsg(CMSG_INFO, VERB_NORMAL, "WTF?  Delta Time = %ld",		  delta_time);	delta_time = 0;    }    /* Delta time is variable length, max of 4 bytes long.       Each byte contains 7 bits of the number.       Every byte but the last one has an MSB of 1, while the last byte       has an MSB of 0 to indicate it is the last byte.     */    dt_byte = (delta_time & 0x0FFFFFFF) >> 21;    if (dt_byte)    {	dt_array[i++] = dt_byte | 0x80;	num_dt_bytes = 4;    }    dt_byte = (delta_time & 0x001FFFFF) >> 14;    if (dt_byte || num_dt_bytes)    {	dt_array[i++] = dt_byte | 0x80;	if (!num_dt_bytes)	    num_dt_bytes = 3;    }    dt_byte = (delta_time & 0x00003FFF) >> 7;    if (dt_byte || num_dt_bytes)    {	dt_array[i++] = dt_byte | 0x80;	if (!num_dt_bytes)	    num_dt_bytes = 2;    }    dt_byte = delta_time & 0x0000007F;    dt_array[i] = dt_byte;    if (!num_dt_bytes)	num_dt_bytes = 1;    return num_dt_bytes;}void scan_ahead_for_m2m_tweaks(MidiEvent * ev, int midi_ch, int midi_note,			       int samplenum){    int ch, event_type, init_ch, init_note, init_velocity;    int32 bend = 0, lowbend = 0, highbend = 0;    int32 pb_offset1 = 0, pb_offset2 = 0;    int note_offset1 = 0, note_offset2 = 0;    uint32 init_time, cur_time, old_time, cut_time = 0;    Sample *sp;    double a, bent_length = 0, delta_length;    uint32 length;    float root_freq, pitch, freq;    init_time = cur_time = old_time = ev->time;    init_ch = ev->channel;    init_note = ev->a;    init_velocity = ev->b;    sp = special_patch[samplenum]->sample;    root_freq = pitch_freq_table[36];    length = sp->data_length >> FRACTION_BITS;    /* check for a pitch bend prior to the note */    if ((ev-1)->type == ME_PITCHWHEEL && (ev-1)->channel == init_ch)    {	bend = (ev-1)->b * 128 + (ev-1)->a;	bend = ROUND((bend - 0x2000) * old_pb_sensitivity /	             (float) pb_sensitivity);	bend += fine_tune[samplenum];	if (bend < lowbend)	    lowbend = bend;	if (bend > highbend)	    highbend = bend;	pitch = init_note + notes_per_pb * bend;	freq = 13.75 * exp((pitch - 9) * 0.05776226505f);    }    else        freq = pitch_freq_table[init_note];    a = (freq * sp->sample_rate) /	(root_freq * play_mode->rate);    for (++ev; ev->type != ME_EOT; ev++)    {	event_type = ev->type;	if (event_type != ME_ALL_NOTES_OFF &&	    event_type != ME_NOTEOFF && event_type != ME_PITCHWHEEL)		continue;	ch = ev->channel;	if (ch != init_ch)	    continue;	cur_time = ev->time;	if (event_type == ME_ALL_NOTES_OFF)	    break;	if (event_type == ME_NOTEOFF)	{	    if (ev->a == init_note)		break;	    continue;	}	delta_length = (cur_time - old_time) * a;	if (!cut_time && bent_length + delta_length > length)	{	    cut_time = ROUND(cur_time - (bent_length + delta_length - length) /			     delta_length * (cur_time - old_time));	}	bent_length += delta_length;	old_time = cur_time;	bend = ev->b * 128 + ev->a;	bend = ROUND((bend - 0x2000) * old_pb_sensitivity /	             (float) pb_sensitivity);	bend += fine_tune[samplenum];	if (bend < lowbend)	    lowbend = bend;	if (bend > highbend)	    highbend = bend;	    	pitch = init_note + notes_per_pb * bend;	freq = 13.75 * exp((pitch - 9) * 0.05776226505f);	a = (freq * sp->sample_rate) /	    (root_freq * play_mode->rate);    }    delta_length = (cur_time - old_time) * a;    if (!cut_time && bent_length + delta_length > length)    {	cut_time = ROUND(cur_time - (bent_length + delta_length - length) /			 delta_length * (cur_time - old_time));    }    bent_length += delta_length;    if (highbend > 8191)    {	pb_offset1 = highbend - 8191;	note_offset1 = ceil(notes_per_pb * pb_offset1);	pb_offset1 = -note_offset1 * pb_per_note;    }    if (lowbend < -8191)    {	pb_offset2 = lowbend - -8191;	note_offset2 = floor(notes_per_pb * pb_offset2);	pb_offset2 = -note_offset2 * pb_per_note;    }    if (note_offset1 > -note_offset2)    {	tweak_note_offset[midi_ch] = note_offset1;	tweak_pb_offset[midi_ch] = pb_offset1;    }    else    {	tweak_note_offset[midi_ch] = note_offset2;	tweak_pb_offset[midi_ch] = pb_offset2;    }    if (note_offset1 || note_offset2)	num_big_pitch_slides++;    if (highbend - lowbend > 16382)	num_huge_pitch_slides++;    /* hmm, need to kill this one early */    kill_early_time[init_ch] = 0;    if (!(sp->modes & MODES_LOOPING))    {	if (bent_length > length)	{	    kill_early_note[init_ch] = midi_note + tweak_note_offset[midi_ch];	    kill_early_velocity[init_ch] = init_velocity;	    kill_early_time[init_ch] = cut_time;	    kill_early_ch[init_ch] = midi_ch;	}    }}void m2m_kill_notes_early(MidiEvent * ev, double time){    int i, j;    int chord, chord_type, chord_subtype;    int extra, newnote;    uint32 kill_time;    int kill_sample;    int kill_ch;    int kill_n;    /* kill notes early if unlooped samples are causing problems */    for (j = 0; j < 34; j++)    {	if (kill_early_time[j] && kill_early_time[j] <= ev->time)	{	    kill_sample = current_track_sample[j];	    kill_ch = kill_early_ch[j];	    kill_time = ROUND(time - ((ev->time - kill_early_time[j]) *			      divisions_ratio) / samples_per_tick);	    /* looks like we got screwed by a tempo event, so skip it */	    if (kill_time < last_track_event_time[kill_ch])	    {		kill_early_time[j] = 0;		continue;	    }	    /* yet another tempo muck up */	    if (current_channel_note[kill_ch] != kill_early_note[j])	    {		kill_early_time[j] = 0;		continue;	    }	    if (kill_time > maxtime)		maxtime = kill_time;	    kill_n = 3;	    newnote = kill_early_note[j];	    while (newnote > 127)	    	newnote -= 12;	    while (newnote < 0)	    	newnote += 12;	    event[0] = 0x80 | (kill_ch & 0x0F);	    event[1] = newnote;	    event[2] = kill_early_velocity[j];	    current_track_note[j] = -1;	    current_channel_note[kill_ch] = -1;	    /* resize the track event array */	    length = track_size[kill_ch];	    num_dt_bytes = set_dt_array(dt_array, kill_time -					last_track_event_time[kill_ch]);	    track_size[kill_ch] += kill_n + num_dt_bytes;	    track_events[kill_ch] =		safe_realloc(track_events[kill_ch],			track_size[kill_ch] * sizeof(unsigned char));	    /* save the delta_time */	    p_track_event = track_events[kill_ch] + length;	    for (i = 0; i < num_dt_bytes; i++)	    {		p_track_event[i] = dt_array[i];	    }	    /* save the events */	    p_track_event += num_dt_bytes;	    for (i = 0; i < kill_n; i++)	    {		p_track_event[i] = event[i];	    }	    /* spawn extra events for chords */	    chord = sample_chords[kill_sample];	    if (chord >= 0)	    {		extra = 2;		length = track_size[kill_ch];		track_size[kill_ch] += 4 * extra;		track_events[kill_ch] =		    safe_realloc(track_events[kill_ch],			    track_size[kill_ch] * sizeof(unsigned char));		p_track_event = track_events[kill_ch] + length;		for (i = 0; i < 3; i++)		{		    chord_type = chord / 3;		    chord_subtype = chord % 3;		    newnote = event[kill_n - 2] +			chord_table[chord_type][chord_subtype][i];		    if (newnote == event[kill_n - 2])			continue;		    while (newnote > 127)		    	newnote -= 12;		    while (newnote < 0)		    	newnote += 12;		    p_track_event[0] = 0x00;		    p_track_event[1] = event[kill_n - 3];		    p_track_event[2] = newnote;		    p_track_event[3] = event[kill_n - 1];		    p_track_event += 4;		}	    }	    last_track_event_time[kill_ch] = kill_time;	    kill_early_time[j] = 0;	    num_killed_early++;	}    }}void m2m_prescan(MidiEvent * ev){    int i, ch;    /* find out which tracks will wind up with notes on them */    for (; ev->type != ME_EOT; ev++)    {	if (ev->type == ME_NOTEON || ev->type == ME_SET_PATCH)	{	    ch = ev->channel;	    if (ch >= 25)		ch++;	    if (ev->type == ME_NOTEON)	    {		if (silent_samples[current_track_sample[ch]])		    continue;		tracks_useless[ch] = 0;		/* move drums to drum channel */		if (is_drum_sample[current_track_sample[ch]])		    ch = 9;		else if (ch == 9)		{		    non_drums_on_drums = 1;		    continue;		}		if (!tracks_enabled[ch])		{		    tracks_enabled[ch] = 1;		    num_tracks++;		}	    }	    else		current_track_sample[ch] = ev->a;	}    }    for (i = 0; i < 34; i++)    {	if (!tracks_enabled[i])	{	    if (i != 9 && i != 25 && first_free_track < 0)		first_free_track = i;	}	else	{	    if (min_enabled_track < 0)		min_enabled_track = i;	    max_enabled_track = i;	}    }    /* all tracks were filled, set it to the last track anyways */    if (first_free_track < 0)	first_free_track = 63;    /* we're going to add another track to move stuff off of the drums */    if (non_drums_on_drums)    {	tracks_enabled[first_free_track] = 1;	num_tracks++;    }    /* re-initialize to unseen sample number to make sure it's not a drum */    for (i = 0; i < 34; i++)    {	current_track_sample[i] = 255;    }    /* Initialize Port Numbers for channels > 15 */    for (i = 0; i < 34; i++)    {	if (tracks_enabled[i])	{	    length = track_size[i];	    track_size[i] += 5;	    track_events[i] = safe_realloc(track_events[i], track_size[i] *				      sizeof(unsigned char));	    p_track_event = track_events[i] + length;	    /* Port Change Event */	    p_track_event[0] = 0x00;	    p_track_event[1] = 0xFF;	    p_track_event[2] = 0x21;	    p_track_event[3] = 0x01;	    p_track_event[4] = i / 16;	}    }    /* Issue Initial Drum Stuff */    length = track_size[9];    track_size[9] += 15;    track_events[9] = safe_realloc(track_events[9], track_size[9] *			      sizeof(unsigned char));    p_track_event = track_events[9] + length;    /* program change to Standard Drums */    p_track_event[0] = 0x00;    p_track_event[1] = 0xC9;    p_track_event[2] = 0x00;    /* set initial volume */    p_track_event[3] = 0x00;    p_track_event[4] = 0xB9;    p_track_event[5] = 0x07;    p_track_event[6] = 127;    /* set initial expression */    p_track_event[7] = 0x00;    p_track_event[8] = 0xB9;    p_track_event[9] = 0x0B;    p_track_event[10] = 127;    /* set center pan */    p_track_event[11] = 0x00;    p_track_event[12] = 0xB9;    p_track_event[13] = 0x0A;    p_track_event[14] = 64;}void m2m_process_events(MidiEvent * ev){    int i;    int moved_to_drums;    int event_type;    int skip_ch_expr_flag;    uint32 oldtime = 0, deltatime;    double time = 0;    int chord, chord_type, chord_subtype;    int ch, n, old_ch, newnote, mod_sample, expression;    int extra;    /* go through the list for real this time */    for (; ev->type != ME_EOT; ev++)    {	/* convert timidity times to midi event times */	samples_per_tick = (double) play_mode->rate * (double) tempo /	    (double) 1000000 / (double) orig_divisions;	deltatime = ev->time - oldtime;	oldtime = ev->time;	time += (deltatime * divisions_ratio) / samples_per_tick;	if (time > maxtime)	    maxtime = time;	m2m_kill_notes_early(ev, time);	n = 0;	ch = ev->channel;	if (ch >= 25)	    ch++;	if (ev->type != ME_TEMPO && tracks_useless[ch])	    continue;	if (ev->type != ME_TEMPO)	    mod_sample = current_track_sample[ch];	/* skip silent sample events */	if (silent_samples[mod_sample] &&	    (ev->type == ME_NOTEON || ev->type == ME_NOTEOFF ||	     ev->type == ME_KEYPRESSURE)) continue;	if (ev->type == ME_SET_PATCH && silent_samples[ev->a])	{	    continue;	}	if (ev->type == ME_EXPRESSION && silent_samples[ev->a] &&	    !current_track_note[ch])	{	    orig_track_expr[ch] = ev->a;	    continue;	}	skip_ch_expr_flag = 0;	moved_to_drums = 0;	old_ch = ch;	if (ev->type != ME_TEMPO && ev->type != ME_SET_PATCH)	{	    /* move non-drums off to first free channel, drums to drum channel */	    if (ch == 9 &&		(!is_drum_sample[mod_sample] ||		 (ev->type != ME_NOTEON &&		  ev->type != ME_NOTEOFF && ev->type != ME_KEYPRESSURE)))	    {		ch = first_free_track;	    }	    else if (is_drum_sample[mod_sample])	    {		if (ch != 9)		{		    ch = 9;		    moved_to_drums = 1;		}	    }	}	event_type = ev->type;	switch (ev->type)	{	case ME_NOTEOFF:	    n = 3;	    if (is_drum_sample[mod_sample])		newnote = sample_to_program[mod_sample];	    else	    {		newnote = ev->a + transpose[mod_sample];		newnote += tweak_note_offset[ch];	    }	    while (newnote > 127)	    	newnote -= 12;	    while (newnote < 0)	    	newnote += 12;

⌨️ 快捷键说明

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