home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 202.lha / MidiToolBox / Sysex-sources / sex.c < prev   
C/C++ Source or Header  |  1988-12-27  |  20KB  |  758 lines

  1. /*    (C) Copyright 1988 Jack Deckard   Helicon Software    */
  2. /*                                */
  3. /*    SYS-EX Filer Program  Load and Save SYS-EX dumps    */
  4.  
  5. #include <exec/types.h>
  6. #include <exec/exec.h>
  7. #include <exec/memory.h>
  8. #include <intuition/intuition.h>
  9. #include <libraries/dos.h>
  10. #include <libraries/dosextens.h>
  11. #include <stdio.h>
  12. #include <midi/midi.h>
  13. #include <functions.h>
  14. #include <fcntl.h>
  15. #include <libraries/arpbase.h>    /* Standard ARP header file */
  16. #include <arpfunc.h>    /* Predeclared functions */
  17.  
  18.  
  19. extern struct NewWindow NewWindowStructure1;
  20. extern struct Menu Menu1;
  21. extern struct Gadget Gadget1;
  22. extern struct IntuiText IText1;
  23. extern struct MenuItem    MenuItem1;
  24. extern struct MenuItem    MenuItem2;
  25. extern struct MenuItem    MenuItem3;
  26. extern struct MenuItem    MenuItem4;
  27. extern struct MenuItem    MenuItem5;
  28. extern struct Border Border3;
  29.  
  30. #define VERSION 33L    /* 1.2 Library Version    */
  31.  
  32. #define OTHER 0
  33. #define DX    1
  34. #define FB    2
  35. #define TX81Z   3
  36. #define MATRX6  10
  37.  
  38. /* Define all global variables, pointers, structures, etc    */
  39.  
  40. struct Window *window;
  41. struct IntuiMessage *message;
  42.  
  43. void *MidiBase;
  44.  
  45. UBYTE datasaved[] =    "       Data Saved         ";
  46. UBYTE ioerror[] =    "I/O ERROR  File not saved ";
  47. UBYTE ioerror2[] =    "I/O ERROR  Can't Read File";
  48. UBYTE ioerror3[] =    "I/O ERROR  Can't Open File";
  49. UBYTE ioerror4[] =    "I/O ERROR  File Not Found ";
  50. UBYTE dataerror[] =    "Data Error in SYS-EX File ";
  51. UBYTE loadaborted[] =    "     Load Aborted         ";
  52. UBYTE saveaborted[] =    "     Save Aborted         ";
  53. UBYTE yamtext[] =    "   File ID is Yamaha      ";
  54. UBYTE seqtext[] =    "File ID is Seq Circuits   ";
  55. UBYTE mootext[] =    "    File ID is Moog       ";
  56. UBYTE obetext[] =    "  File ID is Oberheim     ";
  57. UBYTE emutext[] =    "    File ID is E-mu       ";
  58. UBYTE roltext[] =    "   File ID is Roland      ";
  59. UBYTE kortext[] =    "    File ID is Korg       ";
  60. UBYTE castext[] =    "   File ID is Casio       ";
  61. UBYTE unktext[] =    "  File ID is Unknown      ";
  62.  
  63.  
  64. struct IntuiText Mess1 = {
  65.     1,0,JAM2,    /* front and back text pens, drawmode and fill byte */
  66.     36,35,    /* XY origin relative to container TopLeft */
  67.     NULL,    /* font pointer or NULL for default */
  68.     datasaved,    /* pointer to text */
  69.     NULL    /* next IntuiText structure */
  70. };
  71.  
  72. struct IntuiText Mess2 = {
  73.     1,0,JAM2,    /* front and back text pens, drawmode and fill byte */
  74.     60,47,    /* XY origin relative to container TopLeft */
  75.     NULL,    /* font pointer or NULL for default */
  76.     (UBYTE *)"Transmit Complete",    /* pointer to text */
  77.     NULL    /* next IntuiText structure */
  78. };
  79.  
  80. struct Image cleartext = {
  81. 0,0,
  82. 260,28,0,
  83. NULL,
  84. 0,0,
  85. NULL
  86. };
  87.  
  88. struct MDest *dest=0;
  89. struct MRoute *routei=0;
  90. struct MRouteInfo routeiinfo = { MMF_SYSEX };     /* receive only sys/ex msg's */
  91.  
  92. struct MSource *source=0;
  93. struct MRoute *routeo=0;
  94. struct MRouteInfo routeoinfo = { -1, -1 };    /* support all msg's */
  95.  
  96. char    def_dir[96] = "MIDI_Tools:sysexfiles";
  97. char    def_name[32];
  98. char    pathname[128];
  99.  
  100. BYTE LFR[] = "Load SysEx File";
  101. BYTE SFR[] = "Save SysEx File";
  102.  
  103. struct FileRequester FR = {
  104.     LFR,
  105.     def_name,
  106.     def_dir,
  107.     NULL,
  108.     NULL,
  109.     NULL,
  110.     NULL,
  111. };
  112.  
  113. /************/
  114.  
  115. UBYTE fbreq[] = {0xf0,0x43,0x75,0x00,0x20,0x00,0x00,0xf7};
  116. UBYTE dxreq[] = {0xf0,0x43,0x20,0x04,0xf7};
  117. UBYTE m6req[] = {0xf0,0x10,0x06,0x04,0x01,0x00,0xf7};
  118.  
  119.  
  120. UBYTE    ttxv1[] = "Which Voice Bank (1 - 2)?";
  121. UBYTE    ttxv2[] = "Which Voice Bank (1 - 7)?";
  122. UBYTE    ttxv3[] = "    Which Voice (0 - 99)?";
  123. UBYTE    ttxc1[] = "Which Config Bank (1-16)?";
  124. UBYTE    ttxs1[] = "  Splits Number (0 - 49)?";
  125.  
  126. struct IntuiText Title = {
  127.     1,0,JAM2,    /* front and back text pens, drawmode and fill byte */
  128.     4,5,    /* XY origin relative to container TopLeft */
  129.     NULL,    /* font pointer or NULL for default */
  130.     ttxv1,    /* pointer to text */
  131.     NULL    /* next IntuiText structure */
  132. };
  133.  
  134. UBYTE undo[4];
  135. UBYTE SNum[4];
  136.  
  137. struct StringInfo RSfo = {
  138.     SNum,
  139.     undo,
  140.     0,3,0,0,0,0,0,
  141.     NULL,
  142.     0,
  143.     NULL
  144. };
  145.  
  146. struct Gadget RGadget = {
  147.     NULL,    /* next gadget */
  148.     218,4,    /* origin XY of hit box relative to window TopLeft */
  149.     24,11,    /* hit box width and height */
  150.     NULL,    /* gadget flags */
  151.     RELVERIFY+LONGINT+ENDGADGET,    /* activation flags */
  152.     STRGADGET+REQGADGET,    /* gadget type flags */
  153.     (APTR)&Border3,    /* gadget border or image to be rendered */
  154.     NULL,    /* alternate imagery for selection */
  155.     NULL,    /* first IntuiText structure */
  156.     NULL,    /* gadget mutual-exclude long word */
  157.     (APTR)&RSfo,    /* SpecialInfo structure */
  158.     1,    /* user-definable data */
  159.     NULL    /* pointer to user-definable data */
  160. };
  161.  
  162. SHORT BRV1[] = {
  163.     0,0,
  164.     258,0,
  165.     258,60,
  166.     0,60,
  167.     0,0
  168. };
  169. struct Border BRs1 = {
  170.     -2,-1,    /* XY origin relative to container TopLeft */
  171.     1,0,JAM1,    /* front pen, back pen and drawmode */
  172.     5,    /* number of XY vectors */
  173.     BRV1,    /* pointer to XY vectors */
  174.     NULL    /* next border in list */
  175. };
  176.  
  177. struct Requester Rqstr1 = {
  178.     NULL,
  179.     4,11,256,58,    /* Left, Top, Width, Height */
  180.     0,0,
  181.     &RGadget,    /* first gadget in gadget list */
  182.     &BRs1,        /* Requester Border */
  183.     &Title,        /* window title */
  184.     NULL,        /* Flags */
  185.     0,
  186.     NULL,
  187.     {NULL},
  188.     {NULL},
  189.     NULL,
  190.     {NULL}
  191. };
  192.  
  193. /************************************************************************/
  194. main()
  195. {
  196. SHORT    GetReqNum();
  197. SHORT    savefile();
  198. struct FileLock *lock;
  199. struct FileHandle *filehandle;        /* Load voice file    */
  200. struct FileInfoBlock *fib;
  201. struct Gadget *igad;
  202. UBYTE    *midimsg,
  203.         *buffer;
  204. LONG    len,
  205.         gadgid;
  206. ULONG    class;
  207. USHORT    i,
  208.         j,
  209.         code,
  210.         menunum,
  211.         itemnum,
  212.         subnum,
  213.         checksum;
  214. SHORT    keepgoing = 1,
  215.         errorcheck = OTHER;
  216. char    lastchar;
  217. register LONG error;
  218. register UBYTE    id,
  219.         sysexch;
  220.  
  221. error = 1;
  222. sysexch = 15;
  223.  
  224. /*  Open libraries. If error, exit immediatly */
  225.  
  226. if(!(MidiBase = OpenLibrary (MIDINAME,MIDIVERSION)))
  227.     goto clean;
  228.  
  229. if(!(dest = CreateMDest (NULL,NULL)))
  230.     goto clean;
  231.  
  232. /* create our source node (private) */
  233. if(!(source = CreateMSource (NULL,NULL)))
  234.     goto clean;
  235.  
  236. /* create our routes to MidiIn and MidiOut */
  237. if(!(routei = MRouteDest ("MidiIn", dest, &routeiinfo)))
  238.     goto clean;
  239. if(!(routeo = MRouteSource (source,"MidiOut",&routeoinfo)))
  240.     goto clean;
  241.  
  242.  
  243. /* Initialize window struct, then call OpenWindow. Exit if error */
  244. if((window = (struct Window *)OpenWindow(&NewWindowStructure1)) == NULL)
  245.     goto clean;
  246.  
  247. /*  Initialize Menu items, then submit them to Intuition */
  248. SetMenuStrip(window,&Menu1);
  249.  
  250. /*  Wait for message at IDCMP port  */
  251. while(keepgoing)
  252.     {
  253.     /* wait for window message or midi message */
  254.     Wait((1L<<dest->DestPort->mp_SigBit)|(1L<<window->UserPort->mp_SigBit));
  255.     while((midimsg = GetMidiMsg(dest))!=NULL)
  256.         {
  257.         len = MidiMsgLength(midimsg);
  258.         error = 0;
  259.         if(len>5)
  260.             {
  261.             DrawImage(window->RPort,&cleartext,2L,28L);
  262.             if(errorcheck) /* check file for errors if possible */
  263.                 {
  264.                 checksum = 0;
  265.                 switch(errorcheck)
  266.                     {
  267.                     case DX:
  268.                         if(*(midimsg+3)==9)
  269.                             {
  270.                             error = 1;
  271.                             for (i = 6; i < 4102; ++i)
  272.                                 checksum += *(midimsg+i);
  273.                             checksum = 127 & ((~checksum)+1);
  274.                             if (checksum == *(midimsg+4102))
  275.                                 error = 0;
  276.                             }
  277.                         else if(*(midimsg+3)==1)
  278.                             {
  279.                             error = 1;
  280.                             for (i = 6; i < 161; ++i)
  281.                                 checksum += *(midimsg+i);
  282.                             checksum = 127 & ((~checksum)+1);
  283.                             if (checksum == *(midimsg+161))
  284.                                 error = 0;
  285.                             }
  286.                         break;
  287.                     case FB:
  288.                         if(*(midimsg+5)==0) /* check sum voice data to validate */
  289.                             {
  290.                             for(i=0;i<48;i++)
  291.                                 {
  292.                                 buffer = i * 131 + 74;
  293.                                 checksum = 0;
  294.                                 for (j=2;j<128;++j)
  295.                                     checksum += *(midimsg+buffer+j);
  296.                                 if(*(midimsg+buffer+130) != (UBYTE)(127 & ((~checksum)+1)))
  297.                                     {
  298.                                     error = 1;
  299.                                     i = 48;
  300.                                     }
  301.                                 }
  302.                             }
  303.                         else if((*(midimsg+5)==1)||(*(midimsg+5)==2)) /* check sum config data to validate */
  304.                             {
  305.                             for(i=9;i<169;i++)
  306.                                 checksum += *(midimsg+i);
  307.                             if(*(midimsg+169) != (UBYTE)(127&((~checksum)+1)))
  308.                                 error = 1;
  309.                             }
  310.                         else if(*(midimsg+5)==3) /* check sum all configs */
  311.                             {
  312.                             for(i=0;i<16;i++)
  313.                                 {
  314.                                 buffer = i*169+7;
  315.                                 for(j=2;j<169;j++)
  316.                                     checksum += *(midimsg+buffer+j);
  317.                                 if(*(midimsg+buffer+169)!=(UBYTE)(127&((~checksum)+1)))
  318.                                     error = 1;
  319.                                 }
  320.                             }
  321.                         break;
  322.                     case TX81Z:
  323.                         if(*(midimsg+3)==4)
  324.                             {
  325.                             error = 1;
  326.                             for (i = 6; i < 4102; ++i)
  327.                                 checksum += *(midimsg+i);
  328.                             checksum = 127 & ((~checksum)+1);
  329.                             if (checksum == *(midimsg+4102))
  330.                                 error = 0;
  331.                             }
  332.                         break;
  333.                     case MATRX6:
  334.                         error = 1;
  335.                         if(*(midimsg+3) == 1)
  336.                             {
  337.                             if(*(midimsg+274)==0xf7)
  338.                                 error = 0;
  339.                             }
  340.                         else if(*(midimsg+3)==2)
  341.                             {
  342.                             for(i=5;i<39;i++);
  343.                                 checksum +=*(midimsg+i);
  344.                             checksum = 127 & checksum;
  345.                             if(checksum == *(midimsg+39))
  346.                                 error = 0;
  347.                             }
  348.                         else if(*(midimsg+3)==3)
  349.                             {
  350.                             for(i=5;i<475;i++);
  351.                                 checksum +=*(midimsg+i);
  352.                             checksum = 127 & checksum;
  353.                             if(checksum == *(midimsg+475))
  354.                                 error = 0;
  355.                             }
  356.                         break;
  357.                     }
  358.                 }
  359.             if(error==0)
  360.                 {
  361.                 /* save voicedata to disk    */
  362.                 error = savefile(midimsg,len);
  363.                 FreeMidiMsg(midimsg);
  364.                 if(error == 1)
  365.                     {
  366.                     Mess1.IText = datasaved;
  367.                     PrintIText(window->RPort,&Mess1,0L,0L);
  368.                     }
  369.                 else if(error == 0)
  370.                     {
  371.                     Mess1.IText = ioerror;
  372.                     PrintIText(window->RPort,&Mess1,0L,0L);
  373.                     }
  374.                 else if(error == -1)
  375.                     {
  376.                     Mess1.IText = saveaborted;
  377.                     PrintIText(window->RPort,&Mess1,0L,0L);
  378.                     }
  379.                 }
  380.             else
  381.                 {
  382.                 FreeMidiMsg(midimsg);
  383.                 Mess1.IText = dataerror;
  384.                 PrintIText(window->RPort,&Mess1,0L,0L);
  385.                 }
  386.             }
  387.         else FreeMidiMsg(midimsg);
  388.         }
  389.     while((message=(struct IntuiMessage *)GetMsg(window->UserPort))!=NULL)
  390.         {
  391.         class = message->Class;
  392.         code = message->Code;
  393.         igad = (struct Gadget *) message->IAddress; /* Ptr to a gadget */
  394.         ReplyMsg(message);
  395.         DrawImage(window->RPort,&cleartext,2L,28L);
  396.         switch(class)
  397.             {
  398.             case CLOSEWINDOW:  /* User is ready to quit, so
  399.                 indicate that execution should terminate with
  400.                 next iteration of the loop. */
  401.                 keepgoing = 0;
  402.                 break;
  403.             case GADGETUP:
  404.                 gadgid = igad->GadgetID; /* Get GadgetID */
  405.                 switch(gadgid)
  406.                     {
  407.                     case 0:
  408.                         sysexch = (++sysexch) & 15;
  409.                         sprintf(IText1.IText,"%2d",(SHORT)sysexch + 1);
  410.                         RefreshGList(&Gadget1,window,NULL,1L);
  411.                         break;
  412.                     }
  413.                 break;
  414.             case MENUPICK:
  415.                 if(code!=MENUNULL)
  416.                     {
  417.                     menunum = MENUNUM(code);
  418.                     itemnum = ITEMNUM(code);
  419.                     subnum = SUBNUM(code);
  420.                     switch(menunum)
  421.                         {
  422.                         case 0: /* Amiga send SYSEX */
  423.                             /*  Load the file on disk into array voicefile  */
  424.                                 FR.fr_Hail = LFR;
  425.                                 if(FileRequest(&FR))
  426.                                 {
  427.                                 /* copy path and file name to pathname */
  428.                                 strcpy(pathname,def_dir);
  429.                                 if(strlen(pathname))
  430.                                     {
  431.                                     lastchar = pathname[strlen(pathname)-1];
  432.                                     if((lastchar!='/')||(lastchar!=':'))
  433.                                         strcpy(pathname+strlen(pathname),"/");
  434.                                     }
  435.                                 strcpy(pathname+strlen(pathname),def_name);
  436.                                 if(lock = (struct FileLock *)Lock(pathname,ACCESS_READ))
  437.                                     {
  438.                                     fib=(struct FileInfoBlock *)AllocMem((LONG)sizeof(struct FileInfoBlock),MEMF_CLEAR);
  439.                                     if(Examine(lock,fib))
  440.                                         {
  441.                                         len = (LONG)fib->fib_Size;
  442.                                         FreeMem(fib,(LONG)sizeof(struct FileInfoBlock));
  443.                                         buffer = (UBYTE *)AllocMem((LONG)len,0L);
  444.                                         filehandle = (struct FileHandle *)Open(pathname,MODE_OLDFILE);
  445.                                         if(filehandle)
  446.                                             {
  447.                                             if(Read(filehandle,buffer,(LONG)len) != -1)
  448.                                                 {
  449.                                                 Close(filehandle);
  450.                                                 UnLock(lock);
  451.                                                 if(*(buffer+1)==0x43) /* if yamaha file */
  452.                                                     {
  453.                                                     if(*(buffer+2)==0x75) /* if FB-01 file, get bank number to load to */
  454.                                                         {
  455.                                                         if(*(buffer+5)==0x00) /* Voice bank */
  456.                                                             {
  457.                                                             Title.IText = ttxv1;
  458.                                                             *(buffer+6) = GetReqNum();
  459.                                                             *(buffer+3) = sysexch;
  460.                                                             }
  461.                                                         else if((*(buffer+5)==0x01)||(*(buffer+5)==0x02)) /* Config Bank */
  462.                                                             {
  463.                                                             *(buffer+5) = 0x02;
  464.                                                             Title.IText = ttxc1;
  465.                                                             *(buffer+6) = GetReqNum();
  466.                                                             *(buffer+3) = sysexch;
  467.                                                             }
  468.                                                         }
  469.                                                     else *(buffer+2) = (*(buffer+2) & 0xf0)|sysexch;
  470.                                                     }
  471.                                                 else if(*(buffer+1)==0x10) /* Oberheim ID? */
  472.                                                     {
  473.                                                     if(*(buffer+2)==0x06) /* Matrix 6? */
  474.                                                         {
  475.                                                         if(*(buffer+3)==0x01) /* Single Voice? */
  476.                                                             {
  477.                                                             *(buffer+4)=(UBYTE)GetReqNum();
  478.                                                             }
  479.                                                         }
  480.                                                     }
  481.                                                 id = *(buffer+1);
  482.                                                 /* Print file ID */
  483.                                                 switch(id)
  484.                                                     {
  485.                                                     case 0x01:
  486.                                                         Mess1.IText = seqtext;
  487.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  488.                                                         break;
  489.                                                     case 0x04:
  490.                                                         Mess1.IText = mootext;
  491.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  492.                                                         break;
  493.                                                     case 0x10:
  494.                                                         Mess1.IText = obetext;
  495.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  496.                                                         break;
  497.                                                     case 0x18:
  498.                                                         Mess1.IText = emutext;
  499.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  500.                                                         break;
  501.                                                     case 0x41:
  502.                                                         Mess1.IText = roltext;
  503.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  504.                                                         break;
  505.                                                     case 0x42:
  506.                                                         Mess1.IText = kortext;
  507.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  508.                                                         break;
  509.                                                     case 0x43:
  510.                                                         Mess1.IText = yamtext;
  511.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  512.                                                         break;
  513.                                                     case 0x44:
  514.                                                         Mess1.IText = castext;
  515.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  516.                                                         break;
  517.                                                     Default:
  518.                                                         Mess1.IText = unktext;
  519.                                                         PrintIText(window->RPort,&Mess1,0L,0L);
  520.                                                         break;
  521.                                                     }
  522.                                                 /* transmit file */
  523.                                                 PutMidiMsg(source,buffer);
  524.                                                 FreeMem(buffer,len);
  525.                                                 PrintIText(window->RPort,&Mess1,0L,0L);
  526.                                                 PrintIText(window->RPort,&Mess2,0L,0L);
  527.                                                 }
  528.                                             else /* Can't READ file */ 
  529.                                                 {
  530.                                                 FreeMem(buffer,len);
  531.                                                 Close(filehandle); /* error    */
  532.                                                 UnLock(lock);
  533.                                                 Mess1.IText = ioerror2;
  534.                                                 PrintIText(window->RPort,&Mess1,0L,0L);
  535.                                                 }
  536.                                             }
  537.                                         else /* Can't Open file */ 
  538.                                             {
  539.                                             FreeMem(buffer,len);
  540.                                             UnLock(lock);
  541.                                             Mess1.IText = ioerror3;
  542.                                             PrintIText(window->RPort,&Mess1,0L,0L);
  543.                                             }
  544.                                         }
  545.                                     else /* Can't Examine file */
  546.                                         {
  547.                                         FreeMem(fib,(LONG)sizeof(struct FileInfoBlock));
  548.                                         UnLock(lock);
  549.                                         }
  550.                                     }
  551.                                 else /* Can't Lock file */
  552.                                     {
  553.                                     Mess1.IText = ioerror4;
  554.                                     PrintIText(window->RPort,&Mess1,0L,0L);
  555.                                     }
  556.                                 }
  557.                             else
  558.                                 {
  559.                                 Mess1.IText = loadaborted;
  560.                                 PrintIText(window->RPort,&Mess1,0L,0L);
  561.                                 }
  562.                             break;
  563.                         case 1:    /* Dump Request */
  564.                             switch(itemnum)
  565.                                 {
  566.                                 case 0: /* TX */
  567.                                     errorcheck = DX;
  568.                                     MenuItem1.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* DX, TX */
  569.                                     MenuItem2.Flags = MenuItem3.Flags = MenuItem4.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* Other */
  570.                                     dxreq[2] = 0x20 | sysexch;
  571.                                     dxreq[3] = 9;
  572.                                     PutMidiMsg(source,dxreq);
  573.                                     break;
  574.                                     break;
  575.                                 case 1: /* FB-01 */
  576.                                     errorcheck = FB;
  577.                                     MenuItem2.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* FB-01 */
  578.                                     MenuItem1.Flags = MenuItem3.Flags = MenuItem4.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* Other */
  579.                                     fbreq[3] = sysexch;
  580.                                     switch(subnum)
  581.                                         {
  582.                                         case 0:    /* Voice Bank X */
  583.                                             Title.IText = ttxv2;
  584.                                             i = GetReqNum();
  585.                                             fbreq[5] = 0;
  586.                                             fbreq[6] = i;
  587.                                             PutMidiMsg(source,fbreq);
  588.                                             break;
  589.                                         case 1: /* Config Bank X */
  590.                                             Title.IText = ttxc1;
  591.                                             i = GetReqNum();
  592.                                             fbreq[5] = 2;
  593.                                             fbreq[6] = i;
  594.                                             PutMidiMsg(source,fbreq);
  595.                                             break;
  596.                                         }
  597.                                     break;
  598.                                 case 2:    /* DX27 DX100 */
  599.                                     errorcheck = DX;
  600.                                     MenuItem1.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* DX, TX */
  601.                                     MenuItem2.Flags = MenuItem3.Flags = MenuItem4.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* Other */
  602.                                     dxreq[2] = 0x20 | sysexch;
  603.                                     dxreq[3] = 4;
  604.                                     PutMidiMsg(source,dxreq);
  605.                                     break;
  606.                                 case 3: /* Matrix 6 */
  607.                                     errorcheck = MATRX6;
  608.                                     MenuItem1.Flags = MenuItem2.Flags = MenuItem3.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* TX81Z */
  609.                                     MenuItem4.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* Matrix 6 */
  610.                                     switch(subnum)
  611.                                         {
  612.                                         case 0:    /* Voice file */
  613.                                             Title.IText = ttxv3;
  614.                                             m6req[4] = 0x01;
  615.                                             m6req[5] = (UBYTE)GetReqNum();
  616.                                             PutMidiMsg(source,m6req);
  617.                                             break;
  618.                                         case 1: /* Splits */
  619.                                             Title.IText = ttxs1;
  620.                                             m6req[4] = 2;
  621.                                             m6req[5] = (UBYTE)GetReqNum();
  622.                                             PutMidiMsg(source,m6req);
  623.                                             break;
  624.                                         case 2:
  625.                                             m6req[4] = 3;
  626.                                             PutMidiMsg(source,m6req);
  627.                                             break;
  628.                                         }
  629.                                     break;
  630.                                 }
  631.                             break;
  632.                         case 2: /* Error Checking and identification */
  633.                             switch(itemnum)
  634.                                 {
  635.                                 case 0: /* DX type */
  636.                                     errorcheck = DX;
  637.                                     break;
  638.                                 case 1: /* FB type */
  639.                                     errorcheck = FB;
  640.                                     break;
  641.                                 case 2: /* TX81Z */
  642.                                     errorcheck = TX81Z;
  643.                                     break;
  644.                                 case 3: /* Oberheim Matrix 6 */
  645.                                     errorcheck = MATRX6;
  646.                                     break;
  647.                                 case 4: /* None */
  648.                                     errorcheck = OTHER;
  649.                                     break;
  650.                                 }
  651.                             break;
  652.                         } /* end of switch(menunum) */
  653.                     } /*  end of if(menunum not null) */
  654.                 break;
  655.             } /* end of switch (class) */
  656.         } /* end of while(intuimessage)*/
  657.     } /* end while (keepgoing) */
  658.  
  659.  
  660. /*   Time to quit, so clean up and exit.                */
  661. clean:
  662.  
  663. if(window)
  664.     {
  665.     ClearMenuStrip(window);
  666.     CloseWindow(window);
  667.     }
  668. if(routei)
  669.     DeleteMRoute(routei);
  670. if(routeo)
  671.     DeleteMRoute(routeo);
  672. if(dest)
  673.     DeleteMDest(dest);
  674. if(source)
  675.     DeleteMSource(source);
  676. if(MidiBase)
  677.     CloseLibrary(MidiBase);
  678.  
  679. exit();
  680. }            /* end of main    */
  681.  
  682.  
  683. /************************************************************************/
  684. /*  Create a file on disk using buffered I/O. Open the disk file,    */
  685. /*  write the array to it, and close the file.                */
  686.  
  687. SHORT savefile(buffer,len)
  688. UBYTE *buffer;   /*  pointer to voice file    */
  689. long len;
  690. {
  691. struct FileHandle *filehandle;        /* Save voice file    */
  692. char    lastchar;
  693.  
  694. FR.fr_Hail = SFR;
  695.  
  696. if(FileRequest(&FR))
  697.     {
  698.     strcpy(pathname,def_dir);
  699.     if(strlen(pathname))
  700.         {
  701.         lastchar = pathname[strlen(pathname)-1];
  702.         if((lastchar!='/')||(lastchar!=':'))
  703.             strcpy(pathname+strlen(pathname),"/");
  704.         }
  705.     strcpy(pathname+strlen(pathname),def_name);
  706.     if(!(filehandle = Open(&pathname,MODE_NEWFILE)))
  707.         return(0);
  708.     if(Write(filehandle,buffer,len) == -1L)
  709.         {
  710.         Close(filehandle);    /* error    */
  711.         return(0);
  712.         }
  713.     Close(filehandle);
  714.     return(1);
  715.     }
  716. else
  717.     return(-1);    /* aborted save    */
  718.  
  719. }
  720.  
  721.  
  722. SHORT    GetReqNum()
  723. {
  724. SHORT returncode;
  725. LONG class;
  726.  
  727.  
  728. RGadget.LongInt = 0;
  729. RSfo.BufferPos = 0;
  730. RSfo.DispPos = 0;
  731.  
  732. for(returncode=0;returncode<4;returncode++)
  733.     SNum[returncode] = 0;
  734.  
  735. Request(&Rqstr1,window);
  736.  
  737. for(class = 0;class != REQSET;)
  738.     {
  739.     Wait(1L<<window->UserPort->mp_SigBit);
  740.     message=(struct IntuiMessage *)GetMsg(window->UserPort);
  741.     class = message->Class;
  742.     ReplyMsg(message);
  743.     }
  744.  
  745. ActivateGadget(&RGadget,window,&Rqstr1);
  746.  
  747. for(;class!=GADGETUP;)
  748.     {
  749.     Wait(1L<<window->UserPort->mp_SigBit);
  750.     message=(struct IntuiMessage *)GetMsg(window->UserPort);
  751.     class = message->Class;
  752.     ReplyMsg(message);
  753.     }
  754. returncode = RSfo.LongInt;
  755.  
  756. return(returncode);
  757. }
  758.