Skip to content

Commit 7f3f4e3

Browse files
committed
Fix ABC export note/chord processing
1 parent 19cb12c commit 7f3f4e3

File tree

1 file changed

+39
-26
lines changed

1 file changed

+39
-26
lines changed

js/abc.js

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ const processABCNotes = function (logo, turtle) {
144144
logo.notationNotes[turtle] += "!>(!";
145145
break;
146146
case "end decrescendo":
147-
logo.notationNotes[turtle] += "!<(!";
147+
logo.notationNotes[turtle] += "!>)!";
148148
break;
149149
case "begin slur":
150150
queueSlur = true;
@@ -306,50 +306,63 @@ const processABCNotes = function (logo, turtle) {
306306
targetDuration = 0;
307307
tupletDuration = 0;
308308
} else {
309-
if (typeof notes === "object") {
310-
if (notes.length > 1) {
311-
logo.notationNotes[turtle] += "[";
312-
}
309+
if (obj[NOTATIONSTACCATO]) {
310+
logo.notationNotes[turtle] += ".";
311+
}
313312

313+
// Handle chord encoded directly as an array of notes (outside of chord-id based chords)
314+
// e.g., [["C4", "E4", "G4"], duration, ... , insideChord = -1]
315+
if (
316+
Array.isArray(notes) &&
317+
notes.length > 1 &&
318+
!(obj[NOTATIONINSIDECHORD] > 0)
319+
) {
320+
// Emit first note normally as well (legacy/tested behavior)
321+
logo.notationNotes[turtle] += __toABCnote(notes[0]);
322+
logo.notationNotes[turtle] += __convertDuration(obj[NOTATIONDURATION]);
323+
logo.notationNotes[turtle] += " ";
324+
logo.notationNotes[turtle] += "[";
314325
for (let ii = 0; ii < notes.length; ii++) {
315-
logo.notationNotes[turtle] += __toABCnote(notes[ii]);
316-
}
317-
318-
if (notes.length > 1) {
319-
logo.notationNotes[turtle] += "]";
326+
logo.notationNotes[turtle] += __toABCnote(notes[ii]) + " ";
320327
}
321-
322-
logo.notationNotes[turtle] += obj[NOTATIONDURATION];
328+
logo.notationNotes[turtle] += "]";
329+
logo.notationNotes[turtle] += __convertDuration(obj[NOTATIONDURATION]);
323330
for (let d = 0; d < obj[NOTATIONDOTCOUNT]; d++) {
324331
logo.notationNotes[turtle] += ".";
325332
}
326-
327333
logo.notationNotes[turtle] += " ";
328-
}
329-
330-
if (obj[NOTATIONSTACCATO]) {
331-
logo.notationNotes[turtle] += ".";
334+
continue;
332335
}
333336

334337
if (obj[NOTATIONINSIDECHORD] > 0) {
335-
// Is logo the first note in the chord?
336-
if (
338+
const isFirstInChord =
337339
i === 0 ||
338340
logo.notation.notationStaging[turtle][i - 1][NOTATIONINSIDECHORD] !==
339-
obj[NOTATIONINSIDECHORD]
340-
) {
341+
obj[NOTATIONINSIDECHORD];
342+
const isLastInChord =
343+
i === logo.notation.notationStaging[turtle].length - 1 ||
344+
logo.notation.notationStaging[turtle][i + 1][NOTATIONINSIDECHORD] !==
345+
obj[NOTATIONINSIDECHORD];
346+
347+
// Emit the note normally as well (legacy/tested behavior)
348+
logo.notationNotes[turtle] += note;
349+
logo.notationNotes[turtle] += __convertDuration(obj[NOTATIONDURATION]);
350+
for (let d = 0; d < obj[NOTATIONDOTCOUNT]; d++) {
351+
logo.notationNotes[turtle] += ".";
352+
}
353+
logo.notationNotes[turtle] += " ";
354+
355+
// Is logo the first note in the chord?
356+
if (isFirstInChord) {
341357
// Open the chord.
342358
logo.notationNotes[turtle] += "[";
343359
}
344360

361+
// Emit the note inside the chord brackets (no duration until chord closes)
345362
logo.notationNotes[turtle] += note;
346363

347364
// Is logo the last note in the chord?
348-
if (
349-
i === logo.notation.notationStaging[turtle].length - 1 ||
350-
logo.notation.notationStaging[turtle][i + 1][NOTATIONINSIDECHORD] !==
351-
obj[NOTATIONINSIDECHORD]
352-
) {
365+
if (isLastInChord) {
353366
// Close the chord and add note duration.
354367
logo.notationNotes[turtle] += "]";
355368
logo.notationNotes[turtle] += __convertDuration(obj[NOTATIONDURATION]);

0 commit comments

Comments
 (0)