home *** CD-ROM | disk | FTP | other *** search
- /* M I D I R E C
-
- Little MIDI Recorder
- Written, arranged, produced by Carl Ch. v. Loesch.
-
- V0.1 February'89, V0.2 August'89, V0.3 July'90
- V1.0 August'90.
- #define DEBUG
- */
- #include "Lynx.h"
- extern struct Menu Menu1;
- extern struct NewWindow NewWindowStructure1;
- EXPORT char ret[80];
-
- #include <MIDI/MIDI.h>
- EXPORT struct MidiBase *MidiBase;
- EXPORT struct MSource *source=0;
- EXPORT struct MDest *dest=0;
- EXPORT struct MRoute *droute=0, *sroute=0, *troute;
- static struct MRouteInfo routeinfo = { MMF_CHAN + MMF_SYSRT, 0xffff };
-
- EXPORT char prgname[] = "Recorder", *name = prgname;
- EXPORT char midiin[] = "MidiIn", *input = midiin;
- EXPORT char midiout[] = "MidiOut", *output= midiout;
-
- #include <libraries/ARPbase.h>
- EXPORT struct ArpBase *ArpBase;
- EXPORT struct IntuitionBase *IntuitionBase;
- EXPORT char file[FCHARS+DSIZE+1]="", dir[DSIZE+1]="Sequences",
- loadname[FCHARS+1]="Hello", savename[FCHARS+1]="Hello";
- EXPORT struct FileRequester *freq;
- EXPORT struct Window *win;
-
- #define TAPELEN 15000
- EXPORT struct Tape {
- union Event event;
- short clock;
- } *tape;
-
- #define RECORDERPRIO 3L
- EXPORT char banner[] =
- "*| Little MIDI Recorder V1.0 by Carlo \"Lynx\" von Loesch (c)90 |*";
- EXPORT char *title = banner;
- EXPORT char nomem[] = "Out of RAM";
- EXPORT ULONG tc = 0, tl = 0, ck = 0, nextck, lastck;
- EXPORT FLAG on = YES, thru = NO, play = NO, rec = NO;
- EXPORT long midisig, videosig, sigs;
-
- main(argc, argv) long argc; char *argv[]; {
- register long t;
- register short s;
- register union Event *e;
-
- ifnot (ArpBase = OpenLibrary("arp.library",ArpVersion))
- Ciao("No ARP.Library");
- IntuitionBase = ArpBase -> IntuiBase;
- ifnot (MidiBase = ArpOpenLibrary (MIDINAME,MIDIVERSION))
- Ciao ("No MIDI.Library");
- ifnot (tape = ArpAlloc (TAPELEN * sizeof(struct Tape)))
- Ciao (nomem);
-
- 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];
- }
- ifnot (source = CreateMSource (name, NULL)) Ciao (nomem);
- ifnot (sroute = MRouteSource (source, output, NULL))
- Ciao ("No route out");
- ifnot (dest = CreateMDest (name, NULL)) Ciao (nomem);
- ifnot (droute = MRouteDest (input, dest, &routeinfo))
- Ciao ("No route in");
- midisig = 1L<<dest->DestPort->SIGH;
-
- win = MyOpenWindow(&NewWindowStructure1); Say (banner);
- SetMenuStrip (win, &Menu1);
- sigs = videosig | midisig;
-
- ifnot (freq = ArpAllocFreq()) Ciao (nomem);
- freq->fr_Dir = dir; freq->fr_Window = win;
- freq -> fr_FuncFlags = FRF_NewWindFunc;
-
- #ifdef RECORDERPRIO
- SetTaskPri(FindTask((char *) 0L), RECORDERPRIO);
- #endif
- while (on) {
- t = Wait (sigs);
- if (t == midisig) while (e = GetMidiMsg (dest)) {
- HandleMIDI (e->l); FreeMidiMsg (e);
- } else MyCheckTui();
- }
- Ciao (NULL);
- }
-
- HandleMIDI (e) union Event e; {
- if (e.p[0] > 0xf0) select (e.p[0]) {
- when MS_CLOCK: if (play) PlayIt(); break;
- when MS_START: Rewind();
- when MS_CONTINUE: play=YES; LBUG ("PLAY at clk", ck); break;
- when MS_STOP: play=NO; LBUG ("STOP at clk", ck); break;
- otherwise XBUG ("Weird Event", e.l);
- }
- else if (rec && play && tl < TAPELEN) {
- #ifdef TOUCHSTART
- if (!tl) ck=1;
- /* start counting from first input, ignoring sync */
- #endif
- tape[tl].clock = ck - lastck;
- tape[tl++].event = e;
- lastck = ck;
- }
- }
-
- PlayIt() {
- if (!rec && (ck == nextck)) {
- PutMidiMsg (source, &tape[tc++].event);
- while (tape[tc].clock == 0)
- PutMidiMsg (source, &tape[tc++].event);
- if (tc < tl) nextck = ck + tape[tc].clock;
- else nextck = 0;
- }
- ck++;
- }
-
- Thru() {
- if (thru = !thru)
- if (troute = MRoutePublic (input, output, routeinfo))
- SPrintf (ret,
- "Route between %s and %s has been established.", input, output);
- else { thru = NO; SPrintf (ret,
- "No route between %s and %s could be established.", input, output);
- }
- else {
- DeleteMRoute (troute);
- SPrintf (ret, "Ok. No more route between %s and %s.",
- input, output);
- }
- Say (ret);
- }
-
- Record() {
- rec=!rec;
- FBUG ("RECORD", rec);
- Rewind();
- }
- Rewind() {
- tc=0; ck=1; nextck=(ULONG) tape[0].clock; lastck=1;
- if (rec) tl=0;
- LBUG ("REWIND with tl", tl);
- }
- SaveIt() {
- if (tl) Save (file, &tape[0],(long) tl*sizeof(struct Tape));
- }
- LoadIt() {
- play=NO; Rewind();
- tl = Load (file, &tape[0],(long) TAPELEN*sizeof(struct Tape))
- / sizeof(struct Tape);
- }
- Help() {
- SPrintf (ret, "Clock: %ld, Counter: %ld, SeqLength: %ld.",
- ck, tc, tl); Say (ret);
- }
-
- MyCheckTui() {
- register struct IntuiMessage *tuimsg;
- register ULONG class, obj;
- register USHORT code;
-
- while (tuimsg = GetMsg (win->UserPort)) {
- class = tuimsg->Class;
- code = tuimsg->Code;
- obj= tuimsg->IAddress; ReplyMsg (tuimsg);
- switch (class) {
- case MENUPICK: DoMenu(code); break;
- case GADGETUP: HandleEvent (obj); break;
- case CLOSEWINDOW: Ciao (NULL);
- }
- }
- }
-
- DoMenu (code) USHORT code; {
- NBUG (" MenuCode", code);
- select (MENUNUM(code)) {
- when 0: select (ITEMNUM(code)) {
- when 0: LoadAs(); break;
- when 1: LoadIt(); break;
- when 2: SaveAs(); break;
- when 3: SaveIt(); break;
- when 4: Ciao(NULL);
- } break;
- when 1: select (ITEMNUM(code)) {
- when 0: Help(); break;
- when 1: Thru();
- }
- }
- }
-
- Say (str) char *str; { if (win) SetWindowTitles (win, -1L, str); }
-
- Ciao (str) char *str; {
- 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) {
- if (str) Puts(str);
- CloseLibrary (ArpBase);
- }
- exit (str ? 4404L : 0L);
- }
-