home *** CD-ROM | disk | FTP | other *** search
- /*
- * GLIB - a Generic LIBrarian and editor for synths
- */
-
- #include "glib.h"
- #include <ctype.h>
-
- char *Reason = "";
-
- int Currrow = 0; /* at top of screen, for messages */
- int Libbank = 0; /* from 0 to LIBBANKS-1, is the current library bank*/
- int Nsynths = 0;
-
- char *Currdata;
- char *Yankdata; /* current 'yank' buffer (middle of screen) */
-
- struct peredinfo *PE; /* array of per-editor miscellany */
-
- char Buff[BUFSIZ];
- int Redraw = 0; /* if non-0, edit screen is completely redrawn. */
- /* parameter functions can make use of this. */
- int Changed = 0;
-
- /* All the global values below are set as appropriate for the */
- /* synthesizer currently being dealt with. */
-
- int Nvoices = 0;
- int Voicesize =0;
- int Namesize = 0;
- int Libindex; /* from 0 to Nvoices-1 */
- int Synindex; /* from 0 to Nvoices-1 */
- int Channel;
- int Editrow; /* from 0 to NUMONSCREEN-1 */
- int Editcol; /* 0==synth, 1==library */
- char *Libdata; /* current library data (includes all LIBBANKS) */
- /* ie. the stuff on the right side of the screen */
- char *Syndata; /* current synth data (1 bank), ie. the left side */
- struct paraminfo *P; /* list of parameter info */
- struct labelinfo *L; /* arbitrary screen labels for edit screen */
- char *Synthname;
-
- int (*Sendedit)(); /* function to send parameters to synth's edit buffer*/
- int (*Datain)(); /* convert data from file-storage format to the */
- /* format stored in the P[] parameter array (p_val) */
- int (*Dataout)(); /* reverse of Datain */
- int (*Sendone)(); /* function to send one (permanent) voice to synth */
- int (*Sendbulk)(); /* function to send bulk dump to synth */
- int (*Getbulk)(); /* reverse of Sendbulk */
- char *(*Nameof)(); /* pulls voice name out of file-storage data */
- int (*Setnameof)(); /* reverse of Nameof */
- char *(*Numof)(); /* convert voice number to on-screen text */
- int (*Cvtnum)(); /* convert visible voice number to std. format */
- int (*Cvtanum)(); /* convert alphanumeric voice number to std. format */
- /* should never define both Cvtnum and Cvtanum */
- main()
- {
- int n;
-
- hello();
- windinit();
- initstuff();
-
- if ( Nsynths == 0 )
- windstr("Hey, the E array is empty?");
- else if ( Nsynths == 1 ) {
- /* If there's only 1 synth, don't bother asking */
- setedit(0);
- libinteract();
- }
- else {
- while ( (n=choosesynth()) >= 0 ) {
- setedit(n);
- libinteract();
- unsetedit(n);
- }
- }
- bye();
- }
-
- /* choose a synth, returning its position in the E array */
- choosesynth()
- {
- int n, pick;
-
- retry:
- flushconsole();
- windclear();
- windgoto(2,18);
- windstr("GLIB - A Generic Librarian/Editor");
-
- for ( n=1; n<=Nsynths; n++ )
- libchoice(n);
-
- windgoto(10+n,16);
- windstr("Choose your synth (or 'q' to quit) --> ");
- windrefresh();
- pick = mouseorkey();
- if ( pick == 'q' || pick == EOF )
- return(-1);
- if ( pick != MOUSE )
- pick = pick - '0';
- else {
- int row, col;
- getmouse(&row,&col);
- /* wait until mouse goes down */
- while ( statmouse() > 0 )
- ;
- pick = row - 6;
- }
- if ( pick < 1 || pick > Nsynths )
- goto retry;
- return(pick-1);
- }
-
- libchoice(n)
- {
- windgoto(6+n,27);
- sprintf(Buff,"%d - %s",n,E[n-1].ed_name);
- windstr(Buff);
- }
-
- initstuff()
- {
- int n, banksize, maxvsize = 0;
- char *p;
-
- for ( n=0; E[n].ed_name != NULL; n++ ) {
- if ( maxvsize < E[n].ed_vsize )
- maxvsize = E[n].ed_vsize;
- }
- Nsynths = n;
- Currdata = alloc( maxvsize );
-
- /* allocate an array of peredinfo structs */
- PE =(struct peredinfo *)alloc((int)(Nsynths*sizeof(struct peredinfo)));
- for ( n=0; n<Nsynths; n++ ) {
- banksize = E[n].ed_nvoices * E[n].ed_vsize;
- p = PE[n].ed_libdata = alloc( LIBBANKS * banksize );
- clrdata(p,LIBBANKS*banksize);
- p = PE[n].ed_syndata = alloc( banksize );
- clrdata(p,banksize);
- p = PE[n].ed_yankdata = alloc( E[n].ed_vsize );
- clrdata(p,E[n].ed_vsize);
- PE[n].ed_libindex = 0;
- PE[n].ed_synindex = 0;
- PE[n].ed_channel = 1;
- PE[n].ed_erow = 0;
- PE[n].ed_ecol = 0;
- }
- }
-
- clrdata(data,size)
- char *data;
- {
- register char *p = data, *endp = data+size;
-
- while ( p<endp )
- *p++ = 0;
- }
-
- setedit(n)
- {
- Synthname = E[n].ed_name;
- Datain = E[n].ed_din;
- Dataout = E[n].ed_dout;
- Nvoices = E[n].ed_nvoices;
- Sendedit = E[n].ed_sedit;
- Sendone = E[n].ed_sone;
- Sendbulk = E[n].ed_sbulk;
- Getbulk = E[n].ed_gbulk;
- Nameof = E[n].ed_nof;
- Numof = E[n].ed_numof;
- Cvtnum = E[n].ed_cvtnum;
- Cvtanum = E[n].ed_cvtanum;
- Setnameof = E[n].ed_snof;
- Voicesize = E[n].ed_vsize;
- Namesize = E[n].ed_nsize;
- Libdata = PE[n].ed_libdata;
- Syndata = PE[n].ed_syndata;
- Yankdata = PE[n].ed_yankdata;
- Libindex = PE[n].ed_libindex;
- Synindex = PE[n].ed_synindex;
- Channel = PE[n].ed_channel;
- Editrow = PE[n].ed_erow;
- Editcol = PE[n].ed_ecol;
- clrdata(Currdata,Voicesize);
- P = E[n].ed_params;
- L = E[n].ed_labels;
- }
-
- unsetedit(n)
- {
- int k;
-
- PE[n].ed_libindex = Libindex;
- PE[n].ed_synindex = Synindex;
- PE[n].ed_channel = Channel;
- PE[n].ed_erow = Editrow;
- PE[n].ed_ecol = Editcol;
- for ( k=0; k<Voicesize; k++ )
- PE[n].ed_yankdata[k] = Yankdata[k];
- }
-
- /* template - show the boxes and such on the main library screen */
- template()
- {
- int n, k, r;
-
- r = FIRSTROW-1;
- sprintf(Buff,"%s Voices",Synthname);
- n = 13 - strlen(Buff)/2; /* center it */
- windgoto(r,n<0?0:n);
- windstr(Buff);
- r++;
- windgoto(r,0);
- for ( n=0; n<26; n++ )
- windputc('=');
- windgoto(r,52);
- for ( n=0; n<26; n++ )
- windputc('=');
- for ( n=r+1; n<(r+13); n++ ) {
- windgoto(n,0);
- windputc('|');
- windgoto(n,6);
- windputc('|');
- windgoto(n,25);
- windputc('|');
-
- k=52;
- windgoto(n,k);
- windputc('|');
- windgoto(n,k+6);
- windputc('|');
- windgoto(n,k+25);
- windputc('|');
- }
- windgoto(r+13,0);
- for ( n=0; n<26; n++ )
- windputc('=');
- windgoto(r+13,52);
- for ( n=0; n<26; n++ )
- windputc('=');
-
- windgoto(YANKROW-2,YANKCOL);
- windstr(" Yank Buffer");
- windgoto(YANKROW-1,YANKCOL);
- windstr(" ------------- ");
- windgoto(YANKROW,YANKCOL);
- windstr(" ");
- windgoto(YANKROW+1,YANKCOL);
- windstr(" ------------- ");
- windrefresh();
- }
-
- /* clear the message area */
- clearmess()
- {
- int n;
- for(n=1;n<(FIRSTROW-1);n++)
- winderaserow(n);
- Currrow = 0;
- }
-
- /* set the current voice (ie. the synth's edit buffer) to the indicated */
- /* voice. c==0 is the synth (left) side, c==1 is the library (right) side. */
- editto(r,c)
- {
- int voicenum;
-
- /* Clear the existing '*' */
- editchar(' ',Editrow,Editcol);
- editchar('*',Editrow=r,Editcol=c);
- if ( Editcol==0 ) {
- /* we're on the synth side */
- voicenum = Editrow+Synindex;
- tocurrent(Syndata,voicenum);
- }
- else {
- /* we're on the lib side */
- voicenum = Editrow+Libindex;
- tocurrent(bankvoice(0),voicenum);
- }
- }
-
- editchar(ec,r,c)
- {
- r = r + FIRSTROW + 1;
- if ( c == 0 )
- c = LEFTSIDE-1;
- else
- c = RIGHTSIDE-1;
- windgoto(r,c);
- windputc(ec);
- windrefresh();
- }
-
- /* control interaction on the main library bank screen */
- libinteract()
- {
- int c, n, swap, voicenum, maxindex;
- char *p, *data;
-
- flushmidi();
- drawall();
- for ( ;; ) {
- Currrow = 0;
- winderaserow(Currrow);
- windgoto(Currrow,0);
- windstr("Command --> ");
- windrefresh();
-
- c = mouseorkey();
- if ( c == MOUSE ) {
- libmouse();
- continue;
- }
-
- if ( isprint(c) )
- windputc(c);
- clearmess();
- switch ( c ) {
- case ' ':
- playnote(1);
- break;
- case '\n':
- #ifndef macintosh
- case '\r':
- #endif
- /* ignore */
- break;
- case EOF:
- case 'q':
- return;
- case CH_REDRAW:
- drawall();
- break;
- case 's':
- case 'p':
- swap = (c=='s')?1:0;
- if ( Editcol==0 )
- tosyn(Synindex+Editrow,Yankdata,swap);
- else
- tolib(Libindex+Editrow,Yankdata,swap);
- updatedisplay();
- pryankname();
- break;
- case 'y':
- for(n=0;n<Voicesize;n++)
- Yankdata[n] = Currdata[n];
- pryankname();
- break;
- case '?':
- helpmessage();
- break;
- case SCR_DOWN:
- maxindex = Nvoices - NUMONSCREEN;
- if ( Editcol==0 ) {
- /* we're on the synth side */
- if ( (Synindex+=NUMONSCREEN/2) > maxindex )
- Synindex = maxindex;
- }
- else {
- /* we're on the lib side */
- if ( (Libindex+=NUMONSCREEN/2) > maxindex )
- Libindex = maxindex;
- }
- updatedisplay();
- break;
- case SCR_UP:
- if ( Editcol==0 ) {
- /* we're on the synth side */
- if ( (Synindex-=NUMONSCREEN/2) < 0 )
- Synindex = 0;
- }
- else {
- /* we're on the lib side */
- if ( (Libindex-=NUMONSCREEN/2) < 0 )
- Libindex = 0;
- }
- updatedisplay();
- break;
- case '\033':
- case '`':
- allnotesoff();
- break;
- case 't':
- transcmd();
- break;
- case 'd': /* download from synth to display */
- clrdata(Syndata,Nvoices*Voicesize);
- if ( readsynth(Syndata) == 0 )
- syntodisplay(Synindex=0);
- break;
- case 'u': /* upload TO synth */
- if ( Editcol==0 ) {
- voicenum = Editrow+Synindex;
- data = &(VOICEBYTE(Syndata,voicenum,0));
- }
- else
- data = bankvoice(Editrow+Libindex);
- upload(data);
- break;
- case 'r':
- readall();
- break;
- case 'w':
- writeall();
- break;
- case 'c':
- setchan();
- break;
- case 'b':
- /* cycle through banks, from 0 to LIBBANKS-1 */
- if ( ++Libbank >= LIBBANKS )
- Libbank = 0;
- libtodisplay(Libindex);
- updatedisplay();
- break;
- case 'e':
- p = (*Nameof)(Currdata);
- if ( Editcol==0 ) {
- voicenum = Editrow+Synindex;
- data = &(VOICEBYTE(Syndata,voicenum,0));
- editdata(p,data);
- windclear();
- /* Update Currdata */
- for ( n=0; n<Voicesize; n++ )
- Currdata[n] = VOICEBYTE(Syndata,voicenum,n);
- }
- else {
- data = bankvoice(Editrow+Libindex);
- editdata(p,data);
- }
- drawall();
- break;
- case 'g': /* goto a specific voice */
- do_goto();
- break;
- case CH_LEFT:
- if ( Editcol==1 )
- editto(Editrow,0);
- break;
- case CH_DOWN:
- if ( Editrow < (NUMONSCREEN-1) )
- editto(Editrow+1,Editcol);
- else {
- /* we're at the bottom, so try to scroll */
- if ( Editcol==0 ) {
- /* we're on the synth side */
- if (Synindex<(Nvoices-NUMONSCREEN))
- Synindex++;
- }
- else {
- /* we're on the lib side */
- if (Libindex<(Nvoices-NUMONSCREEN))
- Libindex++;
- }
- updatedisplay();
- }
- break;
- case CH_UP:
- if ( Editrow>0 )
- editto(Editrow-1,Editcol);
- else {
- /* we're at the top, so try to scroll */
- if ( Editcol==0 ) {
- /* we're on the synth side */
- if (Synindex>0)
- Synindex--;
- }
- else {
- /* we're on the lib side */
- if (Libindex>0)
- Libindex--;
- }
- updatedisplay();
- }
- break;
- case CH_RIGHT:
- if ( Editcol==0 )
- editto(Editrow,1);
- break;
- case 'f':
- filelist();
- break;
- default:
- message("Unrecognized command! Press '?' for help.");
- break;
- }
- }
- }
-
- filelist()
- {
- char *p, *q, buff[BUFSIZ];
- int n, ninline = 0, nprinted = 0;
-
- clearmess();
- Currrow = -1; /* To start message on top line */
- openls();
- message("Files in current directory:");
- strcpy(buff," ");
- while ( (p=nextls()) != NULL ) {
- /* add the next file to the line being constructed */
- q = &buff[strlen(buff)];
- strcpy(q,p);
- q += (n=strlen(p));
- while ( n++ < 15 )
- *q++ = ' ';
- *q = '\0';
- if ( ninline++ > 3 ) {
- message(buff);
- if ( nprinted++ > 4 ) {
- message("Press any key to continue ...");
- getconsole();
- clearmess();
- nprinted = 0;
- }
- strcpy(buff," ");
- ninline = 0;
- }
- }
- if ( ninline > 0 )
- message(buff);
- closels();
- }
-
- libmouse()
- {
- int row, col;
-
- getmouse(&row,&col);
- if ( row <= FIRSTROW || row > FIRSTROW+NUMONSCREEN+1 )
- goto getout;
- if ( col < Cols/2 )
- col = 0;
- else
- col = 1;
- row = row - FIRSTROW - 1;
- editto(row,col);
- getout:
- /* wait until mouse button is released */
- while ( statmouse() > 0 )
- ;
- }
-
- do_goto()
- {
- int n, r, maxindex, new_ecol;
- char sbuf[100], *sp;
-
- message("");
- message("Where to? ");
- windgets(sbuf);
-
- sp = sbuf;
- switch(*sp++) {
- case 's': /* synth side */
- new_ecol = 0;
- break;
- case 'l': /* library side */
- new_ecol = 1;
- break;
- default: /* no change in side */
- new_ecol = Editcol;
- sp--; /* but don't trash the first character */
- break;
- }
-
- clearmess();
- r = sscanf(sp, "%d", &n); /* this may fail - we handle it later */
- if(Cvtnum != NULL) { /* convert to internal format if needed */
- n = (*Cvtnum)(n) + 1; /* we are 1-based for user input */
- }
- if (Cvtanum != NULL) { /* convert using alphanumeric voice number */
- n = (*Cvtanum)(sp) + 1;
- }
- if(r != 1) {
- message("type one of: sn, ln, or n");
- message(" s = synth side (literal character 's')");
- message(" l = library side (literal character 'l')");
- message(" n = voice number to select (an integer)");
- return;
- }
- if(n <= 0 || n > Nvoices) { /* 1-based */
- message("Bad voice number!");
- return;
- }
-
- /* it can be done. nuke the old '*' and change columes (if needed) */
- editchar(' ', Editrow, Editcol);
- Editcol = new_ecol;
-
- /* try to center it */
- maxindex = Nvoices - NUMONSCREEN;
- if(Editcol == 0) {
- Synindex = (n - 1) - NUMONSCREEN/2; /* 0-based */
- if(Synindex < 0) { /* impossible to center */
- Synindex = 0; /* so do your best */
- } else if(Synindex > maxindex) {
- Synindex = maxindex;
- }
- Editrow = (n - 1) - Synindex; /* and put a '*' on it */
- } else {
- Libindex = (n - 1) - NUMONSCREEN/2; /* 0-based */
- if(Libindex < 0) {
- Libindex = 0;
- } else if(Libindex > maxindex) {
- Libindex = maxindex;
- }
- Editrow = (n - 1) - Libindex;
- }
-
- updatedisplay(); /* do the real work */
- return;
- }
-
- upload(data)
- char *data;
- {
- int c, n;
- char num[16];
-
- message("");
- message("Upload TO synth:");
- message(" c - current voice");
- message(" a - ALL voices");
- message("Choose --> ");
- c = getconsole();
- if ( c == 'c' ) {
- clearmess();
- if ( Sendone == NULL ) {
- message("Single voices can't be sent to that synth!");
- return;
- }
- message("What voice number to you want to send it TO? --> ");
- windgets(num);
- clearmess();
- n = atoi(num);
- if(Cvtnum != NULL) { /* convert to internal format if needed */
- n = (*Cvtnum)(n) + 1; /* we are 1-based for user input */
- }
- if (Cvtanum != NULL) { /* howzabout alphanumeric format? */
- n = (*Cvtanum)(num) + 1;
- }
- if ( n > 0 && n <= Nvoices ) {
- if ( (*Sendone)(n-1,data) != 0 ) { /* 0-based on calls -SAF */
- message("Unable to write data to synth!");
- sprintf(Buff,"Reason: %s",Reason);
- message(Buff);
- }
- } else {
- message("Bad voice number!");
- }
- }
- else if ( c == 'a' ) {
- clearmess();
- if ( Sendbulk != NULL )
- (*Sendbulk)(Syndata);
- else {
- for ( n=0; n<Nvoices; n++ ) {
- if ( (*Sendone)(n, &(VOICEBYTE(Syndata,n,0)) ) != 0 ) {
- message("Unable to write data to synth!");
- sprintf(Buff,"Reason: %s",Reason);
- message(Buff);
- break;
- }
- }
- }
- /* clearmess(); */
- }
- else {
- clearmess();
- message("Bad choice!");
- }
- }
-
- helpmessage()
- {
- clearmess();
- sprintf(Buff,"%s,%s,%s,%s - move around e - edit current voice",
- STR_LEFT,STR_DOWN,STR_UP,STR_RIGHT);
- message(Buff);
- message("r - read voices from a file y - yank into buffer");
- message("w - write voices to a file p - put from buffer");
- message("b - cycle through library banks s - swap current voice with yank buffer");
- message("t - transfer all voices f - list files in current directory");
- message("d - download voices from synth c - set MIDI channel");
- message("u - upload voices to synth g - 'goto' form of moving around");
- message("q - quit <space> - play a note");
- }
-
- updatedisplay()
- {
- if ( Editcol==0 ) {
- /* we're on the synth side */
- syntodisplay(Synindex);
- editto(Editrow,Editcol);
- }
- else {
- /* we're on the lib side */
- libtodisplay(Libindex);
- editto(Editrow,Editcol);
- }
- }
-
- pryankname()
- {
- char ybuff[33];
- char *p;
-
- windgoto(YANKROW,YANKCOL-4);
- windstr(" ");
- strcpy(ybuff,(*Nameof)(Yankdata));
- /* take off trailing blanks */
- p = ybuff + strlen(ybuff) - 1;
- while ( p>ybuff && *p == ' ' )
- *p-- = '\0';
- windgoto(YANKROW,YANKCOL+7-strlen(ybuff)/2);
- windstr(ybuff);
- windrefresh();
- }
-
- transcmd()
- {
- int fromc;
-
- message("");
- message("Transfer ALL voices:");
- message(" 1: <<----- from library bank to synth bank");
- message(" 2: ----->> from synth bank to library bank");
- message("1 or 2 --> ");
- fromc = getconsole();
- windputc(fromc);
- if ( fromc!='1' && fromc!='2' ) {
- clearmess();
- return;
- }
- switch ( fromc ) {
- case '1':
- copyall(bankvoice(0),Syndata);
- syntodisplay(Synindex);
- clearmess();
- message("Use the 'u'pload command to actually send the synth bank voices to the synth.");
- break;
- case '2':
- copyall(Syndata,bankvoice(0));
- libtodisplay(Libindex);
- clearmess();
- break;
- }
- }
-
- copyall(fromdata,todata)
- char *fromdata;
- char *todata;
- {
- int n, v;
-
- for ( v=0; v<Nvoices; v++ )
- for ( n=0; n<Voicesize; n++ )
- VOICEBYTE(todata,v,n) = VOICEBYTE(fromdata,v,n);
- }
-
- message(s)
- char *s;
- {
- windgoto(++Currrow,0);
- windstr(s);
- windrefresh();
- }
-
- setchan()
- {
- int c;
-
- message("New MIDI channel --> ");
- windgets(Buff);
- if ( (c=atoi(Buff)) <= 0 || c > 16 ) {
- clearmess();
- message("Invalid channel!");
- }
- else {
- clearmess();
- Channel = c;
- showchan();
- }
- }
-
- showchan()
- {
- windgoto(20,31);
- windstr("MIDI Channel: ");
- sprintf(Buff,"%d ",Channel);
- windstr(Buff);
- windrefresh();
- }
-
- /* read data from a file, filling the current library bank. */
- readall()
- {
- char fname[100];
- FILE *f;
- int v, n, r;
-
- message("File name --> ");
- windgets(fname);
- OPENBINFILE(f,fname,"r");
- if (f == NULL ) {
- sprintf(Buff,"Can't open '%s'!",fname);
- message(Buff);
- return;
- }
- /* Check the first byte. If it's 0xdd, then the format is mine. */
- /* If the first byte is 0-31, it's also mine. */
- n = (getc(f) & 0xff);
- if ( n == 0xdd || n<=31 ) {
- if ( n <= 31 )
- ungetc(n,f);
- /* This is my format, just raw data. */
- for ( v=0; v<Nvoices; v++ ) {
- char *p = bankvoice(v);
- for ( n=0; n<Voicesize; n++ )
- *p++ = getc(f);
- }
- r = 0;
- }
- /* code for other formats would go here */
- else {
- message("Unknown file format");
- r = 1;
- }
- fclose(f);
- if ( r==0 ) {
- libtodisplay(Libindex=0);
- clearmess();
- }
- }
-
- /* write current library bank to a file */
- writeall()
- {
- char fname[100];
- FILE *f;
- int v, n;
-
- message("File name --> ");
- windgets(fname);
- OPENBINFILE(f,fname,"w");
- if ( f == NULL ) {
- sprintf(Buff,"Can't open '%s'!",fname);
- message(Buff);
- return;
- }
- putc(0xdd,f); /* magic byte to identify my format */
- for ( v=0; v<Nvoices; v++ ) {
- char *p = bankvoice(v);
- for ( n=0; n<Voicesize; n++ )
- putc(*p++,f);
- }
- fclose(f);
- clearmess();
- }
-
- /* draw main library/synth voice bank screen */
- drawall()
- {
- windclear();
- template();
- libtodisplay(Libindex);
- syntodisplay(Synindex);
- editto(Editrow,Editcol);
- pryankname();
- showchan();
- }
-
- /*
- * tosyn
- *
- * Store the given 'data' in in voice 'voicenum' (both in Syndata
- * AND on the synth itself). If swap is non-zero, the voice is swapped
- * with the current voice in Syndata.
- */
-
- tosyn(voicenum,data,swap)
- char *data;
- {
- int n, t;
-
- for ( n=0; n<Voicesize; n++ ) {
- if ( swap ) {
- t = VOICEBYTE(Syndata,voicenum,n);
- VOICEBYTE(Syndata,voicenum,n) = data[n];
- data[n] = t;
- }
- else
- VOICEBYTE(Syndata,voicenum,n) = data[n];
- }
- }
-
- tolib(voicenum,data,swap)
- char *data;
- {
- int n, t;
- char *p = bankvoice(voicenum);
-
- for ( n=0; n<Voicesize; n++ ) {
- if ( swap ) {
- t = *p;
- *p = data[n];
- data[n] = t;
- }
- else
- *p = data[n];
- p++;
- }
- }
-
- tocurrent(data,voicenum)
- char *data;
- int voicenum;
- {
- int n;
-
- for ( n=0; n<Voicesize; n++ )
- Currdata[n] = VOICEBYTE(data,voicenum,n);
- (*Sendedit)(Currdata);
- }
-
- /*
- * readsynth
- *
- * Read a bulk dump from the synth, with some tolerance for errors.
- */
- readsynth(data)
- char *data;
- {
- if ( Getbulk == NULL ) {
- message("That synth is unable to dump anything!!");
- return(1);
- }
- message("Trying to download data from synth...");
- if ( (*Getbulk)(data) == 0 ) {
- clearmess();
- return(0);
- }
- message("Unable to read data from synth!");
- sprintf(Buff,"Reason: %s",Reason);
- message(Buff);
- message("Perhaps connections are amiss?");
- return(1);
- }
-
- char *
- vnumtext(n)
- {
- static char vnbuff[6];
-
- if ( Numof == NULL ) {
- sprintf(vnbuff,"%2d",n);
- return(vnbuff);
- }
- else
- return((*Numof)(n - 1)); /* keep this 0-based */
- }
-
- /*
- * syntodisplay(n)
- *
- * Tranfer Syndata names to dialog boxes (Dxvoices) starting at n.
- */
- syntodisplay(n)
- {
- int k, r;
-
- /* for the NUMONSCREEN dialog boxes */
- for ( k=0; k<NUMONSCREEN; k++ ) {
- r = FIRSTROW+1+k;
- windgoto(r,LEFTSIDE);
- sprintf(Buff,"%-3s",vnumtext(n+k+1));
- windstr(Buff);
- windgoto(r,LEFTSIDE+6);
- windstr(" ");
-
- /* pull the name out of the Syndata */
- windgoto(r,LEFTSIDE+6);
- windstr((*Nameof)( & (VOICEBYTE(Syndata,n+k,0) )) );
- }
- windrefresh();
- }
-
- /*
- * libtodisplay
- *
- * Tranfer Libdata names to the screen, starting at voice 'firstv'.
- */
-
- libtodisplay(firstv)
- {
- int k, r;
-
- windgoto(FIRSTROW-1,RIGHTSIDE-1);
- sprintf(Buff,"Library Voices (Bank %d)",Libbank+1);
- windstr(Buff);
-
- /* for the NUMONSCREEN dialog boxes */
- for ( k=0; k<NUMONSCREEN; k++ ) {
- r = FIRSTROW+1+k;
- windgoto(r,RIGHTSIDE);
- sprintf(Buff,"%-3s",vnumtext(firstv+k+1));
- windstr(Buff);
- windgoto(r,RIGHTSIDE+6);
- windstr(" ");
-
- /* pull the name out of the Libdata */
- windgoto(r,RIGHTSIDE+6);
- windstr((*Nameof)(bankvoice(firstv+k)));
- }
- windrefresh();
- }
-
- allnotesoff()
- {
- int n;
-
- /* Go through all channels. */
- for ( n=0; n<15; n++ ) {
- sendmidi(n | 0xb0);
- sendmidi(0x7b);
- sendmidi(0x00);
- }
- }
-
- /*
- * Below are generic edit routines, which manage a screen display
- * showing parameter values, and let you roam around and make changes.
- * The display is managed by the contents of the P array, which
- * contains the name, screen location, min/max values, etc. of
- * each parameter.
- */
-
- int Prow = 0;
- int Pcol = 0;
- int Parm = 0;
-
- /* redraw the parameter screen */
- showallparms(name)
- char *name;
- {
- int n;
- char *s;
-
- windclear();
-
- showname(name);
- windgoto(1,0);
- for(n=strlen(name)+6;n>0;n--)
- windputc('=');
-
- /* The L array contains arbitrary screen labels */
- for ( n=0; L[n].l_text != NULL; n++ ) {
- windgoto(L[n].l_row,L[n].l_col);
- windstr(L[n].l_text);
- }
- /* Display each parameter value, and a label if there is one. */
- for ( n=0; P[n].p_name != NULL; n++ ) {
- if ( P[n].p_flags != 0 )
- continue;
- if ( (s=P[n].p_label) != NULL )
- showstr(s,P[n].p_lrow,P[n].p_lcol,0);
- showparam(n,0);
- }
- windrefresh();
- }
-
- showname(name)
- char *name;
- {
- windgoto(0,0);
- windstr("Name: ");
- windgoto(0,6);
- windstr(name);
- }
-
- showparam(n,eras)
- {
- char *p;
-
- /* The p_tovis element of the P array is a function which, given */
- /* the parameter value as an argument, returns a string which is */
- /* what should be displayed on the screen. */
- p = (*(P[n].p_tovis))(P[n].p_val);
- showstr(p,P[n].p_vrow,P[n].p_vcol,eras);
- }
-
- showstr(p,row,col,eras)
- register char *p;
- register int col;
- {
- register int c;
-
- windgoto(row,col);
- while ( (c=(*p++)) != '\0' ) {
- switch(c){
- case '~':
- switch( (c=(*p++)) ) {
- case 'u': row--; goto wgoto;
- case 'd': row++; goto wgoto;
- case 'l': col--; goto wgoto;
- case 'r': col++;
- wgoto:
- windgoto(row,col);
- break;
- default:
- windputc(eras?' ':c);
- col++;
- break;
- }
- break;
- default:
- windputc(eras?' ':c);
- col++;
- break;
- }
- }
- }
-
- /* Allow roaming around and changing of parameter values. */
- editdata(name,data)
- char *name;
- char *data; /* vmem format */
- {
- int c, n;
-
- windclear();
- windrefresh();
- /* enable all the parameters */
- for ( n=0; P[n].p_name != NULL; n++ )
- enableparm(n);
-
- /* Take the voice data and put it into P */
- (*Datain)(data);
-
- Prow = Pcol = 0;
- Changed = 0;
- Redraw = 1;
- gotoparm(CH_RIGHT); /* Get to the first parameter */
- for ( ;; ) {
- if ( Redraw ) {
- showallparms(name);
- Redraw = 0;
- }
- windgoto(Prow,Pcol);
- windrefresh();
- c = mouseorkey();
- if ( c == MOUSE ) {
- editmouse();
- continue;
- }
- switch(c){
- case CH_RIGHT:
- case CH_UP:
- case CH_DOWN:
- case CH_LEFT:
- gotoparm(c);
- break;
- case CH_REDRAW:
- showallparms(name);
- break;
- case 'N':
- /* Allow changing of voice name */
- windgoto(0,5);
- windstr(" ");
- windgoto(0,6);
- windrefresh();
- windgets(Buff);
- if ( Buff[0]!='\0' && Buff[0]!='\n' )
- (*Setnameof)(data,Buff);
- showname(name=(*Nameof)(data));
- Changed = 1;
- break;
-
- case CH_INC:
- adjuparm(1);
- break;
- case CH_INC2:
- adjuparm(4);
- break;
- case CH_INC3:
- adjuparm(P[Parm].p_max - P[Parm].p_min);
- break;
- case CH_DEC:
- adjuparm(-1);
- break;
- case CH_DEC2:
- adjuparm(-4);
- break;
- case CH_DEC3:
- adjuparm(P[Parm].p_min - P[Parm].p_max);
- break;
- #ifdef OLDSTUFF
- case 'a':
- sendaced(data);
- playnote(0);
- break;
- #endif
- case ' ':
- case '\n':
- #ifndef macintosh
- case '\r':
- #endif
- if ( Changed ) {
- (*Dataout)(data);
- (*Sendedit)(data);
- }
- playnote(0);
- break;
- case '\033':
- case '`':
- allnotesoff();
- break;
- case 'q':
- case EOF:
- if ( Changed ) {
- (*Dataout)(data);
- (*Sendedit)(data);
- }
- return;
- default:
- break;
- }
- }
- }
-
- adjuparm(incdec)
- {
- int v, n;
-
- v = P[Parm].p_val + incdec;
- if ( v < (n=P[Parm].p_min) )
- v = n;
- if ( v > (n=P[Parm].p_max) )
- v = n;
- Changed = 1;
- showparam(Parm,1); /* erase the old val */
- P[Parm].p_val = v;
- showparam(Parm,0); /* show the new val */
- }
-
- editmouse()
- {
- int row, col, thisparm;
-
- getmouse(&row,&col);
- thisparm = closeparm(row,col);
- if ( thisparm == Parm ) {
- if ( statmouse() > 1 )
- adjuparm(-1); /* right button */
- else if ( statmouse() == 1 ) /* added by mab - bug fix */
- adjuparm(1); /* left button */
- }
- else {
- Parm = thisparm;
- Prow = P[Parm].p_vrow;
- Pcol = P[Parm].p_vcol;
- }
- }
-
- /* closeparm - Find the closest parameter */
- closeparm(row,col)
- {
- register struct paraminfo *pp;
- register int n;
- int dist, mindist, minparm, dr, dc;
-
- minparm = 0;
- mindist = Rows + Cols;
- for ( n=0,pp=P; pp->p_name != NULL; n++,pp++ ) {
- if ( pp->p_flags != 0 )
- continue;
- if ( (dr=row-(pp->p_vrow)) < 0 )
- dr = -dr;
- if ( (dc=col-(pp->p_vcol)) < 0 )
- dc = -dc;
- if ( (dist=dr*dr+dc*dc) < mindist ) {
- minparm = n;
- mindist = dist;
- }
- }
- return(minparm);
- }
-
- /* playnote - play the 'auto' note */
- playnote(i)
- {
- int pitch, vol, dur, chan;
- long endtime;
-
- pitch = getval("autopitch");
- if(i == 0) { /* called from inside edit-mode */
- chan = getval("autochan");
- } else { /* called from the top level */
- chan = Channel;
- }
- vol = getval("autovol");
- dur = getval("autodur");
- endtime = milliclock() + dur * 100;
- midinote(1,chan,pitch,vol);
- while ( milliclock() < endtime )
- ;
- midinote(0,chan,pitch,vol);
- }
-
- /* gotoparm - search for the next parameter in the specified direction */
- gotoparm(dir)
- {
- int n, k, inc, pm, orig, r = Prow, c = Pcol;
-
- if ( dir==CH_LEFT || dir==CH_RIGHT ) {
- if ( dir==CH_LEFT )
- c--;
- else
- c++;
- orig = c;
- inc = 0;
- pm = -1;
- /* look up and down, alternately */
- for ( n=2*Rows; n>0; n-- ) {
- r += (pm * inc++);
- pm = -pm;
- if ( r < 0 || r >= Rows )
- continue;
- if ( dir == CH_LEFT ) {
- for ( c=orig; c>=0; c-- ) {
- if ( parmat(r,c) )
- return;
- }
- }
- else {
- for ( c=orig; c<Cols; c++ ) {
- if ( parmat(r,c) )
- return;
- }
- }
- }
- return;
- }
- if ( dir==CH_DOWN || dir==CH_UP ) {
- if ( dir==CH_DOWN )
- r++;
- else
- r--;
- orig = c;
- while ( r >= 0 && r < Rows ) {
- /* look toward both sides at the same time */
- inc = 0;
- pm = -1;
- for ( k=2*Cols; k>0; k-- ) {
- c += (pm * inc++);
- pm = -pm;
- if ( c < 0 || c >= Cols )
- continue;
- if ( parmat(r,c) )
- return;
- }
- if ( dir==CH_DOWN )
- r++;
- else
- r--;
- c = orig;
- }
- return;
- }
- }
-
- /* paramat - return non-zero if a parameter value is at position r,c */
- parmat(r,c)
- register int r, c;
- {
- register int n;
- register struct paraminfo *pp;
-
- for ( n=0,pp=P; pp->p_name != NULL; n++,pp++ ) {
- if ( pp->p_flags != 0 )
- continue;
- if ( pp->p_vrow==r && pp->p_vcol==c ) {
- Prow = r;
- Pcol = c;
- Parm = n;
- return(1);
- }
- }
- return(0);
- }
-
- /* parmindex - return index (in P) of a given parameter name. */
- parmindex(name)
- char *name;
- {
- int n;
- char *s;
-
- for ( n=0; (s=P[n].p_name) != NULL; n++ ) {
- if ( strcmp(s,name) == 0 )
- return(n);
- }
- sprintf(Buff,"HEY, PARMINDEX(%s) NOT FOUND!",name);
- windstr(Buff);
- windrefresh();
- return(-1);
- }
-
- setval(name,v)
- char *name;
- {
- int n;
-
- if ( (n=parmindex(name)) < 0 )
- return;
- P[n].p_val = v;
- }
-
- getval(name)
- char *name;
- {
- int n;
-
- if ( (n=parmindex(name)) < 0 )
- return(0);
- return(P[n].p_val);
- }
-
- enableparm(n)
- {
- if ( P[n].p_flags != 0 )
- P[n].p_flags = 0;
- }
-
- disableparm(n)
- {
- if ( P[n].p_flags == 0 )
- P[n].p_flags = 1;
- }
-
- midinote(onoff,chan,pitch,vol)
- {
- sendmidi( ((onoff==1)?(0x90):(0x80)) | ((chan-1)&0xf) );
- sendmidi( pitch & 0x7f );
- sendmidi( vol & 0x7f );
- }
-
- static char Nbuff[16];
-
- char *visnum(v)
- {
- sprintf(Nbuff,"%d",v);
- return(Nbuff);
- }
- char *visonoff(v)
- {
- if ( v==0 )
- return("off");
- else
- return("on");
- }
-
- char *
- bankvoice(voice)
- {
- int offset = Libbank * Nvoices * Voicesize + voice * Voicesize;
- return(Libdata + offset);
- }
-