home *** CD-ROM | disk | FTP | other *** search
- /* 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;
- }
-