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

📄 rcp.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 3 页
字号:
    int yamaha_device_id = 0x10;	/* ??? */    int yamaha_model_id = 0x16;		/* ??? */    unsigned char cs;		/* check sum */    long same_measure = -1;	/* Meassure to stack pointer */    long track_top, data_top;    int time_offset;    char buff[64], *p;    int ret = 0;    /*     * Read Track Header     */    track_top = tf_tell(tf);    ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY, "Track top: %d", track_top);    size = tf_getc(tf);    size |= (tf_getc(tf) << 8);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Track size %d", size);    last_point = size + tf_tell(tf) - 2;    if(gfmt)    {	skip(tf, 2);	cmdlen = 6;    }    else	cmdlen = 4;    i = tf_getc(tf);		/* Track Number */    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Track number %d", i);    skip(tf, 1);		/* Rhythm */    if((ch = tf_getc(tf)) == 0xff) /* No playing */    {	tf_seek(tf, last_point, SEEK_SET);	return 0;    }    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Track channel %d", ch);    if(ch >= RCP_MAXCHANNELS)	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		  "RCP: Invalid channel: %d", ch);    /* Key offset */    key_offset = tf_getc(tf);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Key offset %d", key_offset);    if(key_offset > 64)	key_offset -= 128;    key_offset += play_bias;    /* Time offset */    time_offset = (int)(signed char)tf_getc(tf);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Time offset %d", time_offset);    if(time_offset < -99 || 99 < time_offset)    {	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		  "RCP: Invalid time offset: %d", time_offset);	if(time_offset < -99)	    time_offset = -99;	else	    time_offset = 99;    }    i = tf_getc(tf);		/* mode */    if(i == 1)    {	/* Mute */	tf_seek(tf, last_point, SEEK_SET);	return 0;    }    /* Comment */    tf_read(buff, 1, 36, tf);    buff[36] = '\0';    for(len = 35; len >= 0; len--)    {	if(buff[len] == ' ')	    buff[len] = '\0';	else if(buff[len] != '\0')	    break;    }    len = SAFE_CONVERT_LENGTH(len+1);    p = (char *)new_segment(&tmpbuffer, len);    code_convert(buff, p, len, NULL, NULL);    if(*p)	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "RCP Track name: %s", p);    reuse_mblock(&tmpbuffer);    /*     * End of Track Header     */    sp = 0;    ntr.tempo = current_tempo = 60000000 / init_tempo;    ntr_init(&ntr, gfmt, readmidi_set_track(trackno, 1));    if(trackno == 0 && init_tempo != 120)	ntr.tempo = current_tempo = rcp_tempo_change(&ntr, 64, 0);	if (trackno == 0) {		rcp_timesig_change(ntr_at(ntr));		rcp_keysig_change(ntr_at(ntr), init_keysig);	}    ntr_incr(&ntr, time_offset);    data_top = tf_tell(tf);    while(last_point >= tf_tell(tf) + cmdlen)    {	int cmd, a, b, step, gate;	int st1, gt1, st2, gt2;	if(readmidi_error_flag)	{	    ret = -1;	    break;	}	if(!gfmt)	{	    cmd = tf_getc(tf);	    step = tf_getc(tf);	    gate = a = tf_getc(tf);	    if((b = tf_getc(tf)) == EOF)	    {		ret = -1;		break;	    }	    st1 = gt1 = st2 = gt2 = 0;	    if(ctl->verbosity >= VERB_DEBUG_SILLY)	    {		ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			  "[%d] %d %s: ch=%d step=%d a=%d b=%d sp=%d",			  tf_tell(tf) - 4 - track_top,			  ntr_at(ntr), rcp_cmd_name(cmd), ch, step, a, b, sp);	    }	}	else	{	    cmd = tf_getc(tf);	    b = tf_getc(tf);	    st1 = tf_getc(tf);	    st2 = tf_getc(tf);	    a = gt1 = tf_getc(tf);	    if((gt2 = tf_getc(tf)) == EOF)	    {		ret = -1;		break;	    }	    step = st1 + (st2 << 8);	    gate = gt1 + (gt2 << 8);	    if(ctl->verbosity >= VERB_DEBUG_SILLY)	    {		ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			  "[%d] %d %s: ch=%d step=%d gate=%d a=%d b=%d sp=%d",			  tf_tell(tf) - 6 - track_top,			  ntr_at(ntr), rcp_cmd_name(cmd), ch,			  step, gate, a, b, sp);	    }	}	if(cmd < 0x80)		/* Note event */	{	    if(gate > 0)	    {		int note = cmd + key_offset;		ntr_note_on(&ntr, ch, note & 0x7f, b, gate);	    }	    ntr_incr(&ntr, step);	    continue;	}	/* command */	switch(cmd)	{	  case 0x90:	/* User Exclusive 1 */	  case 0x91:	/* User Exclusive 2 */	  case 0x92:	/* User Exclusive 3 */	  case 0x93:	/* User Exclusive 4 */	  case 0x94:	/* User Exclusive 5 */	  case 0x95:	/* User Exclusive 6 */	  case 0x96:	/* User Exclusive 7 */	  case 0x97:	/* User Exclusive 8 */	    memcpy(sysex, user_exclusive_data[cmd - 0x90],		   USER_EXCLUSIVE_LENGTH);	    sysex[USER_EXCLUSIVE_LENGTH] = 0xf7;	    len = preprocess_sysex(sysex, ch, a, b);	    rcp_parse_sysex_event(ntr_at(ntr), sysex, len);	    ntr_incr(&ntr, step);	    break;	  case 0x98:	/* Channel Exclusive */	    len = 0;	    while(tf_getc(tf) == 0xf7 && len + 6 < sizeof(sysex))	    {		if(gfmt)		{		    if(tf_read(sysex + len, 1, 5, tf) != 5)		    {			ret = -1;			goto end_of_track;		    }		    len += 5;		}		else		{		    tf_getc(tf); /* 0x00 */		    if(tf_read(sysex + len, 1, 2, tf) != 2)		    {			ret = -1;			goto end_of_track;		    }		    len += 2;		}	    }	    tf_seek(tf, -1, SEEK_CUR);	    sysex[len] = 0xf7;	    len = preprocess_sysex(sysex, ch, a, b);	    rcp_parse_sysex_event(ntr_at(ntr), sysex, len);	    ntr_incr(&ntr, step);	    break;	  case 0xd0:	/* Yamaha base */	    a &= 0x7f;	    b &= 0x7f;	    yamaha_base_addr0 = a;	    yamaha_base_addr1 = b;	    yamaha_base_init = 1;	    ntr_incr(&ntr, step);	    break;	  case 0xd1:	/* Yamaha para */	    a &= 0x7f;	    b &= 0x7f;	    if(!yamaha_base_init)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "YamPara used before initializing YamBase");	    if(!yamaha_dev_init)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "YamPara used before initializing YamDev#");	    yamaha_base_init = yamaha_dev_init = 1;	    sysex[0] = 0x43;	    sysex[1] = yamaha_device_id;	    sysex[2] = yamaha_model_id;	    sysex[3] = 0x12;	    cs = 0;	    cs += sysex[4] = yamaha_base_addr0;	    cs += sysex[5] = yamaha_base_addr1;	    cs += sysex[6] = a;	    cs += sysex[7] = b;	    sysex[8] = 128 - (cs & 0x7f);	    sysex[9] = 0xf7;		rcp_parse_sysex_event(ntr_at(ntr), sysex, 10);	    ntr_incr(&ntr, step);	    break;	  case 0xd2:	/* Yamaha device */	    a &= 0x7f;	    b &= 0x7f;	    yamaha_device_id = a;	    yamaha_model_id = b;	    yamaha_dev_init = 1;	    ntr_incr(&ntr, step);	    break;	  case 0xd3:	/* XG para */	    /* ?? */	    a &= 0x7f;	    b &= 0x7f;	    sysex[0] = 0x43;	    sysex[1] = yamaha_device_id;	    sysex[2] = yamaha_model_id;	    sysex[3] = 0x12;	    cs = 0;	    cs += sysex[4] = yamaha_base_addr0;	    cs += sysex[5] = yamaha_base_addr1;	    cs += sysex[6] = a;	    cs += sysex[7] = b;	    sysex[8] = 128 - (cs & 0x7f);	    sysex[9] = 0xf7;		rcp_parse_sysex_event(ntr_at(ntr), sysex, 10);	    ntr_incr(&ntr, step);	    break;	  case 0xdd:	/* Roland base */	    a &= 0x7f;	    b &= 0x7f;	    roland_base_addr0 = a;	    roland_base_addr1 = b;	    roland_base_init = 1;	    ntr_incr(&ntr, step);	    break;	  case 0xde:	/* Roland para */	    a &= 0x7f;	    b &= 0x7f;	    if(!roland_base_init)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "RolPara used before initializing RolBase");	    if(!roland_dev_init)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "RolPara used before initializing RolDev#");	    roland_base_init = roland_dev_init = 1;	    sysex[0] = 0x41;	    sysex[1] = roland_device_id;	    sysex[2] = roland_model_id;	    sysex[3] = 0x12;	    cs = 0;	    cs += sysex[4] = roland_base_addr0;	    cs += sysex[5] = roland_base_addr1;	    cs += sysex[6] = a;	    cs += sysex[7] = b;	    sysex[8] = 128 - (cs & 0x7f);	    sysex[9] = 0xf7;		rcp_parse_sysex_event(ntr_at(ntr), sysex, 10);	    ntr_incr(&ntr, step);	    break;	  case 0xdf:	/* Roland device */	    a &= 0x7f;	    b &= 0x7f;	    roland_device_id = a;	    roland_model_id = b;	    roland_dev_init = 1;	    ntr_incr(&ntr, step);	    break;	  case 0xe1:	/* BnkLPrg */	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		      "BnkLPrg is not supported: 0x%02x 0x%02x", a, b);	    ntr_incr(&ntr, step);	    break;	  case 0xe2:	/* bank & program change */	    readmidi_add_ctl_event(ntr_at(ntr), ch, 0, b); /*Change MSB Bank*/	    MIDIEVENT(ntr_at(ntr), ME_PROGRAM, ch, a & 0x7f, 0);	    ntr_incr(&ntr, step);	    break;	  case 0xe5:	/* key scan */#if 0	    switch(a)	    {	      case 12: /* suspend playing */	      case 18: /* increase play bias */	      case 23: /* stop playing */	      case 32: /* show main screen */	      case 33: /* show 11th track */	      case 34: /* show 12th track */	      case 35: /* show 13th track */	      case 36: /* show 14th track */	      case 37: /* show 15th track */	      case 38: /* show 16th track */	      case 39: /* show 17th track */	      case 40: /* show 18th track */	      case 48: /* show 10th track */	      case 49: /* show 1st track */	      case 50: /* show 2nd track */	      case 51: /* show 3rd track */	      case 52: /* show 4th track */	      case 53: /* show 5th track */	      case 54: /* show 6th track */	      case 55: /* show 7th track */	      case 56: /* show 8th track */	      case 57: /* show 9th track */	      case 61: /* mute 1st track */		break;	    }#endif	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		      "Key scan 0x%02x 0x%02x is not supported", a, b);	    ntr_incr(&ntr, step);	    break;	  case 0xe6:	/* MIDI channel change */	    ch = a - 1;	    if(ch == 0) /* ##?? */		ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "MIDI channel off");	    else if(ch >= RCP_MAXCHANNELS)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "RCP: Invalid channel: %d", ch);	    ntr_incr(&ntr, step);	    break;	  case 0xe7:	/* tempo change */	    if(a == 0)	    {		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "Invalid tempo change\n");		a = 64;	    }	    current_tempo = rcp_tempo_change(&ntr, a, b);	    ntr_incr(&ntr, step);	    break;	  case 0xea:	/* channel after touch (channel pressure) */	    a &= 0x7f;	    MIDIEVENT(ntr_at(ntr), ME_CHANNEL_PRESSURE, ch, a, 0);	    ntr_incr(&ntr, step);	    break;	  case 0xeb:	/* control change */	    readmidi_add_ctl_event(ntr_at(ntr), ch, a, b);	    ntr_incr(&ntr, step);	    break;	  case 0xec:	/* program change */	    a &= 0x7f;	    MIDIEVENT(ntr_at(ntr), ME_PROGRAM, ch, a, 0);	    ntr_incr(&ntr, step);	    break;	  case 0xed:	/* after touch polyphonic (polyphonic key pressure) */	    a &= 0x7f;	    b &= 0x7f;	    MIDIEVENT(ntr_at(ntr), ME_KEYPRESSURE, ch, a, b);	    ntr_incr(&ntr, step);	    break;	  case 0xee:	/* pitch bend */	    a &= 0x7f;	    b &= 0x7f;	    MIDIEVENT(ntr_at(ntr), ME_PITCHWHEEL, ch, a, b);	    ntr_incr(&ntr, step);	    break;	case 0xf5:	/* key change */		if (step < 0 || step >= 32) {			ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Invalid key change\n");			step = 0;		}		rcp_keysig_change(ntr_at(ntr), step);		break;	  case 0xf6:	/* comment */	    len = 0;	    if(!gfmt)	    {		buff[len++] = a;		buff[len++] = b;	    }	    else	    {		buff[len++] = b;		buff[len++] = st1;		buff[len++] = st2;		buff[len++] = gt1;		buff[len++] = gt2;	    }	    while(tf_getc(tf) == 0xf7 && len + 6 < sizeof(buff))	    {		if(gfmt)		{		    if(tf_read(buff + len, 1, 5, tf) != 5)		    {			ret = -1;			goto end_of_track;		    }		    len += 5;		}		else		{		    tf_getc(tf); /* 0x00 */		    if(tf_read(buff + len, 1, 2, tf) != 2)		    {			ret = -1;			goto end_of_track;		    }		    len += 2;		}	    }	    tf_seek(tf, -1, SEEK_CUR);	    if(ctl->verbosity >= VERB_VERBOSE || opt_trace_text_meta_event)	    {		buff[len] = '\0';		for(len--; len >= 0; len--)		{		    if(buff[len] == ' ')			buff[len] = '\0';		    else if(buff[len] != '\0')			break;		}		if(opt_trace_text_meta_event)		{		    MidiEvent ev;		    if(readmidi_make_string_event(ME_TEXT, buff, &ev, 1)		       != NULL)		    {			ev.time = ntr_at(ntr);			readmidi_add_event(&ev);		    }		}

⌨️ 快捷键说明

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