📄 seqread.c
字号:
desc = &HASHENTRY(lookup(symbol)); if (!desc->symb_type) { fieldx = 0; fferror("Function not defined"); } else if (desc->symb_type != fn_symb_type) { fieldx = 0; gprintf(TRANS, "desc->symb_type is %d\n", desc->symb_type); fferror("This is not a function"); } else { error_flag = FALSE; fieldx++; /* skip over paren */ for (i = 0; i < SEQ_MAX_PARMS; i++) value[i] = 0; i = 0; /* note that no params "()" is legal */ while (i < SEQ_MAX_PARMS && token[fieldx] != ')' && parseparm(&value[i])) { i++; if (token[fieldx] == ',') { fieldx++; } else if (token[fieldx] != ')') { fferror("Unexpected character"); error_flag = TRUE; break; } } fieldx++; if (i > SEQ_MAX_PARMS) fferror("Too many parameters"); } while (TRUE) { linex += scan(); if (nullstring(token)) { break; } switch (token[0]) { case 'T': fieldx = 1; dotime(); break; case 'V': fieldx = 1; dovoice(); break; case 'N': fieldx = 1; donextdur(); break; default: fferror("Unexpected character"); } } if (!error_flag) insert_call(the_score, seqround(thetime), lineno, voice, desc->ptr.routine, value, i); /* advance the time only if an N field was given */ if (ndurp) thetime += ntime; } }}/* doclock -- insert a clock command *//* * derivation: if there is no previous clock running, then start the * clock on time. Otherwise, start the clock half a tick early. * ticksize = (beattime / 24) = ((60sec/tempo)/24) = * ((60000ms/tempo)/24) = (60000/24)/tempo = 2500/tempo */private void doclock(){ int oldticksize = ticksize; ticksize = (2500L << 16) / tempo; insert_clock(the_score, seqround(thetime) - (oldticksize >> 17), lineno, ticksize);}/***************************************************************************** docomment* Effect: parses a comment (*) command****************************************************************************/private void docomment(){ line[linex] = '\n'; /* force end of line to skip comment line */ line[linex+1] = EOS;}/***************************************************************************** doctrl* Inputs:* n: control number* Effect: parses a control (K, M, O, X, or Y) command****************************************************************************/private void doctrl(n)int n;{ ctrlval[n] = (int) scanint(); if (token[fieldx]) { fferror("Only digits expected here"); } else { ctrlflag[n] = TRUE; ctrlflag[0] = TRUE; /* ctrlflag[0] set if any flag is set */ }}private void dodef(){ /* maximum def size is 256 + 9 parms * 2 + 2 = 276 */ unsigned char def[280]; char symbol[100]; int nparms = 0; int nibcount = 0; int data = 0; register char c; linex += scan(); if (!token[0]) fferror("Symbol expected"); else { strcpy(symbol, token); def[0] = def[1] = 0; while (TRUE) { linex += scan1(&line[linex]); c = token[0]; if (!c) { linex--; if (nibcount & 1) { fferror("Expected pairs of hex digits: one missing"); return; } break; } else if (c == ' ' || c == '\t' || c == '\n') continue; else if (isdigit(c)) { data = (data << 4) + (c - '0'); nibcount++; if (!(nibcount & 1)) { if (!def_append(def, nparms, data)) return; data = 0; } } else if ('A' <= c && c <= 'F') { data = (data << 4) + (c - 'A') + 10; nibcount++; if (!(nibcount & 1)) { if (!def_append(def, nparms, data)) return; data = 0; } } else if (c == 'V') { data = data << 4; nibcount++; /* v without a leading nibble is equivalent to 0v: */ if (nibcount & 1) nibcount++; if (!def_append(def, nparms, data)) return; def_parm(def, nparms++, nmacroparms+1); } else if (c == '%') { linex += scan1(&line[linex]); c = token[0]; if (c < '1' || c > ('0' + nmacroparms)) { fferror(parm_expected_error); break; } if (!def_append(def, nparms, 0)) return; def_parm(def, nparms++, c - '0'); } else if (c == '^') { linex += scan1(&line[linex]); c = token[0]; if (c < '1' || c > ('0' + nmacroparms)) { fferror(parm_expected_error); break; } if (!def_append(def, nparms, 0)) return; def_parm(def, nparms++, (c - '0') + nmacroparms + 1); } else { /* something unexpected here -- just exit */ linex--; fferror("Unexpected data"); return; } } insert_def(the_score, symbol, def, (nparms << 1) + def[(nparms << 1) + 1] + 2); }}/***************************************************************************** dodur* Effect: parses a duration (sum of dosymdur and/or doabsdur)* sets symbolic_dur_flag (according to the first addend in mixed arithmetic)** Returns: duration in "precise" units****************************************************************************/private time_type dodur(){ time_type result = 0L; symbolic_dur_flag = TRUE; if (token[fieldx-1] == 'U') { result = doabsdur(); symbolic_dur_flag = FALSE; } else result = dosymdur(); while (token[fieldx] == '+') { fieldx += 2; if (token[fieldx-1] == 'U') result += doabsdur(); else result += dosymdur(); } return scale(result, 100L, rate);}/***************************************************************************** doerror* Effect: parse an unrecognized field by reporting an error****************************************************************************/private void doerror(){ fieldx = 0; fferror("Bad field");}/***************************************************************************** doloud* Effect: parse a loudness (L) command****************************************************************************/private int doloud(){ int i, j; int result; int oldfieldx = fieldx; int newfieldx; char symbol[100]; if (!token[fieldx] || token[fieldx]==')' || token[fieldx]==',') { fferror("L must be followed by loudness indication"); return 100; } if (isdigit(token[fieldx])) { result = (int) scanint(); newfieldx = fieldx; if (token[fieldx] && token[fieldx]!=')' && token[fieldx]!=',') fferror("Digits expected after L"); else if (result > 127) { fieldx = oldfieldx; fferror("Maximum loudness of 127 will be used"); fieldx = newfieldx; result = 127; } else if (result == 0) { fieldx = oldfieldx; fferror("Minimum loudness of 1 will be used"); fieldx = newfieldx; result = 1; } return result; } scansymb(symbol); newfieldx = fieldx; if ((i = strlen(symbol)) > 3 ) { /* maximum is 3, e.g. "ppp" */ fieldx = oldfieldx; fferror("Loudness field too long"); fieldx = newfieldx; return 100; } symbol[i + 1] = '\0'; /* pad short symbols with 0 */ /* e.g. "p\0" -> "p\0\0" */ for (i = 0; i <= 7; i++) { /* loop through possibilities */ for (j = 0; j <= 2; j++) { /* test 3 characters */ if (symbol[j] != loudtable[i].symbol[j]) break; } if (j == 3) { return loudtable[i].value; } } fieldx = oldfieldx; fferror("Bad loudness indication"); fieldx = newfieldx; return 100;}void domacro(){ int control_num; int value; if (isdigit(token[1])) { control_num = (int) scanint(); if (token[fieldx] == '(') { fieldx++; if (!isdigit(token[fieldx])) { fferror("Control value expected"); } else { value = (int) scanint(); if (token[fieldx] != ')') { fferror("Missing close paren"); } else { fieldx++; if (token[fieldx]) fferror("Nothing expected after paren"); else if (macctrlx < nmacroctrl - 1) { macctrlnum[macctrlx] = control_num; macctrlparmx[macctrlx] = value; macctrldef[macctrlx] = NULL; macctrlx++; } else fferror("Too many controls"); } } } else fferror("Missing paren"); } else { def_type def; char symbol[100]; scansymb(symbol); if (fieldx == 1) fferror("Macro name expected"); else if (token[fieldx] != '(') fferror("Open paren expected"); else { fieldx++; def = def_lookup(symbol); if (!def) { fieldx = 1; fferror("Undefined macro"); } else { long val; macctrlnum[macctrlx] = 0; macctrlparmx[macctrlx] = macctrlnextparm; macctrldef[macctrlx] = def; while (token[fieldx] != ')' && parseparm(&val)) { macctrlparms[macctrlnextparm++] = (short) val; macctrlnum[macctrlx]++; if (token[fieldx] == ',') { fieldx++; } else if (token[fieldx] != ')') { fferror("Unexpected character"); break; } } fieldx++; macctrlx++; } } }}/***************************************************************************** donextdur* Effect: parse a next (N) command* Implementation:* The syntax is N followed by a duration, so save dur and use dosymdur()* to parse the duration field.* The form N<digits> is parsed directly with scanint().****************************************************************************/private void donextdur(){ ndurp = TRUE; /* flag that N was given */ if (isdigit(token[fieldx])) { ntime = precise(scanint()); ntime = scale(ntime, (ulong)time_scale, rate); if (token[fieldx]) fferror("Only digits were expected here"); } else { fieldx++; ntime = dodur(); }}/***************************************************************************** dopitch* Effect: parses a pitch command****************************************************************************/private int dopitch(){ int p, octave=0; int octflag = FALSE; /* set if octave is specified */ int oldfieldx = fieldx; p = pitchtable[token[fieldx-1]-'A']; while (TRUE) { if (token[fieldx] == 'S') { /* sharp */ p++; fieldx++; } else if (token[fieldx] == 'N') { /* skip */ fieldx++; } else if (token[fieldx] == 'F') { /* flat */ p--; fieldx++; } else if (isdigit(token[fieldx]) && !octflag) { /* octave */ octave = (int) scanint(); octflag = TRUE; } else break; /* none of the above */ } if (octflag) p = (p-48) + 12 * octave; /* adjust p to given octave */ else { /* adjust p to note nearest the default pitch */ int octdiff = (p + 126 - pitch) / 12; p = p + 120 - (octdiff * 12); } if (p > maxpitch) { /* pitch in range? */ int newfield = fieldx; fieldx = oldfieldx; fferror("Pitch too high"); fieldx = newfield; p = maxpitch; } /* We really should test for end-of-field, but we don't know if we're in a parameter list, so comma may or may not be legal */ return p;}/***************************************************************************** doprogram* Effect: parses a program change (Z) command****************************************************************************/private void doprogram(){ register int program = (int) scanint(); ctrlflag[PROGRAM_CTRL] = ctrlflag[0] = TRUE; if (token[fieldx]) { fferror("Z must be followed by digits only"); } else if (program < minprogram) { fieldx = 1; fferror("Minimum program of 1 will be used"); program = minprogram; } else if (program > maxprogram) { fieldx = 1; fferror("Maximum program of 128 will be used"); program = maxprogram; } ctrlval[PROGRAM_CTRL] = program - 1;}private void doramp(){ int values[2]; time_type stepsize = 100L; /* default 10 per second */ int index = 0; ndurp = FALSE; values[0] = values[1] = 0; while (TRUE) { linex += scan(); fieldx = 1; if (nullstring(token)) { break; } else if (index == 2) { /* must be stepsize in dur syntax */ stepsize = dodur(); } else { int ctrlx = 0; static int ctrl_map[] = { -BEND_CTRL, VOLUME, -TOUCH_CTRL, MODWHEEL }; switch (token[0]) { case 'M': ctrlx++; /* modwheel */ case 'O': ctrlx++; /* aftertouch */ case 'X': ctrlx++; /* volume */ case 'Y': /* pitch bend */ if (index < 2) { macctrlnum[index] = ctrl_map[ctrlx]; macctrlparmx[index] = (int) scanint(); if (token[fieldx]) fferror("Only digits expected here"); macctrldef[index] = NULL; } else fferror("Unexpected control"); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -