#define d define
#d ID_DX7      67      /* Yamaha DX7 manufacturer MIDI id # */

/* dx7 buttons (for dx7Button() et al. */
#d DX7store                    32
#d DX7mem_protect_internal     33
#d DX7mem_protect_cartridge    34
#d DX7operator_select          35
#d DX7edit                     36
#d DX7mem_select_internal      37
#d DX7mem_select_cartridge     38
#d DX7function                 39
#d DX7no                       40
#d DX7yes                      41
#d dx7yes(n)           (n)? DX7yes : DX7no
#d DX7sysinfo                   7
#d DX7load                     15

#d DX7VOXLEN   155     /* length of dx7 single voice table */
#d DX732VOXLEN 128     /* length of dx7 32-voice table */
#d DX7COMLEN   4960    /* length of dx7 common voice table */
#d DX7FUNLEN   14      /* length of dx7 function table */
#d DX7CTLLEN   127     /* length of dx7 control table */
#d DX7KBDLEN   127     /* length of dx7 keyboard table */
#d DX7NVOX     32      /* number of dx7 voices */
#d DX7NVOICES  16      /* 16 simultaneous voices in poly mode*/
#d DX7OPLEN    21      /* length of dx7 operator table */
#d DX732VOPLEN 17      /* length of 32-voice operator table */
#d DX7NOPS     6       /* number of dx7 operators per voice */
#d DX7OPSLEN   (DX7OPLEN*DX7NOPS)      /* total len of op tbl*/
#d DX732VOPSLEN        (DX732VOPLEN * DX7NOPS) /* 32-voice op tbl len*/

/* SX == dx7 system exclusive command or field */
#d SX_DX7_1V           0       /* dx7 1 voice format */
#d SX_DX7_32V          9       /* dx7 32 voice format */
#d SX_DX7_BD           0       /* dx7 bulk data sub status */
#d SX_DX7_PC           1       /* dx7 parameter change sub status */
#d SX_DX7_AS           2       /* dx7 pseudo sub status active sense */
#d SX_DX7_GRP_VPAR     0       /* dx7 voice parameter group */
#d SX_DX7_GRP_FPAR     2       /* dx7 function parameter group */

/* CTL == dx7 channel control command indicies */
#d CTL_DX7_MOD_WHEEL   1       /* dx7 chan mod wheel index */
#d CTL_DX7_BREATH      2       /* dx7 chan breath index */
#d CTL_DX7_AFTER       3       /* dx7 chan after touch index */
#d CTL_DX7_FCONT       4       /* dx7 chan foot control index */
#d CTL_DX7_PORTA_TIME  5       /* dx7 chan portamento index */
#d CTL_DX7_DE_KNOB     6       /* dx7 chan data entry knob index */
#d CTL_DX7_VOLUME      7       /* dx7 chan volume control index */
#d CTL_DX7_SUST_FSW    64      /* dx7 chan footswitch control index */
#d CTL_DX7_PORTA_FSW   65      /* dx7 chan portamento control index */
#d CTL_DX7_DE_PLUS     96      /* dx7 chan data entry + sw. index */
#d CTL_DX7_DE_MINUS    97      /* dx7 chan data entry - sw. index */
#d CTL_DX7_OMNI_AKO    125     /* dx7 chan omni all keys off index */
#d CTL_DX7_MONO_AKO    126     /* dx7 chan mono all keys off index */
#d CTL_DX7_POLY_AKO    127     /* dx7 chan poly all keys off index */

extern struct midi_par
       dx7_ini_vox[], dx7_ini_fun[], dx7_ch_info[], dx7_xmit_ctl[],
       dx7_rcv_ctl[], dx7_32v_vox[];
extern unsigned short dx7_ini_vox_len, dx7_ini_fun_len, dx7_ch_info_len,
       dx7_xmit_ctl_len, dx7_rcv_ctl_len, dx7_32v_vox_len;

struct dx7 {   /* one dx7 contains storage for all the following */
    unsigned char dx7_vox_val[DX7NVOX][DX7VOXLEN];     /* voice data */
    unsigned char dx7_fun_val[DX7FUNLEN];              /* function data */
    unsigned char dx7_kbd_val[DX7CTLLEN];              /* keyboard data */
    unsigned char dx7_ctl_val[DX7CTLLEN];              /* controller data */
    unsigned char dx7_nsv;                             /* voices on */
    unsigned char dx7_prg_val;                         /* program */
    unsigned short dx7_pbd_val;                                /* pitch bender *
/
};

/* DX7_... == macros to stuff dx7 structure */
/* set voice parameter */
#d DX7_VP(d, voice, param)     ((d).dx7_vox_val[voice][param])
/* set function parameter */
#d DX7_FP(d, param)            ((d).dx7_fun_val[param])
/* set control parameter */
#d DX7_CP(d, param)            ((d).dx7_ctl_val[param])
/* set keyboard velocity parameter */
#d DX7_KP(d, param)            ((d).dx7_kbd_val[param])
/* set program parameter */
#d DX7_PP(d)                   ((d).dx7_prg_val)
/* set pitch bend parameter */
#d DX7_BP(d)                   ((d).dx7_pbd_val)

/* 
 * translate common voice parameter index in the range
 * 0 to DX7VOXLEN to ini_... array field 
 */
#d DX7_INI_IND(i) ((i)<DX7OPSLEN? (i)%DX7OPLEN : ((i)%DX7OPSLEN) + DX7OPLEN)

/* 
 * set voice parameter with bounds checking - expression evaluates to -1
 * if val < 0 || val > upper bound for that parameter
 */
#d DX7_SET_VP(d, voice, param, v)      X    (DX7_VP(d,voice,param) =           X
       ((v)<0 || (v)>dx7_ini_vox[DX7_INI_IND(param)].par_ub) ? -1 : (val))

