/************************************************************************** * mp.h: Main header file. * 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. ***************************************************************************/ #ifndef _MP_H #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __C_MACROS__ #define __C_MACROS__ #endif #include /************************************************************************** * Types. **************************************************************************/ typedef unsigned char STATE_T; /* An automaton state. */ typedef UBYTE MIDI_VALUE; /* A single MIDI data value. */ typedef signed char MIDI_RESULT; /* What happened while reading? */ typedef char FLAGS; /* Internal flags. */ /************************************************************************** * Return values from our input routine. **************************************************************************/ #define RESULT_OK (MIDI_RESULT)(1) /* Legal value read. */ #define RESULT_ERROR (MIDI_RESULT)(2) /* Illegal value read. */ #define RESULT_OVERFLOW (MIDI_RESULT)(3) /* Value overflowed. */ #define RESULT_STOP (MIDI_RESULT)(4) /* End of data. */ /************************************************************************** * States of our finite automaton for reading input. **************************************************************************/ #define STATE_SUCCESS 1 /* Got a legal value. */ #define STATE_ERROR 2 /* Had an input error. */ #define STATE_OVERFLOW 3 /* Read too big a value. */ #define STATE_NORMAL 4 /* Haven't read anything yet. */ #define STATE_INCOMMENT 5 /* Skipping a comment. */ #define STATE_INDECIMAL 6 /* Reading a base 10 number. */ #define STATE_LEADZERO 7 /* Read a leading zero. */ #define STATE_INOCTAL 8 /* Reading an octal number. */ #define STATE_STARTHEX 9 /* Read 1st digit of hex number. */ #define STATE_INHEX 10 /* Reading a hex number. */ #define STATE_STARTBINARY 11 /* Read 1st symbol of binary num. */ #define STATE_INBINARY 12 /* Reading a binary number. */ #define STATE_NEGATIVE 13 /* UNUSED. FOR FUTURE UPDATE. */ #define STATE_INCHAR 14 /* Reading a char constant. */ #define STATE_EXPECTQUOTE 15 /* Finishing a char constant. */ #define STATE_BACKSLASHINCHAR 16 /* Backslash in a char constant. */ #define STATE_BACKSLASHINSTRING 17 /* Backslash in a string constant. */ #define STATE_INCLUDEFILE 18 /* UNUSED. FOR FUTURE UPDATE. */ /************************************************************************** * Macros for converting characters to numbers: * * D_TO_INT(c) Convert a digit to its numeric value. * L_TO_INT(c) Convert a letter (A..F) to its base 16 value. * H_TO_INT(c) Convert a hex digit to its numeric value. **************************************************************************/ #define D_TO_INT(c) ((long)((c) - '0')) #define L_TO_INT(c) ((long)((toupper(c)) - 'A') + 10) #define H_TO_INT(c) (isdigit(c) ? D_TO_INT(c) : L_TO_INT(c)) /************************************************************************** * Macros for classifying types of input. The rest are in . **************************************************************************/ #define isoctal(c) (((c) >= '0') && ((c) <= '7')) /************************************************************************** * Other macros. **************************************************************************/ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define OpenReadFile(filename) OpenAFile(filename, "r", "read") #define OpenWriteFile(filename) OpenAFile(filename, "w", "write") /************************************************************************** * The largest legal value our input routine can handle. **************************************************************************/ #define LARGEST_VALUE (MIDI_VALUE)(255) #define BITS_IN_MIDI_VALUE BITSPERBYTE /* in types.h */ /*************************************************************************** * Character constants for classifying the input. ***************************************************************************/ #define START_BINARY '#' /* Symbol for start of binary number. */ #define HELP_SYMBOL '?' /* Symbol for help request from user. */ #define START_COMMENT ';' /* Start-comment symbol. */ /*************************************************************************** * Command-line Options. ***************************************************************************/ #define OPT_INPUT 'i' /* Input format. */ #define OPT_OUTPUT 'o' /* Output format. */ #define OPT_TEXT 't' /* Text I/O. */ #define OPT_BINARY 'b' /* Binary I/O. */ #define OPT_MIDI 'm' /* MIDI I/O. */ #define OPT_SYSEX 'x' /* UNUSED. FOR FUTURE UPDATE. */ #define OPT_INFILE 'g' /* Get from file. */ #define OPT_OUTFILE 'p' /* Put to file. */ /* For getopt(). */ #define GETOPT_OPTIONS "i:o:g:p:x"; extern int optind; extern char *optarg; /*************************************************************************** * Flags, and their associated macros. ***************************************************************************/ #define NUM_FLAGS 3 /* How many flags? */ #define FLAG_ITYPE 0 /* Flag ID's. */ #define FLAG_OTYPE 1 #define FLAG_SYSEX 2 /*************************************************************************** * Prototypes. ***************************************************************************/ /* read.c */ STATE_T NewState(int c, STATE_T state, MIDI_VALUE *answer); STATE_T NonStringState(int c, STATE_T state, MIDI_VALUE *answer); STATE_T DoNormal(int c, MIDI_VALUE *answer); STATE_T DoDecimal(int c, MIDI_VALUE *answer); STATE_T DoOctal(int c, MIDI_VALUE *answer); STATE_T DoHex(int c, MIDI_VALUE *answer); STATE_T DoInHex(int c, MIDI_VALUE *answer); STATE_T DoBinary(int c, MIDI_VALUE *answer); STATE_T DoInBinary(int c, MIDI_VALUE *answer); STATE_T DoLeadZero(int c, MIDI_VALUE *answer); STATE_T IncreaseIfPossible(MIDI_VALUE *answer, int newNum, int base, STATE_T newState); STATE_T DoInChar(int c, MIDI_VALUE *answer); STATE_T DoExpectQuote(int c, MIDI_VALUE *answer); STATE_T DoBackslash(int c, MIDI_VALUE *answer, STATE_T newState); STATE_T DoInString(int c, STATE_T state, MIDI_VALUE *answer, short *inString); STATE_T DoComment(int c); void InputHelp(); void PrintNumber(MIDI_VALUE number, FILE *out); void PrintBinary(MIDI_VALUE number, FILE *out); /* serial.c */ short SerialSetup(FLAGS sysex); void SerialShutdown(void); void ResetSerialPort(void); long AnyMidiData(void); void PrepareToReadMidi(UBYTE *buf, int len); void PrepareToWriteMidi(UBYTE *buf, int len); long DoTheIO(void); long FastSerialRead(UBYTE buf[]); /* iofunctions.c */ MIDI_RESULT FromMidi(FILE *in, MIDI_VALUE *value); BOOL ToMidi(FILE *in, MIDI_VALUE value); MIDI_RESULT FromText(FILE *in, MIDI_VALUE *value); BOOL ToText(FILE *in, MIDI_VALUE value); MIDI_RESULT FromBinary(FILE *in, MIDI_VALUE *value); BOOL ToBinary(FILE *in, MIDI_VALUE value); void SkipText(FILE *in, MIDI_VALUE value); void SkipMidi(FILE *in, MIDI_VALUE junk); void SkipBinary(FILE *in, MIDI_VALUE junk); /* main.c */ BOOL IsIOType(char ioType); BOOL CheckIOType(char opt, int ioFlag, FLAGS theFlags[]); BOOL HandleOptions(int argc, char *argv[], FLAGS theFlags[], char **infile, char **outfile); void ReadAndWriteStuff(FLAGS theFlags[], FILE *in, FILE *out); void SetTheFunctions(MIDI_RESULT (**getfcn)(), BOOL (**putfcn)(), void (**skipfcn)(), FLAGS theFlags[]); BOOL CheckFlags(FLAGS theFlags[]); void InitStuff(FLAGS theFlags[], FILE **in, FILE **out, char **inFile, char **outFile); BOOL MIDIPlayground(FLAGS theFlags[], FILE *in, FILE *out); /* wb.c */ /* help.c */ void BegForUsage(char *progName); void Help(char *progName); /* files.c */ FILE *OpenAFile(char *filename, char *mode, char *readOrWrite); BOOL FileExists(char *filename); BOOL DontOverwriteExistingFile(char *filename); BOOL SetupFiles(char *infile, char *outfile, FILE **in, FILE **out); void CloseFiles(FILE *in, FILE *out, char *filein, char *fileout); BOOL MakeFilename(char **dest, char *src); #ifndef OpenReadFile FILE *OpenReadFile(char *filename); #endif #ifndef OpenWriteFile FILE *OpenWriteFile(char *filename); #endif #endif /* _MP_H */