Codebase list abcmidi / upstream/20160505
Imported Upstream version 20160505 Ross Gammon 7 years ago
4 changed file(s) with 154 addition(s) and 130 deletion(s). Raw diff Collapse all Expand all
0 2016 March 03
0 2016 May 05
11
1211212112 this file. (Also readme.txt, abcguide.txt, genmidi.c, toabc.c, abc2midi.1,
1211312113 crack.c, midi2abc.1, history.txt, coding.txt). Thank you Ross Gammon.
1211412114
12115
12116 May 05 2016
12117
12118 Abc2abc: transposition of key modifier bug.
12119
12120 The following example illustrates a problem with the code
12121 to transpose the key modifiers.
12122
12123 X: 25
12124 T: C Natural, with a D sharp added to the key signature
12125 M: 2/4
12126 L: 1/8
12127 K: C ^d
12128 | cdef | gabc |
12129
12130 Transposing this up by one tone (-t 2), this becomes
12131
12132 X:25
12133 T:C Natural, with a D sharp added to the key signature
12134 M:2/4
12135 L:1/8
12136 K:Dmaj =F
12137 | defg | abc'd |
12138
12139 The key modifier was transposed to F natural instead of
12140 e sharp (chromatically identical notes) but as a result
12141 e was not upgraded to e# and the f# became f natural.
12142
12143 The fix was a completely replacement of the code written
12144 in February 21 2011 (see above) in toabc.c. 130 lines of
12145 code was eliminated and a new function transpose_note()
12146 was introduced. The new function borrowed the transposition
12147 code from event_note, so that key modifiers were transposed
12148 the same way the notes in the music body are modified.
12149
12150
11
22 midi2abc version 2.99 October 18 2015
33 abc2midi version 3.88 February 08 2015
4 abc2abc version 1.85 March 03 2016
4 abc2abc version 1.86 May 05 2016
55 yaps version 1.63 November 15 2015
66 abcmatch version 1.70 November 15 2015
77 midicopy version 1.22 November 15 2015
+116
-128
toabc.c less more
2020
2121 /* back-end for outputting (possibly modified) abc */
2222
23 #define VERSION "1.85 March 03 2016 abc2abc"
23 #define VERSION "1.86 May 05 2016 abc2abc"
2424
2525 /* for Microsoft Visual C++ 6.0 or higher */
2626 #ifdef _MSC_VER
144144 void printpitch(int);
145145 void setup_sharps_flats (int sf);
146146 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);
147149
148150
149151 static int purgespace(p)
14471449
14481450 */
14491451
1450 int debugsemi = 0; /* set to one if debugging ! [SS] 2011-02-21 */
1451 int semiseq[12];
1452 int semiseqbase[12];
14531452
14541453 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
14671456
14681457 int modmap_not_empty (char* modmap) {
14691458 int i;
14721461 return 0;
14731462 }
14741463
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 }
15851464
15861465 /* end of [SS] 2011-02-15 */
1466
15871467
15881468 void event_key(sharps, s, modeindex, modmap, modmul, modmicrotone, gotkey, gotclef, clefname,
15891469 octave, xtranspose, gotoctave, gottranspose, explict)
16011481 static char* keys[12] = {"Db", "Ab", "Eb", "Bb", "F", "C",
16021482 "G", "D", "A", "E", "B", "F#"};
16031483 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
16041492
16051493 if (!xinbody && passthru) {print_inputline_nolinefeed(); /* [SS] 2011-06-10 */
16061494 if ((xinhead) && (!xinbody)) {
16291517 };
16301518 setmap(newkey, newtable); /* used by event_note1 */
16311519 new_key_number = (int) keys[newkey+5][0] - (int) 'A';
1520
1521 /* [SS] 2016-05-05 begin */
1522 trans_string[0] = 0;
16321523 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, &note, &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 */
16351558
16361559 };
16371560 emit_string("K:");
22242147 }
22252148
22262149
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
22272215
22282216 void event_note1(decorators, xaccidental, xmult, xnote, xoctave, n, m)
22292217 int decorators[DECSIZE];