📄 seqmwrite.c
字号:
case TOUCH_CTRL: if (!enabled) break; if(debug) gprintf(TRANS, "touch %d (time:%ld)... ", event->value, virttime); seq_midi_touch(seq, voice, 0xFF & event->value); break; case VOLUME_CTRL: if (!enabled) break; if(debug) gprintf(TRANS, "ftvol %d (time:%ld)...", event->value, virttime); seq_midi_ctrl(seq, voice, VOLUME, 0xFF & event->value); break; case BEND_CTRL: if (!enabled) break; if(debug) gprintf(TRANS, "bend %d (time:%ld)... ", event->value, virttime); seq_midi_bend(seq, voice, event->value); break; case PROGRAM_CTRL: if (!enabled) break; if(debug) gprintf(TRANS, "prog %d (time:%ld)\n", event->value, virttime); smfw_deltatime(); putc(MIDI_CH_PROGRAM | (voice - 1), smfw_seq.outfile); putc(0xFF & event->value, smfw_seq.outfile); break; case ESC_CTRL: switch (event->value) { time_type this_event; case CALL_VALUE: /*called routine will write to midifile in execution */ sequence = seq; (*(event->u.call.routine))(event->u.call.args); break; case CLOCK_VALUE: clock_ticksize = event->u.clock.ticksize; if(debug) gprintf(TRANS, "clockevent! ticksize: %lu (time:%ld)\n", clock_ticksize, virttime); if (virttime > 0) { /* any clock before this is already recorded in the header */ if (smfw_seq.track == 0) { /* record clock event on tempo track = 0 */ /* cause clock write in half a newtick, because it was written .5 tick early*/ cause((delay_type) (clock_ticksize >> 17), smfw_clock_event, last_tick_size, clock_ticksize); last_tick_size = clock_ticksize; /*set new ticksize*/ } else { /*not on tempo track*/ this_event = ((virttime - last_clock_event) * ((2500L << 16) / last_tick_size)) / 100; if(debug) gprintf(TRANS, "track != 0: Lastev: %ld Thisev: %ld NewLast: %ld\n", last_event, this_event, this_event - last_event); last_event = 0L - (this_event - last_event); last_clock_event = virttime; /*last_event is negative, so will be ADDED to next this_event*/ last_tick_size = clock_ticksize; } } else if (debug) gprintf(TRANS, "IGNORED\n");/* if virttime <= 0 */ break; case MACCTRL_VALUE: if (!enabled) break; if (debug) gprintf(TRANS, "MACCTRL %d: %d (time:%ld)\n", event->u.macctrl.ctrl_number, event->u.macctrl.value, virttime); smfw_deltatime(); putc(MIDI_CTRL | (voice - 1), smfw_seq.outfile); putc(0xFF & event->u.macctrl.ctrl_number, smfw_seq.outfile); putc(0xFF & event->u.macctrl.value, smfw_seq.outfile); break; case MACRO_VALUE: if (!enabled) break; if (debug) gprintf(TRANS, "MACRO sent to...\n"); smfw_send_macro(event->u.macro.definition, voice, event->u.macro.parameter, -1, 0); break; case CTRLRAMP_VALUE: case DEFRAMP_VALUE: { int from, to; if (!enabled) break; step = event->u.ramp.step; if (event->value == CTRLRAMP_VALUE) { if(debug) gprintf(TRANS, "CTRLRAMP (time:%ld)...", virttime); from = event->u.ramp.u.ctrl.from_value; to = event->u.ramp.u.ctrl.to_value; } else { if (debug) gprintf(TRANS, "DEFRAMP (time:%ld)...", virttime); from = event->u.ramp.u.def.parameter[ event->u.ramp.u.def.parm_num]; to = event->u.ramp.u.def.to_value; } delta = to - from; increment = delta; if (delta < 0) delta = -delta; /* RBD - Note: Step is always non-zero */ n = event->u.ramp.dur / step; increment = (increment << 8) / n; smfw_ramp_event(seq, event, from << 8, to << 8, increment, step, n); seq->noteoff_count++; break; } case SETI_VALUE: seti_counter++; /*will be printed after writing is completed*/ *(event->u.seti.int_to_set) = event->u.seti.value; break; default: gprintf(TRANS, "unexpected ESC_CTRL value\n"); break; } break; default: gprintf(TRANS, "unexpected seq data\n"); break; } } } seq->current = event->next; } if (seq->current) { /* if there is an event: delay, and then process again */ cause((delay_type)(event->ntime - virttime), smfw_process_event, seq); }}/* smfw_ramp_event -- generate a ramp to write*/private void smfw_ramp_event(seq, event, value, to_value, increment, step, n) seq_type seq; register event_type event; unsigned int value; unsigned int to_value; int increment; time_type step; int n;{ if(debug) gprintf(TRANS, "ramp of %d: %d to %d\n", event->u.ramp.ctrl, value >> 8, to_value >> 8); if (seq->runflag) { int voice = vc_voice(event->nvoice); if (n == 0) value = to_value; else cause((delay_type)step, smfw_ramp_event, seq, event, value + increment, to_value, increment, step, n - 1); if (event->value == CTRLRAMP_VALUE) { int ctrl = event->u.ramp.ctrl; if (ctrl == -TOUCH_CTRL) smfw_touch(seq, voice, value >> 8); else if (ctrl == -BEND_CTRL) smfw_bend(seq, voice, value >> 8); else smfw_ctrl(seq, voice, ctrl, value >> 8); } else { /* must be DEFRAMP_VALUE */ smfw_send_macro(event->u.ramp.u.def.definition, vc_voice(event->nvoice), event->u.ramp.u.def.parameter, event->u.ramp.u.def.parm_num, value >> 8); } if (n == 0) seq_end_event(seq); }}/* smfw_send_macro -- write msg to midi file from a seq "macro" event *//**/private void smfw_send_macro(ptr, voice, parameter, parm_num, value) register unsigned char *ptr; int voice; short parameter[]; int parm_num; int value;{ register unsigned char code, *loc; while ((code = *ptr++)) { loc = ptr + *ptr; ptr++; if (code <= nmacroparms) { code--; *loc = (code == parm_num ? value : parameter[code]) & 0x7f; } else if (code == nmacroparms + 1) { *loc = ((voice - 1) & 0xF) | *loc; } else { code -= (nmacroparms + 2); *loc = ((code == parm_num ? value : parameter[code]) >> 7) & 0x7F; } } if (ptr[1] == MIDI_SYSEX) smfw_exclusive(*ptr, ptr + 1); else smfw_msg_write(*ptr, ptr[1], ptr[2], ptr[3]);}/* smfw_touch -- write aftertouch msg to midi file *//**/private void smfw_touch(seq_type seq, int voice, int value){ if(debug) gprintf(TRANS, "smfw_touch %d\n", value); smfw_deltatime(); putc(MIDI_TOUCH | (voice - 1), smfw_seq.outfile); putc(value, smfw_seq.outfile);}void seq_write_smf(seq, outfile) seq_type seq; FILE *outfile;{ time_type put_tick_size; int i; time_type starting_ticksize = 1638400L;/*default midifile tempo 100*/ int track_count = 0; long track_count_marker; register event_type event; seti_counter = 0; /*initialize the smfw_seq struct*/ smfw_seq.outfile = outfile; smfw_seq.seq = seq_copy(seq); smfw_seq.seq->cause_noteoff_fn = smfw_cause_noteoff; smfw_seq.seq->midi_bend_fn = smfw_bend; smfw_seq.seq->midi_ctrl_fn = smfw_ctrl; smfw_seq.seq->midi_touch_fn = smfw_touch; smfw_seq.seq->noteoff_fn = smfw_noteoff; smfw_seq.seq->noteon_fn = smfw_noteon; event = seq_events(smfw_seq.seq); /*search for clock events up till start of score*/ while(event->ntime <= 0){ if(debug) gprintf(TRANS, "event (time:%ld)\n", event->ntime); if(event->value == CLOCK_VALUE) { if(debug) gprintf(TRANS, "clock %lu at 0\n", event->u.clock.ticksize); starting_ticksize = event->u.clock.ticksize; break; } event = event->next; } putc(0x4D, smfw_seq.outfile); /*header: MThd*/ putc(0x54, smfw_seq.outfile); putc(0x68, smfw_seq.outfile); putc(0x64, smfw_seq.outfile); putc(0x00, smfw_seq.outfile); putc(0x00, smfw_seq.outfile); putc(0x00, smfw_seq.outfile); putc(0x06, smfw_seq.outfile); putc(0x00, smfw_seq.outfile); putc(0x01, smfw_seq.outfile); /*format 1 */ putc(0x00, smfw_seq.outfile); track_count_marker = ftell(smfw_seq.outfile); /*number of tracks will be written later*/ putc(0x00, smfw_seq.outfile); /*will be filled by track_count_marker*/ putc(0x02, smfw_seq.outfile);/*division resolution of 600*/ putc(0x58, smfw_seq.outfile); for(i = 0; i < 17; i++){/*for each track..*/ if(((seq_used_mask(smfw_seq.seq) >> (i - 1)) & 0x1) || (i == 0)){ if(debug) gprintf(TRANS, "write track %d \n", i); track_count++; clock_ticksize = starting_ticksize; last_tick_size = starting_ticksize; putc(0x4D, smfw_seq.outfile);/*track header: MTrk*/ putc(0x54, smfw_seq.outfile); putc(0x72, smfw_seq.outfile); putc(0x6B, smfw_seq.outfile); chunk_size_marker = ftell(smfw_seq.outfile);/*size of chunk will be written later*/ putc(0x00, smfw_seq.outfile); /*will be filled by chunk_size_marker*/ putc(0x00, smfw_seq.outfile); putc(0x00, smfw_seq.outfile); putc(0x00, smfw_seq.outfile); if(i == 0) { /*tempo and time signature track*/ putc(0x00, smfw_seq.outfile);/* default time sig stuff*/ putc(0xFF, smfw_seq.outfile); putc(0x58, smfw_seq.outfile); putc(0x04, smfw_seq.outfile); putc(0x04, smfw_seq.outfile); putc(0x02, smfw_seq.outfile); putc(0x18, smfw_seq.outfile); putc(0x08, smfw_seq.outfile); putc(0x00, smfw_seq.outfile); putc(0xFF, smfw_seq.outfile);/*TEMPO: inserted here in case default is used*/ putc(0x51, smfw_seq.outfile); putc(0x03, smfw_seq.outfile); put_tick_size = scale(clock_ticksize, 375L, 1024L); putc((int) ((put_tick_size >> 16) & 0xFF), smfw_seq.outfile); putc((int) ((put_tick_size >> 8) & 0xFF), smfw_seq.outfile); putc((int) (put_tick_size & 0xFF), smfw_seq.outfile); } smfw_seq.track = i; smfw_dotrack(smfw_seq.seq); } } if(seti_counter) gprintf(TRANS, "%d SETI events IGNORED!\n", seti_counter); seq_stop(smfw_seq.seq); fseek(smfw_seq.outfile, track_count_marker, 0);/*go back and insert number of tracks*/ putc(0xFF & track_count, smfw_seq.outfile); fclose(smfw_seq.outfile);}/* writevarlen -- write a variable length integer to midi file *//**/private void writevarlen(value) register long value;{ register ulong buffer; if(debug) gprintf(TRANS, "variable length quantity..."); buffer = value & 0x7f; while((value >>= 7) > 0) { buffer <<= 8; buffer |= 0x80; buffer += (value & 0x7f); } for(;;) { if(debug) gprintf(TRANS, " byte "); putc((int) (buffer & 0xFF), smfw_seq.outfile); if (buffer & 0x80) buffer >>= 8; else break; } if(debug) gprintf(TRANS, "written!\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -