Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!lll-winken!uunet!allbery From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Newsgroups: comp.sources.misc Subject: v06i115: glib part 15 of 15 Message-ID: <55470@uunet.UU.NET> Date: 22 May 89 02:07:01 GMT Sender: allbery@uunet.UU.NET Reply-To: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee ) Lines: 2165 Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Posting-number: Volume 6, Issue 115 Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee ) Archive-name: glib/part13 [Parts 13 and 14 are uuencoded .arc files. Doesn't *ANYBODY* read the guidelines??? (A copy follows this message, to remind you.) I'm going to figure out what they are and dump them elsewhere. In the meantime, don't look for them here. ++bsa] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'glib.c' <<'END_OF_FILE' X#ifndef lint Xstatic char rcsid[] = "$Id: glib.c,v 1.6 89/05/06 17:13:24 lee Exp $"; X#endif X/* X * GLIB - a Generic LIBrarian and editor for synths X * X * Tim Thompson's original with modifications by Michael Kesti, X * Greg Lee, Alan Bland, Scott Snyder, Mark Rinfret X * $Log: glib.c,v $ X * Revision 1.6 89/05/06 17:13:24 lee X * rel. to comp.sources.misc X * X */ X X#include "glib.h" X#include X Xchar *Reason = ""; X Xint Currrow = 0; /* at top of screen, for messages */ Xint Libbank = 0; /* from 0 to LIBBANKS-1, is the current library bank*/ Xint Nsynths = 0; X Xint Lastvalue = 0; X Xchar *Currdata; Xchar *Yankdata; /* current 'yank' buffer (middle of screen) */ X Xstruct peredinfo *PE; /* array of per-editor miscellany */ X Xchar Buff[BUFSIZ]; Xint Redraw = 0; /* if non-0, edit screen is completely redrawn. */ X /* parameter functions can make use of this. */ Xint Changed = 0; Xint DataID = 0; /* Data Id for file write and read operations */ X X/* All the global values below are set as appropriate for the */ X/* synthesizer currently being dealt with. */ X Xint Nvoices = 0; Xint Voicesize =0; Xint Namesize = 0; Xint Libindex; /* from 0 to Nvoices-1 */ Xint Synindex; /* from 0 to Nvoices-1 */ Xint Channel; Xint Editrow; /* from 0 to NUMONSCREEN-1 */ Xint Editcol; /* 0==synth, 1==library */ Xchar *Libdata; /* current library data (includes all LIBBANKS) */ X /* ie. the stuff on the right side of the screen */ Xchar *Syndata; /* current synth data (1 bank), ie. the left side */ Xstruct paraminfo *P; /* list of parameter info */ Xstruct labelinfo *L; /* arbitrary screen labels for edit screen */ Xchar *Synthname; X#ifdef SSS Xint *scr_p; Xint NParams; X#endif X#ifdef KAWAIK1 Xchar sngnames[64][11]; X#endif X Xint synthinfileflag = 0; Xint synthoutfileflag = 0; Xchar Syinfname[100], Syofname[100]; X Xint (*Sendedit)(); /* function to send parameters to synth's edit buffer*/ Xint (*Datain)(); /* convert data from file-storage format to the */ X /* format stored in the P[] parameter array (p_val) */ Xint (*Dataout)(); /* reverse of Datain */ Xint (*Sendone)(); /* function to send one (permanent) voice to synth */ Xint (*Sendbulk)(); /* function to send bulk dump to synth */ Xint (*Getbulk)(); /* reverse of Sendbulk */ Xchar *(*Nameof)(); /* pulls voice name out of file-storage data */ Xint (*Setnameof)(); /* reverse of Nameof */ Xchar *(*Numof)(); /* convert voice number to on-screen text */ Xint (*Cvtnum)(); /* convert visible voice number to std. format */ Xint (*Cvtanum)(); /* convert alphanumeric voice number to std. format */ X /* should never define both Cvtnum and Cvtanum */ X X#ifdef SSS X# define PARAMAT(r, c) (*(scr_p + Cols*(r) + (c))) X#endif X Xmain() X{ X int n; X X hello(); X windinit(); X initstuff(); X X if ( Nsynths == 0 ) X windstr("Hey, the E array is empty?"); X else if ( Nsynths == 1 ) { X /* If there's only 1 synth, don't bother asking */ X setedit(0); X libinteract(); X } X else { X while ( (n=choosesynth()) >= 0 ) { X setedit(n); X libinteract(); X unsetedit(n); X } X } X bye(); X} X X/* choose a synth, returning its position in the E array */ Xchoosesynth() X{ X int n, pick; X X retry: X flushconsole(); X windclear(); X windgoto(2,23); X#ifdef KAWAIK1 X windstr("Kawai K1 Librarian/Editor"); X#else X#ifdef ROLANDD10 X windstr("Roland D-10 Librarian/Editor"); X#else X windstr("GLIB - A Generic Librarian/Editor"); X#endif X#endif X X for ( n=1; n<=Nsynths; n++ ) X libchoice(n); X windgoto(8+Nsynths,27); X windstr("q - Quit"); X windgoto(11+Nsynths,27); X windstr("Make selection --> "); X windrefresh(); X pick = mouseorkey(); X if ( pick == 'q' || pick == EOF ) X return(-1); X if ( pick != MOUSE ) X pick = pick - '0'; X else { X int row, col; X getmouse(&row,&col); X /* wait until mouse goes down */ X while ( statmouse() > 0 ) X ; X pick = row - 6; X } X if ( pick < 1 || pick > Nsynths ) X goto retry; X return(pick-1); X} X Xlibchoice(n) X{ X windgoto(6+n,27); X (void)sprintf(Buff,"%d - %s",n,E[n-1].ed_name); X windstr(Buff); X} X X#ifndef SINGLEDATA X Xinitstuff() X{ X int n, banksize, maxvsize; X X maxvsize = 0; X for ( n=0; E[n].ed_name != NULL; n++ ) { X if ( maxvsize < E[n].ed_vsize ) X maxvsize = E[n].ed_vsize; X } X Nsynths = n; X Currdata = alloc( maxvsize ); X X /* allocate an array of peredinfo structs */ X PE =(struct peredinfo *)alloc((int)(Nsynths*sizeof(struct peredinfo))); X for ( n=0; np_name, p2->p_name); X} X Xinit_params() X{ X int i; X X for (NParams=0; P[NParams].p_name != NULL; NParams++) X ; X qsort((void *)P, NParams, sizeof(struct paraminfo), paramcmp); X X scr_p = (int *)alloc(Rows * Cols * sizeof(int)); X clrdata((char *)scr_p, Rows * Cols * sizeof(int)); X for (i=0; i= 0 && r < Rows && c >= 0 && c < Cols) X PARAMAT(r, c) = i+1; X } X} X#endif X X#ifndef SINGLEDATA X Xsetedit(n) X{ X Synthname = E[n].ed_name; X Datain = E[n].ed_din; X Dataout = E[n].ed_dout; X Nvoices = E[n].ed_nvoices; X Sendedit = E[n].ed_sedit; X Sendone = E[n].ed_sone; X Sendbulk = E[n].ed_sbulk; X Getbulk = E[n].ed_gbulk; X Nameof = E[n].ed_nof; X Numof = E[n].ed_numof; X Cvtnum = E[n].ed_cvtnum; X Cvtanum = E[n].ed_cvtanum; X Setnameof = E[n].ed_snof; X Voicesize = E[n].ed_vsize; X Namesize = E[n].ed_nsize; X DataID = E[n].ed_dataid; X Libdata = PE[n].ed_libdata; X Syndata = PE[n].ed_syndata; X Yankdata = PE[n].ed_yankdata; X Libindex = PE[n].ed_libindex; X Synindex = PE[n].ed_synindex; X Channel = PE[n].ed_channel; X Editrow = PE[n].ed_erow; X Editcol = PE[n].ed_ecol; X clrdata(Currdata,Voicesize); X P = E[n].ed_params; X L = E[n].ed_labels; X X#ifdef SSS X init_params(); X#endif X} X Xunsetedit(n) X{ X int k; X X DataID = 0; X PE[n].ed_libindex = Libindex; X PE[n].ed_synindex = Synindex; X PE[n].ed_channel = Channel; X PE[n].ed_erow = Editrow; X PE[n].ed_ecol = Editcol; X for ( k=0; k "); X windrefresh(); X X c = mouseorkey(); X if ( c == MOUSE ) { X libmouse(); X continue; X } X X if ( isprint(c) ) X windputc(c); X clearmess(); X switch ( c ) { X case ' ': X playnote(1); X break; X case '\n': X#ifndef macintosh X case '\r': X#endif X /* ignore */ X break; X case EOF: X case 'q': X return; X case CH_REDRAW: X drawall(); X break; X case 's': X case 'p': X swap = (c=='s')?1:0; X if ( Editcol==0 ) X tosyn(Synindex+Editrow,Yankdata,swap); X else X tolib(Libindex+Editrow,Yankdata,swap); X updatedisplay(); X pryankname(); X break; X case 'y': X for(n=0;n maxindex ) X Synindex = maxindex; X } X else { X /* we're on the lib side */ X if ( (Libindex+=q/2) > maxindex ) X Libindex = maxindex; X } X updatedisplay(); X break; X case SCR_UP: X if ( Editcol==0 ) { X /* we're on the synth side */ X if ( (Synindex-=NUMONSCREEN/2) < 0 ) X Synindex = 0; X } X else { X /* we're on the lib side */ X if ( (Libindex-=NUMONSCREEN/2) < 0 ) X Libindex = 0; X } X updatedisplay(); X break; X case '\033': X case '`': X allnotesoff(); X break; X case 't': X transcmd(); X editto(Editrow,Editcol); X break; X case 'D': /* download FROM file */ X synthinfileflag = 1; X case 'd': /* download FROM synth */ X clrdata(Syndata,Nvoices*Voicesize); X if ( readsynth(Syndata) == 0 ) { X syntodisplay(Synindex=0); X if(Editcol == 0) X editto(Editrow,Editcol); X } X synthinfileflag = 0; X break; X case 'U': /* upload to file */ X synthoutfileflag = 1; X case 'u': /* upload TO synth */ X if ( Editcol==0 ) { X voicenum = Editrow+Synindex; X data = &(VOICEBYTE(Syndata,voicenum,0)); X } X else X data = bankvoice(Editrow+Libindex); X upload(data); X synthoutfileflag = 0; X break; X case 'r': X readall(); X if(Editcol == 1) X editto(Editrow,Editcol); X break; X case 'R': X readprintable(); X if(Editcol == 1) X editto(Editrow,Editcol); X break; X case 'w': X writeall(); X break; X case 'W': X writeprintable(); X break; X case 'c': X setchan(); X break; X case 'b': X /* cycle through banks, from 0 to LIBBANKS-1 */ X if ( ++Libbank >= LIBBANKS ) X Libbank = 0; X libtodisplay(Libindex); X updatedisplay(); X break; X case 'e': X if ( Namesize == 0) X p = NULL; X else X p = (*Nameof)(Currdata); X if ( Editcol==0 ) { X voicenum = Editrow+Synindex; X data = &(VOICEBYTE(Syndata,voicenum,0)); X editdata(p,data); X windclear(); X /* Update Currdata */ X for ( n=0; n0 ) X editto(Editrow-1,Editcol); X else { X /* we're at the top, so try to scroll */ X if ( Editcol==0 ) { X /* we're on the synth side */ X if (Synindex>0) X Synindex--; X } X else { X /* we're on the lib side */ X if (Libindex>0) X Libindex--; X } X updatedisplay(); X } X break; X case CH_RIGHT: X case ALTCH_RIGHT: X if ( Editcol==0 ) X editto(Editrow,1); X break; X case 'f': X filelist(); X break; X default: X message("Unrecognized command! Press '?' for help."); X break; X } X } X} X Xfilelist() X{ X char *p, *q, buff[BUFSIZ]; X int n, ninline = 0, nprinted = 0; X X clearmess(); X Currrow = -1; /* To start message on top line */ X openls(); X message("Files in current directory:"); X strcpy(buff," "); X while ( (p=nextls()) != NULL ) { X /* add the next file to the line being constructed */ X q = &buff[strlen(buff)]; X strcpy(q,p); X q += (n=strlen(p)); X while ( n++ < 15 ) X *q++ = ' '; X *q = '\0'; X if ( ninline++ > 3 ) { X message(buff); X if ( nprinted++ > 4 ) { X message("Press any key to continue ..."); X (void)getconsole(); X clearmess(); X nprinted = 0; X } X strcpy(buff," "); X ninline = 0; X } X } X if ( ninline > 0 ) X message(buff); X closels(); X} X Xlibmouse() X{ X int row, col, q; X X getmouse(&row,&col); X if(Nvoices < NUMONSCREEN) X q = Nvoices; X else X q = NUMONSCREEN; X if ( row <= FIRSTROW || row > FIRSTROW+q+1 ) X goto getout; X if ( col < Cols/2 ) X col = 0; X else X col = 1; X row = row - FIRSTROW - 1; X editto(row,col); Xgetout: X /* wait until mouse button is released */ X while ( statmouse() > 0 ) X ; X} X Xdo_goto() X{ X int n, r, maxindex, new_ecol,q; X char sbuf[100], *sp; X X message(""); X message("Where to? "); X windgets(sbuf); X X sp = sbuf; X switch(*sp++) { X case 's': /* synth side */ X new_ecol = 0; X break; X case 'l': /* library side */ X new_ecol = 1; X break; X default: /* no change in side */ X new_ecol = Editcol; X sp--; /* but don't trash the first character */ X break; X } X X clearmess(); X r = sscanf(sp, "%d", &n); /* this may fail - we handle it later */ X if(Cvtnum != NULL) { /* convert to internal format if needed */ X n = (*Cvtnum)(n) + 1; /* we are 1-based for user input */ X } X if (Cvtanum != NULL) { /* convert using alphanumeric voice number */ X n = (*Cvtanum)(sp) + 1; X if (n) r = 1; X } X if(r != 1) { X message("type one of: sn, ln, or n"); X message(" s = synth side (literal character 's')"); X message(" l = library side (literal character 'l')"); X#ifdef KAWAIK1 X message(" n = voice number to select (letter + number)"); X#else X#ifdef KAWAIK5 X message(" n = voice number to select (letter + number)"); X#else X message(" n = voice number to select (an integer)"); X#endif X#endif X return; X } X if(n <= 0 || n > Nvoices) { /* 1-based */ X message("Bad voice number!"); X return; X } X X /* it can be done. nuke the old '*' and change columes (if needed) */ X editchar(' ', Editrow, Editcol); X Editcol = new_ecol; X X /* try to center it */ X if(Nvoices < NUMONSCREEN) X q = Nvoices; X else X q = NUMONSCREEN; X maxindex = Nvoices - q; X if(Editcol == 0) { X Synindex = (n - 1) - q/2; /* 0-based */ X if(Synindex < 0) { /* impossible to center */ X Synindex = 0; /* so do your best */ X } else if(Synindex > maxindex) { X Synindex = maxindex; X } X Editrow = (n - 1) - Synindex; /* and put a '*' on it */ X } else { X Libindex = (n - 1) - q/2; /* 0-based */ X if(Libindex < 0) { X Libindex = 0; X } else if(Libindex > maxindex) { X Libindex = maxindex; X } X Editrow = (n - 1) - Libindex; X } X X updatedisplay(); /* do the real work */ X return; X} X Xupload(data) Xchar *data; X{ X int c, n; X char num[16]; X X message(""); X if (synthoutfileflag) { X message("Upload to synth file:"); X message("Output synth file --> "); X windgets(Syofname); X flushmidi(); X } X else message("Upload TO synth:"); X message(" c - current voice"); X message(" a - ALL voices"); X message("Choose --> "); X c = getconsole(); X if ( c == 'c' ) { X clearmess(); X if ( Sendone == NULL ) { X if (synthoutfileflag) (*Sendedit)(data); X else X message("Single voices can't be sent to that synth!"); X return; X } X message("What voice number to you want to send it TO? --> "); X windgets(num); X clearmess(); X n = atoi(num); X if(Cvtnum != NULL) { /* convert to internal format if needed */ X n = (*Cvtnum)(n) + 1; /* we are 1-based for user input */ X } X if (Cvtanum != NULL) { /* howzabout alphanumeric format? */ X n = (*Cvtanum)(num) + 1; X } X if ( n > 0 && n <= Nvoices ) { X if ( (*Sendone)(n-1,data) != 0 ) { /* 0-based on calls -SAF */ X message("Unable to write data to synth!"); X (void)sprintf(Buff,"Reason: %s",Reason); X message(Buff); X return; X } X } else { X message("Bad voice number!"); X } X } X else if ( c == 'a' ) { X clearmess(); X if ( Sendbulk != NULL ) { X message("Uploading to synth using bulk routine."); X if ( (*Sendbulk)(Syndata) != 0 ) { X message("Upload failure!"); X (void)sprintf(Buff,"Reason: %s\n",Reason); X message(Buff); X return; X } X } else { X message("Uploading to synth using single routine."); X for ( n=0; n - play a note"); X} X Xupdatedisplay() X{ X if ( Editcol==0 ) { X /* we're on the synth side */ X syntodisplay(Synindex); X editto(Editrow,Editcol); X } X else { X /* we're on the lib side */ X libtodisplay(Libindex); X editto(Editrow,Editcol); X } X} X Xpryankname() X{ X char ybuff[33]; X char *p; X X if ( Namesize == 0 ) X return; X X windgoto(YANKROW,YANKCOL-4); X windstr(" "); X strcpy(ybuff,(*Nameof)(Yankdata)); X /* take off trailing blanks */ X p = ybuff + strlen(ybuff) - 1; X while ( p>ybuff && *p == ' ' ) X *p-- = '\0'; X windgoto(YANKROW,YANKCOL+7-strlen(ybuff)/2); X windstr(ybuff); X windrefresh(); X} X Xtranscmd() X{ X int fromc; X X message(""); X message("Transfer ALL voices:"); X message(" 1: <<----- from library bank to synth bank"); X message(" 2: ----->> from synth bank to library bank"); X message("1 or 2 --> "); X fromc = getconsole(); X windputc(fromc); X if ( fromc!='1' && fromc!='2' ) { X clearmess(); X return; X } X switch ( fromc ) { X case '1': X copyall(bankvoice(0),Syndata); X syntodisplay(Synindex); X clearmess(); X message("Use the 'u'pload command to actually send the synth bank voices to the synth."); X break; X case '2': X copyall(Syndata,bankvoice(0)); X libtodisplay(Libindex); X clearmess(); X break; X } X} X Xcopyall(fromdata,todata) Xchar *fromdata; Xchar *todata; X{ X int n, v; X X for ( v=0; v "); X windgets(Buff); X if ( (c=atoi(Buff)) <= 0 || c > 16 ) { X clearmess(); X message("Invalid channel!"); X } X else { X clearmess(); X Channel = c; X showchan(); X } X} X Xshowchan() X{ X windgoto(20,31); X windstr("MIDI Channel: "); X (void)sprintf(Buff,"%d ",Channel); X windstr(Buff); X windrefresh(); X} X X#ifdef DX7 X#include X#include Xlong flength(handle) Xint handle; X{ X struct stat buf; X fstat(handle, &buf); X return buf.st_size; X} X#endif X X/* read data from a file, filling the current library bank. */ Xreadall() X{ X char fname[100]; X FILE *f; X int v, n, r; X char *p; X X message("File name --> "); X windgets(fname); X#ifdef BSD X OPENBINFILE(f,fname,"r"); X#else X OPENBINFILE(f,fname,"rb"); X#endif X if (f == NULL ) { X (void)sprintf(Buff,"Can't open '%s'!",fname); X message(Buff); X return; X } X /* If the first byte matches DataID, then the format is OK. */ X if (DataID) n = (getc(f) & 0xff); X else n = 0; X X#ifndef ROLANDD10 X# ifndef KAWAIIK1 X/* If we are running the Aztec C compiler, it's not yet ANSII. The X abominable kludge that follows is therefore necessary. */ X# ifdef AZTEC_C X# ifdef DX7 X# define SKIP_IT X# endif X# ifdef DX7S X# define SKIP_IT X# endif X# ifndef SKIP_IT X if (n != DataID && n <= 31) { X (void)ungetc(n,f); X n = DataID; X } X# endif X# undef SKIP_IT X# else X# if !defined(DX7) && !defined(DX7S) X if (n != DataID && n <= 31) { X (void)ungetc(n,f); X n = DataID; X } X# endif X# endif X# endif X#endif X X#ifdef DX7S X X/* check for reading a DX7 file in DX7s mode */ X X if ( strcmp(Synthname, "DX7s") == 0 ) X if (flength(fileno(f)) == 4096) { X (void)ungetc(n, f); X dx7Sread_dx7(f, bankvoice(0)); X r = 0; X goto done; X } X X/* check for reading a DX7S file in DX7 mode */ X X if ( strcmp(Synthname, "DX7") == 0 ) { X n = getc(f) & 0xff; X if (n == 0xd7) { /* DX7s dataID */ X dx7read_dx7S(f, bankvoice(0)); X r = 0; X goto done; X } X (void)ungetc(n, f); X n = 0; X } X#endif X X#ifdef DX7 X X/* validate a DX7 file based on length */ X X if ( strcmp(Synthname, "DX7") == 0 ) { X if (flength(fileno(f)) != Nvoices * Voicesize) X n = DataID + 1; X } X X#endif X X if ( n == DataID ) { X p = bankvoice(0); X for ( v=0; v "); X windgets(fname); X#ifdef BSD X OPENBINFILE(pfin,fname,"r"); X#else X OPENBINFILE(pfin,fname,"rb"); X#endif X if (pfin == NULL ) { X (void)sprintf(Buff,"Can't open '%s'!",fname); X message(Buff); X return; X } X /* If the first byte matches DataID, then the format is OK. */ X r = fscanf(pfin, "BANK TYPE %d", &n); X X v = -1; X if ( r == 1 && n == DataID ) while (r) { X r = fscanf(pfin, " %s ", vname); X X if (r == 1) { X if (strcmp(vname, "voice") == 0) { X if (v > 0) (*Dataout)(p); X r = fscanf(pfin,"%d = %[ !-~]", &v, vname); X if (r == 2 && v > 0) { X p = bankvoice(v-1); X (*Setnameof)(p, vname); X } X } else { X r = fscanf(pfin, "= %d", &val); X if (r == 1) setval(vname, val); X } X } X if (r == EOF) r = 0; X } else { X (void)sprintf(Buff, "'%s' is invalid for this function!\n", fname); X message(Buff); X r = 1; X } X if (v > 0) (*Dataout)(p); X (void)fclose(pfin); X if ( r==0 ) { X libtodisplay(Libindex=0); X clearmess(); X } X} X X/* write current library bank to a file */ Xwriteall() X{ X char fname[100]; X FILE *f; X int v, n; X char *p; X X message("File name --> "); X windgets(fname); X#ifdef BSD X OPENBINFILE(f,fname,"w"); X#else X OPENBINFILE(f,fname,"wb"); X#endif X if ( f == NULL ) { X (void)sprintf(Buff,"Can't open '%s'!",fname); X message(Buff); X return; X } X if (DataID) putc(DataID,f); /* write data identifier */ X X p = bankvoice(0); X for ( v=0; v "); X windgets(fname); X#ifdef BSD X OPENBINFILE(pfout,fname,"w"); X#else X OPENBINFILE(pfout,fname,"wb"); X#endif X if ( pfout == NULL ) { X (void)sprintf(Buff,"Can't open '%s'!",fname); X message(Buff); X return; X } X fprintf(pfout, "BANK TYPE %d\n", DataID); X X for (v=0; v ' ') { X (*Datain)(p); X fprintf(pfout, "voice %d = %s\n", v+1, q); X pfoutflag = 1; X (*Dataout)(p); X pfoutflag = 0; X } X } X (void)fclose(pfout); X clearmess(); X} X X/* draw main library/synth voice bank screen */ Xdrawall() X{ X windclear(); X template(); X libtodisplay(Libindex); X syntodisplay(Synindex); X editto(Editrow,Editcol); X pryankname(); X showchan(); X} X X/* X * tosyn X * X * Store the given 'data' in in voice 'voicenum' (both in Syndata X * AND on the synth itself). If swap is non-zero, the voice is swapped X * with the current voice in Syndata. X */ X Xtosyn(voicenum,data,swap) Xchar *data; X{ X int n, t; X X for ( n=0; n "); X windgets(Syinfname); X synthoutfileflag = 1; X flushmidi(); X synthoutfileflag = 0; X } X else message("Downloading from synth"); X X if ( (*Getbulk)(data) == 0 ) X return(0); X X message("Unable to read data from synth!"); X (void)sprintf(Buff,"Reason: %s",Reason); X message(Buff); X message("Perhaps connections are amiss?"); X return(1); X} X Xchar * Xvnumtext(n) X{ X static char vnbuff[6]; X X if ( Numof == NULL ) { X (void)sprintf(vnbuff,"%2d",n); X return(vnbuff); X } X else X return((*Numof)(n - 1)); /* keep this 0-based */ X} X X/* X * syntodisplay(n) X * X * Tranfer Syndata names to dialog boxes (Dxvoices) starting at n. X */ Xsyntodisplay(n) X{ X int k, r, q; X X if(Nvoices < NUMONSCREEN) X q = Nvoices; X else X q = NUMONSCREEN; X for ( k=0; k0;n--) X windputc('='); X } X X /* The L array contains arbitrary screen labels */ X for ( n=0; L[n].l_text != NULL; n++ ) { X windgoto(L[n].l_row,L[n].l_col); X windstr(L[n].l_text); X } X /* Display each parameter value, and a label if there is one. */ X for ( n=0; P[n].p_name != NULL; n++ ) { X if ( P[n].p_flags != 0 ) X continue; X if ( (s=P[n].p_label) != NULL ) X showstr(s,P[n].p_lrow,P[n].p_lcol,0); X showparam(n,0); X } X windrefresh(); X} X Xshowname(name) Xchar *name; X{ X windgoto(0,0); X windstr("Name: "); X windgoto(0,6); X windstr(name); X} X Xshowparam(n,eras) X{ X char *p; X X /* The p_tovis element of the P array is a function which, given */ X /* the parameter value as an argument, returns a string which is */ X /* what should be displayed on the screen. */ X#ifdef DX7 X if (P[n].p_vrow < 0 || P[n].p_vcol < 0) return; X p = (*(P[n].p_tovis))(P[n].p_val, eras); X#else X p = (*(P[n].p_tovis))(P[n].p_val); X#endif X showstr(p,P[n].p_vrow,P[n].p_vcol,eras); X} X X#ifdef DX7 X X/* X * define defaults for the graphics characters, if they haven't been specified X * in machdep. X */ X X# ifndef DRAW_VERT X# define DRAW_VERT '|' X# define DRAW_HORIZ '-' X# define DRAW_CROSS '+' X# define DRAW_UPTEE '+' X# define DRAW_DOWNTEE '+' X# define DRAW_LEFTTEE '+' X# define DRAW_RIGHTTEE '+' X# define DRAW_UPLEFT '+' X# define DRAW_UPRIGHT '+' X# define DRAW_DOWNLEFT '+' X# define DRAW_DOWNRIGHT '+' X# endif X Xshowstr(p,row,col,eras) Xregister char *p; Xregister int col; X{ X register int c; X int rept, mincol; X X mincol = col; X X windgoto(row,col); X while ( (c=(*p++)) != '\0' ) { X switch(c){ X case '~': X c = *p++; X if (isdigit(c)) { X rept = 0; X while (isdigit(c)) { X rept = 10*rept + (c-'0'); X c = *p++; X } X } X else X rept = 1; X X while (rept--) { X switch( c ) { X case 'n': row++; col=mincol; goto wgoto; X case 'u': row--; goto wgoto; X case 'd': row++; goto wgoto; X case 'l': col--; if (col < mincol) mincol = col; goto wgoto; X case 'r': col++; X wgoto: X windgoto(row,col); X break; X case '|': c=DRAW_VERT; goto wput; X case '-': c=DRAW_HORIZ; goto wput; X case '+': c=DRAW_CROSS; goto wput; X case 'T': c=DRAW_UPTEE; goto wput; X case '^': c=DRAW_DOWNTEE; goto wput; X case '<': c=DRAW_RIGHTTEE; goto wput; X case '>': c=DRAW_LEFTTEE; goto wput; X case '{': c=DRAW_UPLEFT; goto wput; X case '}': c=DRAW_UPRIGHT; goto wput; X case '[': c=DRAW_DOWNLEFT; goto wput; X case ']': c=DRAW_DOWNRIGHT; X wput: X windputc(eras?' ':c); X col++; X break; X default: X windputc(eras?' ':c); X col++; X break; X } X } X break; X default: X windputc(eras?' ':c); X col++; X break; X } X } X} X X#else /* DX7 */ X Xshowstr(p,row,col,eras) Xregister char *p; Xregister int col; X{ X register int c; X X windgoto(row,col); X while ( (c=(*p++)) != '\0' ) { X switch(c){ X case '~': X switch( (c=(*p++)) ) { X case 'u': row--; goto wgoto; X case 'd': row++; goto wgoto; X case 'l': col--; goto wgoto; X case 'r': col++; X wgoto: X windgoto(row,col); X break; X default: X windputc(eras?' ':c); X col++; X break; X } X break; X default: X windputc(eras?' ':c); X col++; X break; X } X } X} X#endif X X/* Allow roaming around and changing of parameter values. */ Xeditdata(name,data) Xchar *name; Xchar *data; /* vmem format */ X{ X int c, n; X X windclear(); X windrefresh(); X /* enable all the parameters */ X for ( n=0; P[n].p_name != NULL; n++ ) X enableparm(n); X X /* Take the voice data and put it into P */ X (*Datain)(data); X X Prow = Pcol = 0; X Changed = 0; X Redraw = 1; X Lastvalue = 0; X gotoparm(CH_RIGHT); /* Get to the first parameter */ X for ( ;; ) { X if ( Redraw ) { X showallparms(name); X Redraw = 0; X } X windgoto(Prow,Pcol); X windrefresh(); X c = mouseorkey(); X if ( c == MOUSE ) { X editmouse(); X continue; X } X switch(c){ X case CH_RIGHT: X case ALTCH_RIGHT: X case CH_UP: X case ALTCH_UP: X case CH_DOWN: X case ALTCH_DOWN: X case CH_LEFT: X case ALTCH_LEFT: X gotoparm(c); X break; X case CH_SAME: X sameparm(); X break; X case CH_REDRAW: X showallparms(name); X break; X case 'N': X if ( Namesize != 0 ) { X /* Allow changing of voice name */ X windgoto(0,5); X windstr(" "); X windgoto(0,6); X windrefresh(); X windgets(Buff); X if ( Buff[0]!='\0' && Buff[0]!='\n' ) X (*Setnameof)(data,Buff); X showname(name=(*Nameof)(data)); X Changed = 1; X } X break; X X case CH_INC: X adjuparm(1); X break; X case CH_INC2: X adjuparm(4); X break; X case CH_INC3: X adjuparm(P[Parm].p_max - P[Parm].p_min); X break; X case CH_DEC: X adjuparm(-1); X break; X case CH_DEC2: X adjuparm(-4); X break; X case CH_DEC3: X adjuparm(P[Parm].p_min - P[Parm].p_max); X break; X#ifdef OLDSTUFF X case 'a': X sendaced(data); X playnote(0); X break; X#endif X case ' ': X case '\n': X#ifndef macintosh X case '\r': X#endif X if ( Changed ) { X (*Dataout)(data); X (*Sendedit)(data); X Changed = 0; X } X playnote(0); X break; X case '\033': X case '`': X allnotesoff(); X break; X case 'q': X case EOF: X if ( Changed ) { X (*Dataout)(data); X (*Sendedit)(data); X } X return; X default: X break; X } X } X} X Xadjuparm(incdec) X{ X int v, n; X X v = P[Parm].p_val + incdec; X if ( v < (n=P[Parm].p_min) ) X v = n; X if ( v > (n=P[Parm].p_max) ) X v = n; X Lastvalue = v; X Changed = 1; X showparam(Parm,1); /* erase the old val */ X P[Parm].p_val = v; X showparam(Parm,0); /* show the new val */ X} X Xsameparm() X{ X int v, n; X X v = Lastvalue; X if ( v < (n=P[Parm].p_min) ) X v = n; X if ( v > (n=P[Parm].p_max) ) X v = n; X Changed = 1; X showparam(Parm,1); /* erase the old val */ X P[Parm].p_val = v; X showparam(Parm,0); /* show the new val */ X} X Xeditmouse() X{ X int row, col, thisparm; X X getmouse(&row,&col); X thisparm = closeparm(row,col); X if ( thisparm == Parm ) { X if ( statmouse() > 1 ) X adjuparm(-1); /* right button */ X else if ( statmouse() == 1 ) /* added by mab - bug fix */ X adjuparm(1); /* left button */ X } X else { X Parm = thisparm; X Prow = P[Parm].p_vrow; X Pcol = P[Parm].p_vcol; X } X} X X/* closeparm - Find the closest parameter */ Xcloseparm(row,col) X{ X register struct paraminfo *pp; X register int n; X int dist, mindist, minparm, dr, dc; X X minparm = 0; X mindist = Rows + Cols; X for ( n=0,pp=P; pp->p_name != NULL; n++,pp++ ) { X if ( pp->p_flags != 0 ) X continue; X if ( (dr=row-(pp->p_vrow)) < 0 ) X dr = -dr; X if ( (dc=col-(pp->p_vcol)) < 0 ) X dc = -dc; X if ( (dist=dr*dr+dc*dc) < mindist ) { X minparm = n; X mindist = dist; X } X } X return(minparm); X} X X/* playnote - play the 'auto' note */ Xplaynote(i) X{ X int pitch, vol, dur, chan; X long endtime; X X pitch = getval("autopitch"); X if(i == 0) { /* called from inside edit-mode */ X chan = getval("autochan"); X } else { /* called from the top level */ X chan = Channel; X } X vol = getval("autovol"); X dur = getval("autodur"); X endtime = milliclock() + dur * 100; X midinote(1,chan,pitch,vol); X while ( milliclock() < endtime ) X ; X midinote(0,chan,pitch,vol); X} X X/* gotoparm - search for the next parameter in the specified direction */ Xgotoparm(dir) X{ X int n, k, inc, pm, orig, r = Prow, c = Pcol; X X switch(dir) { X case ALTCH_UP: dir = CH_UP; break; X case ALTCH_DOWN: dir = CH_DOWN; break; X case ALTCH_LEFT: dir = CH_LEFT; break; X case ALTCH_RIGHT: dir = CH_RIGHT; break; X } X X if ( dir==CH_LEFT || dir==CH_RIGHT ) { X if ( dir==CH_LEFT ) X c--; X else X c++; X orig = c; X inc = 0; X pm = -1; X /* look up and down, alternately */ X for ( n=2*Rows; n>0; n-- ) { X r += (pm * inc++); X pm = -pm; X if ( r < 0 || r >= Rows ) X continue; X if ( dir == CH_LEFT ) { X for ( c=orig; c>=0; c-- ) { X if ( parmat(r,c) ) X return; X } X } X else { X for ( c=orig; c= 0 && r < Rows ) { X /* look toward both sides at the same time */ X inc = 0; X pm = -1; X for ( k=2*Cols; k>0; k-- ) { X c += (pm * inc++); X pm = -pm; X if ( c < 0 || c >= Cols ) X continue; X if ( parmat(r,c) ) X return; X } X if ( dir==CH_DOWN ) X r++; X else X r--; X c = orig; X } X return; X } X} X X/* paramat - return non-zero if a parameter value is at position r,c */ Xparmat(r,c) Xregister int r, c; X{ X#ifdef SSS X int p = PARAMAT(r, c); X X if (p == 0 || P[p-1].p_flags) X return 0; X else { X Parm = p-1; X Prow = r; X Pcol = c; X return 1; X } X#else X register int n; X register struct paraminfo *pp; X X for ( n=0,pp=P; pp->p_name != NULL; n++,pp++ ) { X if ( pp->p_flags != 0 ) X continue; X if ( pp->p_vrow==r && pp->p_vcol==c ) { X Prow = r; X Pcol = c; X Parm = n; X return(1); X } X } X return(0); X#endif X} X X/* parmindex - return index (in P) of a given parameter name. */ Xparmindex(name) Xchar *name; X{ X#ifdef SSS X struct paraminfo key, *p; X extern char *bsearch(); X X key.p_name = name; X p = (struct paraminfo *)bsearch((void *)&key, (void *)P, NParams, X sizeof(struct paraminfo), paramcmp); X if (p == 0) { X (void)sprintf(Buff,"HEY, PARMINDEX(%s) NOT FOUND!\n",name); X windstr(Buff); X windrefresh(); X return(-1); X } X else X return p-P; X#else X int n; X char *s; X X for ( n=0; (s=P[n].p_name) != NULL; n++ ) { X if ( strcmp(s,name) == 0 ) X return(n); X } X (void)sprintf(Buff,"HEY, PARMINDEX(%s) NOT FOUND!\n",name); X windstr(Buff); X windrefresh(); X return(-1); X#endif X} X Xvoid Xsetval(name,v) XINT16 v; Xchar *name; X{ X int n; X X if ( (n=parmindex(name)) < 0 ) X return; X P[n].p_val = v; X} X Xint Xgetval(name) Xchar *name; X{ X int n; X X if ( (n=parmindex(name)) < 0 ) X return(0); X X if (pfoutflag) X fprintf(pfout, "%s = %d\n", name, P[n].p_val); X X return(P[n].p_val); X} X X Xenableparm(n) X{ X if ( P[n].p_flags != 0 ) X P[n].p_flags = 0; X} X Xdisableparm(n) X{ X if ( P[n].p_flags == 0 ) X P[n].p_flags = 1; X} X Xmidinote(onoff,chan,pitch,vol) X{ X sendmidi( ((onoff==1)?(0x90):(0x80)) | ((chan-1)&0xf) ); X sendmidi( pitch & 0x7f ); X sendmidi( vol & 0x7f ); X} X Xstatic char Nbuff[16]; X Xchar *visnum(v) X{ X (void)sprintf(Nbuff,"%d",v); X return(Nbuff); X} Xchar *visonoff(v) X{ X if ( v==0 ) X return("OFF"); X else X return("ON "); X} X Xchar * Xbankvoice(voice) X{ X int offset = Libbank * Nvoices * Voicesize + voice * Voicesize; X return(Libdata + offset); X} END_OF_FILE if test 41661 -ne `wc -c <'glib.c'`; then echo shar: \"'glib.c'\" unpacked with wrong size! fi # end of 'glib.c' fi echo shar: End of archive 15 \(of 15\). cp /dev/null ark15isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 15 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0