home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / amiga / midi / mstuffpr.zoo / MIDIstuff / src / MIDIkeys.c < prev    next >
C/C++ Source or Header  |  1990-08-16  |  6KB  |  240 lines

  1. /*                  Virtual MIDI Keyboard
  2.         Written, arranged, produced by Carl Ch. v. Loesch.
  3.                 (c)  1989, 1990.
  4. */
  5. #include "Lynx.h"
  6.  
  7. #include <libraries/ARPbase.h>
  8. struct    ArpBase        *ArpBase;
  9. struct    IntuitionBase    *IntuitionBase;
  10. struct    GfxBase        *GfxBase;
  11. struct    Window        *win;
  12. struct    RastPort    *rp;
  13.  
  14. #include <MIDI/MIDI.h>
  15. struct    MidiBase    *MidiBase;
  16. struct    MSource        *source=0;
  17. struct    MDest        *dest=0;
  18. struct    MRoute        *droute=0, *sroute=0, *troute;
  19. struct    MRouteInfo    routeinfo = { MMF_NOTEOFF | MMF_NOTEON, 0xffff };
  20.  
  21. static UBYTE keytable[128] = {
  22.     0,61,63,0,66,68,70,0,73,75,0,78,80,82,0,0,    /*  0..15 */
  23.     62,64,65,67,69,71,72,74,76,77,79,81,0,0,0,0,    /* 16..31 */
  24.     42,44,46,0,49,51,0,54,56,58,0,0,0,0,0,0,    /* 32..47 */
  25.     41,43,45,47,48,50,52,53,55,57,59,0,0,0,0,0,    /* 48..63 */
  26.     0,0,60,0,83,0,0,0,0,0,0,0,0,0,0,0,        /* 64..79 (tab,cr) */
  27.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 80..95 */
  28.     0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 96..111 (rsh) */
  29.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 112..127 */
  30.     };
  31.  
  32. #define    JOKES    6
  33. static    char jokes[JOKES][70] = {
  34. "                    INCORRECT PASSWORD. TRY AGAIN.                    ",
  35. "           The password to go eat at the mensa is 'MAHLZEIT'          ",
  36. "          How many cans can a can can if a can can can cans?          ",
  37. " The Lynx says:    The best is yet to come... to come... to come...   ",
  38. "    The Lord of Sequence. The ultimate Amiga MIDI sequencer program.  ",
  39. "Greet'ns to SNEAK, NOAK, KIR, MADGUIT, KBR, YETI, ANT, WIZ, CRACKAKAN.",
  40. };
  41.  
  42. struct NewWindow nw = {
  43.     0, 11, 640, 40,
  44.     1, 2, CLOSEWINDOW+RAWKEY,
  45.     WINDOWCLOSE+WINDOWDEPTH+WINDOWDRAG+SMART_REFRESH,
  46.     NULL, NULL, NULL, NULL, NULL,
  47.     0, 0, 0, 0,
  48.     WBENCHSCREEN
  49. };
  50.  
  51. char    keyboard[] =    "Keyboard",    *name  = keyboard;
  52. char    midiin[] =    "MidiIn",    *input = midiin;
  53. char    midiout[] =    "MidiOut",    *output= midiout;
  54. char    nomem[] = "Gimme RAM!";
  55. char    banner[] =
  56.  "*| Virtual MIDI Keyboard V1.0 by Carlo \"Lynx\" von Loesch (c)89 |*";
  57. char    header[] = "*| Virtual MIDI Keyboard ", *title = header;
  58. FLAG    logon = TRUE, thru = FALSE;
  59. EXPORT    long    videosig, sigs;
  60.  
  61. main(argc, argv) long argc; char *argv[]; {
  62.     register struct    IntuiMessage    *tuimsg;
  63.     register union Event    *e;
  64.     register long    t;
  65.     register short    s;
  66.  
  67.     ifnot (ArpBase = OpenLibrary("arp.library",ArpVersion))
  68.         Ciao("No ARP.Library");
  69.     IntuitionBase =    ArpBase -> IntuiBase;
  70.     GfxBase =    ArpBase -> GfxBase;
  71.     ifnot (MidiBase = ArpOpenLibrary (MIDINAME,MIDIVERSION))
  72.         Ciao ("No MIDI.Library");
  73.  
  74.     for (t=1; t<argc; t++) {
  75.         if (argv[t][0]=='-') select (argv[t][1]) {
  76. when 'i':        input = argv[++t]; break;
  77. when 'o':        output = argv[++t]; break;
  78. when 't':        Thru(); break;
  79. otherwise        Ciao("Bad args");
  80.         }
  81.         else title = name = argv[t];
  82.     }
  83.     win = MyOpenWindow (&nw);
  84.     SetWindowTitles (win, title, banner);
  85.     rp = win->RPort;
  86.     for (t=0; t<10; t++) DrawOctave (rp, t);
  87.  
  88.     ifnot    (source = CreateMSource (name, NULL))    Ciao (nomem);
  89.     ifnot    (dest = CreateMDest (name, NULL))    Ciao (nomem);
  90.     sroute = MRouteSource (source, output, NULL);
  91.     droute = MRouteDest (input, dest, &routeinfo);
  92.  
  93.     sigs = videosig | (1L << dest->DestPort->SIGH);
  94.     while (logon) {
  95.         if (videosig != Wait (sigs))
  96.             while (e = GetMidiMsg (dest)) {
  97.             Show (e->l);
  98.             FreeMidiMsg (e);
  99.         }
  100.         else while (tuimsg = GetMsg (win->UserPort)) {
  101.             t=tuimsg->Class; s=tuimsg->Code; ReplyMsg (tuimsg);
  102.             select (t) {
  103. when RAWKEY:            HitaKey(s); break;
  104. when CLOSEWINDOW:        logon = FALSE;
  105.             }
  106.         }
  107.     }
  108.     Ciao ("Please close the window, it's cold outside.  *grin*  :-)");
  109. }
  110.  
  111. HitaKey    (raw)
  112. short    raw; {
  113.     static union Event e;
  114.     static char    chan;
  115.     static FLAG amiga = FALSE;
  116. #ifdef    CTRL
  117.     static FLAG ctrl = FALSE;
  118. #endif
  119.     register UBYTE z;
  120.  
  121.     z = (UBYTE) (raw & 0x7f);
  122.     if (z == 103) {
  123.         if (raw & 0x80) amiga=FALSE;
  124.         else amiga=TRUE;
  125.         return;
  126.     }
  127. #ifdef    CTRL
  128.     if (z == 99) {
  129.         if (raw & 0x80) ctrl=FALSE;
  130.         else ctrl=TRUE;
  131.         return;
  132.     }
  133.     if (ctrl) select (raw) {
  134. when 51:/* C */    logon = FALSE;
  135.     }
  136.     else
  137. #endif
  138.     if (amiga) select (raw) {
  139. when 0: /* ` */    Thru();
  140.     }
  141.     else if (e.p[1] = keytable[z]) {
  142.         e.p[0] = MS_NOTEON + chan;
  143.         if (raw & 0x80)    e.p[2] = 0;
  144.         else        e.p[2] = 64;
  145. /* I think 64 is the standard velocity value for non-dynamic keyboards */
  146.         PutMidiMsg (source, &e);
  147.         Show (e);
  148.     }
  149.     else select (raw) {
  150. when 89:/*F10*/    Thru();    break;
  151. when 43:/* # */    Jokerman();    break;
  152. when 81:/*F2*/    chan+=2; if (chan>16) chan=1;
  153. when 80:/*F1*/    if (--chan<0) chan=15;
  154.         title[0] = chan+49; Say (title);
  155.     }
  156. }
  157.  
  158. Thru() {
  159.     register UBYTE *ret;
  160.  
  161.     if (thru = !thru)
  162.         if (troute = MRoutePublic (input, output, routeinfo))
  163.         ret = "Route has been established.";
  164.         else { thru = NO; ret = "No route could be established."; }
  165.     else { DeleteMRoute (troute); ret = "Route deleted."; }
  166.     Say (ret);
  167. }
  168.  
  169. #define COLORS    4
  170. #define DEPTH    2
  171. #define    TOP    11
  172. #define    BOT    37
  173. #define    MID    26
  174. #define    LEFMARG    5
  175.  
  176. Show (e)
  177.  union Event e; {
  178.     register long z, o;
  179.     static char offs[12] =
  180.         { 1, 6, 11, 16, 22, 27, 32, 37, 42, 47, 52, 58 };
  181.     static char white[12] =
  182.         { 1, 0, 10, 0, 19, 28, 0, 37, 0, 46, 0, 55 };
  183.  
  184.     z = e.p[2];            /* velocity */
  185.     if (!z || e.p[0] == MS_NOTEOFF)    SetAPen (rp, 0L);
  186.     else SetAPen (rp, z / (128/(COLORS-1)) + 1 );
  187.     if (z == 7) Jokerman();
  188.  
  189.     z = e.p[1] % 12;    o = 63 * (e.p[1]-z)/12 + LEFMARG;
  190.     if (white[z]) RectFill (rp, o+white[z], MID+1, o+white[z]+7, BOT-1);
  191.     z = o + offs[z] + 1;
  192.     RectFill (rp, z, TOP+1, z+3, MID-1);
  193. }
  194.  
  195. DrawOctave    (raz, x)
  196.    int    raz, x; {
  197.     x = 63*x + LEFMARG;
  198.     Move (raz, x, TOP);    /* box around it */
  199.     Draw (raz, x+63, TOP);    Draw (raz, x+63, BOT);
  200.     Draw (raz, x, BOT);    Draw (raz, x, TOP);
  201.  
  202.     x+=9;    Move (raz, x, BOT);    DrawKey (raz, x, 3);
  203.     x+=9;    Move (raz, x, BOT);    DrawKey (raz, x, 2);
  204.     x+=9;    Move (raz, x, BOT);    Draw    (raz, x, TOP);
  205.     x+=9;    Move (raz, x, BOT);    DrawKey (raz, x, 4);
  206.     x+=9;    Move (raz, x, BOT);    DrawKey (raz, x, 3);
  207.     x+=9;    Move (raz, x, BOT);    DrawKey (raz, x, 2);
  208. }
  209.  
  210. DrawKey        (raz, x, i)
  211.    int    raz, x, i; {
  212.     Draw (raz, x, MID);
  213.     Draw (raz, x-i, MID);
  214.     Draw (raz, x-i, TOP);
  215.     Move (raz, x, MID);
  216.     Draw (raz, x-i+5, MID);
  217.     Draw (raz, x-i+5, TOP);
  218. }
  219.  
  220. Jokerman() {
  221.     static UBYTE    joker = 0;
  222.     SetWindowTitles (win, jokes[joker++], banner);
  223.     if (joker==JOKES) joker = 0;
  224. }
  225.  
  226. Say (str) char *str; { if (win) SetWindowTitles (win, -1L, str); }
  227.  
  228. Ciao    (str)
  229.   char    *str; {
  230.     if (str) { Say (str); Delay (25L); }
  231.     if (win)    CloseWindowSafely (win);
  232.     if (droute)    DeleteMRoute    (droute);
  233.     if (sroute)    DeleteMRoute    (sroute);
  234.     if (thru)    DeleteMRoute    (troute);
  235.     if (dest)    DeleteMDest    (dest);
  236.     if (source)    DeleteMSource    (source);
  237.     if (ArpBase)    CloseLibrary    (ArpBase);
  238.     exit (NULL);
  239. }
  240.