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

📄 midifns.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 4 页
字号:
    int c = getc(stdin);    ungetc(c, stdin);    }    return;}#elsevoid eventwait(timeout)  long timeout;{    while (timeout > gettime() || timeout == -1) {        if (check_ascii() || check_midi()) return;    }}#endif /* WINDOWS */#endif /* UNIX */#endif /* AMIGA *//*****************************************************************************                exclusive* Inputs:*    boolean onflag -- set to TRUE to receive midi exclusive data* Effect: *    Tells module to read exclusive messages into buffer****************************************************************************/void exclusive(boolean onflag){    if  (!initialized) fixup();    if (musictrace) gprintf(TRANS, "exclusive: %d\n", onflag);#ifdef AMIGA    if (onflag) SetMidiFilters(cmt_mi,     cmt_mi->PortFilter, cmt_mi->TypeFilter | CMF_SysEx, cmt_mi->ChanFilter);    else SetMidiFilters(cmt_mi,     cmt_mi->PortFilter, cmt_mi->TypeFilter & ~CMF_SysEx, cmt_mi->ChanFilter);#endif#ifdef  MACINTOSH_OR_DOS    exclFilter = !onflag;#endif}/*****************************************************************************                    fixup* Effect: *    Print error message and call musicinit****************************************************************************/private void fixup(){    gprintf(ERROR, "You forgot to call musicinit.  I'll do it for you.\n");    musicinit();}#ifdef UNIX_IRIX_MIDIFNSprivate void flush_sysex(void);#endiflong get_excl(byte *buffer, long len){    long ret = 0;#ifdef UNIX_IRIX_MIDIFNS    byte *sxp = sysex_p;    long l = len;#endif#ifdef UNIX_ITC  /* was ITC */    ret = mi_getx(midiconn, FALSE, len, (char *) buffer);#endif#ifdef UNIX_MACH    ret = mi_getx(midiconn, FALSE, len, (unsigned char *)buffer);#endif#ifdef UNIX_IRIX_MIDIFNS    if (!sysex_p) return 0;    if (len > sysex_n) len = sysex_n;    while (l--)      {        *buffer = *(sxp++);        if (*(buffer++) == CMT_MIDI_EOX)          {        flush_sysex();        break;          }      }    ret = len - l - 1;#endif#ifdef AMIGA    ret = GetSysEx(cmt_mi, (UBYTE *) buffer, len);    AMIGA_ERROR_CHECK;#endif#ifdef MACINTOSH_OR_DOS#ifndef WINDOWS    /* I'm not sure the following line is a good thing: it forces the     * caller to wait until a full sysex message is received and the     * 1st 4 bytes are fetched via getbuf() before a sysex message can     * be read via get_excl().  Without this, both mm.c and exget.c     * were fetching ahead and getting out of sync with getbuf().  I     * fixed mm.c and exget.c to work (by checking for EOX), but I added     * this line (which should never have any effect) just to make the     * DOS interface behave more like the Amiga and Mac interfaces.  The     * drawback is that you can't fetch bytes until the EOX is seen,     * because nothing goes into the getbuf() buffer until then.     */    if (!sysex_pending) return 0;    while (len-- && (xbufhead != xbuftail)) {    *buffer = xbuff[xbufhead++];    ret++;    if (*buffer == MIDI_EOX) {        sysex_pending = FALSE;        break;    }    buffer++;    xbufhead &= xbufmask;    }#endif#endif    return ret;}/*****************************************************************************                   getbuf* Inputs:*    boolean waitflag: TRUE if routine should wait for data*    byte * p: Pointer to data destination* Result: boolean*    TRUE if data was written to *p*    FALSE if data not written to *p* Effect: *    copies data from buffer to *p*    will wait for buffer to become nonempty if waitflag is TRUE** Modified 24 May 1988 for AMIGA (JCD)****************************************************************************/#ifdef UNIX_IRIX_MIDIFNS    private void setup_sysex(MDevent *event, u_char *buffer);#endif /* UNIX_IRIX */boolean getbuf(boolean waitflag, unsigned char * p){#ifdef UNIX_IRIX_MIDIFNS    MDevent event;    int ret;#endif /* UNIX_IRIX */    if (!initialized) fixup();#ifdef UNIX#ifdef UNIX_IRIX_MIDIFNS/* current IRIX version ignores the waitflag (it never waits) */  if (sysex_p) flush_sysex();  if (ignore_realtime == 0) {      ret = mdReceive(miport, &event, 1);      if (ret) {      if (event.msg[0] != 0xF0) {          *((u_long*) p) = *((u_long*) event.msg);      } else {          setup_sysex(&event, p);      }      }      return ret;  } else {      do /* skip realtime messages */    {       ret = mdReceive(miport, &event, 1);       if (ret == -1) return ret;     } while (event.msg[0] == 0xf8);      if (event.msg[0] != 0xF0) {      *((u_long*) p) = *((u_long*) event.msg);      } else {      setup_sysex(&event, p);      }      return ret;  }#endif /* UNIX_IRIX */#ifdef UNIX_ITC    if (ignore_realtime == 0) {        return(mi_get(midiconn, waitflag, (char *) p));    }    else {        boolean ret=false;        /* filter out realtime msgs */        do {            ret = mi_get(midiconn, waitflag, (char *) p);            if (ret == FALSE)                return(ret);        } while(p[0] == 0xf8);        return(ret);    }#else /* UNIX_ITC */#ifndef UNIX_IRIX    if (waitflag) {    gprintf(ERROR, "getbuf called with waitflag!");    EXIT(1);    }    return FALSE;#endif /* UNIX_IRIX */#endif /* UNIX_ITC */#endif /* UNIX */#ifdef MACINTOSH_OR_DOS#ifndef WINDOWS    if (sysex_pending) { /* flush sysex to keep buffers in sync */        while (xbuff[xbufhead++] != MIDI_EOX) {        xbufhead &= xbufmask;        if (xbufhead == xbuftail) break;        }        sysex_pending = FALSE;    }    if (waitflag) while (buffhead == bufftail) /* wait */ ;    else if (buffhead == bufftail) return(false);    *(long *)p = *(long *)(((char *)buff)+buffhead);    buffhead = (buffhead + 4) & BUFF_MASK;    if (*p == MIDI_SYSEX) { /* if sys-ex, remember to fetch from xbuff */        sysex_pending = TRUE;    }    return(true);#else    return FALSE;#endif /* WINDOWS */#endif /* MACINTOSH_OR_DOS */#ifdef AMIGA    if (waitflag) {        do {        WaitMidi(cmt_mi, &cmt_msg);        AMIGA_ERROR_CHECK;        } while (amigaerrflags);    } else {        AMIGA_ERROR_CHECK;        if (!GetMidi(cmt_mi, &cmt_msg)) return(false);    }        *(long *)p = *(long *)&cmt_msg;    clearmsg(cmt_msg);    return(true);#endif /* AMIGA */}#ifdef UNIX_IRIX_MIDIFNSprivate void setup_sysex(MDevent *event, u_char *buffer)/* N.B. do not leak memory remember to call free(sysex_p) */{   u_char *sxp = (u_char *) event->sysexmsg;   int i;   for (i=0;i<4;i++)     *(buffer++) = *(sxp++);   sysex_p = event->sysexmsg;   sysex_n = event->msglen;}private void flush_sysex(){  mdFree(sysex_p);  sysex_p = 0;  sysex_n = 0;}#endif#ifdef MACINTOSH_OR_DOS#ifndef WINDOWSpublic boolean check_midi(){    if (buffhead == bufftail) return FALSE;    else return TRUE;}#endif#endif/*****************************************************************************                   getkey* Inputs:*    boolean waitflag: TRUE if wait until key depression, FALSE if*             return immediately* Result: int*    key number of key which has been depressed*    It returns -1 if waitflag is FALSE and no key has been pressed*    If waitflag is TRUE this routine will block until a key is pressed* Effect: *    reads a key****************************************************************************//*DMH: in previous version, macmidi.c subtracted 12 from msg to get key at each occurence...*/short getkey(boolean waitflag){    byte msg[4];    short k;    if (!initialized) fixup();    while (TRUE) {    /* process data until you find a note */    /* look for data and exit if none found */    /* NOTE: waitflag will force waiting until data arrives */    if (!getbuf(waitflag, msg)) { /* nothing there */        k = -1;        break;    } else if ((msg[0] & MIDI_CODE_MASK) == MIDI_ON_NOTE) {        if (msg[2] == 0) { /* velocity 0 -> note off */        keyloud = 0;        k = msg[1] + 128;        } else {        keyloud = msg[2];        k = msg[1];        }        break;    } else if ((msg[0] & MIDI_CODE_MASK) == MIDI_OFF_NOTE) {        keyloud = 0;        k = msg[1] + 128;        break;    }    }    if (musictrace) {    if (k != -1) gprintf(TRANS,"getkey got %d\n", k);    }    return k;}/*****************************************************************************                   gettime* Result: ulong*    current timestamp since the last call to*    musicinit or timereset* Effect: *    fakes it****************************************************************************/ulong gettime()         /*DMH: ulong is from mpu->midifns conversion, for Mac*/{#if HAS_GETTIMEOFDAY    struct timeval timeval;#endif#if HAS_FTIME    struct timeb ftime_res;#endif    register ulong ticks = 0L;    BREAKTEST    /* abort if user typed Ctrl Break */    if (!initialized) fixup();#ifdef MACINTOSH#ifdef MIDIMGR    ticks = MIDIGetCurTime(OutputRefNum) - ticksAtStart;#else    ticks = TickCount() - ticksAtStart;#endif    if (initialized) abort_check();     /* give user a chance to abort */    ticks = TICKS_TO_MS(ticks);#endif#ifdef AMIGA    ticks = (*camdtime - timeoffset) << 1;      /* return milliseconds */#endif#ifdef  DOS#ifndef WINDOWS           ticks = elapsedtime(timeoffset, readtimer()); /* return milliseconds */    /* gprintf(TRANS, "currtime = %ld, timeoffset = %ld\n", currtime, timeoffset); */#endif#endif  /* ifdef DOS */#if HAS_GETTIMEOFDAY    gettimeofday(&timeval, 0);    ticks = timeval.tv_sec * 1000 + timeval.tv_usec / 1000 - timeoffset;#endif#if HAS_FTIME    ftime(&ftime_res);    ticks = ((ftime_res.time - timeoffset) * 1000) + ftime_res.millitm;#endif    /* if (miditrace) gprintf(TRANS, "."); */    return(ticks);}/*****************************************************************************                   l_rest* Inputs:*    long time: Amount of time to rest* Effect: *    Waits until the amount of time specified has lapsed****************************************************************************/void l_rest(time)long time;{    if (!initialized) fixup();    l_restuntil(time + gettime());    }/*****************************************************************************                 l_restuntil* Inputs:*    long time: Event time to rest until* Effect: *    Waits until the specified time has been reached (absolute time)****************************************************************************/void l_restuntil(time)long time;{#ifdef MACINTOSH    ulong now = gettime();      ulong junk; /* changed from ulong for ThinkC 7, back to ulong for CW5 */#endif#ifdef AMIGA    while (time > gettime()) eventwait(time);#else      for(; (time_type) time > gettime(););#endif#ifdef MACINTOSH    now = gettime();            if (time > now)  Delay(MS_TO_TICKS(time - now), &junk);    /* else time <= now, so return immediately */#endif}/*****************************************************************************               metronome* Inputs:*    boolean onflag: TRUE or FALSE* Effect:*    enables (true) or disables (false) MPU-401 metronome function.*    must be called before musicinit****************************************************************************/void metronome(boolean onflag){#ifdef DOSmetroflag = onflag;#endif}/*****************************************************************************                  midi_bend* Inputs:*    int channel: midi channel on which to send data*    int value: pitch bend value* Effect: *    Sends a midi pitch bend message****************************************************************************/void midi_bend(int channel, int value){    if (!initialized) fixup();    if (musictrace)    gprintf(TRANS,"midi_bend: ch %d, val %d\n", channel, value - (1 << 13));        bend[MIDI_CHANNEL(channel)] = value;        midi_write(3, MIDI_PORT(channel), (byte) (MIDI_BEND | MIDI_CHANNEL(channel)),        (byte) MIDI_DATA(value), (byte) MIDI_DATA(value >> 7));}/*****************************************************************************               midi_buffer* Inputs:*    byte * buffer: the buffer address*    int size: number of bytes in buffer* Returns:*    FALSE if size is less than 16 or buffer is NULL, otherwise TRUE* Effect: DOS, MAC:*    tells interrupt routine to store system exclusive messages in

⌨️ 快捷键说明

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