@coderline/alphatab 1.9.0-alpha.1855 → 1.9.0-alpha.1861
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/dist/alphaTab.core.min.mjs +2 -2
- package/dist/alphaTab.core.mjs +271 -91
- package/dist/alphaTab.d.ts +77 -3
- package/dist/alphaTab.js +271 -91
- package/dist/alphaTab.min.js +2 -2
- package/dist/alphaTab.min.mjs +1 -1
- package/dist/alphaTab.mjs +1 -1
- package/dist/alphaTab.worker.min.mjs +1 -1
- package/dist/alphaTab.worker.mjs +1 -1
- package/dist/alphaTab.worklet.min.mjs +1 -1
- package/dist/alphaTab.worklet.mjs +1 -1
- package/package.json +2 -2
package/dist/alphaTab.core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* alphaTab v1.9.0-alpha.
|
|
2
|
+
* alphaTab v1.9.0-alpha.1861 (develop, build 1861)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2026, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -186,9 +186,9 @@ class AlphaTabError extends Error {
|
|
|
186
186
|
* @internal
|
|
187
187
|
*/
|
|
188
188
|
class VersionInfo {
|
|
189
|
-
static version = "1.9.0-alpha.
|
|
190
|
-
static date = "2026-07-
|
|
191
|
-
static commit = "
|
|
189
|
+
static version = "1.9.0-alpha.1861";
|
|
190
|
+
static date = "2026-07-11T03:34:14.452Z";
|
|
191
|
+
static commit = "18845390986e826fff8ae285ee3630080dbd6653";
|
|
192
192
|
static print(print) {
|
|
193
193
|
print(`alphaTab ${VersionInfo.version}`);
|
|
194
194
|
print(`commit: ${VersionInfo.commit}`);
|
|
@@ -18187,18 +18187,24 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18187
18187
|
_lyrics = [];
|
|
18188
18188
|
_barCount = 0;
|
|
18189
18189
|
_trackCount = 0;
|
|
18190
|
-
|
|
18190
|
+
/**
|
|
18191
|
+
* For 4 ports, 16 channels of information
|
|
18192
|
+
*/
|
|
18193
|
+
_midiChannelInfo = [];
|
|
18191
18194
|
_doubleBars = /* @__PURE__ */ new Set();
|
|
18192
18195
|
_clefsPerTrack = /* @__PURE__ */ new Map();
|
|
18193
18196
|
_keySignatures = /* @__PURE__ */ new Map();
|
|
18194
18197
|
_beatTextChunksByTrack = /* @__PURE__ */ new Map();
|
|
18195
18198
|
_directionLookup = /* @__PURE__ */ new Map();
|
|
18196
18199
|
_initialTempo;
|
|
18200
|
+
_stringEncoding = "";
|
|
18197
18201
|
get name() {
|
|
18198
18202
|
return "Guitar Pro 3-5";
|
|
18199
18203
|
}
|
|
18200
18204
|
readScore() {
|
|
18201
18205
|
this._directionLookup.clear();
|
|
18206
|
+
if (this.settings.importer.encoding !== "utf-8") this._stringEncoding = this.settings.importer.encoding;
|
|
18207
|
+
else this._stringEncoding = this.settings.importer.gp3To5encoding;
|
|
18202
18208
|
this.readVersion();
|
|
18203
18209
|
this._score = new Score();
|
|
18204
18210
|
this.readScoreInformation();
|
|
@@ -18208,7 +18214,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18208
18214
|
this._initialTempo = Automation.buildTempoAutomation(false, 0, 0, 0);
|
|
18209
18215
|
if (this._versionNumber >= 500) {
|
|
18210
18216
|
this.readPageSetup();
|
|
18211
|
-
this._initialTempo.text = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18217
|
+
this._initialTempo.text = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18212
18218
|
}
|
|
18213
18219
|
this._initialTempo.value = IOHelper.readInt32LE(this.data);
|
|
18214
18220
|
if (this._versionNumber >= 510) GpBinaryHelpers.gpReadBool(this.data);
|
|
@@ -18267,7 +18273,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18267
18273
|
directionsList.push(direction);
|
|
18268
18274
|
}
|
|
18269
18275
|
readVersion() {
|
|
18270
|
-
let version = GpBinaryHelpers.gpReadStringByteLength(this.data, 30, this.
|
|
18276
|
+
let version = GpBinaryHelpers.gpReadStringByteLength(this.data, 30, this._stringEncoding);
|
|
18271
18277
|
if (!version.startsWith(Gp3To5Importer._versionString)) throw new UnsupportedFormatError("Unsupported format");
|
|
18272
18278
|
version = version.substr(Gp3To5Importer._versionString.length + 1);
|
|
18273
18279
|
const dot = version.indexOf(String.fromCharCode(46));
|
|
@@ -18275,21 +18281,21 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18275
18281
|
Logger.debug(this.name, `Guitar Pro version ${version} detected`);
|
|
18276
18282
|
}
|
|
18277
18283
|
readScoreInformation() {
|
|
18278
|
-
this._score.title = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18279
|
-
this._score.subTitle = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18280
|
-
this._score.artist = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18281
|
-
this._score.album = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18282
|
-
this._score.words = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18283
|
-
this._score.music = this._versionNumber >= 500 ? GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18284
|
-
this._score.copyright = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18285
|
-
this._score.tab = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18286
|
-
this._score.instructions = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18284
|
+
this._score.title = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18285
|
+
this._score.subTitle = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18286
|
+
this._score.artist = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18287
|
+
this._score.album = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18288
|
+
this._score.words = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18289
|
+
this._score.music = this._versionNumber >= 500 ? GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize) : this._score.words;
|
|
18290
|
+
this._score.copyright = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18291
|
+
this._score.tab = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18292
|
+
this._score.instructions = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18287
18293
|
const noticeLines = IOHelper.readInt32LE(this.data);
|
|
18288
18294
|
this._ensureLoopBoundary(noticeLines, Gp3To5Importer._maxNoticeLines, "notice line count");
|
|
18289
18295
|
let notice = "";
|
|
18290
18296
|
for (let i = 0; i < noticeLines; i++) {
|
|
18291
18297
|
if (i > 0) notice += "\r\n";
|
|
18292
|
-
notice += GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18298
|
+
notice += GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize)?.toString();
|
|
18293
18299
|
}
|
|
18294
18300
|
this._score.notices = notice;
|
|
18295
18301
|
}
|
|
@@ -18307,7 +18313,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18307
18313
|
for (let i = 0; i < 5; i++) {
|
|
18308
18314
|
const lyrics = new Lyrics();
|
|
18309
18315
|
lyrics.startBar = IOHelper.readInt32LE(this.data) - 1;
|
|
18310
|
-
lyrics.text = GpBinaryHelpers.gpReadStringInt(this.data, this.
|
|
18316
|
+
lyrics.text = GpBinaryHelpers.gpReadStringInt(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18311
18317
|
this._lyrics.push(lyrics);
|
|
18312
18318
|
}
|
|
18313
18319
|
}
|
|
@@ -18315,37 +18321,43 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18315
18321
|
this.data.skip(28);
|
|
18316
18322
|
const flags = IOHelper.readInt16LE(this.data);
|
|
18317
18323
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Title).isVisible = (flags & 1) !== 0;
|
|
18318
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Title).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18324
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Title).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18319
18325
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.SubTitle).isVisible = (flags & 2) !== 0;
|
|
18320
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.SubTitle).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18326
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.SubTitle).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18321
18327
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Artist).isVisible = (flags & 4) !== 0;
|
|
18322
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Artist).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18328
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Artist).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18323
18329
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Album).isVisible = (flags & 8) !== 0;
|
|
18324
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Album).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18330
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Album).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18325
18331
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Words).isVisible = (flags & 16) !== 0;
|
|
18326
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Words).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18332
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Words).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18327
18333
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Music).isVisible = (flags & 32) !== 0;
|
|
18328
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Music).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18334
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Music).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18329
18335
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.WordsAndMusic).isVisible = (flags & 64) !== 0;
|
|
18330
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.WordsAndMusic).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18336
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.WordsAndMusic).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18331
18337
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Copyright).isVisible = (flags & 128) !== 0;
|
|
18332
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Copyright).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18338
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.Copyright).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18333
18339
|
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.CopyrightSecondLine).isVisible = (flags & 128) !== 0;
|
|
18334
|
-
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.CopyrightSecondLine).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18335
|
-
GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18340
|
+
ModelUtils.getOrCreateHeaderFooterStyle(this._score, ScoreSubElement.CopyrightSecondLine).template = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18341
|
+
GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18336
18342
|
}
|
|
18337
18343
|
readPlaybackInfos() {
|
|
18338
|
-
this.
|
|
18339
|
-
let
|
|
18340
|
-
|
|
18341
|
-
|
|
18342
|
-
|
|
18343
|
-
|
|
18344
|
-
|
|
18345
|
-
|
|
18346
|
-
|
|
18347
|
-
|
|
18348
|
-
|
|
18344
|
+
this._midiChannelInfo = [];
|
|
18345
|
+
for (let port = 0; port < 4; port++) {
|
|
18346
|
+
const portInfo = [];
|
|
18347
|
+
this._midiChannelInfo.push(portInfo);
|
|
18348
|
+
for (let channel = 0; channel < 16; channel++) {
|
|
18349
|
+
const info = {
|
|
18350
|
+
program: IOHelper.readInt32LE(this.data),
|
|
18351
|
+
volume: this.data.readByte(),
|
|
18352
|
+
balance: this.data.readByte(),
|
|
18353
|
+
chorus: this.data.readByte(),
|
|
18354
|
+
reverb: this.data.readByte(),
|
|
18355
|
+
phase: this.data.readByte(),
|
|
18356
|
+
tremolo: this.data.readByte()
|
|
18357
|
+
};
|
|
18358
|
+
this.data.skip(2);
|
|
18359
|
+
portInfo.push(info);
|
|
18360
|
+
}
|
|
18349
18361
|
}
|
|
18350
18362
|
}
|
|
18351
18363
|
readMasterBars() {
|
|
@@ -18382,7 +18394,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18382
18394
|
}
|
|
18383
18395
|
if ((flags & 32) !== 0) {
|
|
18384
18396
|
const section = new Section();
|
|
18385
|
-
section.text = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18397
|
+
section.text = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18386
18398
|
section.marker = "";
|
|
18387
18399
|
GpBinaryHelpers.gpReadColor(this.data, false);
|
|
18388
18400
|
newMasterBar.section = section;
|
|
@@ -18421,7 +18433,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18421
18433
|
this._score.addTrack(newTrack);
|
|
18422
18434
|
const mainStaff = newTrack.staves[0];
|
|
18423
18435
|
const flags = this.data.readByte();
|
|
18424
|
-
newTrack.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 40, this.
|
|
18436
|
+
newTrack.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 40, this._stringEncoding);
|
|
18425
18437
|
if ((flags & 1) !== 0) mainStaff.isPercussion = true;
|
|
18426
18438
|
if (this._versionNumber >= 500) newTrack.isVisibleOnMultiTrack = (flags & 8) !== 0;
|
|
18427
18439
|
if (this._score.stylesheet.perTrackDisplayTuning === null) this._score.stylesheet.perTrackDisplayTuning = /* @__PURE__ */ new Map();
|
|
@@ -18433,19 +18445,22 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18433
18445
|
if (stringCount > i) tuning.push(stringTuning);
|
|
18434
18446
|
}
|
|
18435
18447
|
mainStaff.stringTuning.tunings = tuning;
|
|
18436
|
-
const port = IOHelper.readInt32LE(this.data);
|
|
18437
|
-
const
|
|
18448
|
+
const port = IOHelper.readInt32LE(this.data) - 1;
|
|
18449
|
+
const channel = IOHelper.readInt32LE(this.data) - 1;
|
|
18438
18450
|
const effectChannel = IOHelper.readInt32LE(this.data) - 1;
|
|
18439
18451
|
this.data.skip(4);
|
|
18440
|
-
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
|
|
18446
|
-
|
|
18447
|
-
|
|
18448
|
-
|
|
18452
|
+
const mainMidiChannelInfo = this._midiChannelInfo[port][channel];
|
|
18453
|
+
const trackPlaybackInfo = new PlaybackInformation();
|
|
18454
|
+
trackPlaybackInfo.volume = mainMidiChannelInfo.volume;
|
|
18455
|
+
trackPlaybackInfo.balance = mainMidiChannelInfo.balance;
|
|
18456
|
+
trackPlaybackInfo.port = port;
|
|
18457
|
+
trackPlaybackInfo.program = mainMidiChannelInfo.program;
|
|
18458
|
+
trackPlaybackInfo.primaryChannel = channel;
|
|
18459
|
+
trackPlaybackInfo.secondaryChannel = effectChannel;
|
|
18460
|
+
trackPlaybackInfo.isSolo = (flags & 16) !== 0;
|
|
18461
|
+
trackPlaybackInfo.isMute = (flags & 32) !== 0;
|
|
18462
|
+
if (GeneralMidi.isGuitar(trackPlaybackInfo.program)) mainStaff.displayTranspositionPitch = -12;
|
|
18463
|
+
newTrack.playbackInfo = trackPlaybackInfo;
|
|
18449
18464
|
mainStaff.capo = IOHelper.readInt32LE(this.data);
|
|
18450
18465
|
newTrack.color = GpBinaryHelpers.gpReadColor(this.data, false);
|
|
18451
18466
|
if (this._versionNumber >= 500) {
|
|
@@ -18469,8 +18484,8 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18469
18484
|
this._readRseBank();
|
|
18470
18485
|
if (this._versionNumber >= 510) {
|
|
18471
18486
|
this.data.skip(4);
|
|
18472
|
-
GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18473
|
-
GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18487
|
+
GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18488
|
+
GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18474
18489
|
}
|
|
18475
18490
|
} else if (tuning[tuning.length - 1] < Gp3To5Importer._bassClefTuningThreshold) this._clefsPerTrack.set(newTrack.index, Clef.F4);
|
|
18476
18491
|
else this._clefsPerTrack.set(newTrack.index, Clef.G2);
|
|
@@ -18573,7 +18588,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18573
18588
|
if ((flags & 2) !== 0) this.readChord(newBeat);
|
|
18574
18589
|
const beatTextAsLyrics = this.settings.importer.beatTextAsLyrics && track.index !== this._lyricsTrack;
|
|
18575
18590
|
if ((flags & 4) !== 0) {
|
|
18576
|
-
const text = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.
|
|
18591
|
+
const text = GpBinaryHelpers.gpReadStringIntUnused(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18577
18592
|
if (beatTextAsLyrics) {
|
|
18578
18593
|
const lyrics = new Lyrics();
|
|
18579
18594
|
lyrics.text = text.trim();
|
|
@@ -18620,7 +18635,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18620
18635
|
const chordId = ModelUtils.newGuid();
|
|
18621
18636
|
if (this._versionNumber >= 500) {
|
|
18622
18637
|
this.data.skip(17);
|
|
18623
|
-
chord.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 21, this.
|
|
18638
|
+
chord.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 21, this._stringEncoding);
|
|
18624
18639
|
this.data.skip(4);
|
|
18625
18640
|
chord.firstFret = IOHelper.readInt32LE(this.data);
|
|
18626
18641
|
for (let i = 0; i < 7; i++) {
|
|
@@ -18634,7 +18649,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18634
18649
|
this.data.skip(26);
|
|
18635
18650
|
} else if (this.data.readByte() !== 0) if (this._versionNumber >= 400) {
|
|
18636
18651
|
this.data.skip(16);
|
|
18637
|
-
chord.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 21, this.
|
|
18652
|
+
chord.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 21, this._stringEncoding);
|
|
18638
18653
|
this.data.skip(4);
|
|
18639
18654
|
chord.firstFret = IOHelper.readInt32LE(this.data);
|
|
18640
18655
|
for (let i = 0; i < 7; i++) {
|
|
@@ -18648,7 +18663,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18648
18663
|
this.data.skip(26);
|
|
18649
18664
|
} else {
|
|
18650
18665
|
this.data.skip(25);
|
|
18651
|
-
chord.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 34, this.
|
|
18666
|
+
chord.name = GpBinaryHelpers.gpReadStringByteLength(this.data, 34, this._stringEncoding);
|
|
18652
18667
|
chord.firstFret = IOHelper.readInt32LE(this.data);
|
|
18653
18668
|
for (let i = 0; i < 6; i++) {
|
|
18654
18669
|
const fret = IOHelper.readInt32LE(this.data);
|
|
@@ -18658,7 +18673,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18658
18673
|
}
|
|
18659
18674
|
else {
|
|
18660
18675
|
const strings = this._versionNumber >= 406 ? 7 : 6;
|
|
18661
|
-
chord.name = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18676
|
+
chord.name = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18662
18677
|
chord.firstFret = IOHelper.readInt32LE(this.data);
|
|
18663
18678
|
if (chord.firstFret > 0) for (let i = 0; i < strings; i++) {
|
|
18664
18679
|
const fret = IOHelper.readInt32LE(this.data);
|
|
@@ -18778,7 +18793,7 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18778
18793
|
const reverb = IOHelper.readSInt8(this.data);
|
|
18779
18794
|
const phaser = IOHelper.readSInt8(this.data);
|
|
18780
18795
|
const tremolo = IOHelper.readSInt8(this.data);
|
|
18781
|
-
if (this._versionNumber >= 500) tableChange.tempoName = GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18796
|
+
if (this._versionNumber >= 500) tableChange.tempoName = GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18782
18797
|
tableChange.tempo = IOHelper.readInt32LE(this.data);
|
|
18783
18798
|
if (tableChange.volume >= 0) this.data.readByte();
|
|
18784
18799
|
if (tableChange.balance >= 0) this.data.readByte();
|
|
@@ -18797,8 +18812,8 @@ class Gp3To5Importer extends ScoreImporter {
|
|
|
18797
18812
|
else if (wahType >= 0) beat.wahPedal = WahPedal.Open;
|
|
18798
18813
|
}
|
|
18799
18814
|
if (this._versionNumber >= 510) {
|
|
18800
|
-
GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18801
|
-
GpBinaryHelpers.gpReadStringIntByte(this.data, this.
|
|
18815
|
+
GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18816
|
+
GpBinaryHelpers.gpReadStringIntByte(this.data, this._stringEncoding, this.settings.importer.maxDecodingBufferSize);
|
|
18802
18817
|
}
|
|
18803
18818
|
if (tableChange.volume >= 0) {
|
|
18804
18819
|
const volumeAutomation = new Automation();
|
|
@@ -22548,6 +22563,10 @@ class InstrumentArticulationWithPlaybackInfo extends InstrumentArticulation {
|
|
|
22548
22563
|
* The balance to use when playing the note (-1 if using the default track balance).
|
|
22549
22564
|
*/
|
|
22550
22565
|
outputBalance = -1;
|
|
22566
|
+
/**
|
|
22567
|
+
* Whether this instrument was declared as an unpitched/percussion sound via `<midi-unpitched>`.
|
|
22568
|
+
*/
|
|
22569
|
+
isUnpitched = false;
|
|
22551
22570
|
}
|
|
22552
22571
|
/**
|
|
22553
22572
|
* @internal
|
|
@@ -22592,6 +22611,9 @@ class TrackInfo {
|
|
|
22592
22611
|
this.track.percussionArticulations.push(newArticulation);
|
|
22593
22612
|
return index;
|
|
22594
22613
|
}
|
|
22614
|
+
isUnpitchedInstrument(instrumentId) {
|
|
22615
|
+
return this.instruments.has(instrumentId) && this.instruments.get(instrumentId).isUnpitched;
|
|
22616
|
+
}
|
|
22595
22617
|
}
|
|
22596
22618
|
/**
|
|
22597
22619
|
* @internal
|
|
@@ -22906,6 +22928,7 @@ class MusicXmlImporter extends ScoreImporter {
|
|
|
22906
22928
|
break;
|
|
22907
22929
|
case "midi-unpitched":
|
|
22908
22930
|
articulation.outputMidiNumber = Number.parseInt(c.innerText, 10) - 1;
|
|
22931
|
+
articulation.isUnpitched = true;
|
|
22909
22932
|
break;
|
|
22910
22933
|
case "volume":
|
|
22911
22934
|
articulation.outputVolume = MusicXmlImporter._interpolatePercent(Number.parseFloat(c.innerText));
|
|
@@ -24324,11 +24347,15 @@ class MusicXmlImporter extends ScoreImporter {
|
|
|
24324
24347
|
note.isVisible = noteIsVisible;
|
|
24325
24348
|
if (note.percussionArticulation >= 0) return;
|
|
24326
24349
|
const trackInfo = this._indexToTrackInfo.get(track.index);
|
|
24327
|
-
if (
|
|
24328
|
-
|
|
24350
|
+
if (!isPitched) {
|
|
24351
|
+
note.percussionArticulation = trackInfo.getOrCreateArticulation(instrumentId ?? "", note);
|
|
24352
|
+
return;
|
|
24353
|
+
}
|
|
24354
|
+
if (instrumentId !== null && trackInfo.isUnpitchedInstrument(instrumentId)) note.percussionArticulation = trackInfo.getOrCreateArticulation(instrumentId, note);
|
|
24355
|
+
else if (note.beat.voice.bar.staff.isPercussion) {
|
|
24329
24356
|
const knownArticulation = PercussionMapper.getArticulationById(note.displayValue);
|
|
24330
24357
|
if (knownArticulation) note.percussionArticulation = knownArticulation.id;
|
|
24331
|
-
}
|
|
24358
|
+
}
|
|
24332
24359
|
}
|
|
24333
24360
|
_parsePlay(element, note) {
|
|
24334
24361
|
for (const c of element.childElements()) switch (c.localName) {
|
|
@@ -28832,11 +28859,21 @@ class ImporterSettings {
|
|
|
28832
28859
|
*
|
|
28833
28860
|
* * Guitar Pro 7
|
|
28834
28861
|
* * Guitar Pro 6
|
|
28835
|
-
* * Guitar Pro 3-5
|
|
28836
28862
|
* * MusicXML
|
|
28837
28863
|
*/
|
|
28838
28864
|
encoding = "utf-8";
|
|
28839
28865
|
/**
|
|
28866
|
+
* The text encoding to use when decoding strings within GuitarPro3-5 files.
|
|
28867
|
+
* @since 1.9.0
|
|
28868
|
+
* @defaultValue `windows-1252`
|
|
28869
|
+
* @category Importer
|
|
28870
|
+
* @remarks
|
|
28871
|
+
* Guitar Pro 3-5 encode strings as system specific ANSI encoding, typically Windows-1252 in western system cultures.
|
|
28872
|
+
* This is different to the other typically used utf-8 encoding.
|
|
28873
|
+
* Via this setting the Guitar Pro 3-5 specific decoding can be used.
|
|
28874
|
+
*/
|
|
28875
|
+
gp3To5encoding = "windows-1252";
|
|
28876
|
+
/**
|
|
28840
28877
|
* If part-groups should be merged into a single track (MusicXML).
|
|
28841
28878
|
* @since 0.9.6
|
|
28842
28879
|
* @defaultValue `false`
|
|
@@ -29160,11 +29197,45 @@ class PlayerSettings {
|
|
|
29160
29197
|
* @since 0.9.7
|
|
29161
29198
|
* @defaultValue `true`
|
|
29162
29199
|
* @category Player
|
|
29200
|
+
* @json_read_only
|
|
29163
29201
|
* @remarks
|
|
29164
29202
|
* This setting configures whether alphaTab provides the default user interaction features like selection of the playback range and "seek on click".
|
|
29165
29203
|
* By default users can select the desired playback range with the mouse and also jump to individual beats by click. This behavior can be contolled with this setting.
|
|
29204
|
+
* @deprecated Use {@link enableSeekToClick} and {@link enablePlaybackRangeSelection} individually
|
|
29205
|
+
*/
|
|
29206
|
+
get enableUserInteraction() {
|
|
29207
|
+
return this.enableSeekToClick || this.enablePlaybackRangeSelection;
|
|
29208
|
+
}
|
|
29209
|
+
/**
|
|
29210
|
+
* @deprecated Use {@link enableSeekToClick} and {@link enablePlaybackRangeSelection} individually
|
|
29211
|
+
*/
|
|
29212
|
+
set enableUserInteraction(value) {
|
|
29213
|
+
this.enableSeekToClick = value;
|
|
29214
|
+
this.enablePlaybackRangeSelection = value;
|
|
29215
|
+
this.resetPlaybackRangeOnClick = value;
|
|
29216
|
+
}
|
|
29217
|
+
/**
|
|
29218
|
+
* Whether the a click on the music sheet triggers a player seek to the note/beat at the
|
|
29219
|
+
* clicked location.
|
|
29220
|
+
* @since 1.9.0
|
|
29221
|
+
* @defaultValue `true`
|
|
29222
|
+
* @category Player
|
|
29223
|
+
*/
|
|
29224
|
+
enableSeekToClick = true;
|
|
29225
|
+
/**
|
|
29226
|
+
* Whether user click and drag results in a selection defining the playback range.
|
|
29227
|
+
* @since 1.9.0
|
|
29228
|
+
* @defaultValue `true`
|
|
29229
|
+
* @category Player
|
|
29230
|
+
*/
|
|
29231
|
+
enablePlaybackRangeSelection = true;
|
|
29232
|
+
/**
|
|
29233
|
+
* Whether a simple click (no range drag) should reset the current playback range.
|
|
29234
|
+
* @since 1.9.0
|
|
29235
|
+
* @defaultValue `true`
|
|
29236
|
+
* @category Player
|
|
29166
29237
|
*/
|
|
29167
|
-
|
|
29238
|
+
resetPlaybackRangeOnClick = true;
|
|
29168
29239
|
/**
|
|
29169
29240
|
* The X-offset to add when scrolling.
|
|
29170
29241
|
* @since 0.9.6
|
|
@@ -30188,6 +30259,7 @@ class ImporterSettingsSerializer {
|
|
|
30188
30259
|
if (!obj) return null;
|
|
30189
30260
|
const o = /* @__PURE__ */ new Map();
|
|
30190
30261
|
o.set("encoding", obj.encoding);
|
|
30262
|
+
o.set("gp3to5encoding", obj.gp3To5encoding);
|
|
30191
30263
|
o.set("mergepartgroupsinmusicxml", obj.mergePartGroupsInMusicXml);
|
|
30192
30264
|
o.set("beattextaslyrics", obj.beatTextAsLyrics);
|
|
30193
30265
|
o.set("maxdecodingbuffersize", obj.maxDecodingBufferSize);
|
|
@@ -30198,6 +30270,9 @@ class ImporterSettingsSerializer {
|
|
|
30198
30270
|
case "encoding":
|
|
30199
30271
|
obj.encoding = v;
|
|
30200
30272
|
return true;
|
|
30273
|
+
case "gp3to5encoding":
|
|
30274
|
+
obj.gp3To5encoding = v;
|
|
30275
|
+
return true;
|
|
30201
30276
|
case "mergepartgroupsinmusicxml":
|
|
30202
30277
|
obj.mergePartGroupsInMusicXml = v;
|
|
30203
30278
|
return true;
|
|
@@ -30317,7 +30392,9 @@ class PlayerSettingsSerializer {
|
|
|
30317
30392
|
o.set("enablecursor", obj.enableCursor);
|
|
30318
30393
|
o.set("enableanimatedbeatcursor", obj.enableAnimatedBeatCursor);
|
|
30319
30394
|
o.set("enableelementhighlighting", obj.enableElementHighlighting);
|
|
30320
|
-
o.set("
|
|
30395
|
+
o.set("enableseektoclick", obj.enableSeekToClick);
|
|
30396
|
+
o.set("enableplaybackrangeselection", obj.enablePlaybackRangeSelection);
|
|
30397
|
+
o.set("resetplaybackrangeonclick", obj.resetPlaybackRangeOnClick);
|
|
30321
30398
|
o.set("scrolloffsetx", obj.scrollOffsetX);
|
|
30322
30399
|
o.set("scrolloffsety", obj.scrollOffsetY);
|
|
30323
30400
|
o.set("scrollmode", obj.scrollMode);
|
|
@@ -30360,6 +30437,15 @@ class PlayerSettingsSerializer {
|
|
|
30360
30437
|
case "enableuserinteraction":
|
|
30361
30438
|
obj.enableUserInteraction = v;
|
|
30362
30439
|
return true;
|
|
30440
|
+
case "enableseektoclick":
|
|
30441
|
+
obj.enableSeekToClick = v;
|
|
30442
|
+
return true;
|
|
30443
|
+
case "enableplaybackrangeselection":
|
|
30444
|
+
obj.enablePlaybackRangeSelection = v;
|
|
30445
|
+
return true;
|
|
30446
|
+
case "resetplaybackrangeonclick":
|
|
30447
|
+
obj.resetPlaybackRangeOnClick = v;
|
|
30448
|
+
return true;
|
|
30363
30449
|
case "scrolloffsetx":
|
|
30364
30450
|
obj.scrollOffsetX = v;
|
|
30365
30451
|
return true;
|
|
@@ -45358,6 +45444,16 @@ class BeatContainerGlyphBase extends Glyph {
|
|
|
45358
45444
|
scaleToWidth(beatWidth) {
|
|
45359
45445
|
this.width = beatWidth;
|
|
45360
45446
|
}
|
|
45447
|
+
/**
|
|
45448
|
+
* Repositions this beat so its {@link onTimeX} anchor lands at `target`, used for the
|
|
45449
|
+
* centered full-bar note/rest (see {@link BarLayoutingInfo.isCenteredFullBar}). The default
|
|
45450
|
+
* shifts the whole container, matching the regular (non-centered) positioning formula.
|
|
45451
|
+
* {@link BeatContainerGlyph} overrides this to shift only its ink, keeping `x`/`width`
|
|
45452
|
+
* spanning the full bar so bounds lookups and skyline emission stay correct.
|
|
45453
|
+
*/
|
|
45454
|
+
applyCenterOffset(target) {
|
|
45455
|
+
this.x = target - this.onTimeX;
|
|
45456
|
+
}
|
|
45361
45457
|
}
|
|
45362
45458
|
/**
|
|
45363
45459
|
* @internal
|
|
@@ -45461,13 +45557,28 @@ class BeatContainerGlyph extends BeatContainerGlyphBase {
|
|
|
45461
45557
|
this.preNotes.renderer = this.renderer;
|
|
45462
45558
|
this.preNotes.container = this;
|
|
45463
45559
|
this.preNotes.doLayout();
|
|
45464
|
-
this.
|
|
45560
|
+
this._layoutOnsetX();
|
|
45465
45561
|
this.onNotes.renderer = this.renderer;
|
|
45466
45562
|
this.onNotes.container = this;
|
|
45467
45563
|
this.onNotes.doLayout();
|
|
45468
45564
|
this.createBeatTies();
|
|
45469
45565
|
this.updateWidth();
|
|
45470
45566
|
}
|
|
45567
|
+
/**
|
|
45568
|
+
* Resets `preNotes.x`/`onNotes.x` to their natural (un-centered) baseline.
|
|
45569
|
+
* Shared by {@link doLayout} and {@link applyCenterOffset} so the latter can be called
|
|
45570
|
+
* repeatedly (once per `_scaleToForce` pass) without compounding a previous offset.
|
|
45571
|
+
*/
|
|
45572
|
+
_layoutOnsetX() {
|
|
45573
|
+
this.preNotes.x = 0;
|
|
45574
|
+
this.onNotes.x = this.preNotes.x + this.preNotes.width;
|
|
45575
|
+
}
|
|
45576
|
+
applyCenterOffset(target) {
|
|
45577
|
+
this._layoutOnsetX();
|
|
45578
|
+
const offset = target - this.onTimeX;
|
|
45579
|
+
this.preNotes.x = offset;
|
|
45580
|
+
this.onNotes.x = this.preNotes.x + this.preNotes.width;
|
|
45581
|
+
}
|
|
45471
45582
|
createBeatTies() {
|
|
45472
45583
|
let i = this.beat.notes.length - 1;
|
|
45473
45584
|
while (i >= 0) this.createTies(this.beat.notes[i--]);
|
|
@@ -48557,7 +48668,7 @@ class AlphaTabApiBase {
|
|
|
48557
48668
|
}
|
|
48558
48669
|
_onBeatMouseDown(originalEvent, beat) {
|
|
48559
48670
|
if (this._isDestroyed) return;
|
|
48560
|
-
if (this._hasCursor && this.settings.player.
|
|
48671
|
+
if (this._hasCursor && this.settings.player.enablePlaybackRangeSelection) {
|
|
48561
48672
|
this._selectionStart = { beat };
|
|
48562
48673
|
this._selectionEnd = void 0;
|
|
48563
48674
|
}
|
|
@@ -48573,10 +48684,12 @@ class AlphaTabApiBase {
|
|
|
48573
48684
|
}
|
|
48574
48685
|
_onBeatMouseMove(originalEvent, beat) {
|
|
48575
48686
|
if (this._isDestroyed) return;
|
|
48576
|
-
if (this.settings.player.
|
|
48687
|
+
if (this.settings.player.enablePlaybackRangeSelection) {
|
|
48577
48688
|
if (!this._selectionEnd || this._selectionEnd.beat !== beat) {
|
|
48578
|
-
this.
|
|
48579
|
-
|
|
48689
|
+
if (this._selectionStart?.beat !== beat) {
|
|
48690
|
+
this._selectionEnd = { beat };
|
|
48691
|
+
this._cursorSelectRange(this._selectionStart, this._selectionEnd);
|
|
48692
|
+
}
|
|
48580
48693
|
}
|
|
48581
48694
|
}
|
|
48582
48695
|
this.beatMouseMove.trigger(beat);
|
|
@@ -48589,11 +48702,30 @@ class AlphaTabApiBase {
|
|
|
48589
48702
|
}
|
|
48590
48703
|
_onBeatMouseUp(originalEvent, beat) {
|
|
48591
48704
|
if (this._isDestroyed) return;
|
|
48592
|
-
if (this._hasCursor
|
|
48705
|
+
if (this._hasCursor) {
|
|
48706
|
+
let shouldSeekToBeat = beat && this.settings.player.enableSeekToClick;
|
|
48707
|
+
if (this.settings.player.enablePlaybackRangeSelection) {
|
|
48708
|
+
if (this._internalApplyPlaybackRangeFromHighlight()) shouldSeekToBeat = false;
|
|
48709
|
+
}
|
|
48710
|
+
if (shouldSeekToBeat) this._seekToBeat(beat);
|
|
48711
|
+
}
|
|
48593
48712
|
this.beatMouseUp.trigger(beat);
|
|
48594
48713
|
this.uiFacade.triggerEvent(this.container, "beatMouseUp", beat, originalEvent);
|
|
48595
48714
|
this._isBeatMouseDown = false;
|
|
48596
48715
|
}
|
|
48716
|
+
_seekToBeat(beat) {
|
|
48717
|
+
const tickCache = this._tickCache;
|
|
48718
|
+
if (!tickCache) return;
|
|
48719
|
+
this._currentBeat = null;
|
|
48720
|
+
let beatTick = tickCache.getMasterBarStart(beat.voice.bar.masterBar) + (tickCache.getRelativeBeatPlaybackRange(beat)?.startTick ?? beat.playbackStart);
|
|
48721
|
+
const playbackRange = this.playbackRange;
|
|
48722
|
+
if (playbackRange) {
|
|
48723
|
+
if (beatTick < playbackRange.startTick) beatTick = playbackRange.startTick;
|
|
48724
|
+
else if (beatTick > playbackRange.endTick) beatTick = playbackRange.endTick;
|
|
48725
|
+
}
|
|
48726
|
+
if (this._player.state === PlayerState.Paused) this._cursorUpdateTick(beatTick, false, 1);
|
|
48727
|
+
this.tickPosition = beatTick;
|
|
48728
|
+
}
|
|
48597
48729
|
_onNoteMouseUp(originalEvent, note) {
|
|
48598
48730
|
if (this._isDestroyed) return;
|
|
48599
48731
|
this.noteMouseUp.trigger(note);
|
|
@@ -48615,7 +48747,7 @@ class AlphaTabApiBase {
|
|
|
48615
48747
|
_setupClickHandling() {
|
|
48616
48748
|
this.canvasElement.mouseDown.on((e) => {
|
|
48617
48749
|
if (!e.isLeftMouseButton) return;
|
|
48618
|
-
if (this.settings.player.
|
|
48750
|
+
if (this.settings.player.enablePlaybackRangeSelection || this.settings.player.enableSeekToClick) e.preventDefault();
|
|
48619
48751
|
const relX = e.getX(this.canvasElement);
|
|
48620
48752
|
const relY = e.getY(this.canvasElement);
|
|
48621
48753
|
const beat = this._renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
|
|
@@ -48642,7 +48774,7 @@ class AlphaTabApiBase {
|
|
|
48642
48774
|
});
|
|
48643
48775
|
this.canvasElement.mouseUp.on((e) => {
|
|
48644
48776
|
if (!this._isBeatMouseDown) return;
|
|
48645
|
-
if (this.settings.player.
|
|
48777
|
+
if (this.settings.player.enablePlaybackRangeSelection || this.settings.player.enableSeekToClick) e.preventDefault();
|
|
48646
48778
|
const relX = e.getX(this.canvasElement);
|
|
48647
48779
|
const relY = e.getY(this.canvasElement);
|
|
48648
48780
|
const beat = this._renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
|
|
@@ -48653,7 +48785,7 @@ class AlphaTabApiBase {
|
|
|
48653
48785
|
} else this._onNoteMouseUp(e, null);
|
|
48654
48786
|
});
|
|
48655
48787
|
this._renderer.postRenderFinished.on(() => {
|
|
48656
|
-
if (!this._selectionStart || !this._hasCursor || !this.settings.player.
|
|
48788
|
+
if (!this._selectionStart || !this._hasCursor || !this.settings.player.enablePlaybackRangeSelection) return;
|
|
48657
48789
|
this._cursorSelectRange(this._selectionStart, this._selectionEnd);
|
|
48658
48790
|
});
|
|
48659
48791
|
}
|
|
@@ -48745,6 +48877,9 @@ class AlphaTabApiBase {
|
|
|
48745
48877
|
* ```
|
|
48746
48878
|
*/
|
|
48747
48879
|
applyPlaybackRangeFromHighlight() {
|
|
48880
|
+
this._internalApplyPlaybackRangeFromHighlight();
|
|
48881
|
+
}
|
|
48882
|
+
_internalApplyPlaybackRangeFromHighlight() {
|
|
48748
48883
|
if (this._selectionEnd) {
|
|
48749
48884
|
const startTick = this._tickCache?.getBeatStart(this._selectionStart.beat) ?? this._selectionStart.beat.absolutePlaybackStart;
|
|
48750
48885
|
if ((this._tickCache?.getBeatStart(this._selectionEnd.beat) ?? this._selectionEnd.beat.absolutePlaybackStart) < startTick) {
|
|
@@ -48752,27 +48887,32 @@ class AlphaTabApiBase {
|
|
|
48752
48887
|
this._selectionStart = this._selectionEnd;
|
|
48753
48888
|
this._selectionEnd = t;
|
|
48754
48889
|
}
|
|
48755
|
-
}
|
|
48890
|
+
} else if (!this.settings.player.resetPlaybackRangeOnClick) return false;
|
|
48756
48891
|
if (this._selectionStart && this._tickCache) {
|
|
48757
48892
|
const tickCache = this._tickCache;
|
|
48758
48893
|
const realStartMasterBarStart = tickCache.getMasterBarStart(this._selectionStart.beat.voice.bar.masterBar);
|
|
48759
48894
|
const startBeatPlaybackStart = tickCache.getRelativeBeatPlaybackRange(this._selectionStart.beat)?.startTick ?? this._selectionStart.beat.playbackStart;
|
|
48760
|
-
|
|
48761
|
-
if (this._player.state === PlayerState.Paused) this._cursorUpdateTick(realStartMasterBarStart + startBeatPlaybackStart, false, 1);
|
|
48762
|
-
this.tickPosition = realStartMasterBarStart + startBeatPlaybackStart;
|
|
48895
|
+
let seekToStart = this.settings.player.enableSeekToClick;
|
|
48763
48896
|
if (this._selectionEnd && this._selectionStart.beat !== this._selectionEnd.beat) {
|
|
48897
|
+
seekToStart = true;
|
|
48764
48898
|
const realEndMasterBarStart = tickCache.getMasterBarStart(this._selectionEnd.beat.voice.bar.masterBar);
|
|
48765
48899
|
const endBeatPlaybackEnd = tickCache.getRelativeBeatPlaybackRange(this._selectionEnd.beat)?.endTick ?? this._selectionEnd.beat.playbackStart + this._selectionEnd.beat.playbackDuration;
|
|
48766
48900
|
const range = new PlaybackRange();
|
|
48767
48901
|
range.startTick = realStartMasterBarStart + startBeatPlaybackStart;
|
|
48768
48902
|
range.endTick = realEndMasterBarStart + endBeatPlaybackEnd - 50;
|
|
48769
48903
|
this.playbackRange = range;
|
|
48770
|
-
} else {
|
|
48904
|
+
} else if (this.settings.player.resetPlaybackRangeOnClick) {
|
|
48771
48905
|
this._selectionStart = void 0;
|
|
48772
48906
|
this.playbackRange = null;
|
|
48773
48907
|
this._cursorSelectRange(this._selectionStart, this._selectionEnd);
|
|
48774
48908
|
}
|
|
48909
|
+
if (seekToStart) {
|
|
48910
|
+
this._currentBeat = null;
|
|
48911
|
+
if (this._player.state === PlayerState.Paused) this._cursorUpdateTick(realStartMasterBarStart + startBeatPlaybackStart, false, 1);
|
|
48912
|
+
this.tickPosition = realStartMasterBarStart + startBeatPlaybackStart;
|
|
48913
|
+
}
|
|
48775
48914
|
}
|
|
48915
|
+
return true;
|
|
48776
48916
|
}
|
|
48777
48917
|
/**
|
|
48778
48918
|
* Clears the highlight markers marking the currently selected playback range.
|
|
@@ -50058,7 +50198,8 @@ class AlphaTabApi extends AlphaTabApiBase {
|
|
|
50058
50198
|
settings.player.enableCursor = false;
|
|
50059
50199
|
settings.player.playerMode = PlayerMode.Disabled;
|
|
50060
50200
|
settings.player.enableElementHighlighting = false;
|
|
50061
|
-
settings.player.
|
|
50201
|
+
settings.player.enableSeekToClick = false;
|
|
50202
|
+
settings.player.enablePlaybackRangeSelection = false;
|
|
50062
50203
|
settings.player.soundFont = null;
|
|
50063
50204
|
settings.display.scale = .8;
|
|
50064
50205
|
settings.display.stretchForce = .8;
|
|
@@ -50868,7 +51009,9 @@ class AlphaSynthWebWorker {
|
|
|
50868
51009
|
}
|
|
50869
51010
|
handleMessage(e) {
|
|
50870
51011
|
const data = e.data;
|
|
50871
|
-
|
|
51012
|
+
const cmd = data.cmd;
|
|
51013
|
+
if (!cmd) return;
|
|
51014
|
+
switch (cmd) {
|
|
50872
51015
|
case "alphaSynth.initialize":
|
|
50873
51016
|
AlphaSynthWorkerSynthOutput.preferredSampleRate = data.sampleRate;
|
|
50874
51017
|
Logger.logLevel = data.logLevel;
|
|
@@ -50962,7 +51105,7 @@ class AlphaSynthWebWorker {
|
|
|
50962
51105
|
this._player.applyTranspositionPitches(data.transpositionPitches);
|
|
50963
51106
|
break;
|
|
50964
51107
|
}
|
|
50965
|
-
if (
|
|
51108
|
+
if (cmd.startsWith("alphaSynth.exporter")) this._handleExporterMessage(e);
|
|
50966
51109
|
}
|
|
50967
51110
|
_handleExporterMessage(ev) {
|
|
50968
51111
|
const data = ev.data;
|
|
@@ -54466,9 +54609,35 @@ class MultiVoiceContainerGlyph extends Glyph {
|
|
|
54466
54609
|
const force = this.renderer.layoutingInfo.spaceToForce(width);
|
|
54467
54610
|
this._scaleToForce(force, true);
|
|
54468
54611
|
}
|
|
54612
|
+
/**
|
|
54613
|
+
* `true` when every voice/track/staff contributes exactly one beat, of uniform duration,
|
|
54614
|
+
* spanning the bar's entire duration - i.e. a single full-bar note/rest. Common engraving
|
|
54615
|
+
* practice centers such notes horizontally within the bar rather than anchoring them right
|
|
54616
|
+
* after the pre-beat content (Behind Bars, p. 41; see #2464).
|
|
54617
|
+
*/
|
|
54618
|
+
_isCenteredFullBar() {
|
|
54619
|
+
const masterBar = this.renderer.bar.masterBar;
|
|
54620
|
+
const layoutingInfo = this.renderer.layoutingInfo;
|
|
54621
|
+
const springs = layoutingInfo.springs;
|
|
54622
|
+
if (springs.size !== 1 || !springs.has(masterBar.start) || layoutingInfo.allGraceRods.size > 0) return false;
|
|
54623
|
+
const spring = springs.get(masterBar.start);
|
|
54624
|
+
return spring.allDurations.size === 1 && spring.longestDuration === masterBar.calculateDuration();
|
|
54625
|
+
}
|
|
54469
54626
|
/** `emit=false`: positioning-only path; final skyline emission runs later via {@link scaleToWidth}. */
|
|
54470
54627
|
_scaleToForce(force, emit) {
|
|
54471
54628
|
this.width = this.renderer.layoutingInfo.calculateVoiceWidth(force);
|
|
54629
|
+
if (this._isCenteredFullBar()) {
|
|
54630
|
+
const barNumberWidth = this.renderer.barNumberWidth;
|
|
54631
|
+
const target = (this.width - barNumberWidth) / 2;
|
|
54632
|
+
for (const beatGlyphs of this.beatGlyphs.values()) {
|
|
54633
|
+
const soleBeatGlyph = beatGlyphs[0];
|
|
54634
|
+
soleBeatGlyph.x = 0;
|
|
54635
|
+
soleBeatGlyph.applyCenterOffset(target);
|
|
54636
|
+
soleBeatGlyph.scaleToWidth(this.width);
|
|
54637
|
+
if (emit) this._emitBeatContainerSkyline(soleBeatGlyph);
|
|
54638
|
+
}
|
|
54639
|
+
return;
|
|
54640
|
+
}
|
|
54472
54641
|
const positions = this.renderer.layoutingInfo.buildOnTimePositions(force);
|
|
54473
54642
|
for (const beatGlyphs of this.beatGlyphs.values()) for (let i = 0, j = beatGlyphs.length; i < j; i++) {
|
|
54474
54643
|
const currentBeatGlyph = beatGlyphs[i];
|
|
@@ -60790,14 +60959,22 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
60790
60959
|
calculateBeamY(h, x) {
|
|
60791
60960
|
return this.calculateBeamYWithDirection(h, x, this.getBeamDirection(h));
|
|
60792
60961
|
}
|
|
60962
|
+
barNumberGlyph;
|
|
60963
|
+
get barNumberWidth() {
|
|
60964
|
+
return this.barNumberGlyph?.width ?? 0;
|
|
60965
|
+
}
|
|
60793
60966
|
createPreBeatGlyphs() {
|
|
60794
60967
|
super.createPreBeatGlyphs();
|
|
60968
|
+
this.barNumberGlyph = void 0;
|
|
60795
60969
|
this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
|
|
60796
60970
|
this.createLinePreBeatGlyphs();
|
|
60797
60971
|
let hasSpaceAfterStartGlyphs = false;
|
|
60798
60972
|
if (this.index === 0) hasSpaceAfterStartGlyphs = this.createStartSpacing();
|
|
60799
|
-
if (this.shouldCreateBarNumber())
|
|
60800
|
-
|
|
60973
|
+
if (this.shouldCreateBarNumber()) {
|
|
60974
|
+
const barNumberGlyph = new BarNumberGlyph(0, this.getLineHeight(-.5), this.bar.index + 1);
|
|
60975
|
+
this.barNumberGlyph = barNumberGlyph;
|
|
60976
|
+
this.addPreBeatGlyph(barNumberGlyph);
|
|
60977
|
+
} else if (!hasSpaceAfterStartGlyphs) this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
|
|
60801
60978
|
}
|
|
60802
60979
|
resolveClefDisplay() {
|
|
60803
60980
|
return { isVisible: false };
|
|
@@ -64389,8 +64566,11 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
64389
64566
|
if (this.index === 0 || this.bar.masterBar.isRepeatStart && this.staff.isCascadePrimary) this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
|
|
64390
64567
|
this.createLinePreBeatGlyphs();
|
|
64391
64568
|
const hasSpaceAfterStartGlyphs = this.createStartSpacing();
|
|
64392
|
-
if (this.shouldCreateBarNumber())
|
|
64393
|
-
|
|
64569
|
+
if (this.shouldCreateBarNumber()) {
|
|
64570
|
+
const barNumberGlyph = new BarNumberGlyph(0, this.getLineHeight(-.5), this.bar.index + 1);
|
|
64571
|
+
this.barNumberGlyph = barNumberGlyph;
|
|
64572
|
+
this.addPreBeatGlyph(barNumberGlyph);
|
|
64573
|
+
} else if (!hasSpaceAfterStartGlyphs) this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
|
|
64394
64574
|
}
|
|
64395
64575
|
createLinePreBeatGlyphs() {
|
|
64396
64576
|
const timeSignatureDisplay = this.resolveTimeSignatureDisplay();
|
|
@@ -70035,8 +70215,8 @@ class GpifWriter {
|
|
|
70035
70215
|
scoreNode.addElement("FirstPageFooter").setCData("");
|
|
70036
70216
|
scoreNode.addElement("PageHeader").setCData("");
|
|
70037
70217
|
scoreNode.addElement("PageFooter").setCData("");
|
|
70038
|
-
scoreNode.addElement("ScoreSystemsDefaultLayout").
|
|
70039
|
-
scoreNode.addElement("ScoreSystemsLayout").
|
|
70218
|
+
scoreNode.addElement("ScoreSystemsDefaultLayout").innerText = score.defaultSystemsLayout.toString();
|
|
70219
|
+
scoreNode.addElement("ScoreSystemsLayout").innerText = score.systemsLayout.join(" ");
|
|
70040
70220
|
scoreNode.addElement("ScoreZoomPolicy").innerText = "Value";
|
|
70041
70221
|
scoreNode.addElement("ScoreZoom").innerText = "1";
|
|
70042
70222
|
scoreNode.addElement("MultiVoice").innerText = "1>";
|