home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
-
- char *st_copyright[] = {
- " *********************************************************************",
- " * Copyright 1989 by H. Edward Hall *",
- " * *",
- " * Permission is hereby granted to copy and to give away this *",
- " * software as long as this notice is preserved in its entirety. *",
- " * You may modify the software or use it for any purpose just as *",
- " * long as you preserve this notice and do not sell the software. *",
- " * No warranty of any kind is made for this software. The holder *",
- " * of this copyright reserves the right to enhance and/or sell *",
- " * this software with no obligation to provide updates or further *",
- " * free copies; if this should happen you may still use this version *",
- " * of the software under the terms you received it with. *",
- " *********************************************************************",
- NULL};
-
- /*
- * [That said, I expect subsequent versions to remain freeware
- * unless starvation sets it.]
- */
-
- /*
- * Kawai K-1 Patch Editor V0.1
- *
- * This editor is a first (and only slightly successful) attempt
- * to make a hardware-independent patch editor. I expect a great
- * deal more evolution will take place as I adapt it for the
- * Yamaha DX-7II (almost finished!) and other synths.
- *
- * The features are currently rather sparse, but certainly an order
- * of magnitude better than using Kawai's user interface.
- */
-
- /*
- * Patch parameter descriptor structure
- */
- struct param
- {
- unsigned char p_flags; /* special attributes of this field */
- unsigned char p_type; /* data conversion for this field */
- unsigned char p_byte; /* byte within patch */
- unsigned char p_bit; /* starting bit within byte */
- unsigned char p_nbits; /* number of bits in field */
- unsigned char p_secbyte; /* secondary byte within patch */
- unsigned char p_secbit; /* starting bit within byte */
- unsigned char p_secnbits; /* number of bits in field */
- unsigned char p_row; /* row on display screen */
- unsigned char p_col; /* column on display screen */
- int p_bias; /* minimum value */
- int p_limit; /* maximum value */
- char **p_names; /* strings for ENUM type */
- };
-
- /*
- * Enumeration strings for SINGLE display
- */
- char *st_src[] = {"2", "4"};
- char *st_poly[] = {"Poly-1", "Poly-2", "Solo "};
- char *st_am12[] = {"off", "1>2", "2>1"};
- char *st_am34[] = {"off", "3>4", "4>3"};
- char *st_vshp[] = {"TRI", "SAW", "SQR", "RND"};
- char *st_vwhl[] = {"DEP", "SPD"};
- char *st_mute[] = {" ", "*"};
- char *st_trkg[] = {"No ", "Yes"};
- char *st_onof[] = {"off", "On "};
- char *st_wave[] =
- {" 1 Sin 1st ", " 2 Sin 2nd ", " 3 Sin 3rd ", " 4 Sin 4th ",
- " 5 Sin 5th ", " 6 Sin 6th ", " 7 Sin 7th ", " 8 Sin 8th ",
- " 9 Sin 9th ", " 10 Sin 10th ", " 11 Sin 11th ", " 12 Sin 12th ",
- " 13 Sin 16th ", " 14 Saw 1 ", " 15 Saw 2 ", " 16 Saw 3 ",
- " 17 Saw 4 ", " 18 Saw 5 ", " 19 Saw 6 ", " 20 Saw 7 ",
- " 21 Saw 8 ", " 22 Saw 9 ", " 23 Saw 10 ", " 24 Saw 11 ",
- " 25 Saw 12 ", " 26 Saw 13 ", " 27 Saw 14 ", " 28 Saw 15 ",
- " 29 Saw 16 ", " 30 Saw 17 ", " 31 Saw 18 ", " 32 Saw 19 ",
- " 33 Square 1 ", " 34 Square 2 ", " 35 Square 3 ", " 36 Square 4 ",
- " 37 Square 5 ", " 38 Invrse Saw", " 39 Triangle ", " 40 Random ",
- " 41 Frnch Horn", " 42 String 1 ", " 43 String 2 ", " 44 String Pad",
- " 45 Piano 1 ", " 46 El. Grand ", " 47 E. Piano 1", " 48 E. Piano 2",
- " 49 E. Piano 3", " 50 Clavi ", " 51 Vibe ", " 52 A. Guitar ",
- " 53 F. Guitar ", " 54 F. Guitar ", " 55 A. Bass ", " 56 A. Bass ",
- " 57 Dig Bass 1", " 58 Pick Bass ", " 59 Dig Bass 2", " 60 Round Bass",
- " 61 Fretless 1", " 62 Fretless 2", " 63 Flute ", " 64 Pan Flute ",
- " 65 Harmonica ", " 66 Glocken ", " 67 Tine ", " 68 Harp ",
- " 69 Marimba ", " 70 E. Tom ", " 71 Log Drum ", " 72 Jazz Org 1",
- " 73 Mello Pad ", " 74 Synth Solo", " 75 Synth 2 ", " 76 Frnch Horn",
- " 77 Frnch Horn", " 78 Brass ", " 79 Brass ", " 80 Brass ",
- " 81 Brass ", " 82 Trumpet ", " 83 Trumpet ", " 84 Violin ",
- " 85 String ", " 86 Piano 1 ", " 87 Piano 2 ", " 88 Piano 3 ",
- " 89 Piano 2 ", " 90 Piano 3 ", " 91 Piano 4 ", " 92 Piano 4 ",
- " 93 El. Grand ", " 94 E. Piano 1", " 95 E. Piano 2", " 96 E. Piano 2",
- " 97 Clavi ", " 98 Harpschord", " 99 Vibe ", "100 A. Guitar ",
- "101 F. Guitar ", "102 Strat ", "103 Strat ", "104 A. Bass ",
- "105 Pull Bass ", "106 Pull Bass ", "107 Round Bass", "108 Slap Bass ",
- "109 Slap Bass ", "110 Slap Bass ", "111 Fretless ", "112 Fretless ",
- "113 Synth Bass", "114 Synth Bass", "115 Harmonica ", "116 Clarinet ",
- "117 Clarinet ", "118 Oboe ", "119 Oboe ", "120 Shakuhachi",
- "121 Orient Bel", "122 Orient Bel", "123 Bell ", "124 Koto ",
- "125 Sitar ", "126 E. Tom ", "127 Log Drum ", "128 Log Drum ",
- "129 Steel Drum", "130 Steel Drum", "131 Voice 1 ", "132 Voice 2 ",
- "133 Accordion ", "134 Accordion ", "135 Jazz Org 2", "136 Rock Org 1",
- "137 Draw Bar 1", "138 Draw Bar 2", "139 Pipe Org 1", "140 Pipe Org 2",
- "141 Rock Org 2", "142 Synth Solo", "143 Synth Solo", "144 Synth 2 ",
- "145 Synth 2 ", "146 Synth 3 ", "147 Brass ", "148 Brass ",
- "149 Orchestra ", "150 Piano 1 ", "151 Piano 4 ", "152 E. Piano 1",
- "153 E. Piano 1", "154 E. Piano 2", "155 E. Piano 3", "156 Clavi ",
- "157 Harpschord", "158 Harpschord", "159 Vibe ", "160 Dig Bass 1",
- "161 Dig Bass 2", "162 Dig Bass 2", "163 Pick bass ", "164 Glocken ",
- "165 Glocken ", "166 Tine ", "167 Tine ", "168 Tine ",
- "169 Tube Bell ", "170 Tube Bell ", "171 Tube Bell ", "172 Xylophone ",
- "173 Xylophone ", "174 Harp ", "175 Koto ", "176 Sitar ",
- "177 Sitar ", "178 Kalimbra ", "179 Kalimbra ", "180 Kalimbra ",
- "181 Log Drum ", "182 Steel Drum", "183 Pipe Org 3", "184 Pipe Org 3",
- "185 Synth 1 ", "186 Synth 2 ", "187 Synth 3 ", "188 Synth 3 ",
- "189 Synth 4 ", "190 Synth 4 ", "191 Clavi ", "192 Dig Bass 1",
- "193 Dig Bass 1", "194 Pick Bass ", "195 Pick Bass ", "196 Round Bass",
- "197 Round Bass", "198 Harmonica ", "199 Harmonica ", "200 Harp ",
- "201 Koto ", "202 Sitar ", "203 Marimba ", "204 Synth 1 ",
- "205 Bass Drum ", "206 A. Snare ", "207 Tite Snare", "208 E. Snare ",
- "209 Rim ", "210 A. Tom ", "211 High Hat ", "212 Crash ",
- "213 Ride ", "214 Strat Guit", "215 Fuzz Mute ", "216 A. Guitar ",
- "217 F. Guitar ", "218 Guit Harmo", "219 Pull Bass ", "220 Bass Harmo",
- "221 Bowd Strng", "222 Strng Attk", "223 String Sus", "224 Pizzicato ",
- "225 Piano ", "226 El. Grand ", "227 Piano Nois", "228 Trumpet ",
- "229 Shak Attck", "230 Shak Sustn", "231 PanFl Attk", "232 PanFl Sust",
- "233 Voice ", "234 White Nois", "235 Strng Loop", "236 Shak Loop ",
- "237 PanFl Loop", "238 Voice Loop", "239 WhtNois Lp", "240 Snare Loop",
- "241 F. Guit Lp", "242 PulBass Lp", "243 OmniLoop 1", "244 OmniLoop 2",
- "245 OmniLoop 3", "246 OmniLoop 4", "247 OmniLoop 5", "248 OmniLoop 6",
- "249 OmniLoop 7", "250 OmniLoop 8", "251 Snare Rev ", "252 Tom Rev ",
- "253 F. Guit Rv", "254 Hi Hat Alt", "255 Crash Alt ", "256 PnoNois Al"};
-
- char *st_note[] =
- {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
-
-
- /*
- * data types
- */
- #define LSTR 1 /* literal string */
- #define ENUM 2 /* enumeration */
- #define SNUM 3 /* signed number */
- #define UNUM 4 /* unsigned number */
- #define SPL1 5 /* coarse frequency display */
- #define SPL2 6 /* SINGLE name */
- #define SPL3 7 /* MIDI note name */
- #define PEND 15 /* end-of-parameters sentinel */
- #define FNRM 0x00 /* normal flag */
- #define FSC4 0x10 /* display only if SRC == 4 */
- #define FSGL 0x20 /* SINGLE component of a MULTIPLE */
- #define G(x) (FSGL|x) /* a specific SINGLE component */
- #define FRDW 0x40 /* redraw if value changed */
-
- /*
- * SINGLE parameter list
- */
- struct param params[] =
- { {FNRM, LSTR, 0, 0, 8, 0, 0, 0, 1, 21, 0, 10, NULL},
- {FRDW, ENUM, 11, 2, 1, 0, 0, 0, 1, 39, 0, 1, st_src},
- {FNRM, UNUM, 10, 0, 8, 0, 0, 0, 1, 47, 0, 100, NULL},
- {FNRM, ENUM, 11, 0, 2, 0, 0, 0, 1, 53, 0, 2, st_poly},
- {FNRM, ENUM, 11, 3, 2, 0, 0, 0, 1, 65, 0, 2, st_am12},
- {FNRM, ENUM, 11, 5, 2, 0, 0, 0, 1, 74, 0, 2, st_am34},
- {FNRM, SNUM, 13, 0, 8, 0, 0, 0, 2, 23, -50, 50, NULL},
- {FNRM, UNUM, 16, 0, 8, 0, 0, 0, 2, 35, 0, 100, NULL},
- {FNRM, ENUM, 17, 0, 2, 0, 0, 0, 2, 50, 0, 3, st_vshp},
- {FNRM, SNUM, 14, 0, 8, 0, 0, 0, 2, 63, -50, 50, NULL},
- {FNRM, ENUM, 17, 5, 2, 0, 0, 0, 2, 75, 0, 1, st_vwhl},
- {FNRM, UNUM, 17, 2, 3, 0, 0, 0, 3, 7, 1, 5, NULL},
- {FNRM, SNUM, 18, 0, 8, 0, 0, 0, 3, 23, -50, 50, NULL},
- {FNRM, UNUM, 19, 0, 8, 0, 0, 0, 3, 34, 0, 100, NULL},
- {FNRM, SNUM, 20, 0, 8, 0, 0, 0, 3, 45, -50, 50, NULL},
- {FNRM, SNUM, 21, 0, 8, 0, 0, 0, 3, 54, -50, 50, NULL},
- {FNRM, SNUM, 12, 0, 8, 0, 0, 0, 3, 63, -50, 50, NULL},
- {FNRM, UNUM, 15, 0, 4, 0, 0, 0, 3, 75, 0, 12, NULL},
- /*S1*/ {FNRM, ENUM, 22, 0, 1, 0, 0, 0, 5, 3, 0, 1, st_mute},
- {FNRM, ENUM, 31, 0, 7, 35, 0, 1, 5, 9, 0, 255, st_wave},
- {FNRM, ENUM, 35, 1, 1, 0, 0, 0, 5, 25, 0, 1, st_trkg},
- {FNRM, SPL1, 27, 0, 8, 0, 0, 0, 5, 33, 0, 127, NULL},
- {FNRM, SNUM, 23, 0, 8, 0, 0, 0, 5, 39, -50, 50, NULL},
- {FNRM, SNUM, 83, 0, 8, 0, 0, 0, 5, 44, -50, 50, NULL},
- {FNRM, ENUM, 35, 2, 1, 0, 0, 0, 5, 49, 0, 1, st_onof},
- {FNRM, ENUM, 35, 3, 1, 0, 0, 0, 5, 54, 0, 1, st_onof},
- /*S2*/ {FNRM, ENUM, 22, 1, 1, 0, 0, 0, 6, 3, 0, 1, st_mute},
- {FNRM, ENUM, 32, 0, 7, 36, 0, 1, 6, 9, 0, 255, st_wave},
- {FNRM, ENUM, 36, 1, 1, 0, 0, 0, 6, 25, 0, 1, st_trkg},
- {FNRM, SPL1, 28, 0, 8, 0, 0, 0, 6, 33, 0, 127, NULL},
- {FNRM, SNUM, 24, 0, 8, 0, 0, 0, 6, 39, -50, 50, NULL},
- {FNRM, SNUM, 84, 0, 8, 0, 0, 0, 6, 44, -50, 50, NULL},
- {FNRM, ENUM, 36, 2, 1, 0, 0, 0, 6, 49, 0, 1, st_onof},
- {FNRM, ENUM, 36, 3, 1, 0, 0, 0, 6, 54, 0, 1, st_onof},
- /*S3*/ {FSC4, ENUM, 22, 2, 1, 0, 0, 0, 7, 3, 0, 1, st_mute},
- {FSC4, ENUM, 33, 0, 7, 37, 0, 1, 7, 9, 0, 255, st_wave},
- {FSC4, ENUM, 37, 1, 1, 0, 0, 0, 7, 25, 0, 1, st_trkg},
- {FSC4, SPL1, 29, 0, 8, 0, 0, 0, 7, 33, 0, 127, NULL},
- {FSC4, SNUM, 25, 0, 8, 0, 0, 0, 7, 39, -50, 50, NULL},
- {FSC4, SNUM, 85, 0, 8, 0, 0, 0, 7, 44, -50, 50, NULL},
- {FSC4, ENUM, 37, 2, 1, 0, 0, 0, 7, 49, 0, 1, st_onof},
- {FSC4, ENUM, 37, 3, 1, 0, 0, 0, 7, 54, 0, 1, st_onof},
- /*S4*/ {FSC4, ENUM, 22, 3, 1, 0, 0, 0, 8, 3, 0, 1, st_mute},
- {FSC4, ENUM, 34, 0, 7, 38, 0, 1, 8, 9, 0, 255, st_wave},
- {FSC4, ENUM, 38, 1, 1, 0, 0, 0, 8, 25, 0, 1, st_trkg},
- {FSC4, SPL1, 30, 0, 8, 0, 0, 0, 8, 33, 0, 127, NULL},
- {FSC4, SNUM, 26, 0, 8, 0, 0, 0, 8, 39, -50, 50, NULL},
- {FSC4, SNUM, 86, 0, 8, 0, 0, 0, 8, 44, -50, 50, NULL},
- {FSC4, ENUM, 38, 2, 1, 0, 0, 0, 8, 49, 0, 1, st_onof},
- {FSC4, ENUM, 38, 3, 1, 0, 0, 0, 8, 54, 0, 1, st_onof},
- /*S1*/ {FNRM, UNUM, 39, 0, 8, 0, 0, 0, 10, 11, 0, 100, NULL},
- {FNRM, UNUM, 43, 0, 8, 0, 0, 0, 10, 15, 0, 100, NULL},
- {FNRM, UNUM, 47, 0, 8, 0, 0, 0, 10, 19, 0, 100, NULL},
- {FNRM, UNUM, 51, 0, 8, 0, 0, 0, 10, 23, 0, 100, NULL},
- {FNRM, UNUM, 55, 0, 8, 0, 0, 0, 10, 27, 0, 100, NULL},
- {FNRM, UNUM, 59, 0, 8, 0, 0, 0, 10, 31, 0, 100, NULL},
- {FNRM, SNUM, 63, 0, 8, 0, 0, 0, 10, 36, -50, 50, NULL},
- {FNRM, UNUM, 35, 4, 3, 0, 0, 0, 10, 43, 1, 8, NULL},
- {FNRM, SNUM, 67, 0, 8, 0, 0, 0, 10, 48, -50, 50, NULL},
- {FNRM, SNUM, 71, 0, 8, 0, 0, 0, 10, 55, -50, 50, NULL},
- {FNRM, SNUM, 75, 0, 8, 0, 0, 0, 10, 62, -50, 50, NULL},
- {FNRM, SNUM, 79, 0, 8, 0, 0, 0, 10, 68, -50, 50, NULL},
- /*S2*/ {FNRM, UNUM, 40, 0, 8, 0, 0, 0, 11, 11, 0, 100, NULL},
- {FNRM, UNUM, 44, 0, 8, 0, 0, 0, 11, 15, 0, 100, NULL},
- {FNRM, UNUM, 48, 0, 8, 0, 0, 0, 11, 19, 0, 100, NULL},
- {FNRM, UNUM, 52, 0, 8, 0, 0, 0, 11, 23, 0, 100, NULL},
- {FNRM, UNUM, 56, 0, 8, 0, 0, 0, 11, 27, 0, 100, NULL},
- {FNRM, UNUM, 60, 0, 8, 0, 0, 0, 11, 31, 0, 100, NULL},
- {FNRM, SNUM, 64, 0, 8, 0, 0, 0, 11, 36, -50, 50, NULL},
- {FNRM, UNUM, 36, 4, 3, 0, 0, 0, 11, 43, 1, 8, NULL},
- {FNRM, SNUM, 68, 0, 8, 0, 0, 0, 11, 48, -50, 50, NULL},
- {FNRM, SNUM, 72, 0, 8, 0, 0, 0, 11, 55, -50, 50, NULL},
- {FNRM, SNUM, 76, 0, 8, 0, 0, 0, 11, 62, -50, 50, NULL},
- {FNRM, SNUM, 80, 0, 8, 0, 0, 0, 11, 68, -50, 50, NULL},
- /*S3*/ {FSC4, UNUM, 41, 0, 8, 0, 0, 0, 12, 11, 0, 100, NULL},
- {FSC4, UNUM, 45, 0, 8, 0, 0, 0, 12, 15, 0, 100, NULL},
- {FSC4, UNUM, 49, 0, 8, 0, 0, 0, 12, 19, 0, 100, NULL},
- {FSC4, UNUM, 53, 0, 8, 0, 0, 0, 12, 23, 0, 100, NULL},
- {FSC4, UNUM, 57, 0, 8, 0, 0, 0, 12, 27, 0, 100, NULL},
- {FSC4, UNUM, 61, 0, 8, 0, 0, 0, 12, 31, 0, 100, NULL},
- {FSC4, SNUM, 65, 0, 8, 0, 0, 0, 12, 36, -50, 50, NULL},
- {FSC4, UNUM, 37, 4, 3, 0, 0, 0, 12, 43, 1, 8, NULL},
- {FSC4, SNUM, 69, 0, 8, 0, 0, 0, 12, 48, -50, 50, NULL},
- {FSC4, SNUM, 73, 0, 8, 0, 0, 0, 12, 55, -50, 50, NULL},
- {FSC4, SNUM, 77, 0, 8, 0, 0, 0, 12, 62, -50, 50, NULL},
- {FSC4, SNUM, 81, 0, 8, 0, 0, 0, 12, 68, -50, 50, NULL},
- /*S4*/ {FSC4, UNUM, 42, 0, 8, 0, 0, 0, 13, 11, 0, 100, NULL},
- {FSC4, UNUM, 46, 0, 8, 0, 0, 0, 13, 15, 0, 100, NULL},
- {FSC4, UNUM, 50, 0, 8, 0, 0, 0, 13, 19, 0, 100, NULL},
- {FSC4, UNUM, 54, 0, 8, 0, 0, 0, 13, 23, 0, 100, NULL},
- {FSC4, UNUM, 58, 0, 8, 0, 0, 0, 13, 27, 0, 100, NULL},
- {FSC4, UNUM, 62, 0, 8, 0, 0, 0, 13, 31, 0, 100, NULL},
- {FSC4, SNUM, 66, 0, 8, 0, 0, 0, 13, 36, -50, 50, NULL},
- {FSC4, UNUM, 38, 4, 3, 0, 0, 0, 13, 43, 1, 8, NULL},
- {FSC4, SNUM, 70, 0, 8, 0, 0, 0, 13, 48, -50, 50, NULL},
- {FSC4, SNUM, 74, 0, 8, 0, 0, 0, 13, 55, -50, 50, NULL},
- {FSC4, SNUM, 78, 0, 8, 0, 0, 0, 13, 62, -50, 50, NULL},
- {FSC4, SNUM, 82, 0, 8, 0, 0, 0, 13, 68, -50, 50, NULL},
- {FNRM, PEND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL}};
-
- /*
- * MULTIPLE enumeration strings
- */
- char *st_vlsw[] = {"All ", "Soft", "Loud"};
- char *st_mmod[] = {"Kybd", "Midi", "Mix "};
- char *st_chan[] = {"R ", "L+R", "L "};
- char *st_mply[] = {"VR", "0 ", "1 ", "2 ", "3 ", "4 ", "5 ", "6 ", "7 ", "8 "};
-
- /*
- 000000000111111111122222222223333333333444444444455555555556666666666777777
- 123456789012345678901234567890123456789012345678901234567890123456789012345
- Source Levl Tran Tune Out Poly Chan ZnLo ZnHi VSwch Mode
- S1 IA-1 xxxxxxxxxx 100 -24 -50 L+R VR 1 127 127 Loud MIDI
- */
- /*
- * MULTIPLE parameter list
- */
- struct param mparams[] = {
- {FNRM, LSTR, 0, 0, 8, 0, 0, 0, 15, 23, 0, 10, NULL},
- {FNRM, UNUM, 10, 0, 8, 0, 0, 0, 15, 43, 1, 100, NULL},
- /*S1*/ {G(1), SPL2, 11, 0, 6, 0, 0, 0, 17, 4, 0, 63, NULL},
- {G(1), UNUM, 67, 0, 8, 0, 0, 0, 17, 20, 0, 100, NULL},
- {G(1), SNUM, 51, 0, 6, 0, 0, 0, 17, 25, -24, 24, NULL},
- {G(1), SNUM, 59, 0, 8, 0, 0, 0, 17, 30, -50, 50, NULL},
- {G(1), ENUM, 35, 4, 2, 0, 0, 0, 17, 35, 0, 2, st_chan},
- {FRDW, ENUM, 35, 0, 4, 0, 0, 0, 17, 40, 0, 9, st_mply},
- {G(1), UNUM, 43, 0, 4, 0, 0, 0, 17, 45, 1, 16, NULL},
- {G(1), SPL3, 19, 0, 8, 0, 0, 0, 17, 49, 0, 127, NULL},
- {G(1), SPL3, 27, 0, 8, 0, 0, 0, 17, 54, 0, 127, NULL},
- {G(1), ENUM, 43, 4, 2, 0, 0, 0, 17, 59, 0, 2, st_vlsw},
- {G(1), ENUM, 35, 6, 1, 43, 6, 1, 17, 65, 0, 2, st_mmod},
- /*S2*/ {G(2), SPL2, 12, 0, 6, 0, 0, 0, 18, 4, 0, 63, NULL},
- {G(2), UNUM, 68, 0, 8, 0, 0, 0, 18, 20, 0, 100, NULL},
- {G(2), SNUM, 52, 0, 6, 0, 0, 0, 18, 25, -24, 24, NULL},
- {G(2), SNUM, 60, 0, 8, 0, 0, 0, 18, 30, -50, 50, NULL},
- {G(2), ENUM, 36, 4, 2, 0, 0, 0, 18, 35, 0, 2, st_chan},
- {FRDW, ENUM, 36, 0, 4, 0, 0, 0, 18, 40, 0, 9, st_mply},
- {G(2), UNUM, 44, 0, 4, 0, 0, 0, 18, 45, 1, 16, NULL},
- {G(2), SPL3, 20, 0, 8, 0, 0, 0, 18, 49, 0, 127, NULL},
- {G(2), SPL3, 28, 0, 8, 0, 0, 0, 18, 54, 0, 127, NULL},
- {G(2), ENUM, 44, 4, 2, 0, 0, 0, 18, 59, 0, 2, st_vlsw},
- {G(2), ENUM, 36, 6, 1, 44, 6, 1, 18, 65, 0, 2, st_mmod},
- /*S3*/ {G(3), SPL2, 13, 0, 6, 0, 0, 0, 19, 4, 0, 63, NULL},
- {G(3), UNUM, 69, 0, 8, 0, 0, 0, 19, 20, 0, 100, NULL},
- {G(3), SNUM, 53, 0, 6, 0, 0, 0, 19, 25, -24, 24, NULL},
- {G(3), SNUM, 61, 0, 8, 0, 0, 0, 19, 30, -50, 50, NULL},
- {G(3), ENUM, 37, 4, 2, 0, 0, 0, 19, 35, 0, 2, st_chan},
- {FRDW, ENUM, 37, 0, 4, 0, 0, 0, 19, 40, 0, 9, st_mply},
- {G(3), UNUM, 45, 0, 4, 0, 0, 0, 19, 45, 1, 16, NULL},
- {G(3), SPL3, 21, 0, 8, 0, 0, 0, 19, 49, 0, 127, NULL},
- {G(3), SPL3, 29, 0, 8, 0, 0, 0, 19, 54, 0, 127, NULL},
- {G(3), ENUM, 45, 4, 2, 0, 0, 0, 19, 59, 0, 2, st_vlsw},
- {G(3), ENUM, 37, 6, 1, 45, 6, 1, 19, 65, 0, 2, st_mmod},
- /*S4*/ {G(4), SPL2, 14, 0, 6, 0, 0, 0, 20, 4, 0, 63, NULL},
- {G(4), UNUM, 70, 0, 8, 0, 0, 0, 20, 20, 0, 100, NULL},
- {G(4), SNUM, 54, 0, 6, 0, 0, 0, 20, 25, -24, 24, NULL},
- {G(4), SNUM, 62, 0, 8, 0, 0, 0, 20, 30, -50, 50, NULL},
- {G(4), ENUM, 38, 4, 2, 0, 0, 0, 20, 35, 0, 2, st_chan},
- {FRDW, ENUM, 38, 0, 4, 0, 0, 0, 20, 40, 0, 9, st_mply},
- {G(4), UNUM, 46, 0, 4, 0, 0, 0, 20, 45, 1, 16, NULL},
- {G(4), SPL3, 22, 0, 8, 0, 0, 0, 20, 49, 0, 127, NULL},
- {G(4), SPL3, 30, 0, 8, 0, 0, 0, 20, 54, 0, 127, NULL},
- {G(4), ENUM, 46, 4, 2, 0, 0, 0, 20, 59, 0, 2, st_vlsw},
- {G(4), ENUM, 38, 6, 1, 46, 6, 1, 20, 65, 0, 2, st_mmod},
- /*S5*/ {G(5), SPL2, 15, 0, 6, 0, 0, 0, 21, 4, 0, 63, NULL},
- {G(5), UNUM, 71, 0, 8, 0, 0, 0, 21, 20, 0, 100, NULL},
- {G(5), SNUM, 55, 0, 6, 0, 0, 0, 21, 25, -24, 24, NULL},
- {G(5), SNUM, 63, 0, 8, 0, 0, 0, 21, 30, -50, 50, NULL},
- {G(5), ENUM, 39, 4, 2, 0, 0, 0, 21, 35, 0, 2, st_chan},
- {FRDW, ENUM, 39, 0, 4, 0, 0, 0, 21, 40, 0, 9, st_mply},
- {G(5), UNUM, 47, 0, 4, 0, 0, 0, 21, 45, 1, 16, NULL},
- {G(5), SPL3, 23, 0, 8, 0, 0, 0, 21, 49, 0, 127, NULL},
- {G(5), SPL3, 31, 0, 8, 0, 0, 0, 21, 54, 0, 127, NULL},
- {G(5), ENUM, 47, 4, 2, 0, 0, 0, 21, 59, 0, 2, st_vlsw},
- {G(5), ENUM, 39, 6, 1, 47, 6, 1, 21, 65, 0, 2, st_mmod},
- /*S6*/ {G(6), SPL2, 16, 0, 6, 0, 0, 0, 22, 4, 0, 63, NULL},
- {G(6), UNUM, 72, 0, 8, 0, 0, 0, 22, 20, 0, 100, NULL},
- {G(6), SNUM, 56, 0, 6, 0, 0, 0, 22, 25, -24, 24, NULL},
- {G(6), SNUM, 64, 0, 8, 0, 0, 0, 22, 30, -50, 50, NULL},
- {G(6), ENUM, 40, 4, 2, 0, 0, 0, 22, 35, 0, 2, st_chan},
- {FRDW, ENUM, 40, 0, 4, 0, 0, 0, 22, 40, 0, 9, st_mply},
- {G(6), UNUM, 48, 0, 4, 0, 0, 0, 22, 45, 1, 16, NULL},
- {G(6), SPL3, 24, 0, 8, 0, 0, 0, 22, 49, 0, 127, NULL},
- {G(6), SPL3, 32, 0, 8, 0, 0, 0, 22, 54, 0, 127, NULL},
- {G(6), ENUM, 48, 4, 2, 0, 0, 0, 22, 59, 0, 2, st_vlsw},
- {G(6), ENUM, 40, 6, 1, 48, 6, 1, 22, 65, 0, 2, st_mmod},
- /*S7*/ {G(7), SPL2, 17, 0, 6, 0, 0, 0, 23, 4, 0, 63, NULL},
- {G(7), UNUM, 73, 0, 8, 0, 0, 0, 23, 20, 0, 100, NULL},
- {G(7), SNUM, 57, 0, 6, 0, 0, 0, 23, 25, -24, 24, NULL},
- {G(7), SNUM, 65, 0, 8, 0, 0, 0, 23, 30, -50, 50, NULL},
- {G(7), ENUM, 41, 4, 2, 0, 0, 0, 23, 35, 0, 2, st_chan},
- {FRDW, ENUM, 41, 0, 4, 0, 0, 0, 23, 40, 0, 9, st_mply},
- {G(7), UNUM, 49, 0, 4, 0, 0, 0, 23, 45, 1, 16, NULL},
- {G(7), SPL3, 25, 0, 8, 0, 0, 0, 23, 49, 0, 127, NULL},
- {G(7), SPL3, 33, 0, 8, 0, 0, 0, 23, 54, 0, 127, NULL},
- {G(7), ENUM, 49, 4, 2, 0, 0, 0, 23, 59, 0, 2, st_vlsw},
- {G(7), ENUM, 41, 6, 1, 49, 6, 1, 23, 65, 0, 2, st_mmod},
- /*S8*/ {G(8), SPL2, 18, 0, 6, 0, 0, 0, 24, 4, 0, 63, NULL},
- {G(8), UNUM, 74, 0, 8, 0, 0, 0, 24, 20, 0, 100, NULL},
- {G(8), SNUM, 58, 0, 6, 0, 0, 0, 24, 25, -24, 24, NULL},
- {G(8), SNUM, 66, 0, 8, 0, 0, 0, 24, 30, -50, 50, NULL},
- {G(8), ENUM, 42, 4, 2, 0, 0, 0, 24, 35, 0, 2, st_chan},
- {FRDW, ENUM, 42, 0, 4, 0, 0, 0, 24, 40, 0, 9, st_mply},
- {G(8), UNUM, 50, 0, 4, 0, 0, 0, 24, 45, 1, 16, NULL},
- {G(8), SPL3, 26, 0, 8, 0, 0, 0, 24, 49, 0, 127, NULL},
- {G(8), SPL3, 34, 0, 8, 0, 0, 0, 24, 54, 0, 127, NULL},
- {G(8), ENUM, 50, 4, 2, 0, 0, 0, 24, 59, 0, 2, st_vlsw},
- {G(8), ENUM, 42, 6, 1, 50, 6, 1, 24, 65, 0, 2, st_mmod},
- {FNRM, PEND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL}
- };
-
- /*
- * Fixed part of display
- */
- char *st_scrn[] = {
- /*
- 000000000111111111122222222223333333333444444444455555555556666666666777777
- 123456789012345678901234567890123456789012345678901234567890123456789012345
- */
- "SINGLE Patch : \" \" | Src | Vol | | AM | AM",
- " KS | Vibrato: Depth | Speed | Shape | AT | Wheel",
- "Curve | Bend: Depth | Time | Vel | KS | AT | Range",
- "SOURCES: Wave Trkng Coarse Fine f/KS Bend f/AT",
- " S1",
- " S2",
- " S3",
- " S4",
- "Envelope: Lev Del Att Dec Sus Rel Lev/V V/Cur Lev/AT Lev/KS Dur/V Dur/KS",
- " S1",
- " S2",
- " S3",
- " S4",
- "------------------------------------------------------------------------",
- "MULTIPLE Patch : \" \" | Vol",
- " Source Levl Tran Tune Out Poly Chan ZnLo ZnHi VSwch Mode",
- "S1",
- "S2",
- "S3",
- "S4",
- "S5",
- "S6",
- "S7",
- "S8",
- NULL
- };
-
- /*
- 000000000111111111122222222223333333333444444444455555555556666666666777777
- 123456789012345678901234567890123456789012345678901234567890123456789012345
- Source Levl Tran Tune Out Poly Chan ZnLo ZnHi VSwch Mode
- S1 IA-1 xxxxxxxxxx 100 -24 -50 L+R VR 1 127 127 Loud MIDI
- */
-
- unsigned char dump[64][88]; /* 64 SINGLE patch array */
- unsigned char mdump[32][76]; /* 32 MULTIPLE patch array */
-
- int curpatch; /* current SINGLE patch number */
- int curmpatch; /* current MULTIPLE patch number */
- int curparam; /* current SINGLE patch parameter */
- int curmparam; /* current MULTIPLE patch parameter */
- int single; /* true if SINGLE display active; false if MULTIPLE active */
- int echo; /* MIDI echo if true */
-
- /*
- * Show fixed part of screen
- */
- void
- distemplate(screen)
- char *screen[];
- {
- register int n, i;
- char str[82];
-
- clrscr();
- for (n = 0; st_scrn[n] != NULL; n++)
- {
- (void)strcpy(str, screen[n]);
- for (i = strlen(str); i < 79; i++)
- str[i] = ' ';
- str[i] = '\0';
- gotoxy(1, n+1);
- cprintf("%s", str);
- }
- }
-
- /*
- * display patch from data at ``dp''
- */
- void
- dispatch(dp)
- unsigned char *dp;
- {
- register struct param *pp;
- int cur;
- void showparam();
- void eraseparam();
- void showid();
-
- for (pp = single?params:mparams; pp->p_type != PEND; pp++)
- if (visible(pp, dp))
- showparam(pp, dp);
- else
- eraseparam(pp);
-
- if (single)
- {
- gotoxy(14, 1);
- cur = curpatch;
- pp = ¶ms[curparam];
- }
- else
- {
- gotoxy(16, 15);
- cur = curmpatch;
- pp = &mparams[curmparam];
- }
- showid(cur);
- gotoxy((int)pp->p_col, (int)pp->p_row);
- }
-
- /*
- * refresh screen
- */
- void
- refresh()
- {
- int snglsv = single;
-
- distemplate();
- single = 1;
- dispatch(&dump[curpatch][0]);
- single = 0;
- dispatch(&mdump[curmpatch][0]);
- single = snglsv;
- }
-
- char *st_plet[] = {"IA", "IB", "IC", "ID", "iA", "iB", "iC", "iD"};
-
- /*
- * returns Kawai patch ID
- */
- char *
- idstr(n)
- int n;
- {
- static char tstr[10];
-
- n &= 0x3f;
- (void)sprintf(tstr, "%s-%d", st_plet[n>>3], 1+(n&0x7));
- return tstr;
- }
-
- /*
- * displays, at current position, Kawai patch ID
- */
- void
- showid(n)
- {
- highvideo();
- cprintf("%s", idstr(n));
- normvideo();
- }
-
- /*
- * extract the value (integer) of a given parameter, given a pointer
- * of its descriptor and the patch data
- */
- int bitmask[] = {0, 1, 3, 7, 15, 31, 63, 127, 255};
-
- int
- getvalue(pp, dp)
- register struct param *pp;
- unsigned char *dp;
- {
- int val;
-
- val = (dp[pp->p_byte]>>pp->p_bit)&bitmask[pp->p_nbits];
- if (pp->p_secnbits > 0)
- val |= ((dp[pp->p_secbyte]>>pp->p_secbit)
- &bitmask[pp->p_secnbits])<<pp->p_nbits;
- val += pp->p_bias;
- return val;
- }
-
- /*
- * set the value (integer) of a given parameter, given a pointer
- * of its descriptor, the value, and a pointer to the patch data
- */
- void
- setvalue(pp, val, dp)
- register struct param *pp;
- int val;
- unsigned char *dp;
- {
- int oval;
-
- if (val > pp->p_limit)
- val = pp->p_limit;
- val -= pp->p_bias;
- if (val < 0)
- val = 0;
-
- oval = dp[pp->p_byte]&~(bitmask[pp->p_nbits]<<pp->p_bit);
- dp[pp->p_byte] = oval|((val&bitmask[pp->p_nbits])<<pp->p_bit);
- if (pp->p_secnbits == 0)
- return;
-
- oval = dp[pp->p_secbyte]&~(bitmask[pp->p_secnbits]<<pp->p_secbit);
- dp[pp->p_secbyte] = oval|
- (((val>>pp->p_nbits)&bitmask[pp->p_secnbits])<<pp->p_secbit);
- return;
- }
-
- void
- showparam(pp, dp)
- register struct param *pp;
- unsigned char *dp;
- {
- int val;
- void showval();
- void showstr();
-
- if (pp->p_type == LSTR)
- {
- showval(pp, 0, dp);
- return;
- }
- val = getvalue(pp, dp);
- if (val > pp->p_limit)
- showstr(pp, "#");
- else
- showval(pp, val, dp);
- }
-
- /*
- * convert the integer value of a parameter to its display form
- */
- char *
- valstr(pp, val, dp)
- register struct param *pp;
- int val;
- unsigned char *dp;
- {
- static char str[40];
-
- switch (pp->p_type)
- {
- case LSTR:
- (void)strncpy(str, (char *)&dp[pp->p_byte], pp->p_limit);
- str[pp->p_limit] = '\0';
- break;
-
- case ENUM:
- (void)strcpy(str, pp->p_names[val]);
- break;
-
- case UNUM:
- (void)sprintf(str, "%d ", val);
- if (pp->p_limit > 99)
- str[3] = '\0';
- else if (pp->p_limit > 9)
- str[2] = '\0';
- else
- str[1] = '\0';
- break;
-
- case SPL1:
- if ((dp[pp->p_byte+8]&02) == 0)
- (void)sprintf(str, "%s%d ", st_note[val%12], val/12-4);
- else
- {
- if (val >= 84)
- (void)sprintf(str, "+%d ", val-84);
- else
- (void)sprintf(str, "-%d ", 84-val);
- }
- str[4] = '\0';
- break;
-
- case SPL2:
- (void)sprintf(str, "%s ", idstr(val));
- (void)strncpy(str+5, (char *)&dump[val][0], 10);
- str[15] = '\0';
- break;
-
- case SPL3:
- (void)sprintf(str, "%s%d ", st_note[val%12], val/12-2);
- str[4] = '\0';
- break;
-
- case SNUM:
- if (val < 0)
- {
- str[0] = '-';
- val = -val;
- }
- else
- str[0] = '+';
-
- (void)sprintf(str+1, "%d ", val);
-
- if (pp->p_limit > 99)
- str[4] = '\0';
- else if (pp->p_limit > 9)
- str[3] = '\0';
- else
- str[2] = '\0';
- break;
- }
- return str;
- }
-
- /*
- * erase the screen area occupied by a given parameter
- */
- void
- eraseparam(pp)
- register struct param *pp;
- {
- int n;
- char estr[40];
-
- switch (pp->p_type)
- {
- case LSTR:
- n = pp->p_limit;
- break;
-
- case ENUM:
- n = strlen(pp->p_names[0]);
- break;
-
- case UNUM:
- if (pp->p_limit > 99)
- n = 3;
- else if (pp->p_limit > 9)
- n = 2;
- else
- n = 1;
- break;
-
- case SPL1:
- n = 6;
- break;
-
- case SPL2:
- n = 15;
- break;
-
- case SPL3:
- n = 4;
- break;
-
- case SNUM:
- if (pp->p_limit > 99)
- n = 4;
- else if (pp->p_limit > 9)
- n = 3;
- else
- n = 2;
- break;
- }
- estr[n] = '\0';
- while (--n >= 0)
- estr[n] = ' ';
- gotoxy((int)pp->p_col, (int)pp->p_row);
- cprintf("%s", estr);
- }
-
- /*
- * given a parameter desc., value, and patch, display at the appropriate
- * screen position
- */
- void
- showval(pp, val, dp)
- struct param *pp;
- int val;
- unsigned char *dp;
- {
- char *valstr();
- void showstr();
-
- showstr(pp, valstr(pp, val, dp));
- }
-
- /*
- * given a parameter desc. and a string, display the string at the
- * appropriate place on the screen
- */
- void
- showstr(pp, str)
- register struct param *pp;
- char *str;
- {
-
- gotoxy((int)pp->p_col, (int)pp->p_row);
- highvideo();
- cprintf("%s", str);
- normvideo();
- }
-
- /*
- * given a parameter desc. and patch, return true of the parameter is
- * visible, and false if it is not
- */
- int
- visible(pp, dp)
- struct param *pp;
- unsigned char *dp;
- {
- int flags;
-
- flags = pp->p_flags;
- if (single)
- {
- if ((flags&FSC4) != 0 && (dp[11]&0x4) == 0)
- return 0;
- else
- return 1;
- }
- else
- {
- if ((flags&FSGL) != 0 && (dp[34+(flags&0x0f)]&0x0f) == 1)
- return 0;
- else
- return 1;
- }
- /*NOTREACHED*/
- }
-
-
- /*
- * MIDI routines; calls the following low-level routines defined in io401.c:
- */
- extern int getdata();
- extern int putdata();
- extern int putcmd();
-
- #include "mpu401.h"
- /*
- * Many routines call tstesc() to see if an abort is requested. This is
- * useful if the interface hangs, the K-1 doesn't (or can't) answer,
- * and so forth.
- */
-
- int is_midiinit = 0; /* set if MPU401 initialized */
-
- /*
- * put the MPU401 into UART mode
- */
- void
- rawmidi()
- {
- void flushmidi();
- void tstesc();
-
- if (is_midiinit)
- return;
- flushmidi();
- while (putcmd(RESET) < 0)
- tstesc();
- while (putcmd(UART) < 0)
- tstesc();
- is_midiinit = 1;
- }
-
- /*
- * echo any incoming MIDI data
- */
- void
- midiecho()
- {
- int j;
-
- rawmidi();
- while ((j = getdata()) != -1)
- putdata(j);
- }
-
- /*
- * eat up any incoming MIDI data; echo if that option is on
- */
- void
- flushmidi()
- {
- int j;
-
- while ((j = getdata()) != -1)
- {
- if (echo)
- (void) putdata(j);
- tstesc();
- }
- }
-
- /*
- * send a MIDI byte; retries and tests for abort
- */
- void
- sendmidi(x)
- int x;
- {
- void tstesc();
-
- while (putdata(x) < 0)
- tstesc();
- }
-
- /*
- * wait for a particular MIDI byte
- */
- waitmidi(x)
- int x;
- {
- int j;
- void tstesc();
-
- while ((j = getdata()) != x)
- {
- if (echo)
- sendmidi(j);
- tstesc();
- }
- }
-
- /*
- * complains if the next MIDI byte isn't the one given.
- */
- void
- expectmidi(x)
- int x;
- {
- int j;
- void errpnt();
-
- if ((j = getdata()) != x)
- errpnt("Got 0x%x, expected 0x%x", j, x, 0);
- }
-
- /*
- * sound a MIDI note at a given velocity. velocity 0 turns off.
- */
- midinote(n, v)
- int n;
- int v;
- {
- flushmidi();
- sendmidi(0x90);
- sendmidi(n);
- sendmidi(v);
- }
-
- /*
- * do a MIDI program change to a given program (i.e. patch) number.
- */
- midipgm(n)
- int n;
- {
- flushmidi();
- sendmidi(0xc0);
- sendmidi(n);
- }
-
- /*
- * get a positive MIDI byte; ignore all others except choke on a
- * (premature) EOX.
- */
- int
- getposdata()
- {
- int j;
- void errpnt();
-
- while ((j = getdata()) > 0x7f)
- if (j == 0xf7)
- {
- errpnt("Unexpected EOX", 0, 0, 0);
- }
- return j;
- }
-
- /*
- * if there is a character typed at the keyboard, see if it is an ESC.
- * If so, longjmp() to abort the current high-level MIDI routine.
- */
- #include <setjmp.h>
-
- jmp_buf esccontext;
-
- void
- tstesc()
- {
- void longjmp();
-
- if (kbhit())
- if (getch() == 033)
- longjmp(esccontext, 1);
- }
-
- /*
- * have K-1 dump all internal patches into our buffers
- */
- void
- recvdump()
- {
- void recvmidi();
- void errpnt();
-
- if (setjmp(esccontext))
- {
- errpnt("MIDI operation aborted", 0, 0, 0);
- return;
- }
- rawmidi();
- recvmidi(0x01, 0x00, 0x00, 88, 32, &dump[0][0]);
- recvmidi(0x01, 0x00, 0x20, 88, 32, &dump[32][0]);
- recvmidi(0x01, 0x00, 0x40, 76, 32, &mdump[0][0]);
- }
-
- /*
- * dump our buffers into the K-1
- */
- void
- trandump()
- {
- void xmitmidi();
- void errpnt();
-
- if (setjmp(esccontext))
- {
- errpnt("MIDI operation aborted", 0, 0, 0);
- return;
- }
- rawmidi();
- xmitmidi(0x21, 0x00, 0x00, 88, 32, &dump[0][0]);
- xmitmidi(0x21, 0x00, 0x20, 88, 32, &dump[32][0]);
- xmitmidi(0x21, 0x00, 0x40, 76, 32, &mdump[0][0]);
- }
-
- /*
- * have K-1 dump the current patch
- */
- void
- recvpatch()
- {
- if (single)
- recvmidi(0x00, 0x00, curpatch, 88, 1, &dump[curpatch][0]);
- else
- recvmidi(0x00, 0x00, curmpatch+0x40, 76, 1, &mdump[curmpatch][0]);
- }
-
- /*
- * dump the current patch into the K-1
- */
- void
- tranpatch()
- {
- if (single)
- xmitmidi(0x20, 0x00, curpatch, 88, 1, &dump[curpatch][0]);
- else
- xmitmidi(0x20, 0x00, curmpatch+0x40, 76, 1, &mdump[curmpatch][0]);
- }
-
- /*
- * generic K-1 dump receive routine
- */
- void
- recvmidi(func, sub1, sub2, size, howmany, data)
- int func;
- int sub1;
- int sub2;
- int size;
- int howmany;
- unsigned char *data;
- {
- int i, n, j;
- int checksum;
- void errpnt();
-
- flushmidi();
- sendmidi(0xf0);
- sendmidi(0x40);
- sendmidi(0x00);
- sendmidi(func);
- sendmidi(0x00);
- sendmidi(0x03);
- sendmidi(sub1);
- sendmidi(sub2);
- sendmidi(0xf7);
- waitmidi(0xf0);
- expectmidi(0x40);
- expectmidi(0x00);
- expectmidi(func|0x20);
- expectmidi(0x00);
- expectmidi(0x03);
- expectmidi(sub1);
- expectmidi(sub2);
-
- for (n = 0; n < howmany; n++)
- {
- checksum = 0xa5;
- for (i = 0; i < size-1; i++)
- {
- j = getposdata();
- checksum += j;
- *data++ = j;
- }
- j = getposdata();
- *data++ = j;
- if (j != (checksum&0x7f))
- errpnt("Checksum(%d) %x != %x", n, checksum&0x7f, j);
- }
- expectmidi(0xf7);
- }
-
- /*
- * generic K-1 dump transmit routine
- */
- void
- xmitmidi(func, sub1, sub2, size, howmany, data)
- int func;
- int sub1;
- int sub2;
- int size;
- int howmany;
- unsigned char *data;
- {
- int i, n, j;
- int checksum;
- void errpnt();
-
- flushmidi();
- sendmidi(0xf0);
- sendmidi(0x40);
- sendmidi(0x00);
- sendmidi(func);
- sendmidi(0x00);
- sendmidi(0x03);
- sendmidi(sub1);
- sendmidi(sub2);
-
- for (n = 0; n < howmany; n++)
- {
- checksum = 0xa5;
- for (i = 0; i < size-1; i++)
- {
- j = *data++;
- checksum += j;
- sendmidi(j);
- }
- data++;
- sendmidi(checksum&0x7f);
- while (getdata() != -1)
- tstesc();
- }
- sendmidi(0xf7);
-
- waitmidi(0xf0);
- expectmidi(0x40);
- expectmidi(0x00);
- j = getdata();
- expectmidi(0x00);
- expectmidi(0x03);
- expectmidi(0xf7);
- if (j != 0x40)
- errpnt("Write error %d", j-0x40, 0, 0);
- }
-
- /*
- * display an error message on the status line
- */
- void
- errpnt(str, a1, a2, a3)
- char *str;
- {
- gotoxy(1, 25);
- cprintf(str, a1, a2, a3);
- sleep(2);
- }
-
- /*
- * save buffers into named file
- */
- void
- savedump(file)
- char *file;
- {
- FILE *fp = fopen(file, "wb");
-
- if (fp == NULL)
- errpnt("Can't create file %s", file, 0, 0);
- else
- {
- if (fwrite((char *)&dump[0][0], 88, 64, fp) != 64)
- errpnt("Trouble writing %s", file, 0, 0);
- else if (fwrite((char *)&mdump[0][0], 76, 32, fp) != 32)
- errpnt("Trouble writing %s", file, 0, 0);
- }
- }
-
- /*
- * load buffers from named file
- */
- void
- loaddump(file)
- char *file;
- {
- FILE *fp = fopen(file, "rb");
-
- if (fp == NULL)
- errpnt("Can't open file %s", file, 0, 0);
- else
- {
- if (fread((char *)&dump[0][0], 88, 64, fp) != 64)
- errpnt("Trouble reading %s", file, 0, 0);
- else if (fread((char *)&mdump[0][0], 76, 32, fp) != 32)
- errpnt("Trouble reading %s", file, 0, 0);
- }
- }
-
- /*
- * If TurboC's getch() routine returns a 0 first to indicate a special
- * code, we turn on bit 7 in our representation of the code.
- */
- #define cHOME 0xc7 /* HOME key code */
- #define cUP 0xc8 /* UP " " */
- #define cPGUP 0xc9 /* PgUP " " */
- #define cLEFT 0xcb /* LEFT " " */
- #define cRGHT 0xcd /* RIGHT " " */
- #define cEND 0xcf /* END " " */
- #define cDOWN 0xd0 /* DOWN " " */
- #define cPGDN 0xd1 /* PgDOWN " " */
- #define cINS 0xd2 /* INSERT " " */
- #define cDEL 0xd3 /* DELETE " " */
- #define cF1 0xbb /* F1 " " */
- #define cF8 0xc2 /* F2 " " */
- #define cF10 0xc4 /* F10 " " */
- #define cFORM 0x0c /* ^L " " */
-
- #define INROW 25 /* row used for input prompt */
-
- /*
- * Display prompt string and then grab typed value into buffer.
- * Buffer contents displayed, and may be edited.
- */
- char *
- getinput(prompt, str)
- char *prompt;
- char *str;
- {
- int cursor, stcur;
- int c;
- int insert;
-
- gotoxy(1, INROW);
- cprintf("%s: %s", prompt, str);
- stcur = 3+strlen(prompt);
- cursor = 0;
- insert = 0;
- gotoxy(cursor+stcur, INROW);
- for (;;)
- {
- while (kbhit() == 0)
- if (echo)
- midiecho();
- c = getch();
- if (c == 0)
- c = 0x80|getch();
-
- switch(c)
- {
- case cLEFT:
- if (cursor > 0)
- cursor--;
- break;
-
- case '\b':
- case '\177':
- if (cursor > 0)
- {
- cursor--;
- gotoxy(cursor+stcur, INROW);
- cprintf("%s ", str+cursor+1);
- (void)strcpy(str+cursor, str+cursor+1);
- }
- else
- {
- str[0] = '\0';
- clreol();
- }
- break;
-
- case cRGHT:
- if (str[cursor] != '\0')
- cursor++;
- break;
-
- case cDEL:
- if (str[cursor] != '\0')
- {
- gotoxy(cursor+stcur, INROW);
- cprintf("%s ", str+cursor+1);
- (void)strcpy(str+cursor, str+cursor+1);
- }
- break;
-
- case cINS:
- insert = !insert;
- break;
-
- case '\33':
- gotoxy(1, INROW);
- clreol();
- return NULL;
-
- case '\n':
- case '\r':
- gotoxy(1, INROW);
- clreol();
- return str;
-
- default:
- if (c > 0x7f)
- break;
- if (insert)
- {
- char *cp, *op;
-
- for (cp = str+cursor; *cp; cp++)
- ;
- op = cp;
- cp++;
- while (op >= str+cursor)
- *cp-- = *op--;
- }
- if (str[cursor] == '\0')
- str[cursor+1] = '\0';
- str[cursor] = c;
- cprintf("%s ", str+cursor);
- cursor++;
- break;
- }
- gotoxy(stcur+cursor, INROW);
- }
- /*NOTREACHED*/
- }
-
- char noteon[8]; /* true if note is currently on */
-
- /*
- * Top-level command routine.
- */
- void
- docommand()
- {
- int c, cur, size, len, row, col, *curpch, *curprm;
- char str[80];
- unsigned char *dp, *altdp;
- struct param *pp, *altpp, *svpp;
- void strsetval();
-
- if (setjmp(esccontext))
- {
- errpnt("MIDI operation aborted", 0, 0, 0);
- return;
- }
- if (single)
- {
- dp = &dump[curpatch][0];
- altdp = &mdump[curmpatch][0];
- size = 88;
- curpch = &curpatch;
- curprm = &curparam;
- len = 64;
- pp = ¶ms[curparam];
- altpp = &mparams[curmparam];
- }
- else
- {
- altdp = &dump[curpatch][0];
- dp = &mdump[curmpatch][0];
- size = 76;
- curpch = &curmpatch;
- curprm = &curmparam;
- len = 32;
- pp = &mparams[curmparam];
- altpp = ¶ms[curparam];
- }
-
- while (kbhit() == 0)
- if (echo)
- midiecho();
- c = getch();
- if (c == 0)
- {
- c = 0x80|getch();
- /* F1 - F8 play tritone-spaced notes at midling velocity */
- if (is_midiinit && c >= cF1 && c <= cF8)
- {
- c -= cF1;
- if (noteon[c])
- {
- midinote(36+c*6, 0);
- noteon[c] = 0;
- }
- else
- {
- midinote(36+c*6, 72);
- noteon[c] = 1;
- }
- return;
- }
- }
- switch (c)
- {
- /* Save buffers in file */
- case 's':
- case 'S':
- str[0] = '\0';
- if (getinput("Save file name", str) != NULL && str[0] != '\0')
- savedump(str);
- break;
-
- /* Load buffered from file */
- case 'l':
- case 'L':
- str[0] = '\0';
- if (getinput("Load file name", str) != NULL && str[0] != '\0')
- loaddump(str);
- refresh();
- break;
-
- /* receive single patch from K-1 */
- case 'r':
- recvpatch();
- midipgm(single?(*curpch):(*curpch|0x40));
- refresh();
- break;
-
- /* Receive all patches from of K-1 */
- case 'R':
- recvdump();
- midipgm(single?(*curpch):(*curpch|0x40));
- refresh();
- break;
-
- /* transmit single patch to K-1 */
- case 't':
- tranpatch();
- midipgm(single?(*curpch):(*curpch|0x40));
- break;
-
- /* Transmit all patches to K-1 */
- case 'T':
- trandump();
- midipgm(single?(*curpch):(*curpch|0x40));
- break;
-
- /* Quit patch editor */
- case 'q':
- case 'Q':
- (void)strcpy(str, "Yes");
- if (getinput("Confirm (Y/N)", str) != NULL && (str[0]|0x20) == 'y')
- {
- gotoxy(1, 25);
- exit(0);
- }
- break;
-
- /* toggle MIDI echo */
- case 'e':
- echo = !echo;
- break;
-
- /* switch between SINGLE and MULTI */
- case cF10:
- single = !single;
- dp = altdp;
- pp = altpp;
- dispatch(dp);
- if (is_midiinit)
- midipgm(single?(*curpch):(*curpch|0x40));
- break;
-
- /* refresh screen */
- case cFORM:
- refresh();
- break;
-
- /* show previous patch */
- case cPGUP:
- if (*curpch > 0)
- {
- (*curpch)--;
- dp -= size;
- }
- dispatch(dp);
- if (!visible(pp, dp))
- {
- pp -= *curprm;
- *curprm = 0;
- }
- if (is_midiinit)
- midipgm(single?(*curpch):(*curpch|0x40));
- break;
-
- /* show next patch */
- case cPGDN:
- if (*curpch < len-1)
- {
- (*curpch)++;
- dp += size;
- }
- dispatch(dp);
- if (!visible(pp, dp))
- {
- pp -= *curprm;
- *curprm = 0;
- }
- if (is_midiinit)
- midipgm(single?(*curpch):(*curpch|0x40));
- break;
-
- /* move to previous parameter */
- case cLEFT:
- do
- {
- if (*curprm > 0)
- {
- (*curprm)--;
- pp--;
- }
- else
- break;
- } while (!visible(pp, dp));
- break;
-
- /* move to next parameter */
- case cRGHT:
- do
- {
- if ((pp+1)->p_type != PEND)
- {
- (*curprm)++;
- pp++;
- }
- else
- { pp -= *curprm;
- *curprm = 0;
- }
- } while (!visible(pp, dp));
- break;
-
- /* move up one row */
- case cUP:
- row = pp->p_row;
- col = pp->p_col;
- do
- {
- if (*curprm > 0)
- {
- (*curprm)--;
- pp--;
- }
- else
- break;
- } while (pp->p_row >= row
- || pp->p_col > col+3 || !visible(pp, dp));
- break;
-
- /* move down one row */
- case cDOWN:
- row = pp->p_row;
- col = pp->p_col;
- cur = *curprm;
- svpp = pp;
- do
- {
- if ((pp+1)->p_type != PEND)
- {
- (*curprm)++;
- pp++;
- }
- else
- {
- *curprm = cur;
- pp = svpp;
- break;
- }
- } while (pp->p_row <= row
- || pp->p_col < col-3 || !visible(pp, dp));
- break;
-
- /* move to first parameter */
- case cHOME:
- pp -= *curprm;
- *curprm = 0;
- break;
-
- /* move to last parameter */
- case cEND:
- svpp = pp;
- cur = *curprm;
-
- while ((pp+1)->p_type != PEND)
- {
- curparam++;
- pp++;
- if (visible(pp, dp))
- {
- svpp = pp;
- cur = *curprm;
- }
- }
- pp = svpp;
- *curprm = cur;
- break;
-
- /* add one to parameter value */
- case '+':
- if (pp->p_type == LSTR)
- break;
- setvalue(pp, getvalue(pp, dp)+1, dp);
- if (pp->p_flags&FRDW)
- dispatch(dp);
- break;
-
- /* subtract one from parameter value */
- case '-':
- if (pp->p_type == LSTR)
- break;
- setvalue(pp, getvalue(pp, dp)-1, dp);
- if (pp->p_flags&FRDW)
- dispatch(dp);
- break;
-
- /* allow typein of parameter value */
- case '\n':
- case '\r':
- (void)strcpy(str, valstr(pp, getvalue(pp, dp), dp));
- if (getinput("Enter value", str) == NULL || str[0] == '\0')
- break;
- strsetval(pp, str, dp);
- if (pp->p_flags&FRDW)
- dispatch(dp);
- break;
-
- /* ignore other keystrokes */
- default:
- break;
- }
- if (visible(pp, dp))
- showparam(pp, dp);
- gotoxy((int)pp->p_col, (int)pp->p_row);
- }
-
- /*
- * set a parameter from a string
- */
- void
- strsetval(pp, str, dp)
- struct param *pp;
- char *str;
- unsigned char *dp;
- {
- char **cpp;
- char tmp[80];
- int len, val;
- int match();
- int notecv();
-
- val = -9999;
- switch(pp->p_type)
- {
- case LSTR:
- (void)strcpy(tmp, str);
- len = strlen(tmp);
- while (len < pp->p_limit)
- tmp[len++] = ' ';
- (void)strncpy((char *)&dp[pp->p_byte], tmp, pp->p_limit);
- return;
-
- case SNUM:
- case UNUM:
- val = atoi(str);
- break;
- case ENUM:
- val = getvalue(pp, dp);
- for (cpp = pp->p_names; *cpp != NULL; cpp++)
- if (match(str, *cpp))
- {
- val = (cpp-pp->p_names)+pp->p_bias;
- break;
- }
- break;
- case SPL1:
- if ((dp[pp->p_byte+8]&02) != 0)
- val = atoi(str);
- else
- {
- val = notecv(str);
- if (val == -99)
- return;
- val += 24;
- }
- break;
- case SPL3:
- val = notecv(str);
- if (val == -99)
- return;
- break;
- }
- setvalue(pp, val, dp);
- }
-
- /*
- * convert string into MIDI note value
- */
- unsigned char notval[] = {9, 11, 0, 2, 4, 5, 7};
-
- int
- notecv(str)
- char *str;
- {
- int val, c;
-
- c = (int)(str[0]&~0x20)-'A';
- if (c < 0 || c > 6)
- return -99;
- val = notval[c];
- c = 1;
- if (str[1] == '#')
- {
- val++;
- c++;
- }
- if (str[c] != '-' && (str[c] < '0' || str[c] > '9'))
- return -99;
- else
- return val+12*(atoi(str+c)+2);
- }
-
- /*
- * oddball string match; match on first two characters unless digits,
- * then look at up to 3. This allows type-in of waveform numbers,
- * while two characters are unambiguous for the other stuff.
- *
- * Ignore case in the simplest way possible, and ignore the possible
- * synonyms this creates for other chars.
- */
- int
- match(r, t)
- char *r, *t;
- {
- while (*r == ' ')
- r++;
- while (*t == ' ')
- t++;
- if ((*r++&0x3f) != (*t++&0x3f))
- return 0;
- if ((*r++&0x3f) != (*t++&0x3f))
- return 0;
- if (*r < '0' || *r > '9')
- return 1;
- return (*r == *t);
- }
-
- /*
- * Main program -- at end, and I don't even *like* PASCAL...
- */
- void
- main(argc, argv)
- int argc;
- char **argv;
- /*ARGSUSED*/
- {
- textmode(7);
- window(1, 1, 80, 25);
- /*
- * Note: you may remove the next two lines for your personal
- * use but you must replace them before distributing any copies
- * of this software.
- */
- distemplate(st_copyright);
- sleep(5);
-
- distemplate(st_screen);
- curpatch = 0;
- curparam = 0;
- curmpatch = 0;
- curmparam = 0;
- echo = 0;
- single = 0;
- dispatch(&mdump[curmpatch][0]);
- single = 1;
- dispatch(&dump[curpatch][0]);
- showparam(¶ms[curparam], &dump[curpatch][0]);
- for (;;)
- docommand();
- /*NOTREACHED*/
- }
-