home *** CD-ROM | disk | FTP | other *** search
- /* Virtual MIDI Keyboard
- Written, arranged, produced by Carl Ch. v. Loesch.
- (c) 1989, 1990.
- */
- #include "Lynx.h"
-
- #include <libraries/ARPbase.h>
- struct ArpBase *ArpBase;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Window *win;
- struct RastPort *rp;
-
- #include <MIDI/MIDI.h>
- struct MidiBase *MidiBase;
- struct MSource *source=0;
- struct MDest *dest=0;
- struct MRoute *droute=0, *sroute=0, *troute;
- struct MRouteInfo routeinfo = { MMF_NOTEOFF | MMF_NOTEON, 0xffff };
-
- static UBYTE keytable[128] = {
- 0,61,63,0,66,68,70,0,73,75,0,78,80,82,0,0, /* 0..15 */
- 62,64,65,67,69,71,72,74,76,77,79,81,0,0,0,0, /* 16..31 */
- 42,44,46,0,49,51,0,54,56,58,0,0,0,0,0,0, /* 32..47 */
- 41,43,45,47,48,50,52,53,55,57,59,0,0,0,0,0, /* 48..63 */
- 0,0,60,0,83,0,0,0,0,0,0,0,0,0,0,0, /* 64..79 (tab,cr) */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 80..95 */
- 0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 96..111 (rsh) */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 112..127 */
- };
-
- #define JOKES 6
- static char jokes[JOKES][70] = {
- " INCORRECT PASSWORD. TRY AGAIN. ",
- " The password to go eat at the mensa is 'MAHLZEIT' ",
- " How many cans can a can can if a can can can cans? ",
- " The Lynx says: The best is yet to come... to come... to come... ",
- " The Lord of Sequence. The ultimate Amiga MIDI sequencer program. ",
- "Greet'ns to SNEAK, NOAK, KIR, MADGUIT, KBR, YETI, ANT, WIZ, CRACKAKAN.",
- };
-
- struct NewWindow nw = {
- 0, 11, 640, 40,
- 1, 2, CLOSEWINDOW+RAWKEY,
- WINDOWCLOSE+WINDOWDEPTH+WINDOWDRAG+SMART_REFRESH,
- NULL, NULL, NULL, NULL, NULL,
- 0, 0, 0, 0,
- WBENCHSCREEN
- };
-
- char keyboard[] = "Keyboard", *name = keyboard;
- char midiin[] = "MidiIn", *input = midiin;
- char midiout[] = "MidiOut", *output= midiout;
- char nomem[] = "Gimme RAM!";
- char banner[] =
- "*| Virtual MIDI Keyboard V1.0 by Carlo \"Lynx\" von Loesch (c)89 |*";
- char header[] = "*| Virtual MIDI Keyboard ", *title = header;
- FLAG logon = TRUE, thru = FALSE;
- EXPORT long videosig, sigs;
-
- main(argc, argv) long argc; char *argv[]; {
- register struct IntuiMessage *tuimsg;
- register union Event *e;
- register long t;
- register short s;
-
- ifnot (ArpBase = OpenLibrary("arp.library",ArpVersion))
- Ciao("No ARP.Library");
- IntuitionBase = ArpBase -> IntuiBase;
- GfxBase = ArpBase -> GfxBase;
- ifnot (MidiBase = ArpOpenLibrary (MIDINAME,MIDIVERSION))
- Ciao ("No MIDI.Library");
-
- for (t=1; t<argc; t++) {
- if (argv[t][0]=='-') select (argv[t][1]) {
- when 'i': input = argv[++t]; break;
- when 'o': output = argv[++t]; break;
- when 't': Thru(); break;
- otherwise Ciao("Bad args");
- }
- else title = name = argv[t];
- }
- win = MyOpenWindow (&nw);
- SetWindowTitles (win, title, banner);
- rp = win->RPort;
- for (t=0; t<10; t++) DrawOctave (rp, t);
-
- ifnot (source = CreateMSource (name, NULL)) Ciao (nomem);
- ifnot (dest = CreateMDest (name, NULL)) Ciao (nomem);
- sroute = MRouteSource (source, output, NULL);
- droute = MRouteDest (input, dest, &routeinfo);
-
- sigs = videosig | (1L << dest->DestPort->SIGH);
- while (logon) {
- if (videosig != Wait (sigs))
- while (e = GetMidiMsg (dest)) {
- Show (e->l);
- FreeMidiMsg (e);
- }
- else while (tuimsg = GetMsg (win->UserPort)) {
- t=tuimsg->Class; s=tuimsg->Code; ReplyMsg (tuimsg);
- select (t) {
- when RAWKEY: HitaKey(s); break;
- when CLOSEWINDOW: logon = FALSE;
- }
- }
- }
- Ciao ("Please close the window, it's cold outside. *grin* :-)");
- }
-
- HitaKey (raw)
- short raw; {
- static union Event e;
- static char chan;
- static FLAG amiga = FALSE;
- #ifdef CTRL
- static FLAG ctrl = FALSE;
- #endif
- register UBYTE z;
-
- z = (UBYTE) (raw & 0x7f);
- if (z == 103) {
- if (raw & 0x80) amiga=FALSE;
- else amiga=TRUE;
- return;
- }
- #ifdef CTRL
- if (z == 99) {
- if (raw & 0x80) ctrl=FALSE;
- else ctrl=TRUE;
- return;
- }
- if (ctrl) select (raw) {
- when 51:/* C */ logon = FALSE;
- }
- else
- #endif
- if (amiga) select (raw) {
- when 0: /* ` */ Thru();
- }
- else if (e.p[1] = keytable[z]) {
- e.p[0] = MS_NOTEON + chan;
- if (raw & 0x80) e.p[2] = 0;
- else e.p[2] = 64;
- /* I think 64 is the standard velocity value for non-dynamic keyboards */
- PutMidiMsg (source, &e);
- Show (e);
- }
- else select (raw) {
- when 89:/*F10*/ Thru(); break;
- when 43:/* # */ Jokerman(); break;
- when 81:/*F2*/ chan+=2; if (chan>16) chan=1;
- when 80:/*F1*/ if (--chan<0) chan=15;
- title[0] = chan+49; Say (title);
- }
- }
-
- Thru() {
- register UBYTE *ret;
-
- if (thru = !thru)
- if (troute = MRoutePublic (input, output, routeinfo))
- ret = "Route has been established.";
- else { thru = NO; ret = "No route could be established."; }
- else { DeleteMRoute (troute); ret = "Route deleted."; }
- Say (ret);
- }
-
- #define COLORS 4
- #define DEPTH 2
- #define TOP 11
- #define BOT 37
- #define MID 26
- #define LEFMARG 5
-
- Show (e)
- union Event e; {
- register long z, o;
- static char offs[12] =
- { 1, 6, 11, 16, 22, 27, 32, 37, 42, 47, 52, 58 };
- static char white[12] =
- { 1, 0, 10, 0, 19, 28, 0, 37, 0, 46, 0, 55 };
-
- z = e.p[2]; /* velocity */
- if (!z || e.p[0] == MS_NOTEOFF) SetAPen (rp, 0L);
- else SetAPen (rp, z / (128/(COLORS-1)) + 1 );
- if (z == 7) Jokerman();
-
- z = e.p[1] % 12; o = 63 * (e.p[1]-z)/12 + LEFMARG;
- if (white[z]) RectFill (rp, o+white[z], MID+1, o+white[z]+7, BOT-1);
- z = o + offs[z] + 1;
- RectFill (rp, z, TOP+1, z+3, MID-1);
- }
-
- DrawOctave (raz, x)
- int raz, x; {
- x = 63*x + LEFMARG;
- Move (raz, x, TOP); /* box around it */
- Draw (raz, x+63, TOP); Draw (raz, x+63, BOT);
- Draw (raz, x, BOT); Draw (raz, x, TOP);
-
- x+=9; Move (raz, x, BOT); DrawKey (raz, x, 3);
- x+=9; Move (raz, x, BOT); DrawKey (raz, x, 2);
- x+=9; Move (raz, x, BOT); Draw (raz, x, TOP);
- x+=9; Move (raz, x, BOT); DrawKey (raz, x, 4);
- x+=9; Move (raz, x, BOT); DrawKey (raz, x, 3);
- x+=9; Move (raz, x, BOT); DrawKey (raz, x, 2);
- }
-
- DrawKey (raz, x, i)
- int raz, x, i; {
- Draw (raz, x, MID);
- Draw (raz, x-i, MID);
- Draw (raz, x-i, TOP);
- Move (raz, x, MID);
- Draw (raz, x-i+5, MID);
- Draw (raz, x-i+5, TOP);
- }
-
- Jokerman() {
- static UBYTE joker = 0;
- SetWindowTitles (win, jokes[joker++], banner);
- if (joker==JOKES) joker = 0;
- }
-
- Say (str) char *str; { if (win) SetWindowTitles (win, -1L, str); }
-
- Ciao (str)
- char *str; {
- if (str) { Say (str); Delay (25L); }
- if (win) CloseWindowSafely (win);
- if (droute) DeleteMRoute (droute);
- if (sroute) DeleteMRoute (sroute);
- if (thru) DeleteMRoute (troute);
- if (dest) DeleteMDest (dest);
- if (source) DeleteMSource (source);
- if (ArpBase) CloseLibrary (ArpBase);
- exit (NULL);
- }
-