home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d101
/
midi
/
dev
/
example
/
r.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-09-05
|
8KB
|
337 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 */
main()
{
char b[128];
extern int Enable_Abort;
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> - add a route\n");
printf (" m <num> <MsgFlags> <ChanFlags> <ChanOffset> <NoteOffset> - 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;
}