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

📄 seqmwrite.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
/* created by DMH (damonhorowitz): write seq_type as standard midifile *//****************************************************************************      Change Log*  Date     | Change*-----------+---------------------------------------------------------------* 11-Mar-94 | Created Change Log* 11-Mar-94 | PLu : Added private to function defs.* 28-Apr-03 |  DM : Change #include's for portability****************************************************************************/#include "switches.h"#include <stdio.h>#include "cext.h"#include "userio.h"#include "midicode.h"#include "mfmidi.h"#include "midifns.h"#include "timebase.h"#include "moxc.h"#include "seq.h"#include "seqread.h" /* to get scale() */#include "seqmwrite.h"long chunk_size_marker;int seti_counter;extern time_type a_start_time;long last_event;                        /*time from last_clock_event to the last event*/time_type last_clock_event;time_type last_tick_size;       /* millisec per tick shifted 16 bits */struct smf_write_seq {    seq_type seq;    int track;    FILE *outfile;    } smfw_seq;extern seq_type sequence; /* this is a global to be accessed by                * routines called from the sequence *//* clock state: */extern time_type clock_ticksize;  /* millisec per tick shifted 16 bits */extern boolean clock_running;     /* TRUE if clock is running */extern boolean use_midi_clock;private void smfw_bend();private void smfw_cause_noteoff();private void smfw_ctrl();private void smfw_deltatime();private void smfw_dotrack();private void smfw_exclusive();private void smfw_noteoff();private void smfw_noteon();private void smfw_process_event();private void smfw_ramp_event(seq_type seq, event_type event,     unsigned int value, unsigned int to_value, int increment,    time_type step, int n);private void smfw_send_macro();private void smfw_touch(seq_type seq, int voice, int value);private void writevarlen();/* smfw_bend -- write a pitch bend to a midi file *//**/private void smfw_bend(seq_type seq, int voice, int value){    if(debug)   gprintf(TRANS, "smfw_bend %d\n", value);    smfw_deltatime();    putc(MIDI_BEND | (voice - 1), smfw_seq.outfile);    putc(0xFF & ((value & 0x1) << 6) , smfw_seq.outfile);    putc(0xFF & (value >> 1), smfw_seq.outfile);}/* smfw_cause_noteoff -- schedule a noteoff for midi file *//* * NOTE: this is called by smfw_process_event when it handles a note * event node in a seq_type's event list.  The ordinary moxc scheduler * is used to "schedule" the noteoff in the future.  In reality, the * output is done as fast as possible (by attempting an infinite rate), * so no real timing delays occur.  The effect is to sort events by their * specified time. */private void smfw_cause_noteoff(seq, delay, voice, pitch)  seq_type seq;  time_type delay;  int voice;  int pitch;{    if(debug)       gprintf(TRANS, "cause noteoff at %ld...", virttime + delay);    pitch += seq->transpose;    while (pitch <= 0) pitch += 12;    while (pitch >= 127) pitch -= 12;    seq->noteoff_count++;    causepri((delay_type) delay, 10, seq->noteoff_fn,         seq, voice, pitch);    }private void smfw_clock_event(old_ticksize, new_ticksize)  time_type old_ticksize, new_ticksize;{    time_type temp_ticksize = new_ticksize;    new_ticksize = scale(new_ticksize, 375L, 1024L);/* (new_ticksize >> 16) * 24000 ms/clock becomes us/midiquarter */    if(debug)       gprintf(TRANS, "smfw_clock: write %ld (time:%ld) ->->->tempo %ld\n",         new_ticksize, virttime, 2500L / (new_ticksize / 24000));    /*use old ticksize to write the delta for the clock event*/    last_tick_size = old_ticksize;    smfw_deltatime();    last_tick_size = temp_ticksize;/* reset to = new_tick_size */       putc(0xFF, smfw_seq.outfile);    putc(0x51, smfw_seq.outfile);    putc(0x03, smfw_seq.outfile);    putc((int) ((new_ticksize >> 16) & 0xFF), smfw_seq.outfile);    putc((int) ((new_ticksize >> 8) & 0xFF), smfw_seq.outfile);    putc((int) (new_ticksize & 0xFF), smfw_seq.outfile);    last_clock_event = virttime;    last_event = 0L;        /*no time expired between last clockevent and last event(they are the same).*/        /*next clock event will be exactly the next this_event from last_clock_event*/}/* smfw_ctrl -- write a control change to a midi file *//**/private void smfw_ctrl(seq_type seq, int voice, int ctrl_name, int value){    if(debug)   gprintf(TRANS, "smfw_ctrl %d: %d\n", ctrl_name, value);     smfw_deltatime();    putc(MIDI_CTRL | (voice - 1), smfw_seq.outfile);    putc(ctrl_name, smfw_seq.outfile);    putc(value, smfw_seq.outfile);}/* smfw_deltatime -- write the time difference between now an previous event *//**/private void smfw_deltatime(){    /* if last_ and clock_ are different, use last_ for clock deltatime*/    time_type use_ticksize = (clock_ticksize != last_tick_size) ?                last_tick_size : clock_ticksize;    time_type this_event = virttime - last_clock_event;    if(debug)   gprintf(TRANS, "delta! ticksize: %lu Lastev: %ld ThisevScaled: %lu Thisev: %lu ",         clock_ticksize, last_event,  (this_event * ((2500L << 16) / use_ticksize)) / 100,         this_event);        this_event = ((virttime - last_clock_event) * ((2500L << 16) / use_ticksize)) / 100;    if(debug)   gprintf(TRANS, "--- deltatime: %lu\n", this_event - last_event);            writevarlen((long) (this_event - last_event));    last_event = this_event; }/* smfw_dotrack -- write the remainder of a track  */private void smfw_dotrack(seq)  seq_type seq;{    long end_marker;    timebase_type old_timebase = timebase;    unsigned long chunk_size;    if (seq->runflag) {        if ((seq->timebase->virt_base == 0) &&          (seq->timebase->rate == STOPRATE))           /*we just set these last time through... do nothing*/;        seq_stop(seq);    }    timebase_use(seq->timebase);    set_rate(seq->timebase, STOPRATE);    set_virttime(seq->timebase, 0L);    seq->current = seq_events(seq);    seq->noteoff_count = 0L;    seq->runflag = TRUE;    seq->paused = TRUE;    last_clock_event = 0L;    last_event = 0L;    if(debug)   gprintf(TRANS, "dotrack (reset) %d %ld (%lu) \n",         smfw_seq.track, last_event, virttime);    if (seq->current)       cause((delay_type)(seq->current->ntime - virttime), smfw_process_event,         seq);    set_virttime(timebase, MAXTIME);    catchup();    putc(0x00, smfw_seq.outfile);    putc(0xFF, smfw_seq.outfile);/*end of track chunk*/    putc(0x2F, smfw_seq.outfile);    putc(0x00, smfw_seq.outfile);    end_marker = ftell(smfw_seq.outfile);    fseek(smfw_seq.outfile, chunk_size_marker, 0);/*go back to enter chunksize*/    chunk_size = (end_marker - chunk_size_marker) - 4;/* - 4 for 4 size bytes*/     if(debug)   gprintf(TRANS, "bytes written in previous track: %ld \n\n", chunk_size);    putc((int) ((0xFF & (chunk_size >> 24))), smfw_seq.outfile);    putc((int) ((0xFF & (chunk_size >> 16))), smfw_seq.outfile);    putc((int) ((0xFF & (chunk_size >> 8))), smfw_seq.outfile);    putc((int) ((0xFF & chunk_size)), smfw_seq.outfile);    fseek(smfw_seq.outfile, end_marker, 0);/*return file pointer to end of track*/    timebase_use(old_timebase);}/* smfw_exclusive -- write a system excl. msg to midi file */private void smfw_exclusive(length, msg)int length;unsigned char *msg; {    int length_count = 0;    if(debug)   gprintf(TRANS, "SYSEX (time:%ld)\n", virttime);    smfw_deltatime();       while (length > length_count){ /* *(msg-1) != MIDI_EOX) { */        putc(*msg++, smfw_seq.outfile);         length_count++;    }    if(*(--msg) != MIDI_EOX) gprintf(TRANS, "ERROR: no end of sysex\n");}private void smfw_msg_write(n,c1,c2,c3)  int n;  unsigned char c1,c2,c3;{    if(debug)   gprintf(TRANS, "MSGWRITE %d bytes (time:%ld)\n", n, virttime);    smfw_deltatime();    switch(n) {    case 1: putc(c1, smfw_seq.outfile);        break;    case 2: putc(c1, smfw_seq.outfile);        putc(c2, smfw_seq.outfile);        break;    case 3: putc(c1, smfw_seq.outfile);        putc(c2, smfw_seq.outfile);        putc(c3, smfw_seq.outfile);        break;    }}/* smfw_noteoff -- write noteoff to midi file *//**/private void smfw_noteoff(seq_type seq, int voice, int pitch){    if(debug)       gprintf(TRANS, "smfw_noteoff %d: %d (time:%ld)\n", voice, pitch, virttime);    smfw_deltatime();    putc(NOTEOFF | (voice - 1), smfw_seq.outfile);    putc(pitch, smfw_seq.outfile);    putc(0x40, smfw_seq.outfile);} /* smfw_noteon -- write noteon to midi file *//* * NOTE: the seq parameter is not used here, but is passed in by the * seq_noteon macro, so we have to have a placeholder for it. */private void smfw_noteon(seq, voice, pitch, vel)  seq_type seq;  int voice, pitch, vel;{    if(debug)   gprintf(TRANS, "smfw_noteon %d: %d %d(time:%ld)\n", voice, pitch, vel, virttime);    smfw_deltatime();    putc(NOTEON | (voice - 1), smfw_seq.outfile);    putc(pitch, smfw_seq.outfile);    putc(vel, smfw_seq.outfile);}/* smfw_process_event -- write a seq event to a midi file *//**/private void smfw_process_event(seq)  seq_type seq;{    register event_type event;    if (!seq->runflag) return;    while ((event = seq->current) && (event->ntime <= virttime)) {    unsigned int voice;    if ((vc_voice(event->nvoice) == smfw_seq.track) ||       /*if on current track*/        (((vc_voice(event->nvoice) - 16) == smfw_seq.track)             && (smfw_seq.track > 0)) ||        /* acknowledge clock change on all tracks*/        (event->value == CLOCK_VALUE)) {        /* process all current (and earlier) events */        if (is_note(event)) {   /*** play a note or rest ***/        /* if this note is not a rest, play it and schedule an off event */        if (event->value != NO_PITCH &&              (seq_channel_mask(seq) &               (1 << ((voice = vc_voice(event->nvoice)) - 1)))) {            seq_noteon(seq, voice, (0xFF & event->value),             (int) (event->u.note.ndur & 0xFF));                    seq_cause_noteoff(seq, (event->u.note.ndur) >> 8,               voice, (0xFF & event->value));         }        } else {                    /*** send a control command ***/        int n;        time_type step;        int delta;        int increment;        int voice = vc_voice(event->nvoice);        ulong enabled = seq_channel_mask(seq) & (1 << (voice - 1));        switch (vc_ctrl(event->nvoice)) {          case PSWITCH_CTRL:            if (!enabled) break;            if(debug)    gprintf(TRANS, "porta %d (time:%ld)... ", event->value, virttime);            seq_midi_ctrl(seq, voice, PORTASWITCH, 0xFF & event->value);            break;          case MODWHEEL_CTRL:            if (!enabled) break;            if(debug)    gprintf(TRANS, "modw %d (time:%ld)...", event->value, virttime);            seq_midi_ctrl(seq, voice, MODWHEEL, 0xFF & event->value);            break;

⌨️ 快捷键说明

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