/* * GLIB - a Generic LIBrarian and editor for synths * * DW8000 Librarian * * Code completed 8/24/87 -- Steven A. Falco moss!saf */ #define OVERLAY2 #include "glib.h" #define DW8VSIZE 51 char *visnum(), *visd8wave(), *visd8oct(), *visd8trk(); char *visd8ival(), *visd8detu(), *visd8asel(), *dw8vnum(), *visd8amod(); char *visd8mgw(), *visd8mode(), *visd8pol(),*visd8sem(), *visonoff(); /* This array contains arbitrary screen labels */ struct labelinfo Ldw800[] = { 2,0,"+----------------------------------+----------------+------------------+------+", 3,0,"| Osc 1 Osc 2 Noise| ModGen| AutoBend| Mode |", 4,0,"|Octave",4,35,"|Waveform",4,52,"|Select",4,71,"| |", 5,0,"|Waveform",5,35,"|Frequency",5,52,"|Mode",5,71,"| |", 6,0,"|Level",6,35,"|Delay",6,52,"|Time",6,71,"| |", 7,0,"|Interval",7,35,"|Osc",7,52,"|Intensity",7,71,"| |", 8,0,"|Detune",8,35,"|VCF",8,52,"|",8,71,"| |", 9,0,"+------------------+---------------+----------------+------------------+------+", 10,0,"|",10,11,"VCF VCA|",10,30,"Delay| Joystick | Portamento |Key |", 11,0,"|Attack",11,19,"|Time",11,35,"|Osc",11,52,"|Time",11,71,"|Param |", 12,0,"|Decay",12,19,"|Factor",12,35,"|VCF",12,52,"|",12,71,"| |", 13,0,"|Break Pt.",13,19,"|Feedback",13,35,"+----------------+------------------+------+", 14,0,"|Slope",14,19,"|Frequency |", 15,0,"|Sustain",15,19,"|Intensity | +-------------------------+--------------+", 16,0,"|Release",16,19,"|Eff.Level | |Space = Play Note",16,63,"| Auto-Note |", 17,0,"|V.Sensitv",17,19,"+---------------+ |",17,63,"|",17,78,"|", 18,0,"|Cutoff",18,19,"| AftTouch| |h = left q = quit |Pitch",18,78,"|", 19,0,"|Resonance",19,19,"|Osc.MG",19,35,"| |j = down N = Set Name |Duration |", 20,0,"|Tracking",20,19,"|VCF",20,35,"| |k = up J = Decrement |Volume",20,78,"|", 21,0,"|Polarity",21,19,"|VCA",21,35,"| |l = right K = Increment |Channel |", 22,0,"|EG.Intens",22,19,"|",22,35,"| |",22,63,"|",22,78,"|", 23,0,"+------------------+---------------+ +-------------------------+--------------+", -1,-1,NULL }; /* This array defines all the editable parameters. */ struct paraminfo Pdw800[] = { "autopitch",NULL, -1,-1, 18, 73, visnum, 0, 127, 60, 0, "autovol", NULL, -1,-1, 19, 73, visnum, 0, 127, 63, 0, "autodur", NULL, -1,-1, 20, 73, visnum, 1, 20, 5, 0, "autochan", NULL, -1,-1, 21, 73, visnum, 1, 16, 1, 0, "o1oct", NULL, -1,-1, 4, 10, visd8oct, 0, 3, 0, 0, "o1wave", NULL, -1,-1, 5, 10, visd8wave, 0, 15, 0, 0, "o1lev", NULL, -1,-1, 6, 10, visnum, 0, 31, 0, 0, "o2oct", NULL, -1,-1, 4, 20, visd8oct, 0, 3, 0, 0, "o2wave", NULL, -1,-1, 5, 20, visd8wave, 0, 15, 0, 0, "o2lev", NULL, -1,-1, 6, 20, visnum, 0, 31, 0, 0, "o2ival", NULL, -1,-1, 7, 20, visd8ival, 0, 7, 0, 0, "o2detu", NULL, -1,-1, 8, 20, visd8detu, 0, 7, 0, 0, "noise", NULL, -1,-1, 6, 30, visnum, 0, 31, 0, 0, "mgwave", NULL, -1,-1, 4, 46, visd8mgw, 0, 3, 0, 0, "mgfrew", NULL, -1,-1, 5, 46, visnum, 0, 31, 0, 0, "mgdela", NULL, -1,-1, 6, 46, visnum, 0, 31, 0, 0, "mgosc", NULL, -1,-1, 7, 46, visnum, 0, 31, 0, 0, "mgvcf", NULL, -1,-1, 8, 46, visnum, 0, 31, 0, 0, "abndsel", NULL, -1,-1, 4, 63, visd8asel, 0, 3, 0, 0, "abndmod", NULL, -1,-1, 5, 63, visd8amod, 0, 1, 0, 0, "abndtim", NULL, -1,-1, 6, 63, visnum, 0, 31, 0, 0, "abndins", NULL, -1,-1, 7, 63, visnum, 0, 31, 0, 0, "mode", NULL, -1,-1, 4, 72, visd8mode, 0, 3, 0, 0, "fatt", NULL, -1,-1, 11, 11, visnum, 0, 31, 0, 0, "fdec", NULL, -1,-1, 12, 11, visnum, 0, 31, 0, 0, "fbrk", NULL, -1,-1, 13, 11, visnum, 0, 31, 0, 0, "fslp", NULL, -1,-1, 14, 11, visnum, 0, 31, 0, 0, "fsus", NULL, -1,-1, 15, 11, visnum, 0, 31, 0, 0, "frel", NULL, -1,-1, 16, 11, visnum, 0, 31, 0, 0, "fsens", NULL, -1,-1, 17, 11, visnum, 0, 7, 0, 0, "fcut", NULL, -1,-1, 18, 11, visnum, 0, 63, 0, 0, "fres", NULL, -1,-1, 19, 11, visnum, 0, 31, 0, 0, "ftrk", NULL, -1,-1, 20, 11, visd8trk, 0, 3, 0, 0, "fpol", NULL, -1,-1, 21, 11, visd8pol, 0, 1, 0, 0, "fegi", NULL, -1,-1, 22, 11, visnum, 0, 31, 0, 0, "aatt", NULL, -1,-1, 11, 16, visnum, 0, 31, 0, 0, "adec", NULL, -1,-1, 12, 16, visnum, 0, 31, 0, 0, "abrk", NULL, -1,-1, 13, 16, visnum, 0, 31, 0, 0, "aslp", NULL, -1,-1, 14, 16, visnum, 0, 31, 0, 0, "asus", NULL, -1,-1, 15, 16, visnum, 0, 31, 0, 0, "arel", NULL, -1,-1, 16, 16, visnum, 0, 31, 0, 0, "asens", NULL, -1,-1, 17, 16, visnum, 0, 7, 0, 0, "dtim", NULL, -1,-1, 11, 30, visnum, 0, 7, 0, 0, "dfact", NULL, -1,-1, 12, 30, visnum, 0, 15, 0, 0, "dfeed", NULL, -1,-1, 13, 30, visnum, 0, 15, 0, 0, "dfreq", NULL, -1,-1, 14, 30, visnum, 0, 31, 0, 0, "dintns", NULL, -1,-1, 15, 30, visnum, 0, 31, 0, 0, "deff", NULL, -1,-1, 16, 30, visnum, 0, 15, 0, 0, "atosc", NULL, -1,-1, 19, 27, visnum, 0, 3, 0, 0, "atvcf", NULL, -1,-1, 20, 27, visnum, 0, 3, 0, 0, "atvca", NULL, -1,-1, 21, 27, visnum, 0, 3, 0, 0, "joyosc", NULL, -1,-1, 11, 40, visd8sem, 0, 15, 0, 0, "joyvcf", NULL, -1,-1, 12, 40, visonoff, 0, 1, 0, 0, "portam", NULL, -1,-1, 11, 58, visnum, 0, 31, 0, 0, "vnumb", NULL, -1,-1, 12, 72, dw8vnum, 0, 63, 0, 0, NULL, NULL, -1,-1, -1, -1, visnum, 0, 0, 0, 0 }; /* * dw8vnum * * Convert a voice number (0 to 63) to the string displayed in the * librarian (ie. 11 to 88). */ char * dw8vnum(n) { static char v[3]; if ( n < 0 || n > 63 ) return("??"); v[0] = n/8 + '1'; v[1] = n%8 + '1'; v[2] = '\0'; return(v); } /* * dw8numv * * Convert a display-style voice number (11 to 88) to internal * format (0 - 63). */ dw8numv(n) int n; { int ld, rd; /* crack out the digits as octal codes */ ld = (n / 10) - 1; /* left digit */ rd = (n % 10) - 1; /* right digit */ if(ld < 0 || ld > 7 || rd < 0 || rd > 7) { return(-1); } else { return(ld * 8 + rd); /* combine as octal */ } } /* * dw8din * * Take library bank 'data' and stuff values in the P array, by using * the setval function. */ dw8din(data) char *data; { /* The first 20 bytes are reserved (arbitrarily) for the voice name */ setval("o1oct",data[20]); setval("o1wave",data[21]); setval("o1lev",data[22]); setval("abndsel",data[23]); setval("abndmod",data[24]); setval("abndtim",data[25]); setval("abndins",data[26]); setval("o2oct",data[27]); setval("o2wave",data[28]); setval("o2lev",data[29]); setval("o2ival",data[30]); setval("o2detu",data[31]); setval("noise",data[32]); setval("mode",data[33]); setval("vnumb",data[34]); setval("fcut",data[35]); setval("fres",data[36]); setval("ftrk",data[37]); setval("fpol",data[38]); setval("fegi",data[39]); setval("fatt",data[40]); setval("fdec",data[41]); setval("fbrk",data[42]); setval("fslp",data[43]); setval("fsus",data[44]); setval("frel",data[45]); setval("fsens",data[46]); setval("aatt",data[47]); setval("adec",data[48]); setval("abrk",data[49]); setval("aslp",data[50]); setval("asus",data[51]); setval("arel",data[52]); setval("asens",data[53]); setval("mgwave",data[54]); setval("mgfrew",data[55]); setval("mgdela",data[56]); setval("mgosc",data[57]); setval("mgvcf",data[58]); setval("joyosc",data[59]); setval("joyvcf",data[60]); setval("dtim",data[61]); setval("dfact",data[62]); setval("dfeed",data[63]); setval("dfreq",data[64]); setval("dintns",data[65]); setval("deff",data[66]); setval("portam",data[67]); setval("atosc",data[68]); setval("atvcf",data[69]); setval("atvca",data[70]); /* We set the 'auto-note' channel upon entry */ setval("autochan",Channel); } /* * dw8dout * * Take (possibly changed) parameters values out of the P array and * put them back into the library bank 'data'. */ dw8dout(data) char *data; { data[20] = getval("o1oct"); data[21] = getval("o1wave"); data[22] = getval("o1lev"); data[23] = getval("abndsel"); data[24] = getval("abndmod"); data[25] = getval("abndtim"); data[26] = getval("abndins"); data[27] = getval("o2oct"); data[28] = getval("o2wave"); data[29] = getval("o2lev"); data[30] = getval("o2ival"); data[31] = getval("o2detu"); data[32] = getval("noise"); data[33] = getval("mode"); data[34] = getval("vnumb"); data[35] = getval("fcut"); data[36] = getval("fres"); data[37] = getval("ftrk"); data[38] = getval("fpol"); data[39] = getval("fegi"); data[40] = getval("fatt"); data[41] = getval("fdec"); data[42] = getval("fbrk"); data[43] = getval("fslp"); data[44] = getval("fsus"); data[45] = getval("frel"); data[46] = getval("fsens"); data[47] = getval("aatt"); data[48] = getval("adec"); data[49] = getval("abrk"); data[50] = getval("aslp"); data[51] = getval("asus"); data[52] = getval("arel"); data[53] = getval("asens"); data[54] = getval("mgwave"); data[55] = getval("mgfrew"); data[56] = getval("mgdela"); data[57] = getval("mgosc"); data[58] = getval("mgvcf"); data[59] = getval("joyosc"); data[60] = getval("joyvcf"); data[61] = getval("dtim"); data[62] = getval("dfact"); data[63] = getval("dfeed"); data[64] = getval("dfreq"); data[65] = getval("dintns"); data[66] = getval("deff"); data[67] = getval("portam"); data[68] = getval("atosc"); data[69] = getval("atvcf"); data[70] = getval("atvca"); /* If the autochan parameter has changed, update Channel */ Channel = getval("autochan"); } /* * dw8sedit * * Send a single voice to the edit buffer of the DW8000. This will be whatever * voice is currently selected. */ dw8sedit(data) char *data; { int n; sendmidi(0xf0); sendmidi(0x42); sendmidi(0x30 | (Channel - 1)); sendmidi(0x03); sendmidi(0x40); for(n = 0; n < DW8VSIZE; n++) { sendmidi(data[n + 20] & 0x7f); } sendmidi(EOX); } /* * dw8nof * * Return a pointer to the voice name buried in library bank data. */ char * dw8nof(data) char *data; { static char currbuff[17]; char *p; int m; p = currbuff; for ( m=0; m<16; m++ ) *p++ = data[m]; *p = '\0'; return(currbuff); } /* * dw8snof * * Set the voice name buried in data to name. */ dw8snof(data,name) char *data; char *name; { char *p; int m; for ( p=name,m=0; *p!='\0' && m<16; p++,m++ ) data[m] = *p; for ( ; m<16; m++ ) data[m] = ' '; } /* dw8sone - send a single voice to the DW8000 */ dw8sone(iv, data) int iv; char *data; { int c, b2, ret = 1; long begin, toolong; /* select voice n */ sendmidi(0xc0 | (Channel - 1)); sendmidi(iv); /* send data */ dw8sedit(data); /* request write */ sendmidi(0xf0); sendmidi(0x42); sendmidi(0x30 | (Channel - 1)); sendmidi(0x03); sendmidi(0x11); /* write request */ sendmidi(iv); /* the now-current voice */ sendmidi(EOX); /* read the ack/nack - set up for timeout */ begin = milliclock(); toolong = begin + 1000 * TIMEOUT; /* wait for the 0x03 byte (dw8000 ID byte) */ while ( milliclock() < toolong ) { if ( STATMIDI && (c=(getmidi() & 0xff)) == 0x03 ) break; } if ( c != 0x03 ) { Reason = "Timeout waiting for 0x03"; goto getout; } /* next byte is the result code */ while((b2 = getmidi() & 0xff) == 0xfe) ; /* burn active sensing */ if(b2 != 0x21) { Reason = "Write failed - check protect switch!"; goto getout; } while((b2 = getmidi() & 0xff) == 0xfe) ; /* want EOX - burn active sensing */ if ( b2 != EOX ) Reason = "EOX not received"; else { Reason = ""; ret = 0; /* all's well */ } getout: return(ret); } /* dw8gbulk - Request and read a bulk dump from the DW8000 */ dw8gbulk(data) char *data; { int c, n, v, b2, ret = 1; long begin, toolong; flushmidi(); for(v = 0; v < Nvoices; v++) { /* select voice */ sendmidi(0xc0 | (Channel - 1)); sendmidi(v); /* request the voice */ sendmidi(0xf0); sendmidi(0x42); sendmidi(0x30 | (Channel-1)); /* Channel # */ sendmidi(0x03); sendmidi(0x10); sendmidi(EOX); /* set up for timeout */ begin = milliclock(); toolong = begin + 1000 * TIMEOUT; /* wait for the x40 byte starting the dump */ while ( milliclock() < toolong ) { if ( STATMIDI && (c=(getmidi() & 0xff)) == 0x40 ) break; } if ( c != 0x40 ) { Reason = "Timeout waiting for 0x40"; goto getout; } /* now read 51 bytes of voice data */ for(n = 0; n < DW8VSIZE; n++) { /* twiddle your thumbs, but not forever */ while ( ! STATMIDI ) { if ( milliclock() > toolong ) goto timeout; /* the end of an era */ } while((b2 = getmidi() & 0xff) == 0xfe) ; /* burn active sensing */ VOICEBYTE(data,v,n + 20) = b2; } timeout: if ( n != DW8VSIZE ) { Reason = "Timeout while reading!"; goto getout; } while((b2 = getmidi() & 0xff) == 0xfe) ; /* want EOX - burn active sensing */ if ( b2 != EOX ) Reason = "EOX not received"; else { Reason = ""; ret = 0; /* all's well */ } } /* go back for another voice */ getout: return(ret); } /* * Below are functions used for display of parameter values */ char * visd8wave(v) { switch (v) { case 0: return("ramp"); case 1: return("square"); case 2: return("ac. piano"); case 3: return("el. piano"); case 4: return("hd. piano"); case 5: return("clavinet"); case 6: return("organ"); case 7: return("brass"); case 8: return("sax"); case 9: return("violin"); case 10: return("a. guitar"); case 11: return("d. guitar"); case 12: return("el. bass"); case 13: return("dg. bass"); case 14: return("bell"); case 15: return("sine"); } return("*"); } char * visd8oct(v) { switch(v) { case 0: return("16"); case 1: return("8"); case 2: return("4"); case 3: return("*"); } return("*"); } char * visd8ival(v) { switch(v) { case 0: return("unison"); case 1: return("min 3rd"); case 2: return("maj 3rd"); case 3: return("4th"); case 4: return("5th"); case 5: case 6: case 7: return("*"); } return("*"); } char * visd8detu(v) { switch(v) { case 0: return("in tune"); case 1: return("1 cent"); case 2: return("2 cents"); case 3: return("3 cents"); case 4: return("4 cents"); case 5: return("5 cents"); case 6: return("6 cents"); case 7: return("*"); } return("*"); } char *Semicode[] = { "none", "1 semitone", "2 semitones", "3 semitones", "4 semitones", "5 semitones", "6 semitones", "7 semitones", "8 semitones", "9 semitones", "10 semitones", "11 semitones", "1 octave" }; char * visd8sem(v) { if(v >= 0 && v <= 12) { return(Semicode[v]); } return("*"); } char * visd8asel(v) { switch(v) { case 0: return("off"); case 1: return("Osc 1"); case 2: return("Osc 2"); case 3: return("Osc 1+2"); } return("*"); } char * visd8amod(v) { switch(v) { case 0: return("Up"); case 1: return("Down"); } return("*"); } char * visd8pol(v) { switch(v) { case 0: return("/-\\"); case 1: return("\\_/"); } return("*"); } char * visd8mode(v) { switch(v) { case 0: return("Poly 1"); case 1: return("Poly 2"); case 2: return("Uni 1"); case 3: return("Uni 2"); } return("*"); } char * visd8mgw(v) { switch(v) { case 0: return("/\\"); case 1: return("|\\"); case 2: return("/|"); case 3: return("_|-|"); } return("*"); } char * visd8trk(v) { switch(v) { case 0: return("0"); case 1: return("1/4"); case 2: return("1/2"); case 3: return("1"); } return("*"); } /* end */