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

📄 seqmread.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
字号:
/* * seqmread.c *  * Convert a MIDI file to a seq. *//* Copyright 1989 Carnegie Mellon University *//******************************************************************************       Change Log*       Date    | who : Change*-----------+-----------------------------------------------------------------* 17-Feb-92 | GWL : only one stdio.h*                 : fix to satisfy compiler:                    void returns, time_type giotime(), int filegetc()*****************************************************************************/#include "switches.h"#include "stdio.h"#include "cext.h"#include "cmdline.h"#include "midifns.h" /* to get time_type */#include "timebase.h"#include "moxc.h"    /* to get debug declared */#include "seq.h"#include "seqread.h" 	/* to get scale */#include "seqmread.h"#include "userio.h"#include "ctype.h"#include "midifile.h"#include "tempomap.h"int filegetc();void initfuncs();void prtime();void snding_free();typedef struct snding_struct {    struct snding_struct *next;    event_type event_ptr;    int pitch;    int channel;} snding_node, *snding_type;#define snding_alloc() (snding_type) memget(sizeof(snding_node))#define snding_free(s) memfree(s, sizeof(snding_node))snding_type snding_list = NULL;tempomap_type the_tempomap;event_type initial_clock;       /* remember the first clock event */long prev_ticksize;             /* remember the previous ticksize */int sysex_id = 0;void smf_noteoff();void smf_error();void smf_header();void smf_trackstart();void smf_trackend();void smf_noteon();void smf_pressure();void smf_parameter();void smf_pitchbend();void smf_program();void smf_chanpressure();void smf_sysex();void smf_metamisc();void smf_metaseq();void smf_metaeot();void smf_timesig();void smf_smpte();void smf_tempo();void smf_keysig();void smf_metaspecial();void smf_metatext();void smf_arbitrary();private seq_type the_score;static FILE *F;int filegetc(){/*      int temp = getc(F);        printf(" %x ", temp);*/        return(int)(getc(F));}void seq_read_smf(seq, fp)  seq_type seq;  FILE *fp;{    F = fp;    initfuncs();    sysex_id = 0;       /* sysex in seq has to correspond to a symbol */    the_score = seq;    /* current sequence is a global within this module */    if (!seq) return;    the_tempomap = tempomap_create();    /* insert an initial clock to correspond to the default midifile tempo       (tempomap_create creates a corresponding initial entry in the tempomap)       (see smf_tempo for explanation of the scale() call)     */    initial_clock = insert_clock(the_score, 0L, 0, 500L << 16);                  /*   scale(24 * 500000, 1 << 16, 24000) */    if (!the_tempomap) return;    Mf_getc = filegetc;    midifile();    /* fmac_close(F); -- do not close the file because the caller might try to      * close it (in fact XLISP insists on closing it as a side effect of     * garbage collection.     */    gprintf(TRANS, "\nLoaded Midi file with %ld note(s), %ld ctrl(s).\n\n",        seq_notecount(seq), seq_ctrlcount(seq));    seq_reset(seq);    while (snding_list) {        snding_type snding = snding_list;        snding_list = snding_list->next;        gprintf(TRANS, "Note-on (key %d, chan %d) has no matching noteoff\n",                snding->pitch, snding->channel + 1);        snding_free(snding);    }    tempomap_free(the_tempomap);}/* gio_time -- get the time in millisec for Adagio *//* * Since Adagio times are (in their precise form) 1/256 ms, we want * a similar time for midifiles, whose natural unit would be microseconds. * We'll shift the microsecond time by 2 to get 1/250 ms = 4 us units * and convert using the scale function when necessary. * Real time is the time of the last tempo change (last_tempo_time) * which is in 4us units + elapsed time.   * Elapsed time is the elapsed beats times the beat duration. * Elapsed beats is Mf_currtime - last_tempo_beat. * Beat duration is the specified tempo / division, where specified tempo *  is in microseconds, and division is parts per quarternote. */unsigned long divisions = 24L;time_type gio_time(){    return (tempomap_lookup(the_tempomap, Mf_currtime) + 125L) / 250L;}void smf_header(format,ntrks,division){/*      gprintf(TRANS, "Header format=%d ntrks=%d division=%d\n",                format,ntrks,division); */        if (format > 1) gprintf(TRANS,                           "Warning: format %d midi file may not work.\n",                          format);        divisions = division;        /* adjust the initial tempochange */        the_tempomap->entries->tempo = 500000L / division;}void smf_trackstart(){/*      gprintf(TRANS, "Track start\n"); */}void smf_trackend(){/*      gprintf(TRANS, "Track end\n"); */}void smf_noteon(chan,pitch,vol){        snding_type snding;        if (vol == 0) {  /* convert to a noteoff */            smf_noteoff(chan, pitch, 0);            return;        }/*      prtime();        gprintf(TRANS, "Note on, chan=%d pitch=%d vol=%d\n",chan+1,pitch,vol);*/        /* get ready to remember the sounding note */        snding = snding_alloc();        snding->next = snding_list;        snding_list = snding;        /* enter an event into score and remember it */        snding->event_ptr = insert_note(the_score, gio_time(), 0,                                         chan + 1, pitch, 0L, vol);        snding->pitch = pitch;        snding->channel = chan;}void smf_noteoff(chan,pitch,vol){        snding_type *snding_ptr;        register snding_type snding;/*      prtime();        gprintf(TRANS, "Note off, chan=%d pitch=%d vol=%d\n",chan+1,pitch,vol);*/      /* search for the snding record */        for (snding_ptr = &snding_list;                (snding = *snding_ptr) &&                   ((snding->pitch != pitch) || (snding->channel != chan));               snding_ptr = &(snding->next)) /* printf("* search *\n") */;        if (!snding) {            gprintf(TRANS, "Note off %d, channel %d ignored: no note on\n",                        pitch, chan + 1);        } else {                event_type event = snding->event_ptr;            event->u.note.ndur += (gio_time() - event->ntime) << 8;            /* free the snding record */            *snding_ptr = snding->next;            snding_free(snding);        }}void smf_pressure(chan,pitch,press){        prtime();        gprintf(TRANS, "Pressure, chan=%d pitch=%d press=%d (IGNORED)\n",                chan + 1, pitch, press);}void smf_parameter(chan,control,value){        int ctrl = 0;/*      prtime();        gprintf(TRANS, "Parameter, chan=%d c1=%d c2=%d\n",chan+1,control,value); */     /* see if the control is one of the standard Adagio controls that           can be encoded in a special way.  If not, ctrl remains at zero.         */        switch (control) {          case PORTASWITCH: ctrl = PSWITCH_CTRL; break;          case MODWHEEL: ctrl = MODWHEEL_CTRL; break;          case VOLUME: ctrl = VOLUME_CTRL; break;        }        if (ctrl) /* then do special ctrl insert and save storage */            insert_ctrl(the_score, gio_time(), 0, ctrl, chan + 1, value);        else insert_macctrl(the_score, gio_time(), 0, control, chan + 1, value);}       /* smf_pitchbend -- handle a pitch bend event *//* * NOTE: the midifile code from Tim Thompson has the msb and lsb bytes swapped. *   Thus the parameter msb is really the low order byte and lsb is high order. */void smf_pitchbend(chan,msb,lsb){/*      prtime();        gprintf(TRANS, "Pitchbend, chan=%d msb=%d lsb=%d\n",chan+1,msb,lsb); */        insert_ctrl(the_score, gio_time(), 0, BEND_CTRL, chan + 1,                    ((lsb << 7) + msb) >> 6);}void smf_program(chan,program){/*      prtime();        gprintf(TRANS, "Program, chan=%d program=%d\n",chan+1,program); */        insert_ctrl(the_score, gio_time(), 0, PROGRAM_CTRL, chan + 1, program);}void smf_chanpressure(chan,press){/*      prtime();        gprintf(TRANS, "Channel pressure, chan=%d pressure=%d\n",chan+1,press); */        insert_ctrl(the_score, gio_time(), 0, TOUCH_CTRL, chan + 1, press);}void smf_sysex(leng,mess)int leng;char *mess;{        char symb[10];        def_type defn;        int i;        sprintf(symb, "X%d", sysex_id++);        if (leng > 255) {            gprintf(TRANS, "sysex too long (%d bytes), ignored\n", leng - 2);            return;        }        /* need to end up with a prefix of [0][length], so add 2 to length;           note that this will copy past the end of the message -- this is           slightly dangerous and definitely crufty:          */        defn = insert_def(the_score, symb, (unsigned char *) mess, leng + 2);        /* now fix up the definition by inserting the prefix bytes: */        for (i = leng + 1; i > 1; i--)             defn->definition[i] = defn->definition[i - 2];        defn->definition[0] = 0;        defn->definition[1] = leng;        insert_macro(the_score, gio_time(), 0, defn, 1, 0, NULL);/*      prtime();        gprintf(TRANS, "Sysex, leng=%d (IGNORED)\n",leng); */}void smf_metamisc(type,leng,mess)char *mess;{        prtime();        gprintf(TRANS,                "Meta event, unrecognized, type=0x%02x leng=%d (IGNORED)\n",                type, leng);}void smf_metaspecial(type,leng,mess)char *mess;{        prtime();        gprintf(TRANS,         "Meta event, sequencer-specific, type=0x%02x leng=%d (IGNORED)\n",                type, leng);}void smf_metatext(type,leng,mess)char *mess;{        static char *ttype[] = {                NULL,                "Text Event",           /* type=0x01 */                "Copyright Notice",     /* type=0x02 */                "Sequence/Track Name",                "Instrument Name",      /* ...       */                "Lyric",                "Marker",                "Cue Point",            /* type=0x07 */                "Unrecognized"        };        int unrecognized = (sizeof(ttype)/sizeof(char *)) - 1;        if ( type < 1 || type > unrecognized )                type = unrecognized;}void smf_metaseq(num){        prtime();        gprintf(TRANS, "Meta event, sequence number = %d (IGNORED)\n",num);}void smf_metaeot(){/*      prtime();        gprintf(TRANS, "Meta event, end of track\n"); */}void smf_keysig(sf,mi){/*      prtime();        gprintf(TRANS, "Key signature, sharp/flats=%d  minor=%d\n",sf,mi); */}/* smf_tempo -- handle a midifile tempo change *//* * NOTE: if divisions is positive, it gives time units per quarter, and * tempo is microsec per division.  The product is microsec per quarter. * To convert to ticksize (parameter to insert_clock), we divide by 24*1000 * to get units of millisec and 24ths of quarter notes.  insert_clock * expects this to have a 16 bit fractional part. */void smf_tempo(tempo)long tempo;{        time_type ctime = gio_time();        long ticksize = scale(tempo, 1024L, 375L);/*      (tempo / 24000) << 16;   microsec/clock converted to ms/quarter, shifted 16*//*      prtime();        gprintf(TRANS, "Tempo, microseconds-per-MIDI-quarter-note = %ld\n",tempo);*/         tempomap_insert(the_tempomap, Mf_currtime, tempo / divisions);        if (ctime == 0) {            /* we already have a clock event at t=0 -> fix it */            initial_clock->u.clock.ticksize = ticksize;        } else { /* we need a new one */            /* NOTE: after the first clock, insert clock events 1/2 tick early                to make sure ticksize is set before clock_tick() wakes up and                reads it.             */            insert_clock(the_score, ctime - (prev_ticksize >> 17), 0, ticksize);            prev_ticksize = ticksize;        }}void smf_timesig(nn,dd,cc,bb){/*      int denom = 1;        while ( dd-- > 0 )                denom *= 2;        prtime();        gprintf(TRANS, "Time signature=%d/%d  MIDI-clocks/click=%d  32nd-notes/24-MIDI-clocks=%d\n",                nn,denom,cc,bb); */}void smf_smpte(hr,mn,se,fr,ff){        prtime();        gprintf(TRANS,    "SMPTE, hour=%d minute=%d second=%d frame=%d fract-frame=%d (IGNORED)\n",                hr, mn, se, fr, ff);}void smf_arbitrary(leng,mess)char *mess;{        prtime();        gprintf(TRANS, "Arbitrary bytes, leng=%d (IGNORED)\n",leng);}void smf_error(msg)  char *msg;{    gprintf(ERROR, msg);}void prtime(){        gprintf(TRANS, "Time=%ld/%ld ",Mf_currtime, gio_time());}void initfuncs(){        Mf_error = smf_error;        Mf_header =  smf_header;        Mf_starttrack =  smf_trackstart;        Mf_endtrack =  smf_trackend;        Mf_on =  smf_noteon;        Mf_off =  smf_noteoff;        Mf_pressure =  smf_pressure;        Mf_controller =  smf_parameter;        Mf_pitchbend =  smf_pitchbend;        Mf_program =  smf_program;        Mf_chanpressure =  smf_chanpressure;        Mf_sysex =  smf_sysex;        Mf_metamisc =  smf_metamisc;        Mf_seqnum =  smf_metaseq;        Mf_eot =  smf_metaeot;        Mf_timesig =  smf_timesig;        Mf_smpte =  smf_smpte;        Mf_tempo =  smf_tempo;        Mf_keysig =  smf_keysig;        Mf_sqspecific =  smf_metaspecial;        Mf_text =  smf_metatext;        Mf_arbitrary =  smf_arbitrary;}

⌨️ 快捷键说明

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