📄 rcp.c
字号:
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 + -