home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
sound
/
midi
/
midi20.arc
/
XFile.7
< prev
next >
Wrap
Text File
|
1988-10-23
|
8KB
|
342 lines
/* simple MIDI router */
/*
This is considered an example even though it's included with the
utility set. It shows methods for scanning public node lists and
managing routes to public nodes. This might be used as the skeleton
for a graphics-based route manager.
*/
#include <exec/types.h>
#include <exec/lists.h>
#include <midi/midibase.h>
#include <functions.h>
#define DeclareMinList(list)\
struct MinList list = { (void *)&list.mlh_Tail, NULL, (void *)&list.mlh_Head }
struct MidiBase *MidiBase;
DeclareMinList(routelist); /* list or MRoutePtr's for maintaining routes that we create */
_cli_parse(){} /* stub out these two startup routines since we don't need any arguments */
_wb_parse(){} /* or icon parsing */
main()
{
char b[128];
Enable_Abort = 0; /* disable CTRL-C */
if (!(MidiBase = (void *)OpenLibrary (MIDINAME,MIDIVERSION))) {
printf ("can't open midi.library\n");
goto clean;
}
printf ("MIDI Router (type ? for help)\n");
/* process commands */
for (;;) {
printf ("route> ");
if (gets(b) && !parse(b)) break;
}
clean:
if (MidiBase) CloseLibrary (MidiBase);
}
parse(s)
char *s;
{
switch (tolower(*s++)) {
case 'x': /* quit */
case 'q':
zaproutelist();
return 0;
case 'l': /* list */
list();
break;
case 'a': /* add */
addroute(s);
break;
case 'm': /* modify */
modroute(s);
break;
case 'r': /* remove */
remroute(s);
break;
case 'h': /* help */
case '?':
help();
break;
}
return 1;
}
help()
{
printf ("\n");
printf ("Simple MIDI Router\n");
printf (" ? - help\n");
printf (" a <src> <dst> <MsgFlags> <ChanFlags> <ChanOffset> <NoteOffset>\n");
printf (" - add a route\n");
printf (" m <num> <MsgFlags> <ChanFlags> <ChanOffset> <NoteOffset>\n");
printf (" - modify a route\n");
printf (" r <num> - rem a route\n");
printf (" l - list\n");
printf (" q - quit\n");
printf ("\n");
}
list()
{
/* list public sources */
printf ("\nSources:\n");
listnames (&MidiBase->SourceList);
/* list public dests */
printf ("\nDests:\n");
listnames (&MidiBase->DestList);
/* list our routes */
printf ("\nRoutes:\n");
listroutes();
printf ("\n");
}
/*
Lists names in a specified list (like MidiBase->SourceList or
MidiBase->DestList). This requires locking the lists to prevent
changes while scanning them. Ideally, if a similar routine is going
to take any large amount of time or can be halted by the user in
mid-stream, it should take a snapshot of all the data it wishes to
handle rather than locking the lists for the whole process. Locking
the lists prevents anyone else from Creating or Deleting a node or
Finding a node.
*/
listnames(list)
struct List *list;
{
struct Node *node;
LockMidiBase();
for (node = list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
printf (" %s\n",node->ln_Name);
}
UnlockMidiBase();
}
/* Displays our route list. */
listroutes()
{
struct MinNode *node;
int i;
for (i=0,node = routelist.mlh_Head; node->mln_Succ; i++,node=node->mln_Succ) {
prtroute (i,node);
}
}
/*
Displays info about one of our routes. In order to display the node
names, we need to lock the lists to ensure validity of the nodes. This
one is done correctly: it locks the lists, copies the names of the nodes
if present, unlocks the lists, and THEN prints.
*/
prtroute (i,rp)
struct MRoutePtr *rp;
{
struct MRoute *route = rp->Route;
struct MRouteInfo *ri = &route->RouteInfo;
struct MSource *source;
struct MDest *dest;
char sname[64], dname[64];
LockMidiBase(); /* lock node lists */
if (source = route->Source) { /* if the source still exists */
if (source->Node.ln_Name) /* and it has a name (public, for this program this should always be true) */
sprintf (sname,"\"%s\"",source->Node.ln_Name); /* copy the name */
else
strcpy (sname,"(private)");
}
else {
strcpy (sname,"(removed)");
}
if (dest = route->Dest) { /* do the same for the dest */
if (dest->Node.ln_Name)
sprintf (dname,"\"%s\"",dest->Node.ln_Name);
else
strcpy (dname,"(private)");
}
else {
strcpy (dname,"(removed)");
}
UnlockMidiBase(); /* unlock the lists */
/* print */
printf (" %2d: %08lxH %s->%s %04x %04x %d %d\n", i, route, sname, dname, ri->MsgFlags, ri->ChanFlags, ri->ChanOffset, ri->NoteOffset);
}
/* delete all routes in our route list, used on exit */
zaproutelist()
{
struct MRoutePtr *rp;
while (rp = (struct MRoutePtr *)RemHead(&routelist)) {
DeleteMRoute(rp->Route);
free (rp);
}
}
/* adds a new route based on the command line in s */
addroute(s)
char *s;
{
char sname[64],dname[64];
struct MRouteInfo ri;
struct MRoutePtr *rp=NULL;
struct MRoute *route=NULL;
int chanoffset,noteoffset;
void *calloc();
setmem (&ri,sizeof ri,0);
if (sscanf (s,"%s%s%x%x%d%d",sname,dname,&ri.MsgFlags,&ri.ChanFlags,&chanoffset,¬eoffset) != 6) {
printf ("syntax error\n");
goto clean;
}
ri.ChanOffset = chanoffset;
ri.NoteOffset = noteoffset;
/* allocate a RoutePtr to hold ptr to our route */
if (!(rp = calloc(1,sizeof *rp))) {
printf ("out of memory\n");
goto clean;
}
/* try to create the route */
if (!(route = MRoutePublic(sname,dname,&ri))) {
printf ("error creating route\n");
goto clean;
}
rp->Route = route; /* set route pointer in our list */
AddTail (&routelist,rp); /* add to our list */
printf (" Route %d added.\n",findpos (&routelist,rp));
return 0;
clean:
if (route) DeleteMRoute (route);
if (rp) free (rp);
return -1;
}
/* modifies a existing route based on the command line in s */
modroute(s)
char *s;
{
int num;
struct MRouteInfo ri;
struct MRoutePtr *rp;
struct Node *findnode();
int chanoffset,noteoffset;
setmem (&ri,sizeof ri,0);
if (sscanf (s,"%d%x%x%d%d",&num,&ri.MsgFlags,&ri.ChanFlags,&chanoffset,¬eoffset) != 5) {
printf ("syntax error\n");
goto clean;
}
ri.ChanOffset = chanoffset;
ri.NoteOffset = noteoffset;
/* find our routeptr by position */
if (!(rp = (struct MRoutePtr *)findnode(&routelist,num))) {
printf ("can't find route\n");
goto clean;
}
/* modify the route */
ModifyMRoute (rp->Route,&ri);
printf (" Route %d modified.\n",num);
return 0;
clean:
return -1;
}
/* removes the route specifed in the command line s */
remroute(s)
char *s;
{
int num;
struct MRoutePtr *rp;
struct Node *findnode();
if (sscanf (s,"%d",&num) != 1) {
printf ("syntax error\n");
goto clean;
}
/* find our route ptr by number */
if (!(rp = (struct MRoutePtr *)findnode(&routelist,num))) {
printf ("can't find route\n");
goto clean;
}
/* remove from our list */
Remove (rp);
DeleteMRoute (rp->Route); /* delete the route */
free (rp); /* free our route ptr */
printf (" Route %d removed.\n",num);
return 0;
clean:
return -1;
}
/* finds a node by number */
struct Node *findnode (list,num)
struct List *list;
{
struct Node *node;
for (node = list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
if (!num--) return node;
}
return 0;
}
/* returns the ordinal position of a node within a list */
findpos (list,match)
struct List *list;
struct Node *match;
{
struct Node *node;
int num;
for (num=0,node = list->lh_Head; node->ln_Succ; num++,node=node->ln_Succ) {
if (node==match) return num;
}
return -1;
}