v06i113: glib part 12 of 15
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Mon May 15 13:41:39 AEST 1989
Posting-number: Volume 6, Issue 113
Submitted-by: lee at 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 at 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
More information about the Comp.sources.misc
mailing list