/* dx7 voice operator parameter symbolic names */
/* operator rate amplitude envelope array */
#d OP_AMP_RATE_BASE    0
#d OP_AMP_RATE_LEN     4
#d op_amp_rate(i)      (OP_AMP_RATE_BASE + i)
/* operator level amplitude envelope array */
#d OP_AMP_LEVEL_BASE   4
#d OP_AMP_LEVEL_LEN    4
#d op_amp_level(i)     (OP_AMP_LEVEL_BASE + i)
#d op_kls_breakpoint   8       /* keyboard level sense */
#d op_kls_left_depth   9
#d op_kls_right_depth  10
#d op_kls_left_curve   11
#d op_kls_right_curve  12
#d op_kbd_rate_sc      13      /* keyboard rate scale */
#d op_mod_sens_amp     14      /* amp. mod. sensitivity */
#d op_key_vel_sens     15      /* key velocity sensitivity */
#d op_output_level     16      /* output level */
#d op_osc_mode         17      /* osc. mode */
#d op_osc_frq_coarse   18      /* osc. coarse freq. */
#d op_osc_frq_fine     19      /* osc. fine freq. */
#d p_detune            20      /* osc. detune */

/* OP == set operator in voice */
#d OP(n, p)            ((DX7NOPS - n) * DX7OPLEN + p)
/* Note: for each voice, operator table goes from 5 -> 0 */
/* set operator n to parameter p */

/* voice parameters other than operators */
#d VOX_PITCH_RATE_BASE 126
#d VOX_PITCH_RATE_LEN  4
#d vox_pitch_rate(i)   (VOX_PITCH_RATE_BASE + i)
#d VOX_PITCH_LEVEL_BASE        130
#d VOX_PITCH_LEVEL_LEN 4
#d vox_pitch_level(i)  (VOX_PITCH_LEVEL_BASE + i)
#d vox_alg             134     /* algorithm select */
#d vox_feedback                135     /* oscillator feedback ena. */
#d vox_osc_sync                136     /* osc. sync. */
#d lfo_speed           137     /* lfo speed */
#d lfo_delay           138     /* lfo delay */
#d lfo_pmd             139     /* lfo pitch mod. depth */
#d lfo_amd             140     /* lfo amplitude mod. depth */
#d lfo_sync            141     /* lfo sync. ena. */
#d lfo_wave            142     /* lfo waveform select */
#d vox_mod_sens_pitch  143     /* mod. sens. pitch */
#d vox_transpose       144     /* transpose oscillator */
#d VOX_NAME_BASE       145
#d VOX_NAME_LEN                10
#d VOX_32V_NAME_BASE   118
#d vox_voice_name      VOX_NAME_BASE
#d vox_op_ena          155     /* operator enable table */

/* function parameters */
#d fun_mono_poly               0       /* mono/poly mode change */
#d fun_pitch_bend_range                1       /* pitch bend range */
#d fun_pitch_bend_step         2       /* pitch bend step */
#d fun_porta_mode              3       /* portamento ena. */
#d fun_porta_gliss             4       /* portamento glissando ena. */
#d fun_porta_time              5       /* portamento time */
#d fun_mod_wheel_range         6       /* mod. wheel range */
#d fun_mod_wheel_assign                7       /* mod. wheel assign */
#d fun_foot_range              8       /* foot controller range */
#d fun_foot_assign             9       /* foot controller asign */
#d fun_breath_range            10      /* breath controller range */
#d fun_breath_assign           11      /* breath controller assign */
#d fun_after_touch_range       12      /* after touch range */
#d fun_after_touch_assign      13      /* after touch assign */

/* copy voice name field into dx7 structure */
#d DX7_SET_VNAME(dx, voice, name) strncpy(&DX7_VP(dx,voice,vox_voice_name),name,
VOX_NAME_LEN)

/* get voice name address */
#d DX7_VNAME_ADDR(dx, voice) (&(dx).dx7_vox_val[voice][VOX_NAME_BASE])

/* copy voice name field out of dx7 structure */
#d DX7_GET_VNAME(dx, buf, voice) strncpy(buf, DX7_VNAME_ADDR(dx, voice), VOX_NAM
E_LEN)

#d dx7_MIN     36              /* low C2 on the dx7 keyboard */
#d dx7_MAX     96              /* high C7 on the dx7 keyboard */

/* dx7 voice param specifier, stuff needed for talking about a voice param  */
struct dx7_vs {
       char    *name;  /* name of parameter, osc. sync., lfo speed, etc. */
       int     max;    /* maximum value */
};
#undef d
