/* ============================================================================= localkb.c -- local keyboard processing Version 39 -- 1988-11-28 -- D.N. Lynx Crowe List with the pr -e4 option to expand tabs to 4 spaces instead of 8. ============================================================================= */ #include "ram.h" #define LCL_PRT 3 /* 1-origin local keyboard port number */ int16_t lclkmap[24] = { /* local key to MIDI key number map table */ 0, 1, 2, 3, 4, 5, 6, /* 1..7 */ 7, 8, 9, 10, 11, 12, 13, /* 8..14 */ 114, 115, 116, 117, 118, 119, 120, /* 15..21 */ 121, 122, 123 /* 22..24 */ }; int16_t panlkey[24] = { /* default tunings, in cents, for local keys */ 560, 960, 1360, 1760, 2160, 2560, 2960, 3360, 3760, 4160, 4560, 4960, 5360, 5760, 6160, 6560, 6960, 7360, 7760, 8160, 8560, 8960, 9360, 9760 }; int16_t stepfrm[4][17] = { /* step mode frame counts */ /* 1 1 1 1 1 1 */ /* -- -- -- - - - */ /* 64 32 16 8 4 2 1 */ { 3, 4, 10, 22, 46, 94, 190, /* legato - normal */ 7, 16, 34, 70, 142, 286, /* legato - dotted */ 3, 6, 14, 30}, /* legato - triplets */ { 2, 4, 8, 16, 32, 64, 128, /* normal - normal */ 6, 12, 24, 48, 96, 192, /* normal - dotted */ 3, 5, 10, 20}, /* normal - triplets */ { 2, 3, 4, 6, 10, 16, 24, /* stacato - normal */ 4, 5, 8, 12, 20, 30, /* stacato - dotted */ 3, 4, 5, 8}, /* stacato - triplets */ { 3, 6, 12, 24, 48, 96, 192, /* interval - normal */ 9, 18, 36, 72, 144, 288, /* interval - dotted */ 4, 8, 16, 32} /* interval - triplets */ }; /* ============================================================================= setleds() -- set LEDs according to pkctrl, etc. ============================================================================= */ void setleds(void) { register int16_t i; for (i = 0; i < 24; i++) /* turn off all LEDs */ io_leds = 0x0080 | i; switch (pkctrl) { default: case PK_PFRM: /* performance */ case PK_INST: /* instrument */ case PK_LOAD: /* load */ return; case PK_NOTE: /* note entry */ if (stepenb) io_leds = 0x01; io_leds = 6 - stepwgt; io_leds = 7 + stepint; return; case PK_ASGN: /* assignment table */ if (curasg EQ 0) return; io_leds = (curasg - 1) % 20; /* indicate current assignment */ return; case PK_GOTO: /* go to */ if (gomode EQ GO_SECT) { /* indicate active sections */ for (i = 0; i < 20; i++) if (E_NULL NE seclist[curscor][i]) io_leds = i; } else { /* indicate active scores */ for (i = 0; i < 20; i++) if (E_NULL NE scores[i]) io_leds = i; } return; case PK_LIBR: for (i = 0; i < 20; i++) if (E_NULL NE scores[i]) io_leds = i; return; } } /* ============================================================================= localkb() -- local keyboard processing ============================================================================= */ void localkb(int16_t sig) { register int16_t i, trg, lclkey, key, vel; register struct s_entry *ep; int16_t val, disptag; key = sig - 1; switch (pkctrl) { case PK_PFRM: /* performance */ lclkey = lclkmap[key]; trg = ((LCL_PRT - 1) << 11) + lclkey; if (astat) { /* key down */ prstab[trg] = SM_SCALE(aval); if (keystat[key] EQ 0) { /* initial key closure */ trgtab[trg] |= M_KSTATE; veltab[trg] = vel = SM_SCALE(64); keystat[key] = 1; stmproc(trg); /* process as a patch stimulus */ if (editsw) { /* edit mode */ execkey(trg, tuntab[lclkey], curvce, 0); } else { /* normal mode */ for (i = 0; i < 12; i++) if ((grp2prt[i][0] EQ LCL_PRT) AND (grp2prt[i][1] EQ 1)) { asgvce(i, LCL_PRT - 1, 0, lclkey, vel); ne_bgn(i, lclkey, vel); } } } else { /* pressure change */ val = SM_SCALE(aval); for (i = 0; i < 12; i++) { if ((grp2prt[i][0] EQ LCL_PRT) AND (grp2prt[i][1] EQ 1)) { if (newsv(i, SM_KPRS, val)) { if (recsw AND grpstat[i] AND (2 EQ (ancmsw ? varmode[5][i] : grpmode[i]))) { if (E_NULL NE (ep = e_alc(E_SIZE2))) { ep->e_time = t_cur; ep->e_type = EV_ANVL; ep->e_data1 = 0x0050 | i; ep->e_dn = (struct s_entry *)((int32_t)val << 16); p_cur = e_ins(ep, ep_adj(p_cur, 0, t_cur))->e_fwd; ctrsw = TRUE; se_disp(ep, D_FWD, gdstbc, 1); ctrsw = FALSE; } } else if ((angroup - 1) EQ i) { dsanval(5); } } } } } } else { /* key release */ keystat[key] = 0; trgtab[trg] &= ~M_KSTATE; prstab[trg] = 0; if (NOT trgtab[trg]) { for (i = 0; i < 12; i++) { if (vce2trg[i] EQ trg) { vce2trg[i] = -1; procpfl(trg); } if ((grp2prt[i][0] EQ LCL_PRT) AND (grp2prt[i][1] EQ 1)) ne_end(trg, i); } stmproc(0x8000 | trg); /* process as a patch stimulus */ } } return; case PK_NOTE: /* note entry - interval and weight selection */ if (astat) { /* key down */ if (keystat[key] EQ 0) { /* closure */ keystat[key] = 1; if (key EQ 0) { /* delete last entry */ disptag = FALSE; while (lstendc-- > 0) { /* note ends */ ep = lstends[lstendc]; lstends[lstendc] = (struct n_entry *)NULL; if ((struct n_entry *)NULL EQ ep) continue; if (ep EQ p_bak) p_bak = p_bak->e_bak; if (ep EQ p_ctr) p_ctr = p_ctr->e_bak; if (ep EQ p_cur) p_cur = p_cur->e_bak; if (ep EQ p_fwd) p_fwd = p_fwd->e_bak; e_del(e_rmv(ep)); disptag = TRUE; } lstendc = 0; while (lstbgnc-- > 0) { /* note begins */ ep = lstbgns[lstbgnc]; lstbgns[lstbgnc] = (struct n_entry *)NULL; if ((struct n_entry *)NULL EQ ep) continue; if (ep EQ p_bak) p_bak = p_bak->e_bak; if (ep EQ p_ctr) p_ctr = p_ctr->e_bak; if (ep EQ p_cur) p_cur = p_cur->e_bak; if (ep EQ p_fwd) p_fwd = p_fwd->e_bak; e_del(e_rmv(ep)); disptag = TRUE; } lstbgnc = 0; lstflag = FALSE; if (disptag) { if ((fc_val - stepfrm[3][stepint]) GE 0L) fc_val -= stepfrm[3][stepint]; sc_refr(fc_val); } } else if (key EQ 1) { /* enable step */ stepenb = NOT stepenb; setleds(); } else if (key EQ 2) { /* insert bar */ if (recsw) { if (E_NULL NE (ep = e_alc(E_SIZE1))) { ep->e_type = EV_BAR; ep->e_time = t_cur; p_cur = e_ins(ep, ep_adj(p_cur, 1, t_cur)->e_bak)->e_fwd; sc_refr(fc_val); } } } else if (key EQ 3) { /* insert a rest */ if ((fc_val + stepfrm[3][stepint]) < 0x00FFFFFEL) fc_val += stepfrm[3][stepint]; } else if ((key GE 4) AND (key LE 6)) { stepwgt = 6 - key; /* select weight */ setleds(); } else if ((key GE 7) AND (key LE 23)) { stepint = key - 7; /* select interval */ setleds(); } } } else { /* key up */ keystat[key] = 0; } return; case PK_INST: /* instrument selection */ if (astat) { if (keystat[key] EQ 0) { keystat[key] = 1; if (key GE 20) return; if (ismode EQ IS_LORC) selins(key + 1); else selins(key + 21); } } else { keystat[key] = 0; } return; case PK_ASGN: /* assignment table selection */ if (astat) { if (keystat[key] EQ 0) { keystat[key] = 1; if ((asmode EQ 5) AND (key GE 19)) return; else if (key GE 20) return; selasg(key + 1 + ((asmode - 1) * 20)); } } else { keystat[key] = 0; } return; case PK_GOTO: /* go to */ if (astat) { if (keystat[key] EQ 0) { keystat[key] = 1; if (key GE 20) /* limit key range */ return; if (gomode EQ GO_SECT) { /* section */ if (E_NULL NE (ep = seclist[curscor][key])) { if (insmode) { icancel(); dsimode(); } sc_goto(fc_val = ep->e_time); pkctrl = oldpk; gomode = GO_NULL; GLCcurs(G_ON); GLCtext(0, 31, "Go To"); point = GLCplot; lseg(GOTO_XL, GOTO_Y, GOTO_XR, GOTO_Y, 0); GLCcurs(G_OFF); setleds(); return; } } else { /* score */ if (E_NULL NE scores[key]) { if (insmode) { icancel(); dsimode(); } selscor(key); pkctrl = oldpk; gomode = GO_NULL; GLCcurs(G_ON); GLCtext(0, 31, "Go To"); point = GLCplot; lseg(GOTO_XL, GOTO_Y, GOTO_XR, GOTO_Y, 0); GLCcurs(G_OFF); setleds(); return; } } } } else { keystat[key] = 0; } return; case PK_LIBR: if (astat) { if (keystat[key] EQ 0) { keystat[key] = 1; if ((-1 NE lksel) AND (key < 20)) { ldpass = 2; for (i = 0; i < N_SCORES; i++) if (ldmap[i] EQ key) { ldmap[i] = -1; dpy_scr(ldbox[1][4], i); } ldmap[lksel] = key; dpy_scr(ldbox[1][4], lksel); lksel = -1; } } } else { keystat[key] = 0; } return; case PK_NGRP: if (astat) { if (keystat[key] EQ 0) { keystat[key] = 1; if ((-1 NE gtmsel) AND (key < 12)) { for (i = 0; i < 12; i++) if (grptmap[i] EQ key) { grptmap[i] = -1; dsgtme(i); } grptmap[gtmsel] = key; dsgtmn(gtmsel, FALSE); dsgtme(gtmsel); gtmsel = -1; } } } else { keystat[key] = 0; } return; case PK_LOAD: if (astat) keystat[key] = 1; else keystat[key] = 0; return; } }