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

📄 rcp.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 3 页
字号:
		else if(ctl->verbosity >= VERB_VERBOSE)		{		    len = SAFE_CONVERT_LENGTH(len+1);		    p = (char *)new_segment(&tmpbuffer, len);		    code_convert(buff, p, len, NULL, NULL);		    ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "Comment: %s", p);		    reuse_mblock(&tmpbuffer);		}	    }	    break;	  case 0xf7:	/* 2nd Event */	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		      "Something's wrong: 2nd Event is appeared");	    break;	  case 0xf8:	/* loop end */	    if(ctl->verbosity >= VERB_DEBUG_SILLY)		ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			  "Loop end at %d",			  tf_tell(tf) - track_top - cmdlen);	    if(sp == 0)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "Misplaced loop end (ch=%d)", ch);	    else if(sp > MAX_STACK_DEPTH)		sp--;		/* through deeply loop */	    else	    {		int top;		top = sp - 1;		if(same_measure == top)		{		    sp = same_measure;		    tf_seek(tf, stack[sp].loop_start, SEEK_SET);		    same_measure = -1;		    goto break_loop_end;		}		if((!gfmt && step == 0xff) || (gfmt && step == 0xffff))		{		    sp = top;		    goto break_loop_end;		}		if(stack[top].count >= step)		    sp = top;#ifdef RCP_LOOP_CONT_LIMIT		else if(stack[top].count >= RCP_LOOP_CONT_LIMIT)		{		    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			      "Loop limit exceeded (ch=%d)", ch);		    sp = top;		}#endif /* RCP_LOOP_CONT_LIMIT */#ifdef RCP_LOOP_TIME_LIMIT		else if((current_tempo / 1000000.0) *			(ntr_at(ntr) - stack[top].start_at)			/ current_file_info->divisions			> RCP_LOOP_TIME_LIMIT)		{		    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			      "Loop time exceeded (ch=%d)", ch);		    sp = top;		}#endif /* RCP_LOOP_TIME_LIMIT */		else		{		    stack[top].count++;		    ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			      "Jump to %d (cnt=%d)",			      stack[top].loop_start - track_top,			      stack[top].count);		    tf_seek(tf, stack[top].loop_start, SEEK_SET);		}	    }	  break_loop_end:	    break;	  case 0xf9:	/* loop start */#if 1	    if(!gfmt && step == 0xff) /* ##?? */		continue;#endif	    if(ctl->verbosity >= VERB_DEBUG_SILLY)		ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			  "Loop start at %d",			  tf_tell(tf) - track_top - cmdlen);	    if(sp >= MAX_STACK_DEPTH)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "Too deeply nested %d (ch=%d, Ignored this loop)",			  ch, sp);	    else	    {		stack[sp].start_at = ntr_at(ntr);		stack[sp].loop_start = tf_tell(tf);		stack[sp].count = 1;	    }	    sp++;	    break;	  case 0xfc:	/* same measure */	    if(ctl->verbosity >= VERB_DEBUG_SILLY)		ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			  "Same measure at %d",			  tf_tell(tf) - track_top - cmdlen);	    if(sp >= MAX_STACK_DEPTH)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "Too deeply nested %d (ch=%d)", sp, ch);	    else	    {		long jmp, nextflag;		if(same_measure >= 0)		{		    sp = same_measure;		    tf_seek(tf, stack[sp].loop_start, SEEK_SET);		    same_measure = -1;		    goto break_same_measure;		}		nextflag = 0;	      next_same_measure:		if(!gfmt)		{		    jmp = (long)a | ((long)b << 8);		    if(jmp & 0x03) /* ##?? */		    {			/* What do these two bits mean? */			/* Clear them here. */			ctl->cmsg(CMSG_WARNING, VERB_DEBUG,				  "Jump %d is changed to %d",				  jmp, jmp & ~3);			jmp &= ~3;		/* jmp=(jmp/4)*4 */		    }		}		else		{#if 0		    if(b != 0)		    {			/* ##?? */		    }#endif		    jmp = gate;		    if(current_file_info->file_type == IS_G36_FILE)			jmp = jmp * 6 - 242;		    else			jmp -= (jmp + 2) % 6; /* (jmp+2)%6==0 */		}		if(jmp < data_top - track_top ||		   jmp >= last_point - track_top)		{		    ctl->cmsg(CMSG_WARNING, VERB_NOISY,			      "RCP Invalid same measure: %d (ch=%d)", jmp, ch);		    break;		}		if(nextflag == 0)		{		    stack[sp].start_at = ntr_at(ntr);		    stack[sp].loop_start = tf_tell(tf);		    same_measure = sp;		    sp++;		}		ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY, "Jump to %d", jmp);		tf_seek(tf, track_top + jmp, SEEK_SET);		if(tf_getc(tf) == 0xfc)		{		    nextflag = 1;		    if(!gfmt)		    {			tf_getc(tf); /* step */			a = tf_getc(tf);			b = tf_getc(tf);		    }		    else		    {			b = tf_getc(tf);			tf_getc(tf); /* st1 */			tf_getc(tf); /* st2 */			a = gt1 = tf_getc(tf);			gate = gt1 + (gt2 << 8);		    }		    goto next_same_measure;		}		tf_seek(tf, -1, SEEK_CUR);	    }	  break_same_measure:	    break;	  case 0xfd:	/* measure end */	    if(same_measure >= 0)	    {		sp = same_measure;		tf_seek(tf, stack[sp].loop_start, SEEK_SET);		same_measure = -1;	    }	    break;	  case 0xfe:	/* end of track */	    goto end_of_track;	  case 0xc0:	/* DX7 function */	  case 0xc1:	/* DX parameter */	  case 0xc2:	/* DX RERF */	  case 0xc3:	/* TX function */	  case 0xc5:	/* FB-01 P parameter */	  case 0xc6:	/* FB-01 S System */	  case 0xc7:	/* TX81Z V VCED */	  case 0xc8:	/* TX81Z A ACED */	  case 0xc9:	/* TX81Z P PCED */	  case 0xca:	/* TX81Z S System */	  case 0xcb:	/* TX81Z E EFFECT */	  case 0xcc:	/* DX7-2 R REMOTE SW */	  case 0xcd:	/* DX7-2 A ACED */	  case 0xce:	/* DX7-2 P PCED */	  case 0xcf:	/* TX802 P PCED */	  case 0xdc:	/* MKS-7 */	    if(!gfmt)		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "RCP %s is not unsupported: "			  "0x%02x 0x%02x 0x%02x 0x%02x (ch=%d)",			  rcp_cmd_name(cmd), cmd, step, a, b, ch);	    else		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "RCP %s is not unsupported: "			  "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x (ch=%d)",			  rcp_cmd_name(cmd), cmd, b, st1, st2, gt1, gt2, ch);	    ntr_incr(&ntr, step);	    break;	  default:	    if(!gfmt)	    {		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "RCP Unknown Command: 0x%02x 0x%02x 0x%02x 0x%02x "			  "(ch=%d)",			  cmd, step, a, b, ch);		/* ##?? */		if(cmd == 0xe9 && step == 0xf0 && a == 0xe0 && b == 0x80)		{		    ctl->cmsg(CMSG_ERROR, VERB_VERBOSE,			      "RCP e9 f0 e0 80 is end of track ??");		    goto end_of_track;		}	    }	    else		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,			  "RCP Unknown Command: "			  "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x (ch=%d)",			  cmd, b, st1, st2, gt1, gt2, ch);#if 0	    ntr_incr(&ntr, step);#endif	    break;	}    }  end_of_track:    /* All note off */    ntr_wait_all_off(&ntr);    ntr_end(&ntr);    tf_seek(tf, last_point, SEEK_SET);    return ret;}static void ntr_init(struct RCPNoteTracer *ntr, int gfmt, int32 at){    memset(ntr, 0, sizeof(*ntr));    init_mblock(&ntr->pool);    ntr->gfmt = gfmt;    ntr->at = at;    ntr->tempo_grade = 0;}static void ntr_end(struct RCPNoteTracer *ntr){    reuse_mblock(&ntr->pool);}static void ntr_add(struct RCPNoteTracer *ntr, int ch, int note, int gate){    struct NoteList *p;    if(ntr->freelist)    {	p = ntr->freelist;	ntr->freelist = ntr->freelist->next;    }    else	p = (struct NoteList *)new_segment(&ntr->pool,					   sizeof(struct NoteList));    p->gate = gate;    p->ch = ch;    p->note = note;    p->next = ntr->notes;    ntr->notes = p;}static void ntr_note_on(struct RCPNoteTracer *ntr,			int ch, int note, int velo, int gate){    struct NoteList *p;    for(p = ntr->notes; p != NULL; p = p->next)	if(p->ch == ch && p->note == note)	{	    p->gate = gate;	    return;	}    MIDIEVENT(ntr->at, ME_NOTEON, ch, note, velo);    ntr_add(ntr, ch, note, gate);}static void rcp_tempo_gradate(struct RCPNoteTracer *ntr, int step){    int tempo_grade, tempo_step, tempo, diff, sign, at;        if (step <= 0 || (tempo_grade = ntr->tempo_grade) == 0)    	return;    tempo_step = ntr->tempo_step - step;    if (tempo_step <= 0)    {	tempo = ntr->tempo;	diff = ntr->tempo_to - tempo;	sign = (diff < 0) ? -1 : 1;	diff *= sign;	/* abs(diff) */	at = ntr_at(*ntr);	while (tempo_step <= 0 && diff != 0)	{	    if (tempo_grade > diff)		tempo_grade = diff;	    tempo += sign * tempo_grade;	    diff -= tempo_grade;	    rcp_tempo_set(at, tempo);	    at += TEMPO_GRADATION_SKIP;	    tempo_step += TEMPO_GRADATION_SKIP;	}	ntr->tempo = tempo;	if (diff == 0)	    ntr->tempo_grade = 0;    }    ntr->tempo_step = tempo_step;}static void ntr_incr(struct RCPNoteTracer *ntr, int step){    if(step < 0) {	struct NoteList *p;	ntr->at += step;	for(p = ntr->notes; p != NULL; p = p->next)	    p->gate -= step;	return;    }    rcp_tempo_gradate(ntr, step);    while(step >= 0)    {	int32 mingate;	struct NoteList *p, *q;	if(ntr->notes == NULL)	{	    ntr->at += step;	    return;	}	q = NULL;	p = ntr->notes;	mingate = step;	while(p)	{	    struct NoteList *next;	    next = p->next;	    if(p->gate == 0)	    {		if(ctl->verbosity >= VERB_DEBUG_SILLY)		    ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			      "NoteOff %d at %d", p->note, ntr->at);		MIDIEVENT(ntr->at, ME_NOTEOFF, p->ch, p->note, 0);		p->next = ntr->freelist;		ntr->freelist = p;	    }	    else	    {		if(mingate > p->gate)		    mingate = p->gate;		p->next = q;		q = p;	    }	    p = next;	}	ntr->notes = q; 	if(step == 0)	    return;	step -= mingate;	ntr->at += mingate;	for(p = ntr->notes; p != NULL; p = p->next)	    p->gate -= mingate;    }}static void ntr_wait_all_off(struct RCPNoteTracer *ntr){    while(ntr->notes)    {	int32 mingate;	struct NoteList *p, *q;	mingate = 256;	q = NULL;	p = ntr->notes;	while(p)	{	    struct NoteList *next;	    next = p->next;	    if(p->gate == 0)	    {		if(ctl->verbosity >= VERB_DEBUG_SILLY)		    ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,			      "NoteOff %d", p->note);		MIDIEVENT(ntr->at, ME_NOTEOFF, p->ch, p->note, 0);		p->next = ntr->freelist;		ntr->freelist = p;	    }	    else	    {		if(mingate > p->gate)		    mingate = p->gate;		p->next = q;		q = p;	    }	    p = next;	}	ntr->notes = q;	for(p = ntr->notes; p != NULL; p = p->next)	    p->gate -= mingate;	rcp_tempo_gradate(ntr, mingate);	ntr->at += mingate;    }}static int preprocess_sysex(uint8 *ex, int ch, int gt, int vel){    uint8 cs = 0;		/* check sum */    int len = 0;    int i;    for(i = 0; i < MAX_EXCLUSIVE_LENGTH && ex[i] != 0xf7; i++)    {	switch(ex[i])	{	  case 0x80: /* gt */	    cs += ex[len++] = gt;	    break;	  case 0x81: /* ve */	    cs += ex[len++] = vel;	    break;	  case 0x82: /* ch */	    cs += ex[len++] = ch;	    break;	  case 0x83: /* (Clear Sum) */#if 0	    if(ex[0] == 0x41 && len == 3 &&	       ex[len - 2] == 0x10 && ex[len - 1] == 0x12) /* ##?? */	    {		ex[len - 1] = 0x42;		ex[len++] = 0x12;	    }#endif	    cs = 0;	    break;	  case 0x84: /* (Send Sum) */	    ex[len++] = 128 - (cs & 0x7f);	    break;	  default:	    cs += ex[len++] = ex[i];	    break;	}    }    ex[len++] = 0xf7;    return len;}

⌨️ 快捷键说明

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