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

📄 record.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
note_type last;    /* pointer to last valid data */long now;    /* the current time */{    i++;    /* advance to next item */    for (; event_buff + i < last; i++) {        note_type note = &(event_buff[i]);        int cmd = note->n[0] & MIDI_CODE_MASK;        if (istime(note)) {            now = note->when;        }         else if (((cmd == MIDI_ON_NOTE) &&            (note->n[2] != 0)) /* note on */ ||            (cmd == MIDI_CH_PROGRAM) /* program change */ ||            ((cmd == MIDI_CTRL) &&            (note->n[1] != SUSTAIN) /* control change */ ) ||            (cmd == MIDI_TOUCH) ||            (cmd == MIDI_BEND)) {            return(now);        }    }    return(last->when);}/*****************************************************************************               map_ctrl* Inputs:*    int control: a midi control number* Outputs:*    returns char: an adagio control change command letter, EOS if*       control change is not one of PORTARATE, PORTASWITCH,*       MODWHEEL, FOOT****************************************************************************/private char map_ctrl(control)int control;{    switch (control) {/* 'J' is no longer code for PORTARATE      case PORTARATE:        return 'J'; */      case PORTASWITCH:        return 'K';      case MODWHEEL:        return 'M';      case VOLUME:        return 'X';      default:        return EOS;    }#ifdef LATTICE322    return EOS;    /* make Lattice C type checker happy */#endif}/*****************************************************************************               output* Inputs:*    FILE *fp: an opened file pointer*    note_type last: the last data in the buffer*    boolean absflag: set to TRUE if first line of the adagio score should*       include the absolute time* Effect: *    write adagio file using data in event_buff* Implementation:*    NOTE: put all program changes in rests*    use N(ext) notation for all timing*    output no more than one continuous parameter change per*    clock tick for each continuous change parameter****************************************************************************/private void output(fp, last, absflag)FILE *fp;note_type last;boolean absflag;{    int i;                      /* loop counter */    int command;                /* the current command */    int voice;			/* the midi channel of the current event */    int last_velocity = -1;	/* used to filter repeated Lnn attributes */    int last_voice = 0; 	/* the default adagio channel (1) */    int ped = FALSE;            /* flag maintains state of pedal */    int how_many = last - event_buff;    long now=0;                 /* the time of the next event */    if (fp == NULL) {        gprintf(ERROR, "internal error: output called with NULL file.\n");        EXIT(1);    }    if (debug_rec)        gprintf(GDEBUG,"hint: if file is not being closed, decrease MAXSPACE\n");    fprintf(fp, "!MSEC\n");     /* times will be in milliseconds */    /* set the initial absolute time, all other times are relative */    if (absflag) {        now = event_buff[0].when;        if (now < 0) {            fprintf(fp, "* First event took place at Adagio time %d,\n",                    (int)now);            fprintf(fp, "*  but Adagio cannot represent negative times,\n");            fprintf(fp, "*  so this entire score will be %d ms late\n",                    (int)-now);            gprintf(TRANS, "First event took place at Adagio time %d!\n",                    (int)now);            gprintf(TRANS, "All events times will be %d ms late\n",                    (int)-now);            now = 0L;        }        fprintf(fp, "T%ld ", now);    }    for (i = 0; i < how_many; i++) {        if (debug_rec) {            gprintf(GDEBUG,"ev %d: %x %x %x (%ld)\n", i, event_buff[i].n[0],            event_buff[i].n[1], event_buff[i].n[2], event_buff[i].when);        }        if (istime(event_buff+i)) {            now = event_buff[i].when;            if (debug_rec) gprintf(GDEBUG,"i = %d, now = %ld\n", i, now);        } else {            boolean needs_voice = TRUE;            command = event_buff[i].n[0] & MIDI_CODE_MASK;            voice = event_buff[i].n[0] & MIDI_CHN_MASK;            if (command == MIDI_ON_NOTE && event_buff[i].n[2] != 0) {                int velocity =	event_buff[i].n[2];                write_pitch(fp, event_buff[i].n[1]);                fprintf(fp, " U%ld", getdur(i, last, ped, now));                if (last_velocity != velocity) {                    fprintf(fp, " L%d", velocity);                    last_velocity = velocity;                }            } else if (command == MIDI_CH_PROGRAM) {                fprintf(fp, "Z%d", event_buff[i].n[1] + 1);            } else if (command == MIDI_CTRL &&                event_buff[i].n[1] == SUSTAIN) {                ped = (event_buff[i].n[2] != 0);                needs_voice = FALSE;            } else if (command == MIDI_CTRL) {                char c = map_ctrl(event_buff[i].n[1]);                if (c != EOS) fprintf(fp, "%c%d", c, event_buff[i].n[2]);                else fprintf(fp, "~%d(%d)", event_buff[i].n[1], event_buff[i].n[2]);            } else if (command == MIDI_TOUCH) {                fprintf(fp, "O%d", event_buff[i].n[1]);            } else if (command == MIDI_BEND) {                fprintf(fp, "Y%d", event_bend(&event_buff[i]));            } else if (command == MIDI_ON_NOTE || command == MIDI_OFF_NOTE) {                needs_voice = FALSE; /* ignore note-offs */            } else {                gprintf(ERROR, "Command 0x%x ignored\n", command);                needs_voice = FALSE;            }            if (needs_voice) {                if (last_voice != voice) {                    fprintf(fp, " V%d", voice + 1);                    last_voice = voice;                }                fprintf(fp, " N%d", (int)(getnext(i, last, now) - now));                fprintf(fp, "\n");            }        }    }}/*****************************************************************************               write_pitch* Inputs:*    FILE *fp: an open file*    int p: a pitch number* Effect: write out the pitch name for a given number****************************************************************************/void write_pitch(FILE *fp, int p){    static char *ptos[] = {        "C", "CS", "D", "EF", "E", "F", "FS", "G",        "GS", "A", "BF", "B"	};    /* avoid negative numbers: adagio can't express lowest octave: */    while (p < 12) {        if (!fixed_octave) {            gprintf(ERROR, "%s%s%s",                    "A low note was transposed up an octave\n",                    "(Adagio cannot express the lowest MIDI octave).\n",                    "This message will appear only once.\n");            fixed_octave = TRUE;        }        p += 12;    }    fprintf(fp, "%s%d", ptos[p % 12], (p / 12) - 1);}/***********************************************************************           rec_final* Inputs:*    boolean absflag: output absolute time of first note if TRUE* Effect:*    Write recorded data to a file**********************************************************************/void rec_final(FILE *fp, boolean absflag){    next->when = gettime();    last = next;    if (debug_rec) gprintf(GDEBUG,"max_pile_up = %d, ", max_pile_up);    gprintf(TRANS,"%ld times and events recorded.\n",                   (long) (last - event_buff));    filter(last);    output(fp, last, absflag);    fclose(fp);    FREE(event_buff);    max_notes = -1;}/*****************************************************************************               rec_init* Inputs:*    char *file:  pointer to file name from command line (if any)*    boolean bender: TRUE if pitch bend should be enabled* Outputs:*    return TRUE if initialization succeeds* Effect:*    prepares module to record midi input****************************************************************************//* ENOUGH_ROOM says if we have room for 10000 events + 10000 timestamps = * 20000 note_struct's, then that's "enough room" for recording a sequence. * If more ram is available, it won't be used.  If less is available, we'll * use as much as we can get, minus "SPACE_FOR_PLAY", which leaves a little * bit of spare ram in case Moxc or stdio need to allocate some space. *      For DOS, we limit recording space to 64K. */#ifdef DOS#define ENOUGH_ROOM 64000L#else#define ENOUGH_ROOM (20000L * sizeof(union note_struct))#endifboolean rec_init(boolean bender){    size_t biggestChunk, spaceForRecord;    debug_rec = cl_switch("debug");    byteorder();    pile_ups = 0;    max_pile_up = 0;    previous_time = (unsigned) -1L; /* this will force putting in initial timestamp */    fixed_octave = FALSE;    if (max_notes == -1) {    /* allocate space 1st time rec_init called */        biggestChunk = AVAILMEM;        if (biggestChunk <= SPACE_FOR_PLAY) {            /* not enough memory; give up */            return(FALSE);        }         else {            spaceForRecord =                MIN((biggestChunk - SPACE_FOR_PLAY), ENOUGH_ROOM);            /* leave SPACE_FOR_PLAY contiguous bytes of memory */        }        max_notes = spaceForRecord / sizeof(note_node);        /*    gprintf(GDEBUG,"max_notes = %d\n", max_notes);*/        event_buff = (note_type) MALLOC(spaceForRecord);        if (event_buff == NULL) {            /* should never happen */            gprintf(FATAL, "Implementation error (record.c): getting memory.");            return FALSE;        }    }    next = event_buff;    last = event_buff + max_notes - 2; /* it is critical that last not point                                        * to the very last storage loc */    midi_cont(bender);    return((boolean)(max_notes > 10));    /* it would be silly to record with only room enough for 10 notes! */}/*****************************************************************************               rec_event* Inputs:*    long time: the current time*    long data: midi data to record* Outputs:*    returns FALSE if there is no more memory* Effect: reads and stores any input* Implementation:*    time stamps and midi events share the same buffer of 4-byte events*    save time at most once per call to rec_poll*    save time only if it changes****************************************************************************/boolean rec_event(long *data, time_type time){    /* can't allow negative time because sign bit distinguishes      * data from time: */    if (time < 0) time = 0;    if (previous_time != time) {        next++->when = previous_time = time;        if (next >= last) goto overflow;    }    next->when = *data;    next++->n[3] = MIDI_CMD_BIT;        /* set tag bit */    if (next >= last) goto overflow;    return TRUE;overflow:    next = last; /* last doesn't really point to last storage */    gprintf(ERROR, "No more memory.\n");    return FALSE;}

⌨️ 快捷键说明

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