home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
amiga
/
midi
/
mstuffpr.zoo
/
MIDIstuff
/
src
/
MIDIrec.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-16
|
6KB
|
217 lines
/* 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);
}