home *** CD-ROM | disk | FTP | other *** search
/ Chestnut's Multimedia Mania / MM_MANIA.ISO / midi / cmtcmu / dxput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-28  |  7.4 KB  |  221 lines

  1. /* dxput.c -- program to send Yamaha exclusive messages from file */
  2.  
  3. /*****************************************************************************
  4. *        Change Log
  5. *  Date        | Change
  6. *-----------+-----------------------------------------------------------------
  7. * 13-Jun-86 | Created Change Log
  8. *  6-Aug-86 | Adapted to Lattice C V3.00
  9. *****************************************************************************/
  10.  
  11. #include "cext.h"
  12. #include "stdio.h"
  13. #include "midicode.h"
  14. #include "mpu.h"
  15. #include "userio.h"
  16. #include "cmdline.h"
  17.  
  18. #define buffsize 17000
  19. byte midibuff[buffsize];
  20.  
  21. extern int miditrace;
  22.  
  23. int xflag;    /* for debugging */
  24.  
  25. int debptr;
  26.  
  27. /****************************************************************************
  28. * Data for command line parsing
  29. ****************************************************************************/
  30. #define nswitches 8
  31. private char *switches[nswitches] = 
  32.     { "-help", "-miditrace", "-m", "-trace", "-t", "-block", "-d", "-debug" };
  33.  
  34. #define noptions 1
  35. private char *options[noptions] = { "-tune" };
  36.  
  37. /*****************************************************************************
  38. *    Routines local to this module
  39. *****************************************************************************/
  40. private void    instruct();
  41. private boolean isdangerous();
  42. private boolean output();
  43. private    boolean    readbuff();
  44.  
  45. /****************************************************************************
  46. *                instruct
  47. * Effect: prints instructions for this routine
  48. ****************************************************************************/
  49.  
  50. private void instruct()
  51. {
  52. printf("This program will let you send voice programs to a DX7 or TX816.\n");
  53. printf("You must send a file previously created by the dxget program.\n");
  54. printf("To send DX7 programs, you must connect\n");
  55. printf("    MPU 401 MIDI OUT to DX7 MIDI IN.\n");
  56. printf("For TX816 programs, connect MPU 401 MIDI OUT to TX816 MIDI IN.\n");
  57. printf("For a DX7 voice: push the orange FUNCTION key, then the green 8.\n");
  58. printf("    Push 8 repeatedly until the display says SYS INFO AVAIL\n");
  59. printf("    or SYS INFO UNAVAIL.  If the display says SYS INFO\n");
  60. printf("    UNAVAIL, push YES to change to SYS INFO AVAIL.\n");
  61. printf("    Next, push MEMORY PROTECT/INTERNAL, then NO, and then\n");
  62. printf("    then MEMORY SELECT/INTERNAL. Now, type the name of a file\n");
  63. printf("    created by dxget and then the space bar to send data.\n");
  64. printf("    To store the voice program on the DX7, hold down STORE\n");
  65. printf("    while you push a (green) number.  The current voice at\n");
  66. printf("    this number will be erased and replaced by the new voice.\n");
  67. printf("For ALL DX7 voices: Same as for a single DX7 voice, but all 32\n");
  68. printf("    voice programs on the DX7 will be replaced whey you type\n");
  69. printf("    Y in response to `Are you sure?' on the computer.\n");
  70. printf("For all TX816 voices: To store into one module, push NO until the\n");
  71. printf("    MEMORY PROTECT light goes out.    Make sure other MEMORY\n");
  72. printf("    PROTECT lights are ON.    Type Y in response to 'Are you\n");
  73. printf("    sure?' on the computer.\n");
  74. }
  75.  
  76. /****************************************************************************
  77. *                isdangerous
  78. * Inputs:
  79. *    byte *msg: pointer message to check
  80. * Outputs:
  81. *    returns true if message can destroy lots of info (block data message)
  82. ****************************************************************************/
  83.  
  84. private boolean isdangerous(msg)
  85. byte *msg;
  86. {
  87.     /* look for 32 voice and 64 performance data msgs */
  88.     return (msg[1] == 0x43 && (msg[3] == 2 || msg[3] == 9));
  89. }
  90.  
  91. /****************************************************************************
  92. *                main
  93. * Effect: main program -- prompt user for information and put data
  94. ****************************************************************************/
  95.  
  96. void main(argc, argv)
  97.     int argc;
  98.     char *argv[];
  99. {
  100.     FILE *fp;        /* the input file */
  101.     int count;        /* length of data in file */
  102.     byte *msg;        /* message pointer */
  103.     int done = false;    /* flag is true when user is done */
  104.     char filename[100];    /* the output file name */
  105.     char *s;        /* the file name in the command line */
  106.  
  107.     cl_init(switches, nswitches, options, noptions, argv, argc);
  108.     if (cl_switch("-help")) instruct();
  109.     /* get input file name: */
  110.     filename[0] = 0;    /* empty string */
  111.     if ((s = cl_arg(1)) != NULL) strcpy(filename, s);
  112.  
  113.  
  114.     while (!done) {
  115.     if (askbool("Do you want instructions", true)) instruct();
  116.  
  117.     fp = fileopen(filename, "dx7", "r", "file name");
  118.  
  119.     if (!readbuff(fp, midibuff, &count)) {
  120.         printf("Something is wrong with your data or you typed the\n");
  121.         printf("wrong file name.  Please try again.\n");
  122.         exit(1);
  123.     }
  124.  
  125.     printf("\nReady with your data. Type space when you are ready...\n");
  126.     while (true) {
  127.         if (kbhit() && getch() == ' ') break;
  128.     }
  129.     musicinit();
  130.     exclusive(true);
  131.     msg = midibuff;
  132.     while (output(&msg, midibuff + count))
  133.          /* write messages */;
  134.     musicterm();
  135.     fclose(fp);
  136.     printf("DONE\n");
  137.  
  138.     done = !askbool("Do you want to send another file", false);
  139.     filename[0] = 0;    /* force prompt for new file name */
  140.     }    
  141. }
  142.  
  143. /****************************************************************************
  144. *                output
  145. * Inputs:
  146. *    byte **msg: pointer to message to send
  147. *    byte *msg_tail: pointer to byte after last message byte
  148. * Outputs:
  149. *    *msg is set to byte after last byte of the message sent
  150. *    returns true if there is more data to send
  151. * Effect: sends exclusive messages using recorded data
  152. * Assumes: msg_tail > *msg
  153. * Implementation:
  154. ****************************************************************************/
  155.  
  156. private boolean output(msg, msg_tail)
  157.     byte **msg;
  158.     byte *msg_tail;
  159. {
  160.     byte *this_msg = *msg;
  161.     int datalen;
  162.     int cksum;
  163.     int n;        /* counts bytes printed on one line */
  164.     int OK;        /* OK to send message */
  165. /*    printf("*msg %x, this_msg %x, msg_tail %x\n",
  166.         *msg, this_msg, msg_tail);
  167.     printf("%d bytes to go.\n", msg_tail - this_msg);
  168. */
  169.     excldesc(this_msg);
  170.     this_msg = *msg;
  171.     datalen = (this_msg[4] << 7) + this_msg[5];
  172. /*    printf("datalen %x\n", datalen);*/
  173.     cksum = 0;
  174.     for (n = 6; n < datalen+6; n++) {
  175.     cksum = (cksum + this_msg[n]) & 0x7f;
  176.     }
  177.     if (datalen == 0 || (cksum + this_msg[datalen+6]) & 0x7f != 0) {
  178.     printf("Data in your file is garbled.\n");
  179.     return false;
  180.     }
  181.     if (isdangerous(this_msg)) {
  182.     OK = askbool("Are you sure", false);
  183.     } else OK = true;
  184.     if (OK) midi_exclusive(this_msg);
  185.  
  186.     do {    /* always skip first byte, */
  187.         /* then terminate after finding MIDI_EOX */
  188.     this_msg++;
  189.     } while (this_msg < msg_tail && *(this_msg-1) != MIDI_EOX) ;
  190.     *msg = this_msg;
  191.     return this_msg < msg_tail;
  192. }
  193.  
  194. /****************************************************************************
  195. *                readbuff
  196. * Inputs:
  197. *    FILE *fp: file from which to read
  198. * Outputs:
  199. *    byte *buff: where to put the data
  200. *    int *count: count is set to the number of of bytes read
  201. * Effect: 
  202. *    read midi exclusive data from a file into buff
  203. * Assumes:
  204. *    fp is open for reading
  205. ****************************************************************************/
  206.  
  207. private boolean readbuff(fp, buff, count)
  208.     FILE *fp;
  209.     byte *buff;
  210.     int *count; /* result */
  211. {
  212.     int i;
  213.     *count = 0;
  214.     while (fscanf(fp, "%x", &i) > 0) {
  215.     *buff = i;
  216.     buff++;
  217.     (*count)++;
  218.     }
  219.     return *count != 0;
  220. }
  221.