allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (05/15/89)
Posting-number: Volume 6, Issue 113 Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee ) Archive-name: glib/part12 #! /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 <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 12 (of 15)." # Contents: cz1.mnu # Wrapped by lee@uhccux on Sun May 7 00:40:19 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'cz1.mnu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cz1.mnu'\" else echo shar: Extracting \"'cz1.mnu'\" \(33418 characters\) sed "s/^X//" >'cz1.mnu' <<'END_OF_FILE' X/* $Id: cz1.mnu,v 1.6 89/05/06 17:13:14 lee Exp $ X * GLIB - a Generic LIBrarian and editor for synths X * X * CZ-1 routines X * Mark Rinfret X * modified by Greg Lee X * $Log: cz1.mnu,v $ X * Revision 1.6 89/05/06 17:13:14 lee X * rel. to comp.sources.misc X * X */ X X#define OVERLAY1 X X#include "glib.h" X#include <ctype.h> X X#ifdef AMIGA X#define CZ1 X#else Xvoid sendmulti(); X#endif X X#include "cz.h" X X#define RING 1 X#define NOISE 2 X Xchar *visnum(), *visonoff(); Xchar *visczdet(), *visczflag(), *visczline(), *visczmod(), *viscznum2(); X/* char *visczoct(); */ X Xstatic void getenvelope(); Xstatic void getwaveforms(); Xstatic void setenvelope(); Xstatic void setwaveforms(); X X#define RESERVESIZE 0 X/* This array contains arbitrary screen labels */ Xstruct labelinfo Lcz1[] = { X#MENU XName: Line:% Mod:% Octave Vibrato Wave:% X % Delay:% X Envelope Rate:% X w1 w2 1 2 3 4 5 6 7 8 Depth:% XDCO1 % % % @ % @ % @ % @ % @ % @ % @ % @ <-Rate S=SUS E=END X % % % % % % % % <-Level XDCW1 follow: % % @ % @ % @ % @ % @ % @ % @ % @ X % % % % % % % % Level VA VW VP XDCA1 follow: % % @ % @ % @ % @ % @ % @ % @ % @ % % % % X % % % % % % % % X------------------------------------------------- Detune XDCO2 % % % @ % @ % @ % @ % @ % @ % @ % @ % Oct:% Note:% Fine: % X % % % % % % % % XDCW2 follow: % % @ % @ % @ % @ % @ % @ % @ % @ X % % % % % % % % Level VA VW VP XDCA2 follow: % % @ % @ % @ % @ % @ % @ % @ % @ % % % % X % % % % % % % % XPortamento Glide Bend Mod. Wheel Amp. XSweep: % Note: % % Depth: % Aftertouch: % X Time: % Time: % Aftertouch: % X X Pitch % Vol % X Dur % Chan % X X#END X-1,-1,NULL X}; X Xstruct paraminfo Pcz1[] = { X/* XNAME TYPE POS MAX OFFSET MASK SHIFT ADHOC X */ X#O line czline %% 3 0 X#O mod czmod %% 2 0 X#O vwave num %% 4 0 *5 X#O oct num %% 1 0 *5 X#O vdelay cznum2 %% 99 0 X#O vrate cznum2 %% 99 0 X#O vdepth cznum2 %% 99 0 X#O o1w1 num %% 8 0 *5 X#O o1w2 num %% 8 0 X#O 8o1r cznum2 %% 99 0 X#O 8o1f czflag @@ 2 0 X#O 8o1l cznum2 %% 99 0 X#O wf1 num %% 9 0 X#O 8w1r cznum2 %% 99 0 X#O 8w1f czflag @@ 2 0 X#O 8w1l cznum2 %% 99 0 X#O af1 num %% 9 0 X#O 8a1r cznum2 %% 99 0 X#O 8a1f czflag @@ 2 0 X#O level1 cznum2 %% 15 0 *5 X#O va1 cznum2 %% 15 0 X#O vw1 cznum2 %% 15 0 X#O vo1 cznum2 %% 15 0 X#O 8a1l cznum2 %% 99 0 X#O o2w1 num %% 8 0 *5 X#O o2w2 num %% 8 0 *5 X#O 8o2r cznum2 %% 99 0 X#O 8o2f czflag @@ 2 0 X#O detsign czdet %% 1 0 X#O detoct num %% 3 0 X#O detnote cznum2 %% 11 0 X#O detfine cznum2 %% 60 0 X#O 8o2l cznum2 %% 99 0 X#O wf2 num %% 9 0 X#O 8w2r cznum2 %% 99 0 X#O 8w2f czflag @@ 2 0 X#O 8w2l cznum2 %% 99 0 X#O af2 num %% 9 0 X#O 8a2r cznum2 %% 99 0 X#O 8a2f czflag @@ 2 0 X#O level2 cznum2 %% 15 0 *5 X#O va2 cznum2 %% 15 0 X#O vw2 cznum2 %% 15 0 X#O vo2 cznum2 %% 15 0 X#O 8a2l cznum2 %% 99 0 X#O psweep cznum2 %% 1 0 X#O gnote num %% 12 0 X#O bend cznum2 %% 12 0 X#O mdepth cznum2 %% 99 0 X#O amptouch cznum2 %% 99 0 X#O ptime cznum2 %% 99 0 X#O gtime cznum2 %% 99 0 X#O mtouch cznum2 %% 99 0 X#O autopitch num %% 127 -60 X#O autovol num %% 127 -63 X#O autodur num %% 20 -5 *5 X#O autochan num %% 16 -1 *5 XNULL,NULL,-1,-1,-1,-1,visnum,0,0,0,0 X}; X X X/* The following table converts AMP level visual values into X MIDI values 00 - 5F. X */ XUBYTE ampLevelMIDI[10] = { X 0x00, 0x08, 0x11, 0x1a, 0x24, 0x2f, 0x3a, 0x45, 0x52, 0x5f X }; X X/* The following table converts WAVE key follow visual values 0-9 into X MIDI values 00 - FF. X */ XUBYTE keyFollowMIDI[10] = { X 0x00, 0x19, 0x33, 0x4e, 0x6a, 0x86, 0xa3, 0xc1, 0xdf, 0xff X }; X X/* The following table converts a simple VIBRATO depth value (0..99) X into a word representing bytes 1-2 of the vibrato depth group. */ XUSHORT vDepthTable[100] = { X/* 00 */ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, X/* 05 */ 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, X/* 10 */ 0x000b, 0x000c, 0x000e, 0x000e, 0x000f, X/* 15 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, X/* 20 */ 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, X/* 25 */ 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, X/* 30 */ 0x001f, 0x0020, 0x0023, 0x0025, 0x0027, X/* 35 */ 0x0029, 0x002b, 0x002d, 0x002f, 0x0031, X/* 40 */ 0x0033, 0x0035, 0x0037, 0x0039, 0x003b, X/* 45 */ 0x003d, 0x003f, 0x0041, 0x0047, 0x004b, X/* 50 */ 0x004f, 0x0053, 0x0057, 0x005b, 0x005f, X/* 55 */ 0x0063, 0x0067, 0x006b, 0x006f, 0x0073, X/* 60 */ 0x0077, 0x007b, 0x007f, 0x0083, 0x008f, X/* 65 */ 0x0097, 0x009f, 0x00a7, 0x00af, 0x00b7, X/* 70 */ 0x00bf, 0x00c7, 0x00cf, 0x00d7, 0x00df, X/* 75 */ 0x00e7, 0x00ef, 0x00f7, 0x00ff, 0x0107, X/* 80 */ 0x011f, 0x012f, 0x013f, 0x014f, 0x015f, X/* 85 */ 0x016f, 0x017f, 0x018f, 0x019f, 0x01af, X/* 90 */ 0x01bf, 0x01cf, 0x01df, 0x01ef, 0x01ff, X/* 95 */ 0x020f, 0x023f, 0x025f, 0x027f, 0x0300 X}; X X X/* The following table converts a simple VIBRATO delay time index X (0..99) into a word representing the second two bytes of the X vibrato delay group. As usual, this represents some really wierd X encoding. X*/ X XUSHORT vDelayTable[100] = { X/* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, X/* 05 */ 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, X/* 10 */ 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, X/* 15 */ 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, X/* 20 */ 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, X/* 25 */ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, X/* 30 */ 0x001e, 0x001f, 0x0021, 0x0023, 0x0025, /* <== change begins */ X/* 35 */ 0x0027, 0x0029, 0x002b, 0x002d, 0x002f, X/* 40 */ 0x0031, 0x0033, 0x0035, 0x0037, 0x0039, X/* 45 */ 0x003b, 0x003d, 0x003f, 0x0043, 0x0047, X/* 50 */ 0x004b, 0x004f, 0x0053, 0x0057, 0x005b, X/* 55 */ 0x005f, 0x0063, 0x0067, 0x006b, 0x006f, X/* 60 */ 0x0073, 0x0077, 0x007b, 0x007f, 0x0087, X/* 65 */ 0x008f, 0x0097, 0x009f, 0x00a7, 0x00af, X/* 70 */ 0x00b7, 0x00bf, 0x00c7, 0x00d7, 0x00df, X/* 75 */ 0x00e7, 0x00ef, 0x00f7, 0x00ff, 0x000f, X/* 80 */ 0x010f, 0x011f, 0x012f, 0x013f, 0x014f, X/* 85 */ 0x015f, 0x016f, 0x017f, 0x018f, 0x019f, X/* 90 */ 0x01af, 0x01bf, 0x01cf, 0x01df, 0x01ef, X/* 95 */ 0x01ff, 0x021f, 0x023f, 0x025f, 0x017f X}; X X/* The following table converts a simple VIBRATO rate index (0..99) X into the value of bytes 1-2 of the vibrato rate group. */ XUSHORT vRateTable[100] = { X/* 00 */ 0x0020, 0x0040, 0x0060, 0x0080, 0x00a0, X/* 05 */ 0x00c0, 0x00e0, 0x0100, 0x0120, 0x0140, X/* 10 */ 0x0160, 0x0180, 0x01a0, 0x01c0, 0x01e0, X/* 15 */ 0x0200, 0x0220, 0x0240, 0x0260, 0x0280, X/* 20 */ 0x02a0, 0x02c0, 0x02e0, 0x0300, 0x0320, X/* 25 */ 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0, X/* 30 */ 0x03e0, 0x0400, 0x0460, 0x04a0, 0x04e0, X/* 35 */ 0x0520, 0x0560, 0x05a0, 0x05e0, 0x0620, X/* 40 */ 0x0660, 0x06a0, 0x06e0, 0x0720, 0x0760, X/* 45 */ 0x07a0, 0x07e0, 0x0820, 0x08e0, 0x0960, X/* 50 */ 0x09e0, 0x0a60, 0x0ae0, 0x0b60, 0x0be0, X/* 55 */ 0x0c60, 0x0ce0, 0x0d60, 0x0de0, 0x0e60, X/* 60 */ 0x0ee0, 0x0f60, 0x0fe0, 0x1060, 0x11e0, X/* 65 */ 0x12e0, 0x13e0, 0x14e0, 0x15e0, 0x16e0, X/* 70 */ 0x17e0, 0x18e0, 0x19e0, 0x1ae0, 0x1be0, X/* 75 */ 0x1ce0, 0x1de0, 0x1ee0, 0x1fe0, 0x20e0, X/* 80 */ 0x23e0, 0x25e0, 0x27e0, 0x29e0, 0x2be0, X/* 85 */ 0x2d30, 0x2fe0, 0x31e0, 0x33e0, 0x35e0, X/* 90 */ 0x37e0, 0x39e0, 0x3be0, 0x3de0, 0x3fe0, X/* 95 */ 0x41e0, 0x47e0, 0x4be0, 0x4fe0, 0x53e0 X}; X X X X/* FUNCTION X cz1din - convert CZ1 data to program format. X X SYNOPSIS X int cz1din(data) X struct ToneData *data; X X DESCRIPTION X Take info from <data> and stuff values into the P array, using X the setval and setopval functions. X*/ Xint Xcz1din(data) X struct ToneData *data; X{ X register int value; X X setval("line", (INT16)data->lineAndOctave & 3); X value = (data->waveForms1[1] >> 3) & 7; X if (value == 4) X value = RING; X else if (value == 3) X value = NOISE; X setval("mod", (INT16)value); X value = (data->lineAndOctave >> 2) & 3; X if (value == 2) value = -1; /* 2 => -1 */ X setval("oct", (INT16)value); X X /* Extract the DETUNE information: */ X setval("detsign", (INT16)data->detuneSign); X X /* The FINE detune info must have a correction factor applied: */ X value = data->detuneFine >> 2; X if (value > 47) value -= 3; X else if (value > 31) value -= 2; X else if (value > 15) value -= 1; X setval("detfine", (INT16)value); X X /* The NOTE and OCTAVE detune info are obtained by factoring the X semitone info in detuneCoarse: */ X X setval("detnote", (INT16)data->detuneCoarse % 12); X setval("detoct", (INT16)data->detuneCoarse / 12); X X /* Get the VIBRATO info: */ X value = data->vibratoWave & 0x2E; X switch (value) { X case 2: X value = 4; X break; X case 4: X value = 2; X break; X case 8: X value = 1; X break; X X case 32: X value = 3; X break; X X default: X value = 1; X break; X X } X setval("vwave", (INT16)value); X setval("vdelay", (INT16)data->vibratoTime[0]); X setval("vrate", (INT16)data->vibratoRate[0]); X setval("vdepth", (INT16)data->vibratoDepth[0]); X X /* Set onscreen parameters for patch area 1. */ X setwaveforms("o1", data->waveForms1); X X /* setenvelope sets all rates and levels for an envelope. */ X setenvelope("o1", data->DCO_Envelope1, data->DCO_EndStep1); X setenvelope("w1", data->DCW_Envelope1, data->DCW_EndStep1); X setenvelope("a1", data->DCA_Envelope1, data->DCA_EndStep1); X X /* Set key follow parameters for area 1. */ X X setval("wf1", (INT16)data->DCW1_KeyFollow[0] & 0xf); X setval("af1", (INT16)data->DCA1_KeyFollow[0] & 0xf); X X value = 15 - (data->DCA1_KeyFollow[0] >> 4); X setval("level1", (INT16)value); X X /* Set onscreen parameters for patch area 2. */ X setwaveforms("o2", data->waveForms2); X X /* Set the envelope parameters for patch area 2. */ X setenvelope("o2", data->DCO_Envelope2, data->DCO_EndStep2); X setenvelope("w2", data->DCW_Envelope2, data->DCW_EndStep2); X setenvelope("a2", data->DCA_Envelope2, data->DCA_EndStep2); X X /* Set key follow parameters for area 2. */ X X setval("wf2", (INT16)data->DCW2_KeyFollow[0] & 0xf); X setval("af2", (INT16)data->DCA2_KeyFollow[0] & 0xf); X X value = 15 - (data->DCA2_KeyFollow[0] >> 4); X setval("level2", (INT16)value); X return 0; X} X X/* FUNCTION X cz1dout - convert program data to CZ1 format. X X SYNOPSIS X int cz1dout(data) X struct ToneData *data; X X DESCRIPTION X Cz1dout takes data from the P array and converts it to CZ1 format, X storing it in the patch area defined by <data>. X X*/ Xint Xcz1dout(data) X struct ToneData *data; X{ X int value, value2; X X value = getval("oct"); /* Get, correct octave value. */ X if (value < 0) value = 2; X data->lineAndOctave = getval("line") | (value << 2); X data->detuneSign = getval("detsign"); X /* The DETUNE coarse data is converted from OCT and NOTE into a X semitone value ranging from 0 to 47(2F). It is then stored X in the high byte of the pair. X */ X value = getval("detoct") * 12 + getval("detnote"); X data->detuneCoarse = value; X X /* The DETUNE fine data has a correction factor applied to it, X and is then shifted to fit into bits 7-2 of the the low byte. X */ X value = getval("detfine"); X if (value > 45) value += 3; X else if (value > 30) value += 2; X else if (value > 15) value += 1; X data->detuneFine = value << 2; X X value = getval("detnote"); X value += getval("detoct") * 12; X data->detuneCoarse = value; X X /* VIBRATO information: */ X value = getval("vwave"); X switch (value) { X case 1: X value = 8; X break; X case 2: X value = 4; X break; X case 3: X value = 32; X break; X default: X break; X } X data->vibratoWave = data->vibratoWave = value; X X /* Get vibrato delay. */ X value = getval("vdelay"); X data->vibratoTime[0] = value; X value = vDelayTable[value]; X data->vibratoTime[1] = value; X data->vibratoTime[2] = value>>8; X X /* Get vibrato rate. */ X value = getval("vrate"); X data->vibratoRate[0] = value; X value = vRateTable[value]; X data->vibratoRate[1] = value; X data->vibratoRate[2] = value >> 8 ; X X /* Get vibrato depth. */ X value = getval("vdepth"); X data->vibratoDepth[0] = value; X value = vDepthTable[value]; /* Get bytes 1, 2 from table. */ X data->vibratoDepth[1] = value; X data->vibratoDepth[2] = value >> 8; X X /* Get envelope values: */ X getenvelope("o1", data->DCO_Envelope1, &data->DCO_EndStep1); X getenvelope("w1", data->DCW_Envelope1, &data->DCW_EndStep1); X getenvelope("a1", data->DCA_Envelope1, &data->DCA_EndStep1); X getwaveforms("o1", data->waveForms1); X value = getval("wf1"); X data->DCW1_KeyFollow[0] = value; X data->DCW1_KeyFollow[1] = keyFollowMIDI[value]; X X /* The amp level and key follow values share the DCAx_KeyFollow X field. */ X X value = getval("af1"); X value2 = getval("level1"); X value2 = (15 - value2) << 4; X data->DCA1_KeyFollow[0] = value | value2; X data->DCA1_KeyFollow[1] = ampLevelMIDI[value]; X X getenvelope("o2", data->DCO_Envelope2, &data->DCO_EndStep2); X getenvelope("w2", data->DCW_Envelope2, &data->DCW_EndStep2); X getenvelope("a2", data->DCA_Envelope2, &data->DCA_EndStep2); X getwaveforms("o2", data->waveForms2); X data->DCW2_KeyFollow[0] = value = getval("wf2"); X data->DCW2_KeyFollow[1] = keyFollowMIDI[value]; X X value = getval("af2"); X value2 = getval("level2"); X value2 = (15 - value2) << 4; X data->DCA2_KeyFollow[0] = value | value2; X data->DCA2_KeyFollow[1] = ampLevelMIDI[value]; X X return 0; X} X X/* FUNCTION X cz1nof - return a pointer to a patch internal name. X X SYNOPSIS X char *cz1nof(data) X struct ToneData *data; X X DESCRIPTION X Cz1nof extracts a local copy of the voice name (in <data>) and X returns a pointer to it. X X*/ X Xchar * Xcz1nof(data) X struct ToneData *data; X{ X static char name[17]; X UBYTE *n; X int i; X X for (i=0, n = data->name; i < 16; ++i) X name[i] = *n++; X X name[16] = '\0'; X return name; X} X X/* FUNCTION X cz1snof - store a voice name. X X SYNOPSIS X int cz1snof(data, name) X struct ToneData *data, *name; X X DESCRIPTION X Cz1snof stores the new voice <name> into the patch area defined X by <data>. X X*/ Xint Xcz1snof(data, name) X struct ToneData *data; char *name; X X{ X int i; X UBYTE *n; X X for (i = 0, n = data->name; (i < 16) && *name; ++i) X *n++ = *name++; X X while (i < 16) { X *n++ = ' '; X ++i; X } X} X X#ifdef CZ1SBULK X/* FUNCTION X cz1sbulk - send bulk patch data to the CZ1. X X SYNOPSIS X int cz1sbulk(data) X struct ToneData *data; X X DESCRIPTION X Cz1sbulk sends 64 voice patches to the CZ1. X X*/ X Xint Xcz1sbulk(data) X struct ToneData *data; X{ X return 0; X} X#endif X X/* FUNCTION X cz1gbulk - get bulk patch data from CZ1. X X SYNOPSIS X int cz1gbulk(data) X char *data; X X DESCRIPTION X Cz1gbulk reads 64 voices of patch data from the CZ1 into <data>. X X*/ Xint Xcz1gbulk(data) X char *data; X{ X char *addr; X int i; X char msg[40]; X int result, voice; X X /* !!! I want to change this so we can access the cartridge pack X * !!! as well. A simple flag should do it. X */ X X for (voice = FIRST_INTERNAL; voice <= LAST_INTERNAL; ++voice) { X addr = data + voice * sizeof(struct ToneData); X (void)sprintf(msg, "Reading CZ1 voice %d.", voice); X windgoto(3,10); X windstr(msg); X windrefresh(); X if (result = ReceiveCZPatch((struct ToneData *)addr, X (UBYTE)Channel, (UBYTE)voice)) { X (void)sprintf(msg, "Failed to read CZ1 voice %d!", voice); X windgoto(3, 10); X windstr(msg); X windrefresh(); X return result; X } X } X for (i = 0; i < 39; ++i) msg[i] = ' '; X msg[i] = '\0'; X windgoto(3, 10); X windstr(msg); X windrefresh(); X return 0; X} X X/* FUNCTION X cz1sedit - send a single voice to the CZ1 edit buffer. X X SYNOPSIS X int cz1sedit(data) X struct ToneData *data; X X DESCRIPTION X Cz1sedit sends a single voice to the CZ1 edit buffer. X X*/ X Xint Xcz1sedit(data) X struct ToneData *data; X{ X return SendCZPatch(data, Channel, SOUND_DATA); X} X X/* FUNCTION X cz1sone - send one voice to the CZ1. X X SYNOPSIS X int cz1sone(vx, data) X int vx; X struct ToneData *data; X X DESCRIPTION X Cz1sone sends one voice (number specified by <vx>) to the CZ1. X The <data> argument points to the patch data to be sent. X X Cz1sone returns 0 on success, -1 on failure. X X*/ X Xint Xcz1sone(vx, data) X int vx; X char *data; X{ X return SendCZPatch((struct ToneData *)data, Channel, vx); X} X X/* FUNCTION X GetCZSysEx - wait for system exclusive byte or time-out. X X SYNOPSIS X int GetCZEndSysEx(); X X DESCRIPTION X GetCZSysEx waits for a system exclusive byte from the CZ1. X If the next byte received is a system exclusive, a zero X result is returned, indicating success. If the byte received X is not a sysex, or if a timeout occurs, a one (1) is returned X and the error reason, Reason, is set appropriately. X X*/ Xint XGetCZEndSysEx() X{ X unsigned char c; X long begin, toolong; X static char msg[40]; X X begin = milliclock(); X toolong = begin + 2000; /* Wait for 2 seconds. */ X X while (milliclock() < toolong) { X if (STATMIDI) { X c = getmidi() & 0xFF; X if (c != END_SYSTEM_EXCLUSIVE) { X (void)sprintf(msg,"Waited for %02xx, got %02xx", X END_SYSTEM_EXCLUSIVE, c & 0xFF); X Reason = msg; X return 1; X } X return 0; X } X } X Reason = "Timed out waiting for end sysex."; X return 1; X} X X/* FUNCTION X SendCZPatch - send one voice to the CZ1 X X SYNOPSIS X int SendCZPatch(tonedata, channel, voice) X struct ToneData *tonedata; X int channel, voice; X X DESCRIPTION X SendCzPatch sends one voice patch (<tonedata>) to the CZ1, X using the specified <channel>. The <voice> argument determines X which synthesizer program area the data will be sent to. X X Note that the CZ family behaves in a wierd way, splitting all X tone data bytes into two pieces. SendToneData splits the bytes X to a local buffer prior to transmitting them. X*/ Xstatic int XSendCZPatch(tonedata, channel, voice) Xstruct ToneData *tonedata; Xint channel,voice; X{ X long begin, toolong; /* timer values */ X X#ifdef CZ101 X/* Receive request 1 system exclusive */ X Xstatic UBYTE receive_request[] = { X 0xF0,0x44,0x00,0x00,0x70,0x20,0x00 }; X#endif X X#ifdef CZ1 Xstatic UBYTE receive_request[] = { X 0xF0,0x44,0x00,0x00,0x70,0x21,0x00 }; X#endif X X UBYTE data[512]; X UBYTE *ptr; X X int i; X X /* Clear the serial buffer of any unread data */ X if (!synthoutfileflag) X flushmidi(); X X /* Fill in channel and voice, then send request. */ X X receive_request [4] = 0x70 | ((channel - 1) & 0x0F); X receive_request [6] = voice; X X sendmulti(receive_request, sizeof(receive_request)); X X /* Get the reply message. It's six bytes consisting of: X F0 44 00 00 7N 30 where N is the channel number. X */ X X begin = milliclock(); X toolong = begin + 5000L; X if (!synthoutfileflag) X for (i = 0; i < 6; ) { X if (STATMIDI) { /* Something available? */ X data[i++] = getmidi(); X } X else if (milliclock() > toolong) { X Reason = "Timeout waiting for receive request 1 reply."; X return 1; X } X } X X /* Split the data into 4-bit nybbles. */ X X ptr = (UBYTE *) tonedata; X X for (i=0; i<sizeof(struct ToneData)*2; i+=2) { X data[i] = *ptr & 0x0F; X data[i+1] = (*ptr >> 4) & 0x0F; X ++ptr; X } X X /* Add "end-system-exclusive" to tone data buffer */ X X data[i] = END_SYSTEM_EXCLUSIVE; X X /* Send tone data to synth */ X X sendmulti(data, sizeof(struct ToneData) * 2 + 1); X X /* Read "end-system-exclusive" from synth */ X X if (!synthoutfileflag) X return GetCZEndSysEx(); X else return 0; X} X X/* FUNCTION X ReceiveCZPatch - receive one CZ1 voice patch. X X SYNOPSIS X int ReceiveCZPatch(tonedata, channel, voice); X struct ToneData *tonedata; X int channel, voice; X X DESCRIPTION X ReceiveCZPatch requests one CZ1 voice patch. It combines the X voice nybbles sent by the CZ1 into a normal ToneData structure. X X ReceiveCZPatch returns zero on success. On failure, it returns X one (1) after setting Reason to a string describing the failure. X*/ X Xint XReceiveCZPatch(tonedata, channel, voice) Xstruct ToneData *tonedata; XUBYTE channel,voice; X{ X#ifdef CZ101 X/* Send Request 1 system exclusive data */ X Xstatic UBYTE send_request_1A [] = { X 0xF0,0x44,0x00,0x00,0x70,0x10,0x00 }; X Xstatic UBYTE send_request_1B [] = { X 0x70,0x31 }; X#endif X X#ifdef CZ1 Xstatic UBYTE send_request_1A [] = { X 0xF0,0x44,0x00,0x00,0x70,0x11,0x00 }; X Xstatic UBYTE send_request_1B [] = { X 0x70,0x31 }; X#endif X X long begin, toolong; X UBYTE data[512]; X UBYTE *ptr; X X int i; X X /* Clear the serial buffer of any unread data */ X X flushmidi(); X X /* Set channel and voice info, then send the request to the CZ1. */ X X send_request_1A [4] = 0x70 | ((channel - 1) & 0x0F); X send_request_1A [6] = voice; X X sendmulti(send_request_1A, sizeof(send_request_1A)); X X /* Get the reply message. It's six bytes consisting of: X F0 44 00 00 7N 30 where N is the channel number. X */ X X begin = milliclock(); X toolong = begin + 5000L; X for (i = 0; i < 6; ) { X if (STATMIDI) { /* Something available? */ X data[i++] = getmidi(); X } X else if (milliclock() > toolong) { X Reason = "Timeout waiting for send request 1 reply."; X return 1; X } X } X /* if from file, one more byte of header to read -- gl */ X if (synthinfileflag) (void)getmidi(); X X /* Send secondary request */ X X send_request_1B [0] = 0x70 | ((channel - 1) & 0x0F); X sendmulti(send_request_1B, sizeof(send_request_1B)); X X /* Read tone data and "end-system-exclusive" from synth */ X X begin = milliclock(); X toolong = begin + TIMEOUT*1000; X for (i = 0; i < (sizeof(struct ToneData) * 2) + 1; ) { X if (STATMIDI) { X data[i++] = getmidi(); X } X else if (milliclock() > toolong) { X Reason = "Timed out waiting for patch data."; X return 1; X } X } X X /* Pack the 4-bit nybbles into a ToneData structure. */ X X ptr = (UBYTE *) tonedata; X X for (i=0; i<sizeof(struct ToneData)*2; i+=2) X *(ptr++) = (data[i] | (data[i+1] << 4)); X X /* Echo "end-system-exclusive" */ X X sendmidi(END_SYSTEM_EXCLUSIVE); X return 0; X} X X X/******************************* X * Screen Formatting Functions * X *******************************/ X Xchar * Xvisczdet(v) X{ X if (v == 0 || v == 1) return (v ? "-" : "+"); X else return("*"); X} X Xchar * Xvisczflag(v) X int v; X{ X static char *flags[3] = {" ", "S", "E"}; X X if (v >= 0 && v < 3) return flags[v]; X else return("*"); X} X Xchar * Xvisczline(v) X int v; X{ X static char *modes[4] = {"1", "2", "1+1'", "1+2'"}; X X return modes[v & 3]; X} X Xchar * Xvisczmod(v) X int v; X{ X static char *modValues[] = { "Off", "Ring", "Noise" }; X X if (v > 2) v = 0; X if (v >= 0) return modValues[v]; X else return("*"); X} X Xchar * Xviscznum2(v) X{ X static char num[4]; X X if (v >= 0 && v < 100) { X (void)sprintf(num,"%02d",v); X return num; X } X return("*"); X} X X/* not used Xchar * Xvisczoct(v) X int v; X{ X static char *octaves[3] = {"0", "+1", "-1"}; X X if (v >= 0 && v < 3) return octaves[v]; X else return("*"); X} X*/ X X/* FUNCTION X getenvelope - get rate, level pairs for one envelope X X SYNOPSIS X static void getenvelope(prefix, envelope, endStep) X char *prefix; X UBYTE *envelope; X UBYTE *endStep; X X DESCRIPTION X getenvelope() retrieves data values from the P array and stuffs X them back into the synthesizer patch record. The <prefix> X argument describes the envelope being retrieved, while the X <envelope> argument is a pointer to the envelope data. <endStep> X points to the appropriate end-of-step byte. X*/ Xstatic void Xgetenvelope(prefix, envelope, endStep) X char *prefix; X UBYTE *envelope; X UBYTE *endStep; X{ X int prevLevel = 0; X UBYTE sign; X int step, sx; X int flag, level, rate; X char varName[32]; X UBYTE velocity; X X for (step = 0, sx = 0; step < 8; ++step, sx += 2) { X /* Retrieve RATE value: */ X (void)sprintf(varName, "%sr%d", prefix, step + 1); X rate = getval(varName); X X /* Now, get LEVEL value: */ X (void)sprintf(varName,"%sl%d", prefix, step+1); X level = getval(varName); X X /* Get flag (SUS/END): */ X (void)sprintf(varName, "%sf%d", prefix, step+1); X flag = getval(varName); X X /* The next statement depends upon the velocity parameters X being named "vo1", "vw1", "va1", etc. */ X X (void)sprintf(varName, "v%s", prefix); X velocity = getval(varName); X X /* Convert rate,level to MIDI value: */ X switch (*prefix) { X case 'o': X if (rate == 99) X rate = 127; X else if (rate != 0) X rate = (127 * rate) / 99; X X if (level > 63) level += 4; X break; X case 'w': X rate = (119 * rate) / 99 + 8; X level = (127 * level) / 99; X break; X case 'a': X rate = (119 * rate) / 99; X if (level) level += 28; X break; X default: X rate = 127; X level = 0; X break; X } X X /* For RATE bytes, if the current level is less than the X previous level, set the sign bit: */ X sign = (level < prevLevel ? 0x80 : 0); X envelope[sx] = rate | sign; X X /* If this is step 7 and the flag does not indicate the end X step, we must force the end step now: */ X X if ((step == 7) && flag != 2) { X Redraw = 1; X flag = 2; X (void)sprintf(varName,"%sf8",prefix); X setval(varName, (INT16)flag); X } X if (flag == 2) { /* Is this the end step? */ X level = 0; X *endStep = step | (velocity << 4); X break; X } X X /* For LEVEL bytes, set the sign bit if the current step is X a SUSTAIN step: */ X X sign = (flag == 1 ? 0x80 : 0); X envelope[sx+1] = level | sign; X prevLevel = level; X if (flag == 2) break; X } X X} X X/* FUNCTION X getwaveforms - stuff waveform info into patch area. X X SYNOPSIS X static void getwaveforms(prefix, waveForms) X char *prefix; X UBYTE *waveForms; X X DESCRIPTION X getwaveforms() converts the local representation of the X waveform data into the CZ1 representation. The <prefix> X argument determines if the waveforms to be converted are X for DCO1 (prefix = "o1") or DCO2 (prefix = "o2"). X*/ X Xstatic void Xgetwaveforms(prefix, waveForms) X char *prefix; UBYTE *waveForms; X{ X USHORT modulation; X USHORT second, waveWord, w1, w2; X char varName[32]; X X (void)sprintf(varName,"%sw1", prefix); X w1 = getval(varName); X if (w1) --w1; /* Do "normalization" */ X (void)sprintf(varName,"%sw2", prefix); X w2 = getval(varName); X if (w2) { X --w2; X second = 0x200; /* Indicate second waveform present. */ X } X else X second = 0; X X modulation = getval("mod"); X if (modulation == RING) X modulation = 0x20; X else if (modulation == NOISE) X modulation = 0x18; X X /* Save bits 8-6 (resonance?) of the old waveForms word. */ X waveWord = ((waveForms[0] << 8) | waveForms[1]) & 0x1c0; X waveWord |= modulation; X X /* Perform an inclusive OR with the new waveform components. */ X waveWord |= ((w1<<13) | (w2<<10) | second); X waveForms[1] = waveWord; X waveForms[0] = waveWord >> 8; X} X X/* FUNCTION X setenvelope - set rate, level pairs for one envelope. X X SYNOPSIS X static void setenvelope(prefix, envelope, endStep) X char *prefix; X UBYTE *envelope; X UBYTE endStep; X X DESCRIPTION X setenvelope stuffs the P array with the <envelope> values. It X uses the <prefix> string to compute the variable names that X are to be set. Typical values for the <prefix> string are: X X "o1" - DCO1 X "w1" - DCW1 X "a2" - DCA2 X X Of course, they must match the names used in the P array. X*/ Xstatic void Xsetenvelope(prefix, envelope, endStep) X char *prefix; UBYTE *envelope; UBYTE endStep; X{ X int step, sx, value; X char varName[32]; X X for (step = 0, sx = 0; step < 8; ++step, sx += 2) { X (void)sprintf(varName, "%sr%d", prefix, step + 1); X value = envelope[sx] & 0x7f; X /* Perform rate value conversion, based on envelope name: */ X switch (*prefix) { X case 'o': X if (value == 127) X value = 99; X else if (value != 0) X value = (value * 99) / 127 + 1; X break; X case 'w': X value -= 8; /* Nice stuff! :-( */ X if (value == 0x77) X value = 99; X else if (value != 0) X value = (value * 99) / 119 + 1; X break; X case 'a': X if (value == 0x77) X value = 99; X else if (value != 0) X value = (99 * value) / 119 + 1; X break; X default: X break; X } X setval(varName, (INT16)value); X X (void)sprintf(varName, "%sl%d", prefix, step + 1); X value = envelope[sx+1] & 0x7f; X /* Perform nasty conversion on level value: */ X switch (*prefix) { X case 'o': X if (value > 63) value -= 4; /* Sure! Why not? Grrr... */ X break; X case 'w': X if (value == 0x7f) X value = 99; X else if (value != 0) X value = (value * 99) / 127 + 1; X break; X case 'a': X if (value) value -= 28; /* Makes sense to me! Phht! */ X break; X default: X break; X } X setval(varName, (INT16)value); X X /* Set SUS/END flag. */ X (void)sprintf(varName, "%sf%d", prefix, step+1); X if ((endStep & 7) == step) X value = 2; X else if (envelope[sx+1] & 0x80) X value = 1; X else X value = 0; X setval(varName, (INT16)value); X X /* Get VELOCITY parameter. */ X (void)sprintf(varName, "v%s", prefix); X setval( varName, (INT16)endStep >> 4 ); X } X} X X/* FUNCTION X setwaveforms - extract waveform data from patch area. X X SYNOPSIS X static void setwaveforms(prefix, waveForms) X char *prefix; X UBYTE *waveForms; X X DESCRIPTION X setwaveforms extracts the waveform data from a CZ1 patch X and converts it to the on-screen representation. X X*/ Xstatic void Xsetwaveforms(prefix, waveForms) X char *prefix; UBYTE *waveForms; X{ X char varName[33]; X USHORT waveWord; X USHORT w1, w2; X X waveWord = waveForms[0] << 8 | waveForms[1]; X w1 = ((waveWord >> 13) & 7) + 1; X w2 = ((waveWord >> 10) & 7); X if (waveWord & 0x200) /* Second waveform is present? */ X w2 += 1; X else X w2 = 0; X (void)sprintf(varName,"%sw1", prefix); X setval(varName, (INT16)w1); X (void)sprintf(varName,"%sw2", prefix); X setval(varName, (INT16)w2); X} X X X#ifndef AMIGA X/* FUNCTION X sendmulti - send multiple bytes to midi device X X SYNOPSIS X void sendmulti(buffer, count) X char *buffer; X int count; X X DESCRIPTION X sendmulti transfers <count> bytes from <buffer> to the currently X open midi device. X X*/ X Xvoid Xsendmulti(buffer, count) X UBYTE *buffer; int count; X{ X while (count--) sendmidi((int)*buffer++); X} X#endif X END_OF_FILE if test 33418 -ne `wc -c <'cz1.mnu'`; then echo shar: \"'cz1.mnu'\" unpacked with wrong size! fi # end of 'cz1.mnu' fi echo shar: End of archive 12 \(of 15\). cp /dev/null ark12isdone 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