abcjs 6.6.2 → 6.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RELEASE.md +41 -0
- package/dist/abcjs-basic-min.js +2 -2
- package/dist/abcjs-basic.js +698 -171
- package/dist/abcjs-basic.js.map +1 -1
- package/dist/abcjs-plugin-min.js +2 -2
- package/package.json +1 -1
- package/src/api/abc_timing_callbacks.js +45 -15
- package/src/parse/abc_parse.js +2 -0
- package/src/parse/abc_parse_header.js +3 -1
- package/src/parse/abc_parse_key_voice.js +35 -0
- package/src/synth/chord-track.js +379 -130
- package/src/synth/create-synth.js +14 -8
- package/src/synth/repeats.js +2 -2
- package/src/write/creation/abstract-engraver.js +5 -4
- package/src/write/creation/create-note-head.js +6 -5
- package/src/write/creation/elements/relative-element.js +3 -0
- package/src/write/draw/absolute.js +6 -0
- package/src/write/draw/print-line.js +1 -2
- package/src/write/draw/print-stem.js +1 -1
- package/src/write/draw/triplet.js +3 -3
- package/src/write/engraver-controller.js +1 -1
- package/src/write/layout/layout.js +90 -0
- package/src/write/layout/set-upper-and-lower-elements.js +18 -2
- package/src/write/layout/to-time-and-staff-based.js +35 -0
- package/src/write/layout/triplet.js +61 -14
- package/src/write/renderer.js +1 -1
- package/types/index.d.ts +133 -34
- package/version.js +1 -1
package/dist/abcjs-basic.js
CHANGED
|
@@ -203,10 +203,6 @@ var TimingCallbacks = function TimingCallbacks(target, params) {
|
|
|
203
203
|
var self = this;
|
|
204
204
|
if (!params) params = {};
|
|
205
205
|
self.qpm = params.qpm ? parseInt(params.qpm, 10) : null;
|
|
206
|
-
if (!self.qpm) {
|
|
207
|
-
var tempo = target.metaText ? target.metaText.tempo : null;
|
|
208
|
-
self.qpm = target.getBpm(tempo);
|
|
209
|
-
}
|
|
210
206
|
self.extraMeasuresAtBeginning = params.extraMeasuresAtBeginning ? parseInt(params.extraMeasuresAtBeginning, 10) : 0;
|
|
211
207
|
self.beatCallback = params.beatCallback; // This is called for each beat.
|
|
212
208
|
self.eventCallback = params.eventCallback; // This is called for each note or rest encountered.
|
|
@@ -216,6 +212,10 @@ var TimingCallbacks = function TimingCallbacks(target, params) {
|
|
|
216
212
|
if (!self.beatSubdivisions) self.beatSubdivisions = 1;
|
|
217
213
|
self.joggerTimer = null;
|
|
218
214
|
self.replaceTarget = function (newTarget) {
|
|
215
|
+
if (!params.qpm) {
|
|
216
|
+
var tempo = newTarget.metaText ? newTarget.metaText.tempo : null;
|
|
217
|
+
self.qpm = newTarget.getBpm(tempo);
|
|
218
|
+
}
|
|
219
219
|
self.noteTimings = newTarget.setTiming(self.qpm, self.extraMeasuresAtBeginning);
|
|
220
220
|
if (newTarget.noteTimings.length === 0) self.noteTimings = newTarget.setTiming(0, 0);
|
|
221
221
|
if (self.lineEndCallback) {
|
|
@@ -442,14 +442,40 @@ var TimingCallbacks = function TimingCallbacks(target, params) {
|
|
|
442
442
|
startTime: self.startTime
|
|
443
443
|
};
|
|
444
444
|
}
|
|
445
|
-
var thisStartTime = self.startTime; // the beat callback can call seek and change the position from beneath us.
|
|
446
|
-
self.beatCallback(self.beatStarts[self.currentBeat].b, self.totalBeats / self.beatSubdivisions, self.lastMoment, position, debugInfo);
|
|
447
|
-
if (thisStartTime !== self.startTime) {
|
|
448
|
-
return timestamp - self.startTime;
|
|
449
|
-
} // else
|
|
450
|
-
// self.currentBeat++;
|
|
451
|
-
}
|
|
452
445
|
|
|
446
|
+
// there is a case where self.beatStarts[self.currentBeat] doesn't exist, but I don't know how. Give more info in that case for better debugging.
|
|
447
|
+
if (self.currentBeat < 0 || self.currentBeat >= self.beatStarts.length || !self.beatStarts[self.currentBeat]) {
|
|
448
|
+
var obj = {
|
|
449
|
+
currentBeat: self.currentBeat,
|
|
450
|
+
beatStartLength: self.beatStarts.length,
|
|
451
|
+
totalBeats: self.totalBeats,
|
|
452
|
+
startTime: self.startTime,
|
|
453
|
+
currentTime: self.currentTime,
|
|
454
|
+
lastMoment: self.lastMoment,
|
|
455
|
+
lastTimestamp: self.lastTimestamp,
|
|
456
|
+
qpm: self.qpm,
|
|
457
|
+
millisecondsPerBeat: self.millisecondsPerBeat,
|
|
458
|
+
beatSubdivisions: self.beatSubdivisions,
|
|
459
|
+
currentEvent: self.currentEvent,
|
|
460
|
+
currentLine: self.currentLine,
|
|
461
|
+
isPaused: self.isPaused,
|
|
462
|
+
isRunning: self.isRunning,
|
|
463
|
+
pausedPercent: self.pausedPercent,
|
|
464
|
+
justUnpaused: self.justUnpaused,
|
|
465
|
+
newSeekPercent: self.newSeekPercent
|
|
466
|
+
};
|
|
467
|
+
setTimeout(function () {
|
|
468
|
+
// throw the error outside of the normal processing so that everything else continues working.
|
|
469
|
+
throw new Error("abcjs-timing-callback error: " + JSON.stringify(obj));
|
|
470
|
+
}, 1);
|
|
471
|
+
} else {
|
|
472
|
+
var thisStartTime = self.startTime; // the beat callback can call seek and change the position from beneath us.
|
|
473
|
+
self.beatCallback(self.beatStarts[self.currentBeat].b, self.totalBeats / self.beatSubdivisions, self.lastMoment, position, debugInfo);
|
|
474
|
+
if (thisStartTime !== self.startTime) {
|
|
475
|
+
return timestamp - self.startTime;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
453
479
|
return null;
|
|
454
480
|
};
|
|
455
481
|
|
|
@@ -3220,6 +3246,8 @@ var Parse = function Parse() {
|
|
|
3220
3246
|
}
|
|
3221
3247
|
strTune = arr.join(" "); //. the split removed two characters, so this puts them back
|
|
3222
3248
|
}
|
|
3249
|
+
// If there is an escaped percent, then temporarily change it so it doesn't affect the processing.
|
|
3250
|
+
strTune = strTune.replace(/\\%/g, "\u200B\uFF05");
|
|
3223
3251
|
// take care of line continuations right away, but keep the same number of characters
|
|
3224
3252
|
strTune = strTune.replace(/\\([ \t]*)(%.*)*\n/g, function (all, backslash, comment) {
|
|
3225
3253
|
var padding = comment ? Array(comment.length + 1).join(' ') : "";
|
|
@@ -5211,7 +5239,7 @@ var ParseHeader = function ParseHeader(tokenizer, warn, multilineVars, tune, tun
|
|
|
5211
5239
|
return [e - i + 1 + ws];
|
|
5212
5240
|
case "[M:":
|
|
5213
5241
|
var meter = this.setMeter(line.substring(i + 3, e));
|
|
5214
|
-
if (tuneBuilder.hasBeginMusic() && meter) tuneBuilder.appendStartingElement('meter', startChar, endChar, meter);else multilineVars.meter = meter;
|
|
5242
|
+
if (startLine && multilineVars.currentVoice && meter) multilineVars.staves[multilineVars.currentVoice.staffNum].meter = meter;else if (tuneBuilder.hasBeginMusic() && meter) tuneBuilder.appendStartingElement('meter', startChar, endChar, meter);else multilineVars.meter = meter;
|
|
5215
5243
|
return [e - i + 1 + ws];
|
|
5216
5244
|
case "[K:":
|
|
5217
5245
|
var result = parseKeyVoice.parseKey(line.substring(i + 3, e), true);
|
|
@@ -5682,8 +5710,17 @@ var parseKeyVoice = {};
|
|
|
5682
5710
|
key.accidentals.forEach(function (k) {
|
|
5683
5711
|
ret.accidentals.push(Object.assign({}, k));
|
|
5684
5712
|
});
|
|
5713
|
+
if (key.explicitAccidentals) {
|
|
5714
|
+
ret.explicitAccidentals = [];
|
|
5715
|
+
key.explicitAccidentals.forEach(function (k) {
|
|
5716
|
+
ret.explicitAccidentals.push(Object.assign({}, k));
|
|
5717
|
+
});
|
|
5718
|
+
}
|
|
5685
5719
|
return ret;
|
|
5686
5720
|
};
|
|
5721
|
+
var setVoiceKey = function setVoiceKey() {
|
|
5722
|
+
if (multilineVars.currentVoice) multilineVars.currentVoice.key = parseKeyVoice.deepCopyKey(multilineVars.key);
|
|
5723
|
+
};
|
|
5687
5724
|
var pitches = {
|
|
5688
5725
|
A: 5,
|
|
5689
5726
|
B: 6,
|
|
@@ -5814,6 +5851,10 @@ var parseKeyVoice = {};
|
|
|
5814
5851
|
};
|
|
5815
5852
|
ret.foundKey = true;
|
|
5816
5853
|
tokens.shift();
|
|
5854
|
+
if (!isInline) {
|
|
5855
|
+
multilineVars.globalKey = parseKeyVoice.deepCopyKey(multilineVars.key);
|
|
5856
|
+
}
|
|
5857
|
+
setVoiceKey();
|
|
5817
5858
|
break;
|
|
5818
5859
|
case 'Hp':
|
|
5819
5860
|
parseDirective.addDirective("bagpipes");
|
|
@@ -5834,6 +5875,10 @@ var parseKeyVoice = {};
|
|
|
5834
5875
|
};
|
|
5835
5876
|
ret.foundKey = true;
|
|
5836
5877
|
tokens.shift();
|
|
5878
|
+
if (!isInline) {
|
|
5879
|
+
multilineVars.globalKey = parseKeyVoice.deepCopyKey(multilineVars.key);
|
|
5880
|
+
}
|
|
5881
|
+
setVoiceKey();
|
|
5837
5882
|
break;
|
|
5838
5883
|
case 'none':
|
|
5839
5884
|
// we got the none key - that's the same as C to us
|
|
@@ -5845,6 +5890,10 @@ var parseKeyVoice = {};
|
|
|
5845
5890
|
};
|
|
5846
5891
|
ret.foundKey = true;
|
|
5847
5892
|
tokens.shift();
|
|
5893
|
+
if (!isInline) {
|
|
5894
|
+
multilineVars.globalKey = parseKeyVoice.deepCopyKey(multilineVars.key);
|
|
5895
|
+
}
|
|
5896
|
+
setVoiceKey();
|
|
5848
5897
|
break;
|
|
5849
5898
|
default:
|
|
5850
5899
|
var retPitch = tokenizer.getKeyPitch(tokens[0].token);
|
|
@@ -5905,6 +5954,10 @@ var parseKeyVoice = {};
|
|
|
5905
5954
|
}
|
|
5906
5955
|
}
|
|
5907
5956
|
}
|
|
5957
|
+
if (!isInline) {
|
|
5958
|
+
multilineVars.globalKey = parseKeyVoice.deepCopyKey(multilineVars.key);
|
|
5959
|
+
}
|
|
5960
|
+
setVoiceKey();
|
|
5908
5961
|
}
|
|
5909
5962
|
break;
|
|
5910
5963
|
}
|
|
@@ -5956,6 +6009,10 @@ var parseKeyVoice = {};
|
|
|
5956
6009
|
}
|
|
5957
6010
|
}
|
|
5958
6011
|
}
|
|
6012
|
+
if (!isInline) {
|
|
6013
|
+
multilineVars.globalKey = parseKeyVoice.deepCopyKey(multilineVars.key);
|
|
6014
|
+
}
|
|
6015
|
+
setVoiceKey();
|
|
5959
6016
|
}
|
|
5960
6017
|
|
|
5961
6018
|
// Now see if any optional parameters are present. They have the form "key=value", except that "clef=" is optional
|
|
@@ -6183,6 +6240,7 @@ var parseKeyVoice = {};
|
|
|
6183
6240
|
}
|
|
6184
6241
|
|
|
6185
6242
|
multilineVars.currentVoice = currentVoice;
|
|
6243
|
+
if (currentVoice.key) multilineVars.key = parseKeyVoice.deepCopyKey(currentVoice.key);else if (multilineVars.globalKey) multilineVars.key = parseKeyVoice.deepCopyKey(multilineVars.globalKey);
|
|
6186
6244
|
return tuneBuilder.setCurrentVoice(currentVoice.staffNum, currentVoice.index, id);
|
|
6187
6245
|
};
|
|
6188
6246
|
parseKeyVoice.parseVoice = function (line, i, e) {
|
|
@@ -14231,9 +14289,13 @@ ChordTrack.prototype.interpretChord = function (name) {
|
|
|
14231
14289
|
};
|
|
14232
14290
|
};
|
|
14233
14291
|
ChordTrack.prototype.chordNotes = function (bass, modifier) {
|
|
14234
|
-
|
|
14292
|
+
// accept either chord spelling
|
|
14293
|
+
modifier = modifier.replace(/♭/g, 'b').replace(/♯/g, '#');
|
|
14294
|
+
var intervals = chordIntervals[modifier];
|
|
14235
14295
|
if (!intervals) {
|
|
14236
|
-
|
|
14296
|
+
// If the chord isn't in our list, we can at least guess
|
|
14297
|
+
// whether it is major or minor.
|
|
14298
|
+
if (modifier.slice(0, 2).toLowerCase() === 'ma' || modifier[0] === 'M') intervals = chordIntervals.M;else if (modifier[0] === 'm' || modifier[0] === '-') intervals = chordIntervals.m;else intervals = chordIntervals.M;
|
|
14237
14299
|
}
|
|
14238
14300
|
bass += 12; // the chord is an octave above the bass note.
|
|
14239
14301
|
|
|
@@ -14396,7 +14458,7 @@ function extractNote(chord, index) {
|
|
|
14396
14458
|
// This creates an arpeggio note no matter how many notes are in the chord - if it runs out of notes it continues in the next octave
|
|
14397
14459
|
var octave = Math.floor(index / chord.chick.length);
|
|
14398
14460
|
var note = chord.chick[index % chord.chick.length];
|
|
14399
|
-
//console.log(chord.chick, {index, octave, note
|
|
14461
|
+
//console.log(chord.chick, {index, octave, note, index % chord.chick.length)
|
|
14400
14462
|
return note + octave * 12;
|
|
14401
14463
|
}
|
|
14402
14464
|
function parseGChord(gchord) {
|
|
@@ -14488,118 +14550,366 @@ ChordTrack.prototype.basses = {
|
|
|
14488
14550
|
'F': 41,
|
|
14489
14551
|
'G': 43
|
|
14490
14552
|
};
|
|
14491
|
-
|
|
14492
|
-
//
|
|
14493
|
-
|
|
14494
|
-
|
|
14495
|
-
|
|
14496
|
-
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
|
|
14505
|
-
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
|
|
14513
|
-
|
|
14514
|
-
|
|
14515
|
-
|
|
14516
|
-
|
|
14517
|
-
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
|
|
14561
|
-
|
|
14562
|
-
|
|
14563
|
-
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
14589
|
-
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14553
|
+
var chordIntervals = {
|
|
14554
|
+
// unusual chords
|
|
14555
|
+
"-addb2": [0, 1, 3, 7],
|
|
14556
|
+
"maddb2": [0, 1, 3, 7],
|
|
14557
|
+
"addb2": [0, 1, 4, 7],
|
|
14558
|
+
"susb2": [0, 1, 7],
|
|
14559
|
+
"-add2": [0, 2, 3, 7],
|
|
14560
|
+
"madd2": [0, 2, 3, 7],
|
|
14561
|
+
"add2": [0, 2, 4, 7],
|
|
14562
|
+
"sus2": [0, 2, 7],
|
|
14563
|
+
"-7sus2": [0, 2, 7, 10],
|
|
14564
|
+
"7sus2": [0, 2, 7, 10],
|
|
14565
|
+
"m7sus2": [0, 2, 7, 10],
|
|
14566
|
+
"min7sus2": [0, 2, 7, 10],
|
|
14567
|
+
"7sus2/9": [0, 2, 7, 10, 14],
|
|
14568
|
+
"add#2": [0, 3, 4, 7],
|
|
14569
|
+
"-add4": [0, 3, 5, 7],
|
|
14570
|
+
"madd4": [0, 3, 5, 7],
|
|
14571
|
+
// diminished chords
|
|
14572
|
+
"dim": [0, 3, 6],
|
|
14573
|
+
"m(b5)": [0, 3, 6],
|
|
14574
|
+
"°": [0, 3, 6],
|
|
14575
|
+
"˚": [0, 3, 6],
|
|
14576
|
+
"-add#4": [0, 3, 6, 7],
|
|
14577
|
+
"madd#4": [0, 3, 6, 7],
|
|
14578
|
+
"dim7": [0, 3, 6, 9],
|
|
14579
|
+
"°7": [0, 3, 6, 9],
|
|
14580
|
+
"˚7": [0, 3, 6, 9],
|
|
14581
|
+
"-7(b5)": [0, 3, 6, 10],
|
|
14582
|
+
"-7b5": [0, 3, 6, 10],
|
|
14583
|
+
"m7(b5)": [0, 3, 6, 10],
|
|
14584
|
+
"m7b5": [0, 3, 6, 10],
|
|
14585
|
+
"ø": [0, 3, 6, 10],
|
|
14586
|
+
"ø7": [0, 3, 6, 10],
|
|
14587
|
+
// minor chords
|
|
14588
|
+
"-": [0, 3, 7],
|
|
14589
|
+
"m": [0, 3, 7],
|
|
14590
|
+
"-(b6)": [0, 3, 7, 8],
|
|
14591
|
+
"-b6": [0, 3, 7, 8],
|
|
14592
|
+
"m(b6)": [0, 3, 7, 8],
|
|
14593
|
+
"mb6": [0, 3, 7, 8],
|
|
14594
|
+
"-6": [0, 3, 7, 9],
|
|
14595
|
+
"m6": [0, 3, 7, 9],
|
|
14596
|
+
"-6(9)": [0, 3, 7, 9, 14],
|
|
14597
|
+
"-6/9": [0, 3, 7, 9, 14],
|
|
14598
|
+
"-69": [0, 3, 7, 9, 14],
|
|
14599
|
+
"m6(9)": [0, 3, 7, 9, 14],
|
|
14600
|
+
"m6/9": [0, 3, 7, 9, 14],
|
|
14601
|
+
"m69": [0, 3, 7, 9, 14],
|
|
14602
|
+
"-7": [0, 3, 7, 10],
|
|
14603
|
+
"m7": [0, 3, 7, 10],
|
|
14604
|
+
"-7(b9)": [0, 3, 7, 10, 13],
|
|
14605
|
+
"-7b9": [0, 3, 7, 10, 13],
|
|
14606
|
+
"-7(9)": [0, 3, 7, 10, 14],
|
|
14607
|
+
"-7/9": [0, 3, 7, 10, 14],
|
|
14608
|
+
"-9": [0, 3, 7, 10, 14],
|
|
14609
|
+
"m7(9)": [0, 3, 7, 10, 14],
|
|
14610
|
+
"m7/9": [0, 3, 7, 10, 14],
|
|
14611
|
+
"m9": [0, 3, 7, 10, 14],
|
|
14612
|
+
"-7(9,11)": [0, 3, 7, 10, 14, 17],
|
|
14613
|
+
"-7/9/11": [0, 3, 7, 10, 14, 17],
|
|
14614
|
+
"m7(9,11)": [0, 3, 7, 10, 14, 17],
|
|
14615
|
+
"m7/9/11": [0, 3, 7, 10, 14, 17],
|
|
14616
|
+
"-13": [0, 3, 7, 10, 14, 17, 21],
|
|
14617
|
+
"-7(9,11,13)": [0, 3, 7, 10, 14, 17, 21],
|
|
14618
|
+
"-7/9/11/13": [0, 3, 7, 10, 14, 17, 21],
|
|
14619
|
+
"m13": [0, 3, 7, 10, 14, 17, 21],
|
|
14620
|
+
"m7(9,11,13)": [0, 3, 7, 10, 14, 17, 21],
|
|
14621
|
+
"m7/9/11/13": [0, 3, 7, 10, 14, 17, 21],
|
|
14622
|
+
"-7(9,13)": [0, 3, 7, 10, 14, 21],
|
|
14623
|
+
"-7/9/13": [0, 3, 7, 10, 14, 21],
|
|
14624
|
+
"m7(9,13)": [0, 3, 7, 10, 14, 21],
|
|
14625
|
+
"m7/9/13": [0, 3, 7, 10, 14, 21],
|
|
14626
|
+
"-7(11)": [0, 3, 7, 10, 17],
|
|
14627
|
+
"-7/11": [0, 3, 7, 10, 17],
|
|
14628
|
+
"m7(11)": [0, 3, 7, 10, 17],
|
|
14629
|
+
"m7/11": [0, 3, 7, 10, 17],
|
|
14630
|
+
"-7(11,13)": [0, 3, 7, 10, 17, 21],
|
|
14631
|
+
"-7/11/13": [0, 3, 7, 10, 17, 21],
|
|
14632
|
+
"m7(11,13)": [0, 3, 7, 10, 17, 21],
|
|
14633
|
+
"m7/11/13": [0, 3, 7, 10, 17, 21],
|
|
14634
|
+
"-(maj7)": [0, 3, 7, 11],
|
|
14635
|
+
"-7M": [0, 3, 7, 11],
|
|
14636
|
+
"-maj7": [0, 3, 7, 11],
|
|
14637
|
+
"-∆7": [0, 3, 7, 11],
|
|
14638
|
+
"m(maj7)": [0, 3, 7, 11],
|
|
14639
|
+
"mM7": [0, 3, 7, 11],
|
|
14640
|
+
"min(maj7)": [0, 3, 7, 11],
|
|
14641
|
+
"-9+7": [0, 3, 7, 11, 13],
|
|
14642
|
+
"-(maj9)": [0, 3, 7, 11, 14],
|
|
14643
|
+
"-7M(9)": [0, 3, 7, 11, 14],
|
|
14644
|
+
"-maj9": [0, 3, 7, 11, 14],
|
|
14645
|
+
"-∆9": [0, 3, 7, 11, 14],
|
|
14646
|
+
"m(maj9)": [0, 3, 7, 11, 14],
|
|
14647
|
+
"mM9": [0, 3, 7, 11, 14],
|
|
14648
|
+
"min(maj9)": [0, 3, 7, 11, 14],
|
|
14649
|
+
"-11": [0, 3, 7, 11, 14, 17],
|
|
14650
|
+
"m11": [0, 3, 7, 11, 14, 17],
|
|
14651
|
+
"-addb9": [0, 3, 7, 13],
|
|
14652
|
+
"maddb9": [0, 3, 7, 13],
|
|
14653
|
+
"-add9": [0, 3, 7, 14],
|
|
14654
|
+
"madd9": [0, 3, 7, 14],
|
|
14655
|
+
"-add11": [0, 3, 7, 17],
|
|
14656
|
+
"madd11": [0, 3, 7, 17],
|
|
14657
|
+
"-add#11": [0, 3, 7, 18],
|
|
14658
|
+
"madd#11": [0, 3, 7, 18],
|
|
14659
|
+
// altered minor chords
|
|
14660
|
+
"-#5": [0, 3, 8],
|
|
14661
|
+
"-(#5)": [0, 3, 8],
|
|
14662
|
+
"m#5": [0, 3, 8],
|
|
14663
|
+
"m(#5)": [0, 3, 8],
|
|
14664
|
+
"-7#5": [0, 3, 8, 10],
|
|
14665
|
+
"-7(#5)": [0, 3, 8, 10],
|
|
14666
|
+
"dim7(b13)": [0, 3, 9, 20],
|
|
14667
|
+
"°7(b13)": [0, 3, 9, 20],
|
|
14668
|
+
"˚7(b13)": [0, 3, 9, 20],
|
|
14669
|
+
// altered major chords
|
|
14670
|
+
"add4": [0, 4, 5, 7],
|
|
14671
|
+
"maj(b5)": [0, 4, 6],
|
|
14672
|
+
"majb5": [0, 4, 6],
|
|
14673
|
+
"add#4": [0, 4, 6, 7],
|
|
14674
|
+
"7(b5)": [0, 4, 6, 10],
|
|
14675
|
+
"7b5": [0, 4, 6, 10],
|
|
14676
|
+
"7(b5,b9)": [0, 4, 6, 10, 13],
|
|
14677
|
+
"7(b9,b5)": [0, 4, 6, 10, 13],
|
|
14678
|
+
"7b5(b9)": [0, 4, 6, 10, 13],
|
|
14679
|
+
"7b9,b5": [0, 4, 6, 10, 13],
|
|
14680
|
+
"7b9b5": [0, 4, 6, 10, 13],
|
|
14681
|
+
"7(b5,b9,b13)": [0, 4, 6, 10, 13, 20],
|
|
14682
|
+
"7/b5/b9/b13": [0, 4, 6, 10, 13, 20],
|
|
14683
|
+
"7b5/b9/b13": [0, 4, 6, 10, 13, 20],
|
|
14684
|
+
"7(b5,b9,13)": [0, 4, 6, 10, 13, 21],
|
|
14685
|
+
"7/b5/b9/13": [0, 4, 6, 10, 13, 21],
|
|
14686
|
+
"7b5/b9/13": [0, 4, 6, 10, 13, 21],
|
|
14687
|
+
"7(9,b5)": [0, 4, 6, 10, 14],
|
|
14688
|
+
"7(b5,9)": [0, 4, 6, 10, 14],
|
|
14689
|
+
"7b5(9)": [0, 4, 6, 10, 14],
|
|
14690
|
+
"9b5": [0, 4, 6, 10, 14],
|
|
14691
|
+
"13(b5)": [0, 4, 6, 10, 14, 21],
|
|
14692
|
+
"13b5": [0, 4, 6, 10, 14, 21],
|
|
14693
|
+
"7(b5,9,13)": [0, 4, 6, 10, 14, 21],
|
|
14694
|
+
"7/b5/9/13": [0, 4, 6, 10, 14, 21],
|
|
14695
|
+
"7b5/9/13": [0, 4, 6, 10, 14, 21],
|
|
14696
|
+
"7#9b5": [0, 4, 6, 10, 15],
|
|
14697
|
+
"7(#9,b5)": [0, 4, 6, 10, 15],
|
|
14698
|
+
"7(b5,#9)": [0, 4, 6, 10, 15],
|
|
14699
|
+
"7b5(#9)": [0, 4, 6, 10, 15],
|
|
14700
|
+
"7(b5,#9,b13)": [0, 4, 6, 10, 15, 20],
|
|
14701
|
+
"7/b5/#9/b13": [0, 4, 6, 10, 15, 20],
|
|
14702
|
+
"7b5/#9/b13": [0, 4, 6, 10, 15, 20],
|
|
14703
|
+
"7(b5,#9,13)": [0, 4, 6, 10, 15, 21],
|
|
14704
|
+
"7/b5/#9/13": [0, 4, 6, 10, 15, 21],
|
|
14705
|
+
"7b5/#9/13": [0, 4, 6, 10, 15, 21],
|
|
14706
|
+
"7(b5,b13)": [0, 4, 6, 10, 20],
|
|
14707
|
+
"7/b5/b13": [0, 4, 6, 10, 20],
|
|
14708
|
+
"7b5/b13": [0, 4, 6, 10, 20],
|
|
14709
|
+
"7(b5,13)": [0, 4, 6, 10, 21],
|
|
14710
|
+
"7/b5/13": [0, 4, 6, 10, 21],
|
|
14711
|
+
"7b5(13)": [0, 4, 6, 10, 21],
|
|
14712
|
+
"7b5/13": [0, 4, 6, 10, 21],
|
|
14713
|
+
"7M(b5)": [0, 4, 6, 11],
|
|
14714
|
+
"maj7(b5)": [0, 4, 6, 11],
|
|
14715
|
+
"maj7b5": [0, 4, 6, 11],
|
|
14716
|
+
"7M(b5,9)": [0, 4, 6, 11, 14],
|
|
14717
|
+
"maj7(b5,9)": [0, 4, 6, 11, 14],
|
|
14718
|
+
"maj7b5/9": [0, 4, 6, 11, 14],
|
|
14719
|
+
"7M(b5,9,13)": [0, 4, 6, 11, 14, 21],
|
|
14720
|
+
"maj7(b5,9,13)": [0, 4, 6, 11, 14, 21],
|
|
14721
|
+
"maj7b5/9/13": [0, 4, 6, 11, 14, 21],
|
|
14722
|
+
"7M(b5,13)": [0, 4, 6, 11, 21],
|
|
14723
|
+
"maj7(b5,13)": [0, 4, 6, 11, 21],
|
|
14724
|
+
"maj7b5/13": [0, 4, 6, 11, 21],
|
|
14725
|
+
// major chords
|
|
14726
|
+
"M": [0, 4, 7],
|
|
14727
|
+
"Δ": [0, 4, 7],
|
|
14728
|
+
"∆": [0, 4, 7],
|
|
14729
|
+
"6": [0, 4, 7, 9],
|
|
14730
|
+
"6(9)": [0, 4, 7, 9, 14],
|
|
14731
|
+
"6/9": [0, 4, 7, 9, 14],
|
|
14732
|
+
"69": [0, 4, 7, 9, 14],
|
|
14733
|
+
"6add9": [0, 4, 7, 9, 14],
|
|
14734
|
+
"6(9,11)": [0, 4, 7, 9, 14, 17],
|
|
14735
|
+
"6/9/11": [0, 4, 7, 9, 14, 17],
|
|
14736
|
+
"6911": [0, 4, 7, 9, 14, 17],
|
|
14737
|
+
"6(9,#11)": [0, 4, 7, 9, 14, 18],
|
|
14738
|
+
"6/9/#11": [0, 4, 7, 9, 14, 18],
|
|
14739
|
+
"69#11": [0, 4, 7, 9, 14, 18],
|
|
14740
|
+
"6(11)": [0, 4, 7, 9, 17],
|
|
14741
|
+
"6/11": [0, 4, 7, 9, 17],
|
|
14742
|
+
"611": [0, 4, 7, 9, 17],
|
|
14743
|
+
"6#11": [0, 4, 7, 9, 18],
|
|
14744
|
+
"6(#11)": [0, 4, 7, 9, 18],
|
|
14745
|
+
"6/#11": [0, 4, 7, 9, 18],
|
|
14746
|
+
"7": [0, 4, 7, 10],
|
|
14747
|
+
"7(b9)": [0, 4, 7, 10, 13],
|
|
14748
|
+
"7b9": [0, 4, 7, 10, 13],
|
|
14749
|
+
"7(9)": [0, 4, 7, 10, 14],
|
|
14750
|
+
"7/9": [0, 4, 7, 10, 14],
|
|
14751
|
+
"9": [0, 4, 7, 10, 14],
|
|
14752
|
+
"7(9,11)": [0, 4, 7, 10, 14, 17],
|
|
14753
|
+
"7/9/11": [0, 4, 7, 10, 14, 17],
|
|
14754
|
+
"7(9,11,13)": [0, 4, 7, 10, 14, 17, 21],
|
|
14755
|
+
"7/9/11/13": [0, 4, 7, 10, 14, 17, 21],
|
|
14756
|
+
"7#11": [0, 4, 7, 10, 14, 18],
|
|
14757
|
+
"7(#11)": [0, 4, 7, 10, 14, 18],
|
|
14758
|
+
"9#11": [0, 4, 7, 10, 14, 18],
|
|
14759
|
+
"9(#11)": [0, 4, 7, 10, 14, 18],
|
|
14760
|
+
"(13)": [0, 4, 7, 10, 14, 21],
|
|
14761
|
+
"13": [0, 4, 7, 10, 14, 21],
|
|
14762
|
+
"7(9,13)": [0, 4, 7, 10, 14, 21],
|
|
14763
|
+
"7/9/13": [0, 4, 7, 10, 14, 21],
|
|
14764
|
+
"9/13": [0, 4, 7, 10, 14, 21],
|
|
14765
|
+
"7#9": [0, 4, 7, 10, 15],
|
|
14766
|
+
"7(#9)": [0, 4, 7, 10, 15],
|
|
14767
|
+
"7(#9,b13)": [0, 4, 7, 10, 15, 20],
|
|
14768
|
+
"7(11)": [0, 4, 7, 10, 17],
|
|
14769
|
+
"7/11": [0, 4, 7, 10, 17],
|
|
14770
|
+
"7(11,13)": [0, 4, 7, 10, 17, 21],
|
|
14771
|
+
"7/11/13": [0, 4, 7, 10, 17, 21],
|
|
14772
|
+
"13#11": [0, 4, 7, 10, 18, 21],
|
|
14773
|
+
"13(#11)": [0, 4, 7, 10, 18, 21],
|
|
14774
|
+
"7(b13)": [0, 4, 7, 10, 20],
|
|
14775
|
+
"7b13": [0, 4, 7, 10, 20],
|
|
14776
|
+
"7(13)": [0, 4, 7, 10, 21],
|
|
14777
|
+
"7/13": [0, 4, 7, 10, 21],
|
|
14778
|
+
"7M": [0, 4, 7, 11],
|
|
14779
|
+
"maj7": [0, 4, 7, 11],
|
|
14780
|
+
"Δ7": [0, 4, 7, 11],
|
|
14781
|
+
"∆7": [0, 4, 7, 11],
|
|
14782
|
+
"7M(9)": [0, 4, 7, 11, 14],
|
|
14783
|
+
"7M/9": [0, 4, 7, 11, 14],
|
|
14784
|
+
"maj7(9)": [0, 4, 7, 11, 14],
|
|
14785
|
+
"maj7/9": [0, 4, 7, 11, 14],
|
|
14786
|
+
"maj9": [0, 4, 7, 11, 14],
|
|
14787
|
+
"Δ9": [0, 4, 7, 11, 14],
|
|
14788
|
+
"∆9": [0, 4, 7, 11, 14],
|
|
14789
|
+
"7M(9,11)": [0, 4, 7, 11, 14, 17],
|
|
14790
|
+
"7M/9/11": [0, 4, 7, 11, 14, 17],
|
|
14791
|
+
"maj11": [0, 4, 7, 11, 14, 17],
|
|
14792
|
+
"maj7(9,11)": [0, 4, 7, 11, 14, 17],
|
|
14793
|
+
"maj7/9/11": [0, 4, 7, 11, 14, 17],
|
|
14794
|
+
"Δ11": [0, 4, 7, 11, 14, 17],
|
|
14795
|
+
"∆11": [0, 4, 7, 11, 14, 17],
|
|
14796
|
+
"7M(9,11,13)": [0, 4, 7, 11, 14, 17, 21],
|
|
14797
|
+
"7M/9/11/13": [0, 4, 7, 11, 14, 17, 21],
|
|
14798
|
+
"maj13": [0, 4, 7, 11, 14, 17, 21],
|
|
14799
|
+
"maj7(9,11,13)": [0, 4, 7, 11, 14, 17, 21],
|
|
14800
|
+
"maj7/9/11/13": [0, 4, 7, 11, 14, 17, 21],
|
|
14801
|
+
"Δ11(13)": [0, 4, 7, 11, 14, 17, 21],
|
|
14802
|
+
"Δ13": [0, 4, 7, 11, 14, 17, 21],
|
|
14803
|
+
"∆11(13)": [0, 4, 7, 11, 14, 17, 21],
|
|
14804
|
+
"7M(9,#11)": [0, 4, 7, 11, 14, 18],
|
|
14805
|
+
"7M/9/#11": [0, 4, 7, 11, 14, 18],
|
|
14806
|
+
"maj7(9,#11)": [0, 4, 7, 11, 14, 18],
|
|
14807
|
+
"maj7/9/#11": [0, 4, 7, 11, 14, 18],
|
|
14808
|
+
"maj9#11": [0, 4, 7, 11, 14, 18],
|
|
14809
|
+
"maj9(#11)": [0, 4, 7, 11, 14, 18],
|
|
14810
|
+
"maj9/#11": [0, 4, 7, 11, 14, 18],
|
|
14811
|
+
"Δ9(#11)": [0, 4, 7, 11, 14, 18],
|
|
14812
|
+
"7M(9,#11,13)": [0, 4, 7, 11, 14, 18, 21],
|
|
14813
|
+
"7M/9/#11/13": [0, 4, 7, 11, 14, 18, 21],
|
|
14814
|
+
"maj13#11": [0, 4, 7, 11, 14, 18, 21],
|
|
14815
|
+
"maj13(#11)": [0, 4, 7, 11, 14, 18, 21],
|
|
14816
|
+
"maj13/#11": [0, 4, 7, 11, 14, 18, 21],
|
|
14817
|
+
"Δ13(#11)": [0, 4, 7, 11, 14, 18, 21],
|
|
14818
|
+
"∆13(#11)": [0, 4, 7, 11, 14, 18, 21],
|
|
14819
|
+
"7M(9,13)": [0, 4, 7, 11, 14, 21],
|
|
14820
|
+
"7M/9/13": [0, 4, 7, 11, 14, 21],
|
|
14821
|
+
"maj7(9,13)": [0, 4, 7, 11, 14, 21],
|
|
14822
|
+
"maj7/9/13": [0, 4, 7, 11, 14, 21],
|
|
14823
|
+
"maj9(13)": [0, 4, 7, 11, 14, 21],
|
|
14824
|
+
"Δ9(13)": [0, 4, 7, 11, 14, 21],
|
|
14825
|
+
"∆9(13)": [0, 4, 7, 11, 14, 21],
|
|
14826
|
+
"7M(11)": [0, 4, 7, 11, 17],
|
|
14827
|
+
"7M/11": [0, 4, 7, 11, 17],
|
|
14828
|
+
"maj7(11)": [0, 4, 7, 11, 17],
|
|
14829
|
+
"maj7/11": [0, 4, 7, 11, 17],
|
|
14830
|
+
"Δ7(11)": [0, 4, 7, 11, 17],
|
|
14831
|
+
"∆7(11)": [0, 4, 7, 11, 17],
|
|
14832
|
+
"7M(#11)": [0, 4, 7, 11, 18],
|
|
14833
|
+
"7M/#11": [0, 4, 7, 11, 18],
|
|
14834
|
+
"maj7(#11)": [0, 4, 7, 11, 18],
|
|
14835
|
+
"maj7/#11": [0, 4, 7, 11, 18],
|
|
14836
|
+
"Δ7(#11)": [0, 4, 7, 11, 18],
|
|
14837
|
+
"∆7(#11)": [0, 4, 7, 11, 18],
|
|
14838
|
+
"7M(13)": [0, 4, 7, 11, 21],
|
|
14839
|
+
"7M/13": [0, 4, 7, 11, 21],
|
|
14840
|
+
"maj7(13)": [0, 4, 7, 11, 21],
|
|
14841
|
+
"maj7/13": [0, 4, 7, 11, 21],
|
|
14842
|
+
"Δ7(13)": [0, 4, 7, 11, 21],
|
|
14843
|
+
"∆7(13)": [0, 4, 7, 11, 21],
|
|
14844
|
+
"addb9": [0, 4, 7, 13],
|
|
14845
|
+
"add9": [0, 4, 7, 14],
|
|
14846
|
+
"add#9": [0, 4, 7, 15],
|
|
14847
|
+
"add11": [0, 4, 7, 17],
|
|
14848
|
+
"add#11": [0, 4, 7, 18],
|
|
14849
|
+
// augmented chords
|
|
14850
|
+
"+": [0, 4, 8],
|
|
14851
|
+
"aug": [0, 4, 8],
|
|
14852
|
+
"+7": [0, 4, 8, 10],
|
|
14853
|
+
"7#5": [0, 4, 8, 10],
|
|
14854
|
+
"7(#5)": [0, 4, 8, 10],
|
|
14855
|
+
"7+5": [0, 4, 8, 10],
|
|
14856
|
+
"aug7": [0, 4, 8, 10],
|
|
14857
|
+
"7(b9,#5)": [0, 4, 8, 10, 13],
|
|
14858
|
+
"7b9#5": [0, 4, 8, 10, 13],
|
|
14859
|
+
"9#5": [0, 4, 8, 10, 14],
|
|
14860
|
+
"9(#5)": [0, 4, 8, 10, 14],
|
|
14861
|
+
"9+5": [0, 4, 8, 10, 14],
|
|
14862
|
+
"13#5": [0, 4, 8, 10, 14, 21],
|
|
14863
|
+
"13(#5)": [0, 4, 8, 10, 14, 21],
|
|
14864
|
+
"7M(#5)": [0, 4, 8, 11],
|
|
14865
|
+
"maj7#5": [0, 4, 8, 11],
|
|
14866
|
+
"maj7(#5)": [0, 4, 8, 11],
|
|
14867
|
+
"7M(#5,9)": [0, 4, 8, 11, 14],
|
|
14868
|
+
"maj7#5/9": [0, 4, 8, 11, 14],
|
|
14869
|
+
"maj7(#5,9)": [0, 4, 8, 11, 14],
|
|
14870
|
+
"maj7#5#11": [0, 4, 8, 11, 18],
|
|
14871
|
+
"maj7(#5,#11)": [0, 4, 8, 11, 18],
|
|
14872
|
+
// sus4 chords
|
|
14873
|
+
"sus": [0, 5, 7],
|
|
14874
|
+
"sus4": [0, 5, 7],
|
|
14875
|
+
"-7sus4": [0, 5, 7, 10],
|
|
14876
|
+
"7sus": [0, 5, 7, 10],
|
|
14877
|
+
"7sus4": [0, 5, 7, 10],
|
|
14878
|
+
"m7sus4": [0, 5, 7, 10],
|
|
14879
|
+
"min7sus4": [0, 5, 7, 10],
|
|
14880
|
+
"7sus(b9)": [0, 5, 7, 10, 13],
|
|
14881
|
+
"7sus4(b9)": [0, 5, 7, 10, 13],
|
|
14882
|
+
"-9sus4": [0, 5, 7, 10, 14],
|
|
14883
|
+
"7sus4(9)": [0, 5, 7, 10, 14],
|
|
14884
|
+
"7sus4/9": [0, 5, 7, 10, 14],
|
|
14885
|
+
"9sus": [0, 5, 7, 10, 14],
|
|
14886
|
+
"9sus4": [0, 5, 7, 10, 14],
|
|
14887
|
+
"m9sus4": [0, 5, 7, 10, 14],
|
|
14888
|
+
"min9sus4": [0, 5, 7, 10, 14],
|
|
14889
|
+
"11sus4": [0, 5, 7, 10, 14, 17],
|
|
14890
|
+
"13sus4": [0, 5, 7, 10, 14, 21],
|
|
14891
|
+
"7sus(#9)": [0, 5, 7, 10, 15],
|
|
14892
|
+
"7sus4(#9)": [0, 5, 7, 10, 15],
|
|
14893
|
+
"7sus4(11)": [0, 5, 7, 10, 17],
|
|
14894
|
+
"7sus4(13)": [0, 5, 7, 10, 21],
|
|
14895
|
+
"7Msus": [0, 5, 7, 11],
|
|
14896
|
+
"7Msus4": [0, 5, 7, 11],
|
|
14897
|
+
"maj7sus": [0, 5, 7, 11],
|
|
14898
|
+
"maj7sus4": [0, 5, 7, 11],
|
|
14899
|
+
// power chords and unusual chords
|
|
14900
|
+
"#4": [0, 6],
|
|
14901
|
+
"b5": [0, 6],
|
|
14902
|
+
"sus#4": [0, 6, 7],
|
|
14903
|
+
"7Msus#4": [0, 6, 11],
|
|
14904
|
+
"maj7sus#4": [0, 6, 11],
|
|
14905
|
+
"5": [0, 7],
|
|
14906
|
+
"11": [0, 7, 10, 14, 17],
|
|
14907
|
+
"5(8)": [0, 7, 12],
|
|
14908
|
+
"5add8": [0, 7, 12],
|
|
14909
|
+
"5(9)": [0, 7, 14],
|
|
14910
|
+
"5add9": [0, 7, 14],
|
|
14911
|
+
"#5": [0, 8],
|
|
14912
|
+
"b6": [0, 8]
|
|
14603
14913
|
};
|
|
14604
14914
|
ChordTrack.prototype.rhythmPatterns = {
|
|
14605
14915
|
"2/2": ['boom', '', '', '', 'chick', '', '', ''],
|
|
@@ -15180,7 +15490,14 @@ function CreateSynth() {
|
|
|
15180
15490
|
// There might be a previous run that needs to be turned off.
|
|
15181
15491
|
self.stop();
|
|
15182
15492
|
var noteMapTracks = createNoteMap(self.flattened);
|
|
15183
|
-
if (self.options.swing)
|
|
15493
|
+
if (self.options.swing) {
|
|
15494
|
+
// If we have a drum intro, then the pickup is already incorporated into the beat.
|
|
15495
|
+
// That is, without a drum intro, the first note starts at 0 whether it
|
|
15496
|
+
// is a pickup or not. With a drum intro, the first note will be in its
|
|
15497
|
+
// proper place.
|
|
15498
|
+
var pickupLength = self.options.drumIntro ? 0 : self.pickupLength;
|
|
15499
|
+
addSwing(noteMapTracks, self.options.swing, self.meterFraction, pickupLength);
|
|
15500
|
+
}
|
|
15184
15501
|
if (self.sequenceCallback) self.sequenceCallback(noteMapTracks, self.callbackContext);
|
|
15185
15502
|
var panDistances = setPan(noteMapTracks.length, self.pan);
|
|
15186
15503
|
|
|
@@ -15393,7 +15710,7 @@ function CreateSynth() {
|
|
|
15393
15710
|
};
|
|
15394
15711
|
function addSwing(noteMapTracks, swing, meterFraction, pickupLength) {
|
|
15395
15712
|
// we can only swing in X/4 and X/8 meters.
|
|
15396
|
-
if (meterFraction.den
|
|
15713
|
+
if (meterFraction.den !== 4 && meterFraction.den !== 8) return;
|
|
15397
15714
|
swing = parseFloat(swing);
|
|
15398
15715
|
|
|
15399
15716
|
// 50 (or less) is no swing,
|
|
@@ -15411,7 +15728,7 @@ function CreateSynth() {
|
|
|
15411
15728
|
// could be also in the settings. Try out values such 0.1, 0.2
|
|
15412
15729
|
var volumeIncrease = 0.0;
|
|
15413
15730
|
|
|
15414
|
-
// the beatLength in X/
|
|
15731
|
+
// the beatLength in X/4 meters
|
|
15415
15732
|
var beatLength = 0.25;
|
|
15416
15733
|
|
|
15417
15734
|
// in X/8 meters the 16s swing so the beatLength is halved
|
|
@@ -15428,11 +15745,11 @@ function CreateSynth() {
|
|
|
15428
15745
|
var event = track[i];
|
|
15429
15746
|
if (
|
|
15430
15747
|
// is halfbeat
|
|
15431
|
-
(event.start - pickupLength) % halfbeatLength
|
|
15748
|
+
(event.start - pickupLength) % halfbeatLength === 0 && (event.start - pickupLength) % beatLength !== 0 && (
|
|
15432
15749
|
// the previous note is on the beat or before OR there is no previous note
|
|
15433
|
-
i
|
|
15750
|
+
i === 0 || track[i - 1].start <= track[i].start - halfbeatLength) && (
|
|
15434
15751
|
// the next note is on the beat or after OR there is no next note
|
|
15435
|
-
i
|
|
15752
|
+
i === track.length - 1 || track[i + 1].start >= track[i].start + halfbeatLength)) {
|
|
15436
15753
|
var oldEventStart = event.start;
|
|
15437
15754
|
event.start += swingDuration;
|
|
15438
15755
|
|
|
@@ -15441,7 +15758,7 @@ function CreateSynth() {
|
|
|
15441
15758
|
|
|
15442
15759
|
// if there is a previous note ending at the start of this note, extend its end
|
|
15443
15760
|
// and decrease its volume
|
|
15444
|
-
if (i > 0 && track[i - 1].end
|
|
15761
|
+
if (i > 0 && track[i - 1].end === oldEventStart) {
|
|
15445
15762
|
track[i - 1].end = event.start;
|
|
15446
15763
|
track[i - 1].volume *= 1 - volumeIncrease;
|
|
15447
15764
|
}
|
|
@@ -16179,15 +16496,15 @@ function Repeats(voice) {
|
|
|
16179
16496
|
index: thisIndex
|
|
16180
16497
|
});
|
|
16181
16498
|
}
|
|
16182
|
-
if (isStartRepeat) this.sections.push({
|
|
16183
|
-
type: "startRepeat",
|
|
16184
|
-
index: thisIndex
|
|
16185
|
-
});
|
|
16186
16499
|
if (startEnding) this.sections.push({
|
|
16187
16500
|
type: "startEnding",
|
|
16188
16501
|
index: thisIndex,
|
|
16189
16502
|
endings: startEnding
|
|
16190
16503
|
});
|
|
16504
|
+
if (isStartRepeat) this.sections.push({
|
|
16505
|
+
type: "startRepeat",
|
|
16506
|
+
index: thisIndex
|
|
16507
|
+
});
|
|
16191
16508
|
};
|
|
16192
16509
|
this.resolveRepeats = function () {
|
|
16193
16510
|
// this.sections contain all the interesting bars - start and end repeats.
|
|
@@ -19014,6 +19331,7 @@ AbstractEngraver.prototype.addNoteToAbcElement = function (abselem, elem, dot, s
|
|
|
19014
19331
|
}
|
|
19015
19332
|
}
|
|
19016
19333
|
var hasStem = !nostem && durlog <= -1;
|
|
19334
|
+
var chordPos = pp > 1 ? p + 1 : null;
|
|
19017
19335
|
var ret = createNoteHead(abselem, c, elem.pitches[p], {
|
|
19018
19336
|
dir: dir,
|
|
19019
19337
|
extrax: -roomTaken,
|
|
@@ -19023,7 +19341,8 @@ AbstractEngraver.prototype.addNoteToAbcElement = function (abselem, elem, dot, s
|
|
|
19023
19341
|
scale: this.voiceScale,
|
|
19024
19342
|
accidentalSlot: accidentalSlot,
|
|
19025
19343
|
shouldExtendStem: !stemdir,
|
|
19026
|
-
printAccidentals: !voice.isPercussion
|
|
19344
|
+
printAccidentals: !voice.isPercussion,
|
|
19345
|
+
chordPos: chordPos
|
|
19027
19346
|
});
|
|
19028
19347
|
symbolWidth = Math.max(glyphs.getSymbolWidth(c), symbolWidth);
|
|
19029
19348
|
abselem.extraw -= ret.extraLeft;
|
|
@@ -19074,7 +19393,7 @@ AbstractEngraver.prototype.addNoteToAbcElement = function (abselem, elem, dot, s
|
|
|
19074
19393
|
symbolWidth: symbolWidth
|
|
19075
19394
|
};
|
|
19076
19395
|
};
|
|
19077
|
-
AbstractEngraver.prototype.addLyric = function (abselem, elem) {
|
|
19396
|
+
AbstractEngraver.prototype.addLyric = function (abselem, elem, voiceNumber) {
|
|
19078
19397
|
var lyricStr = "";
|
|
19079
19398
|
elem.lyric.forEach(function (ly) {
|
|
19080
19399
|
var div = ly.divider === ' ' ? "" : ly.divider;
|
|
@@ -19086,7 +19405,8 @@ AbstractEngraver.prototype.addLyric = function (abselem, elem) {
|
|
|
19086
19405
|
type: "lyric",
|
|
19087
19406
|
position: position,
|
|
19088
19407
|
height: lyricDim.height / spacing.STEP,
|
|
19089
|
-
dim: this.getTextSize.attr('vocalfont', "lyric")
|
|
19408
|
+
dim: this.getTextSize.attr('vocalfont', "lyric"),
|
|
19409
|
+
voiceNumber: voiceNumber
|
|
19090
19410
|
}));
|
|
19091
19411
|
};
|
|
19092
19412
|
AbstractEngraver.prototype.createNote = function (elem, nostem, isSingleLineStaff, voice) {
|
|
@@ -19138,7 +19458,7 @@ AbstractEngraver.prototype.createNote = function (elem, nostem, isSingleLineStaf
|
|
|
19138
19458
|
symbolWidth = ret2.symbolWidth;
|
|
19139
19459
|
}
|
|
19140
19460
|
if (elem.lyric !== undefined) {
|
|
19141
|
-
this.addLyric(abselem, elem);
|
|
19461
|
+
this.addLyric(abselem, elem, voice.voicenumber);
|
|
19142
19462
|
}
|
|
19143
19463
|
if (elem.gracenotes !== undefined) {
|
|
19144
19464
|
roomtaken += this.addGraceNotes(elem, voice, abselem, notehead, this.stemHeight * this.voiceScale, this.isBagpipes, roomtaken);
|
|
@@ -19784,6 +20104,7 @@ var createNoteHead = function createNoteHead(abselem, c, pitchelem, options) {
|
|
|
19784
20104
|
var accidentalSlot = options.accidentalSlot !== undefined ? options.accidentalSlot : [];
|
|
19785
20105
|
var shouldExtendStem = options.shouldExtendStem !== undefined ? options.shouldExtendStem : false;
|
|
19786
20106
|
var printAccidentals = options.printAccidentals !== undefined ? options.printAccidentals : true;
|
|
20107
|
+
var chordPos = options.chordPos;
|
|
19787
20108
|
|
|
19788
20109
|
// TODO scale the dot as well
|
|
19789
20110
|
var pitch = pitchelem.verticalPos;
|
|
@@ -19794,7 +20115,9 @@ var createNoteHead = function createNoteHead(abselem, c, pitchelem, options) {
|
|
|
19794
20115
|
if (c === undefined) abselem.addFixed(new RelativeElement("pitch is undefined", 0, 0, 0, {
|
|
19795
20116
|
type: "debug"
|
|
19796
20117
|
}));else if (c === "") {
|
|
19797
|
-
notehead = new RelativeElement(null, 0, 0, pitch
|
|
20118
|
+
notehead = new RelativeElement(null, 0, 0, pitch, {
|
|
20119
|
+
chordPos: chordPos
|
|
20120
|
+
});
|
|
19798
20121
|
} else {
|
|
19799
20122
|
var shiftheadx = headx;
|
|
19800
20123
|
if (pitchelem.printer_shift) {
|
|
@@ -19805,7 +20128,8 @@ var createNoteHead = function createNoteHead(abselem, c, pitchelem, options) {
|
|
|
19805
20128
|
scalex: scale,
|
|
19806
20129
|
scaley: scale,
|
|
19807
20130
|
thickness: glyphs.symbolHeightInPitches(c) * scale,
|
|
19808
|
-
name: pitchelem.name
|
|
20131
|
+
name: pitchelem.name,
|
|
20132
|
+
chordPos: chordPos
|
|
19809
20133
|
};
|
|
19810
20134
|
notehead = new RelativeElement(c, shiftheadx, glyphs.getSymbolWidth(c) * scale, pitch, opts);
|
|
19811
20135
|
notehead.stemDir = dir;
|
|
@@ -19820,13 +20144,16 @@ var createNoteHead = function createNoteHead(abselem, c, pitchelem, options) {
|
|
|
19820
20144
|
var xdelta = dir === "down" ? headx : headx + notehead.w - 0.6;
|
|
19821
20145
|
abselem.addRight(new RelativeElement(flag, xdelta, glyphs.getSymbolWidth(flag) * scale, pos, {
|
|
19822
20146
|
scalex: scale,
|
|
19823
|
-
scaley: scale
|
|
20147
|
+
scaley: scale,
|
|
20148
|
+
chordPos: chordPos
|
|
19824
20149
|
}));
|
|
19825
20150
|
}
|
|
19826
20151
|
newDotShiftX = notehead.w + dotshiftx - 2 + 5 * dot;
|
|
19827
20152
|
for (; dot > 0; dot--) {
|
|
19828
20153
|
var dotadjusty = 1 - Math.abs(pitch) % 2; //PER: take abs value of the pitch. And the shift still happens on ledger lines.
|
|
19829
|
-
abselem.addRight(new RelativeElement("dots.dot", notehead.w + dotshiftx - 2 + 5 * dot, glyphs.getSymbolWidth("dots.dot"), pitch + dotadjusty
|
|
20154
|
+
abselem.addRight(new RelativeElement("dots.dot", notehead.w + dotshiftx - 2 + 5 * dot, glyphs.getSymbolWidth("dots.dot"), pitch + dotadjusty, {
|
|
20155
|
+
chordPos: chordPos
|
|
20156
|
+
}));
|
|
19830
20157
|
}
|
|
19831
20158
|
}
|
|
19832
20159
|
if (notehead) notehead.highestVert = pitchelem.highestVert;
|
|
@@ -19875,7 +20202,8 @@ var createNoteHead = function createNoteHead(abselem, c, pitchelem, options) {
|
|
|
19875
20202
|
scalex: scale,
|
|
19876
20203
|
scaley: scale,
|
|
19877
20204
|
top: pitch + h / 2,
|
|
19878
|
-
bottom: pitch - h / 2
|
|
20205
|
+
bottom: pitch - h / 2,
|
|
20206
|
+
chordPos: chordPos
|
|
19879
20207
|
}));
|
|
19880
20208
|
extraLeft = glyphs.getSymbolWidth(symb) / 2; // TODO-PER: We need a little extra width if there is an accidental, but I'm not sure why it isn't the full width of the accidental.
|
|
19881
20209
|
}
|
|
@@ -21112,6 +21440,7 @@ var RelativeElement = function RelativeElement(c, dx, w, pitch, opt) {
|
|
|
21112
21440
|
this.pitch2 = opt.pitch2;
|
|
21113
21441
|
this.linewidth = opt.linewidth;
|
|
21114
21442
|
this.klass = opt.klass;
|
|
21443
|
+
this.chordPos = opt.chordPos;
|
|
21115
21444
|
this.anchor = opt.anchor ? opt.anchor : 'middle';
|
|
21116
21445
|
this.top = pitch;
|
|
21117
21446
|
if (this.pitch2 !== undefined && this.pitch2 > this.top) this.top = this.pitch2;
|
|
@@ -21126,6 +21455,7 @@ var RelativeElement = function RelativeElement(c, dx, w, pitch, opt) {
|
|
|
21126
21455
|
}
|
|
21127
21456
|
if (opt.dim) this.dim = opt.dim;
|
|
21128
21457
|
if (opt.position) this.position = opt.position;
|
|
21458
|
+
if (opt.voiceNumber !== undefined) this.voiceNumber = opt.voiceNumber;
|
|
21129
21459
|
this.height = opt.height ? opt.height : 4; // The +1 is to give a little bit of padding.
|
|
21130
21460
|
if (opt.top) this.top = opt.top;
|
|
21131
21461
|
if (opt.bottom) this.bottom = opt.bottom;
|
|
@@ -22679,6 +23009,11 @@ function drawAbsolute(renderer, params, bartop, selectables, staffPos) {
|
|
|
22679
23009
|
if (child.type === "symbol" && child.c && child.c.indexOf('notehead') >= 0) {
|
|
22680
23010
|
el.setAttribute('class', 'abcjs-notehead');
|
|
22681
23011
|
}
|
|
23012
|
+
if (el && child.chordPos && child.name.indexOf('flags.') !== 0) {
|
|
23013
|
+
var klass = el.getAttribute("class");
|
|
23014
|
+
if (klass) klass = klass + ' abcjs-chord-pos-' + child.chordPos;else klass = 'abcjs-chord-pos-' + child.chordPos;
|
|
23015
|
+
el.setAttribute('class', klass);
|
|
23016
|
+
}
|
|
22682
23017
|
}
|
|
22683
23018
|
}
|
|
22684
23019
|
var klass = params.type;
|
|
@@ -23644,7 +23979,7 @@ function printLine(renderer, x1, x2, y, klass, name, dy) {
|
|
|
23644
23979
|
var y1 = roundNumber(y - dy);
|
|
23645
23980
|
var y2 = roundNumber(y + dy);
|
|
23646
23981
|
// TODO-PER: This fixes a firefox bug where it isn't displayed
|
|
23647
|
-
if (renderer.
|
|
23982
|
+
if (renderer.firefox) {
|
|
23648
23983
|
y += dy / 2; // Because the y coordinate is the edge of where the line goes but the width widens from the middle.
|
|
23649
23984
|
var attr = {
|
|
23650
23985
|
x1: x1,
|
|
@@ -23708,7 +24043,7 @@ function printStem(renderer, x, dx, y1, y2, klass, name) {
|
|
|
23708
24043
|
x = roundNumber(x);
|
|
23709
24044
|
var x2 = roundNumber(x + dx);
|
|
23710
24045
|
// TODO-PER: This fixes a firefox bug where it isn't displayed
|
|
23711
|
-
if (renderer.
|
|
24046
|
+
if (renderer.firefox) {
|
|
23712
24047
|
x += dx / 2; // Because the x coordinate is the edge of where the line goes but the width widens from the middle.
|
|
23713
24048
|
var attr = {
|
|
23714
24049
|
x1: x,
|
|
@@ -24842,7 +25177,7 @@ function drawTriplet(renderer, params, selectables) {
|
|
|
24842
25177
|
"data-name": "triplet"
|
|
24843
25178
|
});
|
|
24844
25179
|
if (!params.hasBeam) {
|
|
24845
|
-
drawBracket(renderer, params.anchor1.x, params.startNote, params.anchor2.x + params.anchor2.w, params.endNote);
|
|
25180
|
+
drawBracket(renderer, params.anchor1.x, params.startNote, params.anchor2.x + params.anchor2.w, params.endNote, params.up);
|
|
24846
25181
|
}
|
|
24847
25182
|
// HACK: adjust the position of "3". It is too high in all cases so we fudge it by subtracting 1 here.
|
|
24848
25183
|
renderText(renderer, {
|
|
@@ -24866,10 +25201,10 @@ function drawTriplet(renderer, params, selectables) {
|
|
|
24866
25201
|
function drawLine(l, t, r, b) {
|
|
24867
25202
|
return sprintf("M %f %f L %f %f", roundNumber(l), roundNumber(t), roundNumber(r), roundNumber(b));
|
|
24868
25203
|
}
|
|
24869
|
-
function drawBracket(renderer, x1, y1, x2, y2) {
|
|
25204
|
+
function drawBracket(renderer, x1, y1, x2, y2, up) {
|
|
24870
25205
|
y1 = renderer.calcY(y1);
|
|
24871
25206
|
y2 = renderer.calcY(y2);
|
|
24872
|
-
var bracketHeight = 5;
|
|
25207
|
+
var bracketHeight = up ? 5 : -5;
|
|
24873
25208
|
|
|
24874
25209
|
// Draw vertical lines at the beginning and end
|
|
24875
25210
|
var pathString = "";
|
|
@@ -25338,7 +25673,7 @@ function splitSvgIntoLines(renderer, output, title, responsive, scale) {
|
|
|
25338
25673
|
if (responsive !== 'resize') svg.setAttribute("height", height);
|
|
25339
25674
|
if (responsive === 'resize') svg.style.position = '';
|
|
25340
25675
|
// TODO-PER: Hack! Not sure why this is needed.
|
|
25341
|
-
var viewBoxHeight = renderer.
|
|
25676
|
+
var viewBoxHeight = renderer.firefox ? height + 1 : height;
|
|
25342
25677
|
svg.setAttribute("viewBox", "0 " + nextTop + " " + width + " " + viewBoxHeight);
|
|
25343
25678
|
svg.appendChild(style.cloneNode(true));
|
|
25344
25679
|
var titleEl = document.createElement("title");
|
|
@@ -26592,6 +26927,7 @@ var setUpperAndLowerElements = __webpack_require__(/*! ./set-upper-and-lower-ele
|
|
|
26592
26927
|
var layoutStaffGroup = __webpack_require__(/*! ./staff-group */ "./src/write/layout/staff-group.js");
|
|
26593
26928
|
var getLeftEdgeOfStaff = __webpack_require__(/*! ./get-left-edge-of-staff */ "./src/write/layout/get-left-edge-of-staff.js");
|
|
26594
26929
|
var layoutInGrid = __webpack_require__(/*! ./layout-in-grid */ "./src/write/layout/layout-in-grid.js");
|
|
26930
|
+
var toTimeAndStaffBased = __webpack_require__(/*! ./to-time-and-staff-based */ "./src/write/layout/to-time-and-staff-based.js");
|
|
26595
26931
|
|
|
26596
26932
|
// This sets the "x" attribute on all the children in abctune.lines
|
|
26597
26933
|
// It also sets the "w" and "startx" attributes on "voices"
|
|
@@ -26627,6 +26963,16 @@ var layout = function layout(renderer, abctune, width, space, expandToWidest, ti
|
|
|
26627
26963
|
}
|
|
26628
26964
|
}
|
|
26629
26965
|
|
|
26966
|
+
// See if there are collisions between voices that need to be tweaked
|
|
26967
|
+
var timeBased = toTimeAndStaffBased(abctune.lines);
|
|
26968
|
+
for (i = 0; i < abctune.lines.length; i++) {
|
|
26969
|
+
abcLine = abctune.lines[i];
|
|
26970
|
+
if (abcLine.staffGroup) {
|
|
26971
|
+
fixVoiceCollisions(timeBased[i]);
|
|
26972
|
+
//setUpperAndLowerElements(renderer, abcLine.staffGroup);
|
|
26973
|
+
}
|
|
26974
|
+
}
|
|
26975
|
+
|
|
26630
26976
|
// Set the staff spacing
|
|
26631
26977
|
// TODO-PER: we should have been able to do this by the time we called setUpperAndLowerElements, but for some reason the "bottom" element seems to be set as a side effect of setting the X spacing.
|
|
26632
26978
|
for (i = 0; i < abctune.lines.length; i++) {
|
|
@@ -26709,6 +27055,82 @@ function centerWholeRests(voices) {
|
|
|
26709
27055
|
}
|
|
26710
27056
|
}
|
|
26711
27057
|
}
|
|
27058
|
+
function fixVoiceCollisions(timeBasedLine) {
|
|
27059
|
+
for (var s = 0; s < timeBasedLine.length; s++) {
|
|
27060
|
+
var timeSlot = timeBasedLine[s];
|
|
27061
|
+
// If there is more than one thing happening at the same time,
|
|
27062
|
+
// and one of those things is a rest, then:
|
|
27063
|
+
// If the rest is in the first element, check to see if the bottom bumps into the top of any of the rest of the elements
|
|
27064
|
+
// If the rest is in the last element, check to see if the top bumps into the bottom of any of the rest of the elements.
|
|
27065
|
+
// Note: if there are more than two voices the staff will get sloppy, so there is a limit to how much that can be improved, but this should be fine when there are two voices.
|
|
27066
|
+
// If there is a collision, move the rest up or down to fix that.
|
|
27067
|
+
var keys = Object.keys(timeSlot);
|
|
27068
|
+
for (var z = 0; z < keys.length; z++) {
|
|
27069
|
+
var slot = timeSlot[keys[z]]; // slot is an array of all the things happening at a particular time
|
|
27070
|
+
var lastIndex = slot.length - 1;
|
|
27071
|
+
if (slot.length > 1) {
|
|
27072
|
+
var isRealRest = slot[0].abcelem.rest && slot[0].abcelem.rest.type === 'rest'; // weed out invisible rests
|
|
27073
|
+
var isRealRest2 = slot[lastIndex].abcelem.rest && slot[lastIndex].abcelem.rest.type === 'rest'; // weed out invisible rests
|
|
27074
|
+
if (isRealRest && !slot[lastIndex].abcelem.rest) {
|
|
27075
|
+
// the first voice has a rest and the second doesn't
|
|
27076
|
+
var restTop = slot[0].children.find(function (ch) {
|
|
27077
|
+
return ch.name.includes('rest');
|
|
27078
|
+
});
|
|
27079
|
+
var otherTop = closeTop(slot[lastIndex]);
|
|
27080
|
+
if (restTop) {
|
|
27081
|
+
var distance1 = restTop.bottom - otherTop;
|
|
27082
|
+
distance1 -= 2; // give some room between the rest and the note
|
|
27083
|
+
if (distance1 < 0 && slot[0].children.length > 0) {
|
|
27084
|
+
slot[0].bottom -= distance1;
|
|
27085
|
+
slot[0].top -= distance1;
|
|
27086
|
+
slot[0].children[0].bottom -= distance1;
|
|
27087
|
+
slot[0].children[0].top -= distance1;
|
|
27088
|
+
slot[0].children[0].pitch -= distance1;
|
|
27089
|
+
}
|
|
27090
|
+
}
|
|
27091
|
+
} else if (isRealRest2 && !slot[0].abcelem.rest) {
|
|
27092
|
+
// the last voice has a rest and the first doesn't
|
|
27093
|
+
var restBottom = slot[lastIndex].children.find(function (ch) {
|
|
27094
|
+
return ch.name.includes('rest');
|
|
27095
|
+
});
|
|
27096
|
+
if (restBottom) {
|
|
27097
|
+
var distance2 = restBottom.top - closeBottom(slot[0]);
|
|
27098
|
+
distance2 += 2; // give some room between the rest and the note
|
|
27099
|
+
if (distance2 > 0 && slot[lastIndex].children.length > 0) {
|
|
27100
|
+
slot[lastIndex].bottom -= distance2;
|
|
27101
|
+
slot[lastIndex].top -= distance2;
|
|
27102
|
+
slot[lastIndex].children[0].bottom -= distance2;
|
|
27103
|
+
slot[lastIndex].children[0].top -= distance2;
|
|
27104
|
+
slot[lastIndex].children[0].pitch -= distance2;
|
|
27105
|
+
}
|
|
27106
|
+
}
|
|
27107
|
+
}
|
|
27108
|
+
}
|
|
27109
|
+
}
|
|
27110
|
+
}
|
|
27111
|
+
}
|
|
27112
|
+
function closeTop(absElem) {
|
|
27113
|
+
if (absElem.children) {
|
|
27114
|
+
var max = -90; // This is clearly way lower than the max calculated below
|
|
27115
|
+
for (var i = 0; i < absElem.children.length; i++) {
|
|
27116
|
+
var child = absElem.children[i];
|
|
27117
|
+
if (child.type !== 'chord') max = Math.max(max, child.top);
|
|
27118
|
+
}
|
|
27119
|
+
if (max > -90) return max;
|
|
27120
|
+
}
|
|
27121
|
+
return absElem.top;
|
|
27122
|
+
}
|
|
27123
|
+
function closeBottom(absElem) {
|
|
27124
|
+
if (absElem.children) {
|
|
27125
|
+
var min = 90; // This is clearly way higher than the min calculated below
|
|
27126
|
+
for (var i = 0; i < absElem.children.length; i++) {
|
|
27127
|
+
var child = absElem.children[i];
|
|
27128
|
+
if (child.type !== 'lyric') min = Math.min(min, child.bottom);
|
|
27129
|
+
}
|
|
27130
|
+
if (min < 90) return min;
|
|
27131
|
+
}
|
|
27132
|
+
return absElem.bottom;
|
|
27133
|
+
}
|
|
26712
27134
|
module.exports = layout;
|
|
26713
27135
|
|
|
26714
27136
|
/***/ }),
|
|
@@ -26788,7 +27210,8 @@ var setUpperAndLowerElements = function setUpperAndLowerElements(renderer, staff
|
|
|
26788
27210
|
|
|
26789
27211
|
for (var j = 0; j < staff.voices.length; j++) {
|
|
26790
27212
|
var voice = staffGroup.voices[staff.voices[j]];
|
|
26791
|
-
setUpperAndLowerVoiceElements(positionY, voice, renderer.spacing);
|
|
27213
|
+
var diff = setUpperAndLowerVoiceElements(positionY, voice, renderer.spacing);
|
|
27214
|
+
staff.bottom -= diff; //
|
|
26792
27215
|
}
|
|
26793
27216
|
// We might need a little space in between staves if the staves haven't been pushed far enough apart by notes or extra vertical stuff.
|
|
26794
27217
|
// Only try to put in extra space if this isn't the top staff.
|
|
@@ -26821,10 +27244,18 @@ function incTop(staff, positionY, item, count) {
|
|
|
26821
27244
|
function setUpperAndLowerVoiceElements(positionY, voice, spacing) {
|
|
26822
27245
|
var i;
|
|
26823
27246
|
var abselem;
|
|
27247
|
+
var diff = 0;
|
|
26824
27248
|
for (i = 0; i < voice.children.length; i++) {
|
|
26825
27249
|
abselem = voice.children[i];
|
|
26826
|
-
setUpperAndLowerAbsoluteElements(positionY, abselem, spacing);
|
|
27250
|
+
var bottom = setUpperAndLowerAbsoluteElements(positionY, abselem, spacing);
|
|
27251
|
+
if (bottom < abselem.bottom) {
|
|
27252
|
+
// We're moving things down so tell the staff that it needs to be taller
|
|
27253
|
+
diff = abselem.bottom - bottom;
|
|
27254
|
+
abselem.bottom = bottom; //
|
|
27255
|
+
voice.bottom = bottom; //
|
|
27256
|
+
}
|
|
26827
27257
|
}
|
|
27258
|
+
|
|
26828
27259
|
for (i = 0; i < voice.otherchildren.length; i++) {
|
|
26829
27260
|
abselem = voice.otherchildren[i];
|
|
26830
27261
|
switch (abselem.type) {
|
|
@@ -26847,6 +27278,7 @@ function setUpperAndLowerVoiceElements(positionY, voice, spacing) {
|
|
|
26847
27278
|
break;
|
|
26848
27279
|
}
|
|
26849
27280
|
}
|
|
27281
|
+
return diff;
|
|
26850
27282
|
}
|
|
26851
27283
|
|
|
26852
27284
|
// For each of the relative elements that can't be placed in advance (because their vertical placement depends on everything
|
|
@@ -26854,6 +27286,7 @@ function setUpperAndLowerVoiceElements(positionY, voice, spacing) {
|
|
|
26854
27286
|
// hash with the vertical placement (in pitch units) for each type.
|
|
26855
27287
|
// TODO-PER: I think this needs to be separated by "above" and "below". How do we know that for dynamics at the point where they are being defined, though? We need a pass through all the relative elements to set "above" and "below".
|
|
26856
27288
|
function setUpperAndLowerAbsoluteElements(specialYResolved, element, spacing) {
|
|
27289
|
+
var bottom = element.bottom;
|
|
26857
27290
|
// specialYResolved contains the actual pitch for each of the classes of elements.
|
|
26858
27291
|
for (var i = 0; i < element.children.length; i++) {
|
|
26859
27292
|
var child = element.children[i];
|
|
@@ -26863,6 +27296,12 @@ function setUpperAndLowerAbsoluteElements(specialYResolved, element, spacing) {
|
|
|
26863
27296
|
if (child[key]) {
|
|
26864
27297
|
// If this relative element has defined a height for this class of element
|
|
26865
27298
|
child.pitch = specialYResolved[key];
|
|
27299
|
+
if (key === 'lyricHeightBelow' && child.type === 'lyric' && child.voiceNumber) {
|
|
27300
|
+
// TODO-PER: This can result in extra unused vertical space if there are lyrics only on the second but not the first voice.
|
|
27301
|
+
child.pitch -= child.voiceNumber * child[key]; //
|
|
27302
|
+
bottom = Math.min(element.bottom, child.pitch); //
|
|
27303
|
+
}
|
|
27304
|
+
|
|
26866
27305
|
if (child.top === undefined) {
|
|
26867
27306
|
// TODO-PER: HACK! Not sure this is the right place to do this.
|
|
26868
27307
|
if (child.type === 'TempoElement') {
|
|
@@ -26877,6 +27316,7 @@ function setUpperAndLowerAbsoluteElements(specialYResolved, element, spacing) {
|
|
|
26877
27316
|
}
|
|
26878
27317
|
}
|
|
26879
27318
|
}
|
|
27319
|
+
return bottom;
|
|
26880
27320
|
}
|
|
26881
27321
|
function setUpperAndLowerCrescendoElements(positionY, element) {
|
|
26882
27322
|
if (element.dynamicHeightAbove) element.pitch = positionY.dynamicHeightAbove;else element.pitch = positionY.dynamicHeightBelow;
|
|
@@ -27083,6 +27523,47 @@ module.exports = layoutStaffGroup;
|
|
|
27083
27523
|
|
|
27084
27524
|
/***/ }),
|
|
27085
27525
|
|
|
27526
|
+
/***/ "./src/write/layout/to-time-and-staff-based.js":
|
|
27527
|
+
/*!*****************************************************!*\
|
|
27528
|
+
!*** ./src/write/layout/to-time-and-staff-based.js ***!
|
|
27529
|
+
\*****************************************************/
|
|
27530
|
+
/***/ (function(module) {
|
|
27531
|
+
|
|
27532
|
+
function toTimeAndStaffBased(abcLines) {
|
|
27533
|
+
var results = [];
|
|
27534
|
+
for (var lin = 0; lin < abcLines.length; lin++) {
|
|
27535
|
+
var line = abcLines[lin];
|
|
27536
|
+
var staffGroup = line.staffGroup;
|
|
27537
|
+
var group = [];
|
|
27538
|
+
if (staffGroup && staffGroup && staffGroup.staffs) {
|
|
27539
|
+
for (var s = 0; s < staffGroup.staffs.length; s++) {
|
|
27540
|
+
var staff = staffGroup.staffs[s];
|
|
27541
|
+
var timeSlot = {};
|
|
27542
|
+
for (var i = 0; i < staff.voices.length; i++) {
|
|
27543
|
+
var voice = staffGroup.voices[staff.voices[i]];
|
|
27544
|
+
var time = 0;
|
|
27545
|
+
for (var k = 0; k < voice.children.length; k++) {
|
|
27546
|
+
var index = 'T' + Math.round(time * 1000); // There can be inexactness when calculating triplets, so we'll round, but we'll make sure that no make sure that we don't lose necessary precision by making it a shorter time than would ever happen
|
|
27547
|
+
if (!timeSlot[index]) timeSlot[index] = [];
|
|
27548
|
+
if (voice.children[k].abcelem.el_type === 'note') {
|
|
27549
|
+
timeSlot[index].push(voice.children[k]);
|
|
27550
|
+
time += voice.children[k].duration;
|
|
27551
|
+
}
|
|
27552
|
+
}
|
|
27553
|
+
}
|
|
27554
|
+
// Now timeSlot is an object with all the voices on a particular staff that
|
|
27555
|
+
// happen at the same time as an array.
|
|
27556
|
+
group.push(timeSlot);
|
|
27557
|
+
}
|
|
27558
|
+
}
|
|
27559
|
+
results.push(group);
|
|
27560
|
+
}
|
|
27561
|
+
return results;
|
|
27562
|
+
}
|
|
27563
|
+
module.exports = toTimeAndStaffBased;
|
|
27564
|
+
|
|
27565
|
+
/***/ }),
|
|
27566
|
+
|
|
27086
27567
|
/***/ "./src/write/layout/triplet.js":
|
|
27087
27568
|
/*!*************************************!*\
|
|
27088
27569
|
!*** ./src/write/layout/triplet.js ***!
|
|
@@ -27108,30 +27589,56 @@ function layoutTriplet(element) {
|
|
|
27108
27589
|
element.bottom = element.yTextPos - 2;
|
|
27109
27590
|
if (isAbove(beam)) element.endingHeightAbove = 4;
|
|
27110
27591
|
} else {
|
|
27111
|
-
// If there isn't a beam, then we need to draw the bracket and the text. The bracket is
|
|
27592
|
+
// If there isn't a beam, then we need to draw the bracket and the text. The bracket is either above or below depending on the stem direction of the notes.
|
|
27593
|
+
// Above:
|
|
27112
27594
|
// The bracket is never lower than the 'a' line, but is 4 pitches above the first and last notes. If there is
|
|
27113
27595
|
// a tall note in the middle, the bracket is horizontal and above the highest note.
|
|
27114
|
-
|
|
27115
|
-
|
|
27596
|
+
// Below: The bracket is never higher than the 'C' line, and is 4 pitches below.
|
|
27597
|
+
|
|
27598
|
+
// To decide if the bracket goes above or below, go in the direction of the most stems. If there are the same number it will put the bracket above.
|
|
27599
|
+
var up = stemDirectionUp(element);
|
|
27600
|
+
element.up = up;
|
|
27601
|
+
element.startNote = up ? Math.max(element.anchor1.parent.top, 9) + 4 : Math.min(element.anchor1.parent.bottom, 0) - 2;
|
|
27602
|
+
element.endNote = up ? Math.max(element.anchor2.parent.top, 9) + 4 : Math.min(element.anchor2.parent.bottom, 0) - 2;
|
|
27603
|
+
|
|
27116
27604
|
// If it starts or ends on a rest, make the beam horizontal
|
|
27117
27605
|
if (element.anchor1.parent.type === "rest" && element.anchor2.parent.type !== "rest") element.startNote = element.endNote;else if (element.anchor2.parent.type === "rest" && element.anchor1.parent.type !== "rest") element.endNote = element.startNote;
|
|
27118
|
-
|
|
27119
|
-
|
|
27120
|
-
|
|
27121
|
-
|
|
27122
|
-
|
|
27123
|
-
|
|
27124
|
-
|
|
27125
|
-
element.startNote
|
|
27126
|
-
|
|
27606
|
+
if (up) {
|
|
27607
|
+
// See if the middle note is really high.
|
|
27608
|
+
var max = 0;
|
|
27609
|
+
for (var i = 0; i < element.middleElems.length; i++) {
|
|
27610
|
+
max = Math.max(max, element.middleElems[i].top);
|
|
27611
|
+
}
|
|
27612
|
+
max += 4;
|
|
27613
|
+
if (max > element.startNote || max > element.endNote) {
|
|
27614
|
+
element.startNote = max + 3;
|
|
27615
|
+
element.endNote = max + 3;
|
|
27616
|
+
}
|
|
27617
|
+
} else {
|
|
27618
|
+
// See if the middle note is really low.
|
|
27619
|
+
var min = 0;
|
|
27620
|
+
for (var i = 0; i < element.middleElems.length; i++) {
|
|
27621
|
+
min = Math.min(min, element.middleElems[i].bottom - element.middleElems[i].height);
|
|
27622
|
+
}
|
|
27623
|
+
min -= 3;
|
|
27624
|
+
if (min < element.startNote && min < element.endNote) {
|
|
27625
|
+
element.startNote = Math.min(min, element.startNote) - 2;
|
|
27626
|
+
element.endNote = Math.min(min, element.endNote) - 2;
|
|
27627
|
+
}
|
|
27127
27628
|
}
|
|
27128
27629
|
if (element.flatBeams) {
|
|
27129
|
-
|
|
27130
|
-
|
|
27630
|
+
if (up) {
|
|
27631
|
+
element.startNote = Math.max(element.startNote, element.endNote);
|
|
27632
|
+
element.endNote = Math.max(element.startNote, element.endNote);
|
|
27633
|
+
} else {
|
|
27634
|
+
element.startNote = Math.min(element.startNote, element.endNote);
|
|
27635
|
+
element.endNote = Math.min(element.startNote, element.endNote);
|
|
27636
|
+
}
|
|
27131
27637
|
}
|
|
27132
27638
|
element.yTextPos = element.startNote + (element.endNote - element.startNote) / 2;
|
|
27133
27639
|
element.xTextPos = element.anchor1.x + (element.anchor2.x + element.anchor2.w - element.anchor1.x) / 2;
|
|
27134
27640
|
element.top = element.yTextPos + 1;
|
|
27641
|
+
element.bottom = element.yTextPos - 2;
|
|
27135
27642
|
}
|
|
27136
27643
|
}
|
|
27137
27644
|
delete element.middleElems;
|
|
@@ -27140,6 +27647,26 @@ function layoutTriplet(element) {
|
|
|
27140
27647
|
function isAbove(beam) {
|
|
27141
27648
|
return beam.stemsUp;
|
|
27142
27649
|
}
|
|
27650
|
+
function stemDirectionUp(element) {
|
|
27651
|
+
var up = 0;
|
|
27652
|
+
var down = 0;
|
|
27653
|
+
if (element.anchor1) {
|
|
27654
|
+
if (element.anchor1.stemDir === 'up') up++;
|
|
27655
|
+
if (element.anchor1.stemDir === 'down') down++;
|
|
27656
|
+
}
|
|
27657
|
+
if (element.anchor2) {
|
|
27658
|
+
if (element.anchor2.stemDir === 'up') up++;
|
|
27659
|
+
if (element.anchor2.stemDir === 'down') down++;
|
|
27660
|
+
}
|
|
27661
|
+
if (element.middleElems) {
|
|
27662
|
+
for (var i = 0; i < element.middleElems.length; i++) {
|
|
27663
|
+
var elem = element.middleElems[i];
|
|
27664
|
+
if (elem.stemDir === 'up') up++;
|
|
27665
|
+
if (elem.stemDir === 'down') down++;
|
|
27666
|
+
}
|
|
27667
|
+
}
|
|
27668
|
+
return up >= down;
|
|
27669
|
+
}
|
|
27143
27670
|
|
|
27144
27671
|
// We can't just use the entire beam for the calculation. The range has to be passed in, because the beam might extend into some unrelated notes. for instance, (3_a'f'e'f'2 when L:16
|
|
27145
27672
|
function heightAtMidpoint(startX, endX, beam) {
|
|
@@ -27432,7 +27959,7 @@ var Renderer = function Renderer(paper) {
|
|
|
27432
27959
|
this.space = 3 * spacing.SPACE;
|
|
27433
27960
|
this.padding = {}; // renderer's padding is managed by the controller
|
|
27434
27961
|
this.reset();
|
|
27435
|
-
this.
|
|
27962
|
+
this.firefox = navigator.userAgent.indexOf('Firefox/') >= 0;
|
|
27436
27963
|
};
|
|
27437
27964
|
Renderer.prototype.reset = function () {
|
|
27438
27965
|
this.paper.clear();
|
|
@@ -27980,7 +28507,7 @@ module.exports = Svg;
|
|
|
27980
28507
|
\********************/
|
|
27981
28508
|
/***/ (function(module) {
|
|
27982
28509
|
|
|
27983
|
-
var version = '6.6.
|
|
28510
|
+
var version = '6.6.4';
|
|
27984
28511
|
module.exports = version;
|
|
27985
28512
|
|
|
27986
28513
|
/***/ })
|