20 | 20 |
|
21 | 21 |
/* back-end for outputting (possibly modified) abc */
|
22 | 22 |
|
23 | |
#define VERSION "1.85 March 03 2016 abc2abc"
|
|
23 |
#define VERSION "1.86 May 05 2016 abc2abc"
|
24 | 24 |
|
25 | 25 |
/* for Microsoft Visual C++ 6.0 or higher */
|
26 | 26 |
#ifdef _MSC_VER
|
|
144 | 144 |
void printpitch(int);
|
145 | 145 |
void setup_sharps_flats (int sf);
|
146 | 146 |
int pitchof(char note,int accidental,int mult,int octave);
|
|
147 |
void transpose_note(char xaccidental,int xmult,char xnote,int xoctave,int transpose,
|
|
148 |
char* accidental, int* mult, char* note, int* octave);
|
147 | 149 |
|
148 | 150 |
|
149 | 151 |
static int purgespace(p)
|
|
1447 | 1449 |
|
1448 | 1450 |
*/
|
1449 | 1451 |
|
1450 | |
int debugsemi = 0; /* set to one if debugging ! [SS] 2011-02-21 */
|
1451 | |
int semiseq[12];
|
1452 | |
int semiseqbase[12];
|
1453 | 1452 |
|
1454 | 1453 |
char modmap[7];
|
1455 | |
int convertnote[7] = {0,2,3,5,7,8,10};
|
1456 | |
/* needed to convert modmap to semiseq representation */
|
1457 | |
|
1458 | |
int sfpos[7] = {8, 3, 10, 5, 0, 7, 2}; /* FCGDAEB */
|
1459 | |
int sfneg[7] = {2, 7, 0, 5, 10, 3, 8};
|
1460 | |
/* needed to convert the key signature to semiseq representation */
|
1461 | |
|
1462 | |
char *semisharp[12] = {"=A", "^A", "=B", "=C", "^C", "D",
|
1463 | |
"^D", "=E", "=F", "^F", "=G", "^G"};
|
1464 | |
char *semiflat[12] = {"=A", "_B", "=B", "=C", "_D", "=D",
|
1465 | |
"_E", "=E", "=F", "_G", "=G", "_A"};
|
1466 | |
/* needed to convert the semiseq representation to the notes */
|
|
1454 |
|
|
1455 |
|
1467 | 1456 |
|
1468 | 1457 |
int modmap_not_empty (char* modmap) {
|
1469 | 1458 |
int i;
|
|
1472 | 1461 |
return 0;
|
1473 | 1462 |
}
|
1474 | 1463 |
|
1475 | |
void print_semiseq();
|
1476 | |
|
1477 | |
void sf2semi (int sf) {
|
1478 | |
/* apply key signature to semiseq */
|
1479 | |
int i;
|
1480 | |
for (i=0;i<12;i++) semiseqbase[i]=0;
|
1481 | |
for (i=0;i<7;i++) semiseqbase[sfpos[i]] = 1;
|
1482 | |
if (sf == 0) return;
|
1483 | |
if (sf > 0) {for (i=0;i<sf;i++) {
|
1484 | |
semiseqbase[sfpos[i]] = 0;
|
1485 | |
semiseqbase[sfpos[i]+1] = 1;
|
1486 | |
}
|
1487 | |
return;
|
1488 | |
} else {
|
1489 | |
sf = -sf;
|
1490 | |
for (i=0;i<sf;i++) {
|
1491 | |
semiseqbase[sfneg[i]] = 0;
|
1492 | |
semiseqbase[(sfneg[i] + 11) % 12] = 1;
|
1493 | |
}
|
1494 | |
}
|
1495 | |
}
|
1496 | |
|
1497 | |
void note2semi (char *modmap) {
|
1498 | |
/* to convert modmap to semiseq representation */
|
1499 | |
int i;
|
1500 | |
int semi;
|
1501 | |
for (i=0;i<8;i++) {
|
1502 | |
semi = convertnote[i];
|
1503 | |
switch (modmap[i]) {
|
1504 | |
case ' ':
|
1505 | |
break;
|
1506 | |
case '=':
|
1507 | |
semiseq[semi] = 1;
|
1508 | |
if (semiseq[(semi+1) % 12]) semiseq[(semi+1) % 12] = 0;
|
1509 | |
else semiseq[(semi+11) % 12] = 0;
|
1510 | |
break;
|
1511 | |
|
1512 | |
case '^':
|
1513 | |
semiseq[semi] = 0;
|
1514 | |
semiseq[semi+1] = 1;
|
1515 | |
break;
|
1516 | |
case '_':
|
1517 | |
semiseq[semi] = 0;
|
1518 | |
semiseq[(semi+11) % 12] = 1;
|
1519 | |
break;
|
1520 | |
}
|
1521 | |
}
|
1522 | |
}
|
1523 | |
|
1524 | |
void transpose_semiseq (shift)
|
1525 | |
int shift;
|
1526 | |
{
|
1527 | |
int i,j;
|
1528 | |
int newseq[12];
|
1529 | |
for (i=0;i<12;i++) {
|
1530 | |
j = (i-shift+12)%12;
|
1531 | |
newseq[i] = semiseq[j];
|
1532 | |
}
|
1533 | |
for (i=0;i<12;i++) semiseq[i]=newseq[i];
|
1534 | |
}
|
1535 | |
|
1536 | |
void print_semiseq() {
|
1537 | |
int i;
|
1538 | |
if (!debugsemi) return; /* [SS] 2011-02-11 */
|
1539 | |
printf(" A B C D E F G\n");
|
1540 | |
for (i=0;i<12;i++) printf(" %d",semiseq[i]);
|
1541 | |
printf("\n");
|
1542 | |
}
|
1543 | |
|
1544 | |
char trans_string[20];
|
1545 | |
|
1546 | |
char *pickup_accidentals_for (int sf, int explict) {
|
1547 | |
/* remove non-accidentals */
|
1548 | |
int i;
|
1549 | |
if (explict) sf2semi(0);
|
1550 | |
else sf2semi(sf);
|
1551 | |
/* [SS] 2011-02-20 */
|
1552 | |
if (debugsemi) {
|
1553 | |
for (i=0;i<12;i++) printf(" %d",semiseqbase[i]);
|
1554 | |
printf(" semiseqbase\n");
|
1555 | |
}
|
1556 | |
|
1557 | |
/* everything left are accidentals */
|
1558 | |
trans_string[0] = ' ';
|
1559 | |
for (i=0;i<12;i++)
|
1560 | |
if(semiseq[i] != semiseqbase[i] && semiseqbase[i] == 0) {
|
1561 | |
if (sf <0) strcat(trans_string,semiflat[i]);
|
1562 | |
else strcat(trans_string,semisharp[i]);
|
1563 | |
}
|
1564 | |
return trans_string;
|
1565 | |
};
|
1566 | |
|
1567 | |
char *transpose_modmap(int oldkeysigsf, int semitranspose, char* modmap, int explict) {
|
1568 | |
int newkeysigsf;
|
1569 | |
int i;
|
1570 | |
newkeysigsf = (oldkeysigsf + 7*semitranspose)%12;
|
1571 | |
if (newkeysigsf > 6) newkeysigsf = newkeysigsf -12;
|
1572 | |
if (newkeysigsf <-5) newkeysigsf = newkeysigsf +12;
|
1573 | |
if (debugsemi) printf("newkeysigsf= %d\n",newkeysigsf);
|
1574 | |
sf2semi(oldkeysigsf);
|
1575 | |
for (i=0;i<12;i++) semiseq[i] = semiseqbase[i];
|
1576 | |
print_semiseq();
|
1577 | |
note2semi(modmap);
|
1578 | |
if (debugsemi) printf("applying note2semi\n");
|
1579 | |
print_semiseq();
|
1580 | |
transpose_semiseq(semitranspose);
|
1581 | |
if (debugsemi) printf("applying transpose %d\n",semitranspose);
|
1582 | |
print_semiseq();
|
1583 | |
return pickup_accidentals_for(newkeysigsf,explict);
|
1584 | |
}
|
1585 | 1464 |
|
1586 | 1465 |
/* end of [SS] 2011-02-15 */
|
|
1466 |
|
1587 | 1467 |
|
1588 | 1468 |
void event_key(sharps, s, modeindex, modmap, modmul, modmicrotone, gotkey, gotclef, clefname,
|
1589 | 1469 |
octave, xtranspose, gotoctave, gottranspose, explict)
|
|
1601 | 1481 |
static char* keys[12] = {"Db", "Ab", "Eb", "Bb", "F", "C",
|
1602 | 1482 |
"G", "D", "A", "E", "B", "F#"};
|
1603 | 1483 |
char signature[10];
|
|
1484 |
|
|
1485 |
/* [SS] 2016-05-05 */
|
|
1486 |
int i,k,slength;
|
|
1487 |
int xmult,xoctave;
|
|
1488 |
int mult;
|
|
1489 |
char accidental,note,xnote;
|
|
1490 |
char trans_string[32];
|
|
1491 |
|
1604 | 1492 |
|
1605 | 1493 |
if (!xinbody && passthru) {print_inputline_nolinefeed(); /* [SS] 2011-06-10 */
|
1606 | 1494 |
if ((xinhead) && (!xinbody)) {
|
|
1629 | 1517 |
};
|
1630 | 1518 |
setmap(newkey, newtable); /* used by event_note1 */
|
1631 | 1519 |
new_key_number = (int) keys[newkey+5][0] - (int) 'A';
|
|
1520 |
|
|
1521 |
/* [SS] 2016-05-05 begin */
|
|
1522 |
trans_string[0] = 0;
|
1632 | 1523 |
if (modmap_not_empty (modmap)) {
|
1633 | |
transpose_modmap(sharps,transpose,modmap,explict);
|
1634 | |
}
|
|
1524 |
k=0;
|
|
1525 |
trans_string[k++] = ' ';
|
|
1526 |
xmult = 1;
|
|
1527 |
xoctave = 1;
|
|
1528 |
slength = strlen(s);
|
|
1529 |
/*printf("length of s = %d\n",slength);*/
|
|
1530 |
for (i = 0; i<slength;i++) {
|
|
1531 |
switch (*(s+i)) {
|
|
1532 |
case '^':
|
|
1533 |
case '_':
|
|
1534 |
case '=':
|
|
1535 |
/*printf("%c%c\n",*(s+i),*(s+i+1)); */
|
|
1536 |
xnote = *(s+i+1);
|
|
1537 |
if (xnote >= 'A' && xnote <= 'G') {
|
|
1538 |
xnote = xnote + 'a' - 'A';
|
|
1539 |
xoctave = 0;
|
|
1540 |
}
|
|
1541 |
if (xnote < 'a' || xnote > 'g') {
|
|
1542 |
event_error ("expecting A-G or a-g after accidental in key modifier");
|
|
1543 |
break;
|
|
1544 |
}
|
|
1545 |
transpose_note(*(s+i),xmult, xnote, xoctave, transpose,
|
|
1546 |
&accidental, &mult, ¬e, &octave);
|
|
1547 |
/*printf("%c%c\n",accidental,note); */
|
|
1548 |
trans_string[k++] = accidental;
|
|
1549 |
if (mult == 2)
|
|
1550 |
trans_string[k++] = accidental;
|
|
1551 |
trans_string[k++] = note;
|
|
1552 |
break;
|
|
1553 |
}
|
|
1554 |
}
|
|
1555 |
trans_string[k] =0;
|
|
1556 |
}
|
|
1557 |
/* [SS] 2016-05-05 end */
|
1635 | 1558 |
|
1636 | 1559 |
};
|
1637 | 1560 |
emit_string("K:");
|
|
2224 | 2147 |
}
|
2225 | 2148 |
|
2226 | 2149 |
|
|
2150 |
/* [SS] 2016-05-05 */
|
|
2151 |
/* This function is used to transpose the key signature modifiers. */
|
|
2152 |
/* The code was borrowed from event_note1(). */
|
|
2153 |
void transpose_note(xaccidental,xmult, xnote, xoctave, transpose,
|
|
2154 |
accidental, mult, note, octave)
|
|
2155 |
char xaccidental, xnote;
|
|
2156 |
int xoctave, transpose;
|
|
2157 |
char *accidental, *note;
|
|
2158 |
int *octave, *mult;
|
|
2159 |
{
|
|
2160 |
*mult = 0;
|
|
2161 |
if (transpose == 0 || drumchan) {
|
|
2162 |
*accidental = xaccidental;
|
|
2163 |
*mult = xmult;
|
|
2164 |
*note = xnote;
|
|
2165 |
*octave = xoctave;
|
|
2166 |
} else {
|
|
2167 |
int val, newval;
|
|
2168 |
int acc;
|
|
2169 |
char *anoctave = "cdefgab";
|
|
2170 |
|
|
2171 |
*octave = xoctave;
|
|
2172 |
val = (int) ((long) strchr(anoctave, xnote) - (long) anoctave);
|
|
2173 |
newval = val + lines;
|
|
2174 |
*octave = *octave + (newval/7);
|
|
2175 |
newval = newval % 7;
|
|
2176 |
if (newval < 0) {
|
|
2177 |
newval = newval + 7;
|
|
2178 |
*octave = *octave - 1;
|
|
2179 |
};
|
|
2180 |
*note = *(anoctave+newval);
|
|
2181 |
if (xaccidental == ' ') {
|
|
2182 |
*accidental = ' ';
|
|
2183 |
} else {
|
|
2184 |
switch (xaccidental) {
|
|
2185 |
case '_':
|
|
2186 |
acc = -xmult;
|
|
2187 |
break;
|
|
2188 |
case '^':
|
|
2189 |
acc = xmult;
|
|
2190 |
break;
|
|
2191 |
case '=':
|
|
2192 |
acc = 0;
|
|
2193 |
break;
|
|
2194 |
default:
|
|
2195 |
event_error("Internal error");
|
|
2196 |
};
|
|
2197 |
acc = acc - oldtable[(int)anoctave[val] - (int)'a'] +
|
|
2198 |
newtable[(int)anoctave[newval] - (int)'a'];
|
|
2199 |
*mult = 1;
|
|
2200 |
*accidental = '=';
|
|
2201 |
if (acc > 0) {
|
|
2202 |
*accidental = '^';
|
|
2203 |
*mult = acc;
|
|
2204 |
};
|
|
2205 |
if (acc < 0) {
|
|
2206 |
*accidental = '_';
|
|
2207 |
*mult = -acc;
|
|
2208 |
};
|
|
2209 |
};
|
|
2210 |
}
|
|
2211 |
}
|
|
2212 |
|
|
2213 |
|
|
2214 |
|
2227 | 2215 |
|
2228 | 2216 |
void event_note1(decorators, xaccidental, xmult, xnote, xoctave, n, m)
|
2229 | 2217 |
int decorators[DECSIZE];
|