📄 midifns.c
字号:
* buffer. The largest power of 2 bytes less than size will be* used. xbufhead and xbuftail will be initialized to zero,* and xbuftail will be one greater than the index of the last* system exclusive byte read. Since there may already be a buffer* and therefore the normal midi message buffer may have the first* 4 bytes of some sysex messages, clear the normal midi buffer too.* AMIGA:* adds buffer to midi interface*****************************************************************************/boolean midi_buffer(byte huge *buffer, ulong size){ if (!buffer) return FALSE;#ifdef AMIGA if (!SetSysExQueue(cmt_mi, (UBYTE *) buffer, (ULONG) size)) return(false); cu_register(remove_sysex_buffer, buffer);#endif#ifdef MACINTOSH_OR_DOS#ifndef WINDOWS { int mask = 0x000F; if (size < 16) return(false); while (mask < size && mask > 0) mask = ((mask << 1) | 1); midi_flush(); xbuff = NULL; /* turn off buffering */ xbufmask = mask >> 1; xbufhead = xbuftail = 0; xbuff = buffer; /* set buffer, turn on buffering */ }#endif#endif#ifdef UNIX return FALSE;#else exclusive(TRUE); return TRUE;#endif}/* midi_clock -- send a midi time clock message *//**/void midi_clock(){ if (!initialized) fixup(); if (musictrace) gprintf(TRANS, "+"); midi_write(1, 0, MIDI_TIME_CLOCK, 0, 0);}/***************************************************************************** midi_cont* Inputs:* boolean onflag: TRUE or FALSE* Effect:* enables (true) or disables (false) continuous control****************************************************************************/void midi_cont(boolean onflag){ if (!initialized) fixup(); if (onflag) {#ifdef AMIGA SetMidiFilters(cmt_mi, cmt_mi->PortFilter, cmt_mi->TypeFilter | CONTCONT, cmt_mi->ChanFilter);#endif#ifdef DOS#ifndef WINDOWS mPutCmd(BENDERON);#endif#endif } else {#ifdef AMIGA SetMidiFilters(cmt_mi, cmt_mi->PortFilter, cmt_mi->TypeFilter & ~CONTCONT, cmt_mi->ChanFilter);#endif }#ifdef MACINTOSH_OR_DOS ctrlFilter = !onflag;#endif if (musictrace) gprintf(TRANS,"midi_cont: %d\n", onflag);}/***************************************************************************** midi_ctrl* Inputs:* int channel: midi channel on which to send data* int control: control number* int value: control value* Effect: * Sends a midi control change message****************************************************************************/void midi_ctrl(int channel, int control, int value){ if (!initialized) fixup(); if (musictrace) gprintf(TRANS,"midi_ctrl: ch %d, ctrl %d, val %d\n", channel, control, value); midi_write(3, MIDI_PORT(channel), (byte) (MIDI_CTRL | MIDI_CHANNEL(channel)), (byte) MIDI_DATA(control), (byte) MIDI_DATA(value));}/***************************************************************************** midi_exclusive* Inputs:* byte *msg: pointer to a midi exclusive message, terminated by 0xF7* Effect: * Sends a midi exclusive message* Bugs:* 18-mar-94 PLu : This function does not know which port to send to in* case of multiple midi-ports (MAC, IRIX)****************************************************************************/#ifdef MACINTOSH#define INTERBYTE_DELAY 10#endifvoid midi_exclusive(msg)unsigned char *msg; /* the data to be sent */{#ifdef ITC int count, done, tosend, willsend; unsigned char *m; mi_status ret;#endif#ifdef UNIX_IRIX_MIDIFNS unsigned char *m; MDevent mdevent;#endif#ifdef MACINTOSH#ifndef NYQUIST int i; /* for DX7 delay loop */ int count = 0; /* counter for formatting midi byte trace */ MIDIPacket TheMIDIPacket; unsigned char prev = 0; boolean first_packet = TRUE;#endif#endif /* * if user mistakenly called midi_exclusive instead of exclusive, * the argument will be TRUE or FALSE, both of which are highly * unlikely valid arguments for midi_exclusive: */ if (msg == (byte *) FALSE || msg == (byte *) TRUE) { gprintf(ERROR,"midi_exclusive: invalid argument %u.\n", msg); EXIT(1); } if (!initialized) fixup(); if (musictrace) gprintf(TRANS,"midi_exclusive\n");#ifdef AMIGA PutSysEx(cmt_mi, msg);#endif#ifdef MACINTOSH#ifndef NYQUIST /* if NYQUIST, do nothing */#ifdef MIDIMGR while (prev != MIDI_EOX) { int len = 0; while (prev != MIDI_EOX && len < 249) { TheMIDIPacket.data[len++] = prev = *msg++; } TheMIDIPacket.len = 6 + len; TheMIDIPacket.tStamp = 0; if (first_packet && (prev != MIDI_EOX)) { TheMIDIPacket.flags = midiTimeStampCurrent + midiStartCont; first_packet = FALSE; } else if (first_packet) { TheMIDIPacket.flags = midiTimeStampCurrent + midiNoCont; } else if (prev == MIDI_EOX) { TheMIDIPacket.flags = midiTimeStampCurrent + midiEndCont; } else { TheMIDIPacket.flags = midiTimeStampCurrent + midiMidCont; } MIDIWritePacket(OutputRefNum, &TheMIDIPacket); }#else while (*msg != MIDI_EOX) { Xmit(0, *msg); msg++; count++; /* this is a delay loop, without which your DX7 will crash */ for (i = INTERBYTE_DELAY; i > 0; i--) abort_check(); } Xmit(0, MIDI_EOX);#endif /* MIDIMGR */#endif /* NYQUIST */#endif /* MACINTOSH */#ifdef DOS#ifndef WINDOWS do { mPutData(*msg); } while (*msg++ != MIDI_EOX);#endif#endif#ifdef ITC for (m = msg, tosend = 1; (*m) != MIDI_EOX; m++, tosend++); for (count = 0; count < tosend; count += done) { willsend = min(16384, tosend); ret = mi_exclusive(midiconn, 1, msg, (short) willsend); if (ret != MI_SUCCESS) { gprintf(GWARN, "Got %d from mi_exclusive\n", ret); } done = willsend; }#endif#ifdef UNIX_IRIX_MIDIFNS/* we don't know which device to sent SYSEX messages to so port zero is assumed. */ for (m = msg, mdevent.msglen = 1; (*m) != CMT_MIDI_EOX; m++, mdevent.msglen++); mdevent.sysexmsg = msg; if (mdSend(miport, &mdevent, 1) == -1) { gprintf(GWARN, "could not send SYSEX message\n"); }#endif if (miditrace) { do { gprintf(TRANS, "~%2x", *msg);#ifdef UNIX_IRIX_MIDIFNS } while (*msg++ != CMT_MIDI_EOX);#else } while (*msg++ != MIDI_EOX);#endif }}/***************************************************************************** midi_note* Inputs:* int channel: midi channel on which to send data* int pitch: midi pitch code* int velocity: velocity with which to sound it (0=> release)* Effect: * Sends a midi note-play request out****************************************************************************/void midi_note(int channel, int pitch, int velocity){ if (!initialized) fixup(); if (musictrace) gprintf(TRANS,"midi_note: ch %d, key %d, vel %d\n", channel, pitch, velocity); if (user_scale) { /* check for correct pitch bend */ if ((pit_tab[pitch].pbend != bend[MIDI_CHANNEL(channel)]) && (velocity != 0)) { midi_bend(channel, pit_tab[pitch].pbend); bend[channel] = pit_tab[pitch].pbend; } pitch = pit_tab[pitch].ppitch; } midi_write(3, MIDI_PORT(channel), (byte) (MIDI_ON_NOTE | MIDI_CHANNEL(channel)), (byte) MIDI_DATA(pitch), (byte) MIDI_DATA(velocity));}/***************************************************************************** midi_program* Inputs:* int channel: Channel on which to send midi program change request* int program: Program number to send (decremented by 1 before* being sent as midi data)* Effect: * Sends a program change request out the channel****************************************************************************/void midi_program(int channel, int program){#ifdef MACINTOSH int port, midi_chan;#endif if (!initialized) fixup(); if (musictrace) gprintf(TRANS,"midi_program: ch %d, prog %d\n", channel, program); channel = MIDI_CHANNEL(channel); if (cur_midi_prgm[channel] != program) { midi_write(2, MIDI_PORT(channel), (byte) (MIDI_CH_PROGRAM | channel), (byte) (MIDI_PROGRAM(program)), 0); cur_midi_prgm[channel] = program; }}/***************************************************************************** midi_real* Inputs:* boolean onflag: TRUE or FALSE* Effect:* enables (true) or disables (false) midi realtime messages F8-FF****************************************************************************/void midi_real(boolean onflag) { if (!initialized) fixup();#ifdef UNIX_ITC { mi_status ret; ret = mi_realtime(midiconn, onflag); if (ret != MI_SUCCESS) { gprintf(ERROR, "Warning: bad ret = %d in midi_real\n", ret); } }#endif /* UNIX_ITC */#ifdef ITC ignore_realtime = !onflag;#endif /* ITC */#ifdef AMIGA if (onflag) { SetMidiFilters(cmt_mi, cmt_mi->PortFilter, cmt_mi->TypeFilter | CMF_RealTime, cmt_mi->ChanFilter); } else { SetMidiFilters(cmt_mi, cmt_mi->PortFilter, cmt_mi->TypeFilter & ~CMF_RealTime, cmt_mi->ChanFilter); }#endif#ifdef MACINTOSH_OR_DOS realFilter = !onflag;#endif if (musictrace) gprintf(TRANS,"midi_real: %d\n", onflag);}/* midi_start -- send a midi start message *//**/void midi_start(){ if (!initialized) fixup(); if (musictrace) gprintf(TRANS, "`"); midi_write(1, 0, MIDI_START, 0, 0);}/* midi_stop -- send a midi stop message *//**/void midi_stop(){ if (!initialized) fixup(); if (musictrace) gprintf(TRANS, "'"); midi_write(1, 0 /* ignored */, MIDI_STOP, 0, 0);}/***************************************************************************** midi_thru* Inputs:* boolean onflag: TRUE or FALSE* Effect:* DOS: enables (true) or disables (false) midi thru info from* MPU-401 to host. (Default is set; reset with cmdline -block.)* AMIGA: enables (true) or disables (false) midi route from AMIGA* midi input to AMIGA midi output.****************************************************************************/void midi_thru(boolean onflag) /* DMH: midi thru is not supported on the MAC or DOS */{ if (!initialized) fixup();#ifndef MIDI_THRU gprintf(ERROR, "midi_thru called but not implemented\n");#else#ifdef AMIGA MidiThru(0L, (long) onflag);#endif#ifdef MACINTOSH /* this currently does not do anything - Mac driver doesn't * support THRU */ do_midi_thru = onflag;#endif#endif if (musictrace) gprintf(TRANS,"midi_thru: %d\n", onflag);}/***************************************************************************** midi_touch* Inputs:* int channel: midi channel on which to send data* int value: control value* Effect: * Sends a midi after touch message****************************************************************************/void midi_touch(int channel, int value){ if (!initialized) fixup(); if (musictrace) gprintf(TRANS,"midi_touch: ch %d, val %d\n",channel,value); midi_write(2, MIDI_PORT(channel), (byte) (MIDI_TOUCH | MIDI_CHANNEL(channel)), (byte) MIDI_DATA(value), 0);}/***************************************************************************** midi_write* Inputs:* UBYTE n: number of characters to send (1, 2 or 3); int port: the port number (usually 0), on MAC, this may be 1* char c1,c2,c3: Character(s) to write to MIDI data port* Effect: * Writes the data to the serial interface designated by port***************************************************************************** Change log* Date | Change*-----------+----------------------------------------------------------------* 15-Mar-94 | PLu : Added IRIX version****************************************************************************/ #ifdef UNIX#ifdef UNIX_IRIX_MIDIFNSvoid midi_write(int n, int port, unsigned char c1, unsigned char c2, unsigned char c3){ MDevent event; if (port < 0) return; * ((u_long *) event.msg) = 0xe0000000 | ((port & 0x1f) << 24) | (c1 << 16) | (c2 << 8) | c3; if (mdSend(miport, &event, 1) == -1) gprintf(ERROR, "Can not send midi message in midi_write"); midi_write_trace(n, port, c1, c2, c3);}#else#ifdef ITCvoid midi_write(int n, int port, unsigned char c1, unsigned char c2, unsigned char c3){ unsigned char outb[3]; mi_channel mch; mi_status ret; if (port < 0) return; outb[0] = c1; outb[1] = c2; outb[2] = c3; mch = (16*port)+((int)MI_CHANNEL(c1)); ret = mi_put(midiconn, mch, outb); if (ret != MI_SUCCESS) gprintf(ERROR, "Warning: bad ret = %d in midi_write\n", (int)ret); midi_write_trace(n, port, c1, c2, c3);}#elsevoid midi_write(int n, int port, unsigned char c1, unsigned char c2, unsigned char c3){ /* no output */ midi_write_trace(n, port, c1, c2, c3);}#endif /* ITC */#endif /* UNIX_IRIX */#endif /* UNIX */#ifdef DOS#ifndef WINDOWS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -