/************************************************************************** * iofunctions.c: * Functions for input/output in a variety of formats. * Part of MP, the MIDI Playground. * * Author: Daniel Barrett * Version: See the file "version.h". * Copyright: None! This program is in the Public Domain. * Please share it with others. ***************************************************************************/ #include "mp.h" #include "midi.h" /* Read data from MIDI. Return the value of the next MIDI byte. Because * reading byte-by-byte from the MIDI port is inefficient, we read as * much as we can and keep it in a static buffer. */ MIDI_RESULT FromMidi(FILE *in, MIDI_VALUE *value) { static long bytesWaiting = 0L; /* # bytes waiting at serial port. */ static UBYTE buf[BUFSIZ]; /* Static buffer. */ static long currentByte = 0L; /* Index of next byte to return. */ if (currentByte >= bytesWaiting) { bytesWaiting = FastSerialRead(buf); currentByte = 0L; } if (bytesWaiting == CTRL_C_NO_BYTES) { bytesWaiting = currentByte = 0L; return(RESULT_STOP); } else if (bytesWaiting <= 0) { bytesWaiting = currentByte = 0L; return(RESULT_ERROR); } else { *value = buf[currentByte++]; return(RESULT_OK); } } /* Write a byte to MIDI. It is inefficient to write 1 byte at a time, but * we want instant transmission. I will rewrite this eventually. */ BOOL ToMidi(FILE *dummy, MIDI_VALUE value) { PrepareToWriteMidi(&value, 1); return(DoTheIO() == 1L); } /* Read 1 byte from text. We use a finite state automaton. * If an error occurs, assign the value of the last character read * to *answer. */ MIDI_RESULT FromText(FILE *in, MIDI_VALUE *value) { STATE_T state = STATE_NORMAL; int c; *value = 0L; while ((state != STATE_SUCCESS) && (state != STATE_ERROR) && (state != STATE_OVERFLOW) && ((c = getc(in)) != EOF)) state = NewState(c, state, value); if (state == STATE_SUCCESS) return(RESULT_OK); else if (c == EOF && state == STATE_NORMAL) return(RESULT_STOP); else if (c == EOF) return(RESULT_ERROR); else if (state == STATE_OVERFLOW) return(RESULT_OVERFLOW); else { *value = c; return(RESULT_ERROR); } } /* Write 1 MIDI value as text. */ BOOL ToText(FILE *out, MIDI_VALUE value) { static long byt = 0L; fprintf(out, "<%6ld> ", ++byt); PrintNumber(value, out); } /* Read 1 MIDI value from a binary file. Inefficient. */ MIDI_RESULT FromBinary(FILE *in, MIDI_VALUE *value) { int c; if ((c = getc(in)) != EOF) { *value = (MIDI_VALUE)c; return(RESULT_OK); } return(RESULT_STOP); } /* Write 1 MIDI value to a binary file. Inefficient. */ BOOL ToBinary(FILE *out, MIDI_VALUE value) { return(putc(value, out) != EOF); } /**************************************************************************** * Skipping input. ****************************************************************************/ /* Skip to the next valid text input. */ void SkipText(FILE *in, MIDI_VALUE value) { register int c; if (isspace(value)) return; while ((c = getc(in)) != EOF && !isspace(c)) ; if (c != EOF) ungetc(c, in); } /* Skip to the next valid MIDI input by clearing the serial port buffer. */ void SkipMidi(FILE *dummy, MIDI_VALUE junk) { ResetSerialPort(); } /* Skip to the next valid binary value. This is currently just a stub. */ void SkipBinary(FILE *in, MIDI_VALUE junk) { return; }