@coderline/alphatab 1.3.0-alpha.369 → 1.3.0-alpha.376

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * alphaTab v1.3.0-alpha.369 (develop, build 369)
2
+ * alphaTab v1.3.0-alpha.376 (develop, build 376)
3
3
  *
4
4
  * Copyright © 2022, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -3639,6 +3639,9 @@ class Beat {
3639
3639
  let index = this.notes.indexOf(note);
3640
3640
  if (index >= 0) {
3641
3641
  this.notes.splice(index, 1);
3642
+ if (note.isStringed) {
3643
+ this.noteStringLookup.delete(note.string);
3644
+ }
3642
3645
  }
3643
3646
  }
3644
3647
  getAutomation(type) {
@@ -4031,6 +4034,73 @@ class Chord {
4031
4034
  }
4032
4035
  }
4033
4036
 
4037
+ /**
4038
+ * This public enumeration lists all available key signatures
4039
+ */
4040
+ var KeySignature;
4041
+ (function (KeySignature) {
4042
+ /**
4043
+ * Cb (7 flats)
4044
+ */
4045
+ KeySignature[KeySignature["Cb"] = -7] = "Cb";
4046
+ /**
4047
+ * Gb (6 flats)
4048
+ */
4049
+ KeySignature[KeySignature["Gb"] = -6] = "Gb";
4050
+ /**
4051
+ * Db (5 flats)
4052
+ */
4053
+ KeySignature[KeySignature["Db"] = -5] = "Db";
4054
+ /**
4055
+ * Ab (4 flats)
4056
+ */
4057
+ KeySignature[KeySignature["Ab"] = -4] = "Ab";
4058
+ /**
4059
+ * Eb (3 flats)
4060
+ */
4061
+ KeySignature[KeySignature["Eb"] = -3] = "Eb";
4062
+ /**
4063
+ * Bb (2 flats)
4064
+ */
4065
+ KeySignature[KeySignature["Bb"] = -2] = "Bb";
4066
+ /**
4067
+ * F (1 flat)
4068
+ */
4069
+ KeySignature[KeySignature["F"] = -1] = "F";
4070
+ /**
4071
+ * C (no signs)
4072
+ */
4073
+ KeySignature[KeySignature["C"] = 0] = "C";
4074
+ /**
4075
+ * G (1 sharp)
4076
+ */
4077
+ KeySignature[KeySignature["G"] = 1] = "G";
4078
+ /**
4079
+ * D (2 sharp)
4080
+ */
4081
+ KeySignature[KeySignature["D"] = 2] = "D";
4082
+ /**
4083
+ * A (3 sharp)
4084
+ */
4085
+ KeySignature[KeySignature["A"] = 3] = "A";
4086
+ /**
4087
+ * E (4 sharp)
4088
+ */
4089
+ KeySignature[KeySignature["E"] = 4] = "E";
4090
+ /**
4091
+ * B (5 sharp)
4092
+ */
4093
+ KeySignature[KeySignature["B"] = 5] = "B";
4094
+ /**
4095
+ * F# (6 sharp)
4096
+ */
4097
+ KeySignature[KeySignature["FSharp"] = 6] = "FSharp";
4098
+ /**
4099
+ * C# (7 sharp)
4100
+ */
4101
+ KeySignature[KeySignature["CSharp"] = 7] = "CSharp";
4102
+ })(KeySignature || (KeySignature = {}));
4103
+
4034
4104
  var LyricsState;
4035
4105
  (function (LyricsState) {
4036
4106
  LyricsState[LyricsState["IgnoreSpaces"] = 0] = "IgnoreSpaces";
@@ -4166,73 +4236,6 @@ Lyrics.CharCodeBrackedClose = 93;
4166
4236
  Lyrics.CharCodeBrackedOpen = 91;
4167
4237
  Lyrics.CharCodeDash = 45;
4168
4238
 
4169
- /**
4170
- * This public enumeration lists all available key signatures
4171
- */
4172
- var KeySignature;
4173
- (function (KeySignature) {
4174
- /**
4175
- * Cb (7 flats)
4176
- */
4177
- KeySignature[KeySignature["Cb"] = -7] = "Cb";
4178
- /**
4179
- * Gb (6 flats)
4180
- */
4181
- KeySignature[KeySignature["Gb"] = -6] = "Gb";
4182
- /**
4183
- * Db (5 flats)
4184
- */
4185
- KeySignature[KeySignature["Db"] = -5] = "Db";
4186
- /**
4187
- * Ab (4 flats)
4188
- */
4189
- KeySignature[KeySignature["Ab"] = -4] = "Ab";
4190
- /**
4191
- * Eb (3 flats)
4192
- */
4193
- KeySignature[KeySignature["Eb"] = -3] = "Eb";
4194
- /**
4195
- * Bb (2 flats)
4196
- */
4197
- KeySignature[KeySignature["Bb"] = -2] = "Bb";
4198
- /**
4199
- * F (1 flat)
4200
- */
4201
- KeySignature[KeySignature["F"] = -1] = "F";
4202
- /**
4203
- * C (no signs)
4204
- */
4205
- KeySignature[KeySignature["C"] = 0] = "C";
4206
- /**
4207
- * G (1 sharp)
4208
- */
4209
- KeySignature[KeySignature["G"] = 1] = "G";
4210
- /**
4211
- * D (2 sharp)
4212
- */
4213
- KeySignature[KeySignature["D"] = 2] = "D";
4214
- /**
4215
- * A (3 sharp)
4216
- */
4217
- KeySignature[KeySignature["A"] = 3] = "A";
4218
- /**
4219
- * E (4 sharp)
4220
- */
4221
- KeySignature[KeySignature["E"] = 4] = "E";
4222
- /**
4223
- * B (5 sharp)
4224
- */
4225
- KeySignature[KeySignature["B"] = 5] = "B";
4226
- /**
4227
- * F# (6 sharp)
4228
- */
4229
- KeySignature[KeySignature["FSharp"] = 6] = "FSharp";
4230
- /**
4231
- * C# (8 sharp)
4232
- */
4233
- KeySignature[KeySignature["CSharp"] = 7] = "CSharp";
4234
- })(KeySignature || (KeySignature = {}));
4235
-
4236
4239
  /**
4237
4240
  * This public enumeration lists all available types of KeySignatures
4238
4241
  */
@@ -5701,11 +5704,11 @@ class AlphaTexError extends AlphaTabError {
5701
5704
  }
5702
5705
  static symbolError(position, nonTerm, expected, symbol, symbolData = null) {
5703
5706
  let message;
5704
- if (!symbolData) {
5707
+ if (expected !== symbol) {
5705
5708
  message = `MalFormed AlphaTex: @${position}: Error on block ${nonTerm}, expected a ${AlphaTexSymbols[expected]} found a ${AlphaTexSymbols[symbol]}: '${symbolData}'`;
5706
5709
  }
5707
5710
  else {
5708
- message = `MalFormed AlphaTex: @${position}: Error on block ${nonTerm}, invalid value: ${symbolData}`;
5711
+ message = `MalFormed AlphaTex: @${position}: Error on block ${nonTerm}, invalid value: '${symbolData}'`;
5709
5712
  }
5710
5713
  let exception = new AlphaTexError(message);
5711
5714
  exception.position = position;
@@ -5716,7 +5719,7 @@ class AlphaTexError extends AlphaTabError {
5716
5719
  return exception;
5717
5720
  }
5718
5721
  static errorMessage(position, message) {
5719
- message = 'MalFormed AlphaTex: @' + position + ': ' + message;
5722
+ message = `MalFormed AlphaTex: @${position}: ${message}`;
5720
5723
  let exception = new AlphaTexError(message);
5721
5724
  exception.position = position;
5722
5725
  return exception;
@@ -5804,7 +5807,7 @@ class AlphaTexImporter extends ScoreImporter {
5804
5807
  error(nonterm, expected, symbolError = true) {
5805
5808
  let e;
5806
5809
  if (symbolError) {
5807
- e = AlphaTexError.symbolError(this._curChPos, nonterm, expected, this._sy, null);
5810
+ e = AlphaTexError.symbolError(this._curChPos, nonterm, expected, this._sy, this._syData);
5808
5811
  }
5809
5812
  else {
5810
5813
  e = AlphaTexError.symbolError(this._curChPos, nonterm, expected, expected, this._syData);
@@ -5945,37 +5948,65 @@ class AlphaTexImporter extends ScoreImporter {
5945
5948
  parseKeySignature(str) {
5946
5949
  switch (str.toLowerCase()) {
5947
5950
  case 'cb':
5948
- return -7;
5951
+ case 'cbmajor':
5952
+ return KeySignature.Cb;
5949
5953
  case 'gb':
5950
- return -6;
5954
+ case 'gbmajor':
5955
+ case 'd#minor':
5956
+ return KeySignature.Gb;
5951
5957
  case 'db':
5952
- return -5;
5958
+ case 'dbmajor':
5959
+ case 'bbminor':
5960
+ return KeySignature.Db;
5953
5961
  case 'ab':
5954
- return -4;
5962
+ case 'abmajor':
5963
+ case 'fminor':
5964
+ return KeySignature.Ab;
5955
5965
  case 'eb':
5956
- return -3;
5966
+ case 'ebmajor':
5967
+ case 'cminor':
5968
+ return KeySignature.Eb;
5957
5969
  case 'bb':
5958
- return -2;
5970
+ case 'bbmajor':
5971
+ case 'gminor':
5972
+ return KeySignature.Bb;
5959
5973
  case 'f':
5960
- return -1;
5974
+ case 'fmajor':
5975
+ case 'dminor':
5976
+ return KeySignature.F;
5961
5977
  case 'c':
5962
- return 0;
5978
+ case 'cmajor':
5979
+ case 'aminor':
5980
+ return KeySignature.C;
5963
5981
  case 'g':
5964
- return 1;
5982
+ case 'gmajor':
5983
+ case 'eminor':
5984
+ return KeySignature.G;
5965
5985
  case 'd':
5966
- return 2;
5986
+ case 'dmajor':
5987
+ case 'bminor':
5988
+ return KeySignature.D;
5967
5989
  case 'a':
5968
- return 3;
5990
+ case 'amajor':
5991
+ case 'f#minor':
5992
+ return KeySignature.A;
5969
5993
  case 'e':
5970
- return 4;
5994
+ case 'emajor':
5995
+ case 'c#minor':
5996
+ return KeySignature.E;
5971
5997
  case 'b':
5972
- return 5;
5998
+ case 'bmajor':
5999
+ case 'g#minor':
6000
+ return KeySignature.B;
5973
6001
  case 'f#':
5974
- return 6;
6002
+ case 'f#major':
6003
+ case 'ebminor':
6004
+ return KeySignature.FSharp;
5975
6005
  case 'c#':
5976
- return 7;
6006
+ case 'c#major':
6007
+ return KeySignature.CSharp;
5977
6008
  default:
5978
- return 0;
6009
+ return KeySignature.C;
5979
6010
  // error("keysignature-value", AlphaTexSymbols.String, false); return 0
5980
6011
  }
5981
6012
  }
@@ -6016,7 +6047,7 @@ class AlphaTexImporter extends ScoreImporter {
6016
6047
  }
6017
6048
  else if (this._ch === 0x2a /* * */) {
6018
6049
  // multiline comment
6019
- while (this._ch !== 0) {
6050
+ while (this._ch !== AlphaTexImporter.Eof) {
6020
6051
  if (this._ch === 0x2a /* * */) {
6021
6052
  this._ch = this.nextChar();
6022
6053
  if (this._ch === 0x2f /* / */) {
@@ -6049,9 +6080,8 @@ class AlphaTexImporter extends ScoreImporter {
6049
6080
  // negative number
6050
6081
  // is number?
6051
6082
  if (this._allowNegatives && this.isDigit(this._ch)) {
6052
- let num = this.readNumber();
6053
6083
  this._sy = AlphaTexSymbols.Number;
6054
- this._syData = num;
6084
+ this._syData = this.readNumber();
6055
6085
  }
6056
6086
  else {
6057
6087
  this._sy = AlphaTexSymbols.String;
@@ -6072,9 +6102,8 @@ class AlphaTexImporter extends ScoreImporter {
6072
6102
  }
6073
6103
  else if (this._ch === 0x5c /* \ */) {
6074
6104
  this._ch = this.nextChar();
6075
- let name = this.readName();
6076
6105
  this._sy = AlphaTexSymbols.MetaCommand;
6077
- this._syData = name;
6106
+ this._syData = this.readName();
6078
6107
  }
6079
6108
  else if (this._ch === 0x29 /* ) */) {
6080
6109
  this._sy = AlphaTexSymbols.RParensis;
@@ -6101,9 +6130,8 @@ class AlphaTexImporter extends ScoreImporter {
6101
6130
  this._ch = this.nextChar();
6102
6131
  }
6103
6132
  else if (this.isDigit(this._ch)) {
6104
- let num = this.readNumber();
6105
6133
  this._sy = AlphaTexSymbols.Number;
6106
- this._syData = num;
6134
+ this._syData = this.readNumber();
6107
6135
  }
6108
6136
  else if (AlphaTexImporter.isLetter(this._ch)) {
6109
6137
  let name = this.readName();
@@ -7366,8 +7394,8 @@ class AlphaTexImporter extends ScoreImporter {
7366
7394
  }
7367
7395
  this._sy = this.newSy();
7368
7396
  }
7369
- toFinger(syData) {
7370
- switch (syData) {
7397
+ toFinger(num) {
7398
+ switch (num) {
7371
7399
  case 1:
7372
7400
  return Fingers.Thumb;
7373
7401
  case 2:
@@ -7403,6 +7431,8 @@ class AlphaTexImporter extends ScoreImporter {
7403
7431
  return Duration.SixtyFourth;
7404
7432
  case 128:
7405
7433
  return Duration.OneHundredTwentyEighth;
7434
+ case 256:
7435
+ return Duration.TwoHundredFiftySixth;
7406
7436
  default:
7407
7437
  return Duration.Quarter;
7408
7438
  }
@@ -7435,6 +7465,9 @@ class AlphaTexImporter extends ScoreImporter {
7435
7465
  if (this._sy !== AlphaTexSymbols.Number) {
7436
7466
  this.error('repeatclose', AlphaTexSymbols.Number, true);
7437
7467
  }
7468
+ if (this._syData > 2048) {
7469
+ this.error('repeatclose', AlphaTexSymbols.Number, false);
7470
+ }
7438
7471
  master.repeatCount = this._syData;
7439
7472
  this._sy = this.newSy();
7440
7473
  }
@@ -7466,14 +7499,14 @@ class AlphaTexImporter extends ScoreImporter {
7466
7499
  if (this._sy !== AlphaTexSymbols.String) {
7467
7500
  this.error('keysignature', AlphaTexSymbols.String, true);
7468
7501
  }
7469
- master.keySignature = this.parseKeySignature(this._syData.toLowerCase());
7502
+ master.keySignature = this.parseKeySignature(this._syData);
7470
7503
  this._sy = this.newSy();
7471
7504
  }
7472
7505
  else if (syData === 'clef') {
7473
7506
  this._sy = this.newSy();
7474
7507
  switch (this._sy) {
7475
7508
  case AlphaTexSymbols.String:
7476
- bar.clef = this.parseClefFromString(this._syData.toLowerCase());
7509
+ bar.clef = this.parseClefFromString(this._syData);
7477
7510
  break;
7478
7511
  case AlphaTexSymbols.Number:
7479
7512
  bar.clef = this.parseClefFromInt(this._syData);
@@ -7524,7 +7557,7 @@ class AlphaTexImporter extends ScoreImporter {
7524
7557
  this._allowTuning = true;
7525
7558
  switch (this._sy) {
7526
7559
  case AlphaTexSymbols.String:
7527
- master.tripletFeel = this.parseTripletFeelFromString(this._syData.toLowerCase());
7560
+ master.tripletFeel = this.parseTripletFeelFromString(this._syData);
7528
7561
  break;
7529
7562
  case AlphaTexSymbols.Number:
7530
7563
  master.tripletFeel = this.parseTripletFeelFromInt(this._syData);
@@ -14530,7 +14563,7 @@ class MidiFileSequencer {
14530
14563
  }
14531
14564
  }
14532
14565
  get currentTime() {
14533
- return this._currentState.currentTime;
14566
+ return this._currentState.currentTime / this.playbackSpeed;
14534
14567
  }
14535
14568
  /**
14536
14569
  * Gets the duration of the song in ticks.
@@ -17457,6 +17490,11 @@ class AlphaSynth {
17457
17490
  this._notPlayedSamples += samples.length;
17458
17491
  this.output.addSamples(samples);
17459
17492
  }
17493
+ else {
17494
+ // Tell output that there is no data left for it.
17495
+ let samples = new Float32Array(0);
17496
+ this.output.addSamples(samples);
17497
+ }
17460
17498
  });
17461
17499
  this.output.samplesPlayed.on(this.onSamplesPlayed.bind(this));
17462
17500
  this.output.open(bufferTimeInMilliseconds);
@@ -17559,7 +17597,7 @@ class AlphaSynth {
17559
17597
  Logger.debug('AlphaSynth', 'Starting countin');
17560
17598
  this._sequencer.startCountIn();
17561
17599
  this._synthesizer.setupMetronomeChannel(this._countInVolume);
17562
- this.tickPosition = 0;
17600
+ this.updateTimePosition(0, true);
17563
17601
  }
17564
17602
  this.output.play();
17565
17603
  return true;
@@ -17711,6 +17749,7 @@ class AlphaSynth {
17711
17749
  this._sequencer.resetCountIn();
17712
17750
  this.timePosition = this._sequencer.currentTime;
17713
17751
  this.playInternal();
17752
+ this.output.resetSamples();
17714
17753
  }
17715
17754
  else if (this._sequencer.isPlayingOneTimeMidi) {
17716
17755
  Logger.debug('AlphaSynth', 'Finished playback (one time)');
@@ -17962,6 +18001,7 @@ class FontParser {
17962
18001
  this.lineHeight = 'normal';
17963
18002
  this.size = '1rem';
17964
18003
  this.families = [];
18004
+ this.parseOnlyFamilies = false;
17965
18005
  this._currentTokenIndex = -1;
17966
18006
  this._input = '';
17967
18007
  this._currentToken = null;
@@ -17999,13 +18039,26 @@ class FontParser {
17999
18039
  return;
18000
18040
  }
18001
18041
  }
18002
- this.fontStyleVariantWeight();
18003
- this.fontSizeLineHeight();
18042
+ if (!this.parseOnlyFamilies) {
18043
+ this.fontStyleVariantWeight();
18044
+ this.fontSizeLineHeight();
18045
+ }
18004
18046
  this.fontFamily();
18005
18047
  }
18048
+ static parseFamilies(value) {
18049
+ const parser = new FontParser(value);
18050
+ parser.parseOnlyFamilies = true;
18051
+ parser.parse();
18052
+ return parser.families;
18053
+ }
18006
18054
  fontFamily() {
18007
18055
  if (!this._currentToken) {
18008
- throw new Error(`Missing font list`);
18056
+ if (this.parseOnlyFamilies) {
18057
+ return;
18058
+ }
18059
+ else {
18060
+ throw new Error(`Missing font list`);
18061
+ }
18009
18062
  }
18010
18063
  const familyListInput = this._input.substr(this._currentToken.startPos).trim();
18011
18064
  let pos = 0;
@@ -18181,6 +18234,13 @@ class FontParser {
18181
18234
  this._currentTokenIndex = -1;
18182
18235
  this.nextToken();
18183
18236
  }
18237
+ static quoteFont(f) {
18238
+ if (f.indexOf(' ') === -1) {
18239
+ return f;
18240
+ }
18241
+ const escapedQuotes = f.replaceAll('"', '\\"');
18242
+ return `"${escapedQuotes}"`;
18243
+ }
18184
18244
  }
18185
18245
  /**
18186
18246
  * Lists all flags for font styles.
@@ -18223,7 +18283,7 @@ class Font {
18223
18283
  */
18224
18284
  constructor(family, size, style = FontStyle.Plain, weight = FontWeight.Regular) {
18225
18285
  this._cssScale = 0.0;
18226
- this._family = family;
18286
+ this._families = FontParser.parseFamilies(family);
18227
18287
  this._size = size;
18228
18288
  this._style = style;
18229
18289
  this._weight = weight;
@@ -18234,16 +18294,30 @@ class Font {
18234
18294
  this._css = this.toCssString();
18235
18295
  }
18236
18296
  /**
18237
- * Gets the font family name.
18297
+ * Gets the first font family name.
18298
+ * @deprecated Consider using {@link families} for multi font family support.
18238
18299
  */
18239
18300
  get family() {
18240
- return this._family;
18301
+ return this._families[0];
18241
18302
  }
18242
18303
  /**
18243
- * Sets the font family name.
18304
+ * Sets the font family list.
18305
+ * @deprecated Consider using {@link families} for multi font family support.
18244
18306
  */
18245
18307
  set family(value) {
18246
- this._family = value;
18308
+ this.families = FontParser.parseFamilies(value);
18309
+ }
18310
+ /**
18311
+ * Gets the font family name.
18312
+ */
18313
+ get families() {
18314
+ return this._families;
18315
+ }
18316
+ /**
18317
+ * Sets the font family name.
18318
+ */
18319
+ set families(value) {
18320
+ this._families = value;
18247
18321
  this.reset();
18248
18322
  }
18249
18323
  /**
@@ -18291,6 +18365,18 @@ class Font {
18291
18365
  get isItalic() {
18292
18366
  return this.style === FontStyle.Italic;
18293
18367
  }
18368
+ /**
18369
+ * Initializes a new instance of the {@link Font} class.
18370
+ * @param families The families.
18371
+ * @param size The size.
18372
+ * @param style The style.
18373
+ * @param weight The weight.
18374
+ */
18375
+ static withFamilyList(families, size, style = FontStyle.Plain, weight = FontWeight.Regular) {
18376
+ const f = new Font("", size, style, weight);
18377
+ f.families = families;
18378
+ return f;
18379
+ }
18294
18380
  toCssString(scale = 1) {
18295
18381
  if (!this._css || !(Math.abs(scale - this._cssScale) < 0.01)) {
18296
18382
  let buf = '';
@@ -18302,9 +18388,7 @@ class Font {
18302
18388
  }
18303
18389
  buf += this.size * scale;
18304
18390
  buf += 'px ';
18305
- buf += "'";
18306
- buf += this.family;
18307
- buf += "'";
18391
+ buf += this.families.map(f => FontParser.quoteFont(f)).join(', ');
18308
18392
  this._css = buf;
18309
18393
  this._cssScale = scale;
18310
18394
  }
@@ -18316,21 +18400,17 @@ class Font {
18316
18400
  return null;
18317
18401
  case 'object': {
18318
18402
  const m = v;
18319
- let family = m.get('family');
18403
+ let families = m.get('families');
18320
18404
  // tslint:disable-next-line: no-unnecessary-type-assertion
18321
18405
  let size = m.get('size');
18322
18406
  let style = JsonHelper.parseEnum(m.get('style'), FontStyle);
18323
18407
  let weight = JsonHelper.parseEnum(m.get('weight'), FontWeight);
18324
- return new Font(family, size, style, weight);
18408
+ return Font.withFamilyList(families, size, style, weight);
18325
18409
  }
18326
18410
  case 'string': {
18327
18411
  const parser = new FontParser(v);
18328
18412
  parser.parse();
18329
- let family = parser.families[0];
18330
- if ((family.startsWith("'") && family.endsWith("'")) ||
18331
- (family.startsWith('"') && family.endsWith('"'))) {
18332
- family = family.substr(1, family.length - 2);
18333
- }
18413
+ let families = parser.families;
18334
18414
  let fontSizeString = parser.size.toLowerCase();
18335
18415
  let fontSize = 0;
18336
18416
  // as per https://websemantics.uk/articles/font-size-conversion/
@@ -18393,7 +18473,7 @@ class Font {
18393
18473
  fontWeight = FontWeight.Bold;
18394
18474
  break;
18395
18475
  }
18396
- return new Font(family, fontSize, fontStyle, fontWeight);
18476
+ return Font.withFamilyList(families, fontSize, fontStyle, fontWeight);
18397
18477
  }
18398
18478
  default:
18399
18479
  return null;
@@ -18401,7 +18481,7 @@ class Font {
18401
18481
  }
18402
18482
  static toJson(font) {
18403
18483
  const o = new Map();
18404
- o.set('family', font.family);
18484
+ o.set('families', font.families);
18405
18485
  o.set('size', font.size);
18406
18486
  o.set('style', font.style);
18407
18487
  o.set('weight', font.weight);
@@ -18485,8 +18565,8 @@ class RenderingResources {
18485
18565
  this.scoreInfoColor = new Color(0, 0, 0, 0xff);
18486
18566
  }
18487
18567
  }
18488
- RenderingResources.sansFont = 'Arial';
18489
- RenderingResources.serifFont = 'Georgia';
18568
+ RenderingResources.sansFont = 'Arial, sans-serif';
18569
+ RenderingResources.serifFont = 'Georgia, serif';
18490
18570
 
18491
18571
  /**
18492
18572
  * The display settings control how the general layout and display of alphaTab is done.
@@ -21052,9 +21132,17 @@ class FontSizes {
21052
21132
  FontSizes.FontSizeLookupTables.set(family, new Uint8Array([8]));
21053
21133
  }
21054
21134
  }
21055
- static measureString(s, family, size, style, weight) {
21135
+ static measureString(s, families, size, style, weight) {
21056
21136
  let data;
21057
21137
  let dataSize = 11;
21138
+ let family = families[0]; // default to first font
21139
+ // find a font which is maybe registered already
21140
+ for (let i = 0; i < families.length; i++) {
21141
+ if (FontSizes.FontSizeLookupTables.has(families[i])) {
21142
+ family = families[i];
21143
+ break;
21144
+ }
21145
+ }
21058
21146
  if (!FontSizes.FontSizeLookupTables.has(family)) {
21059
21147
  FontSizes.generateFontLookup(family);
21060
21148
  }
@@ -24353,6 +24441,10 @@ class AlphaTabApiBase {
24353
24441
  * Applies any changes that were done to the settings object and informs the {@link renderer} about any new values to consider.
24354
24442
  */
24355
24443
  updateSettings() {
24444
+ const score = this.score;
24445
+ if (score) {
24446
+ ModelUtils.applyPitchOffsets(this.settings, score);
24447
+ }
24356
24448
  this.renderer.updateSettings(this.settings);
24357
24449
  // enable/disable player if needed
24358
24450
  if (this.settings.player.enablePlayer) {
@@ -24434,8 +24526,8 @@ class AlphaTabApiBase {
24434
24526
  }
24435
24527
  }
24436
24528
  internalRenderTracks(score, tracks) {
24529
+ ModelUtils.applyPitchOffsets(this.settings, score);
24437
24530
  if (score !== this.score) {
24438
- ModelUtils.applyPitchOffsets(this.settings, score);
24439
24531
  this.score = score;
24440
24532
  this.tracks = tracks;
24441
24533
  this._trackIndexes = [];
@@ -25727,11 +25819,12 @@ HtmlElementContainer.resizeObserver = new Lazy(() => new ResizeObserver((entries
25727
25819
  * @target web
25728
25820
  */
25729
25821
  class FontLoadingChecker {
25730
- constructor(family) {
25822
+ constructor(families) {
25731
25823
  this._isStarted = false;
25732
25824
  this.isFontLoaded = false;
25733
25825
  this.fontLoaded = new EventEmitterOfT();
25734
- this._family = family;
25826
+ this._originalFamilies = families;
25827
+ this._families = families;
25735
25828
  }
25736
25829
  checkForFontAvailability() {
25737
25830
  if (Environment.isRunningInWorker) {
@@ -25745,30 +25838,62 @@ class FontLoadingChecker {
25745
25838
  this._isStarted = true;
25746
25839
  let failCounter = 0;
25747
25840
  let failCounterId = window.setInterval(() => {
25748
- failCounter++;
25749
- Logger.warning('Rendering', `Could not load font '${this._family}' within ${failCounter * 5} seconds`, null);
25841
+ Logger.warning('Rendering', `Could not load font '${this._families[0]}' within ${(failCounter + 1) * 5} seconds`, null);
25842
+ // try loading next font if there are more than 1 left
25843
+ if (this._families.length > 1) {
25844
+ this._families.shift();
25845
+ failCounter = 0;
25846
+ }
25847
+ else {
25848
+ failCounter++;
25849
+ }
25750
25850
  }, 5000);
25751
- Logger.debug('Font', `Start checking for font availablility: ${this._family}`);
25752
- Logger.debug('Font', `[${this._family}] Font API available`);
25851
+ Logger.debug('Font', `Start checking for font availablility: ${this._families.join(', ')}`);
25852
+ let errorHandler = () => {
25853
+ if (this._families.length > 1) {
25854
+ Logger.debug('Font', `[${this._families[0]}] Loading Failed, switching to ${this._families[1]}`);
25855
+ this._families.shift();
25856
+ window.setTimeout(() => {
25857
+ checkFont();
25858
+ }, 0);
25859
+ }
25860
+ else {
25861
+ Logger.error('Font', `[${this._originalFamilies.join(',')}] Loading Failed, rendering cannot start`);
25862
+ window.clearInterval(failCounterId);
25863
+ }
25864
+ };
25865
+ let successHandler = (font) => {
25866
+ Logger.debug('Rendering', `[${font}] Font API signaled available`);
25867
+ this.isFontLoaded = true;
25868
+ window.clearInterval(failCounterId);
25869
+ this.fontLoaded.trigger(this._families[0]);
25870
+ };
25753
25871
  let checkFont = () => {
25754
- document.fonts.load(`1em ${this._family}`).then(() => {
25755
- Logger.debug('Font', `[${this._family}] Font API signaled loaded`);
25756
- if (document.fonts.check('1em ' + this._family)) {
25757
- Logger.debug('Rendering', `[${this._family}] Font API signaled available`);
25758
- this.isFontLoaded = true;
25759
- window.clearInterval(failCounterId);
25760
- this.fontLoaded.trigger(this._family);
25872
+ // Fast Path: check if one of the specified fonts is already available.
25873
+ for (const font of this._families) {
25874
+ if (document.fonts.check('1em ' + font)) {
25875
+ successHandler(font);
25876
+ return;
25877
+ }
25878
+ }
25879
+ // Slow path: Wait for fonts to be loaded sequentially
25880
+ const promise = document.fonts.load(`1em ${this._families[0]}`);
25881
+ promise.then(() => {
25882
+ Logger.debug('Font', `[${this._families[0]}] Font API signaled loaded`);
25883
+ if (document.fonts.check('1em ' + this._families[0])) {
25884
+ successHandler(this._families[0]);
25761
25885
  }
25762
25886
  else {
25763
- Logger.debug('Font', `[${this._family}] Font API loaded reported, but font not available, checking later again`, null);
25764
- window.setTimeout(() => {
25765
- checkFont();
25766
- }, 250);
25887
+ errorHandler();
25767
25888
  }
25768
25889
  return true;
25890
+ }, reason => {
25891
+ errorHandler();
25769
25892
  });
25770
25893
  };
25771
- checkFont();
25894
+ document.fonts.ready.then(() => {
25895
+ checkFont();
25896
+ });
25772
25897
  }
25773
25898
  }
25774
25899
 
@@ -26893,9 +27018,9 @@ class BrowserUiFacade {
26893
27018
  this.registerFontChecker(settings.display.resources.subTitleFont);
26894
27019
  }
26895
27020
  registerFontChecker(font) {
26896
- if (!this._fontCheckers.has(font.family)) {
26897
- let checker = new FontLoadingChecker(font.family);
26898
- this._fontCheckers.set(font.family, checker);
27021
+ if (!this._fontCheckers.has(font.families.join(', '))) {
27022
+ let checker = new FontLoadingChecker(font.families);
27023
+ this._fontCheckers.set(font.families.join(', '), checker);
26899
27024
  checker.fontLoaded.on(this.onFontLoaded.bind(this));
26900
27025
  checker.checkForFontAvailability();
26901
27026
  }
@@ -27870,7 +27995,7 @@ class SvgCanvas {
27870
27995
  if (!text) {
27871
27996
  return 0;
27872
27997
  }
27873
- return FontSizes.measureString(text, this.font.family, this.font.size, this.font.style, this.font.weight);
27998
+ return FontSizes.measureString(text, this.font.families, this.font.size, this.font.style, this.font.weight);
27874
27999
  }
27875
28000
  onRenderFinished() {
27876
28001
  // nothing to do
@@ -31362,7 +31487,7 @@ class TripletFeelGlyph extends EffectGlyph {
31362
31487
  renderTriplet(cx, cy, canvas) {
31363
31488
  cy += 2 * this.scale;
31364
31489
  let font = this.renderer.resources.effectFont;
31365
- canvas.font = new Font(font.family, font.size * 0.8, font.style);
31490
+ canvas.font = Font.withFamilyList(font.families, font.size * 0.8, font.style);
31366
31491
  let rightX = cx + TripletFeelGlyph.NoteSeparation * this.scale + 3 * this.scale;
31367
31492
  canvas.beginPath();
31368
31493
  canvas.moveTo(cx, cy + 3 * this.scale);
@@ -32875,7 +33000,7 @@ class ScoreLayout {
32875
33000
  let size = 12 * this.renderer.settings.display.scale;
32876
33001
  let height = Math.floor(size * 2);
32877
33002
  const e = new RenderFinishedEventArgs();
32878
- const font = new Font(resources.copyrightFont.family, size, FontStyle.Plain, FontWeight.Bold);
33003
+ const font = Font.withFamilyList(resources.copyrightFont.families, size, FontStyle.Plain, FontWeight.Bold);
32879
33004
  this.renderer.canvas.font = font;
32880
33005
  const centered = Environment.getLayoutEngineFactory(this.renderer.settings.display.layoutMode).vertical;
32881
33006
  e.width = this.renderer.canvas.measureText(msg);
@@ -38386,8 +38511,8 @@ class TabBrushGlyph extends Glyph {
38386
38511
  }
38387
38512
  paint(cx, cy, canvas) {
38388
38513
  let tabBarRenderer = this.renderer;
38389
- let startY = cy + this.x + (tabBarRenderer.getNoteY(this._beat.maxNote, NoteYPosition.Top));
38390
- let endY = cy + this.y + tabBarRenderer.getNoteY(this._beat.minNote, NoteYPosition.Bottom);
38514
+ let startY = cy + this.x + (tabBarRenderer.getNoteY(this._beat.maxStringNote, NoteYPosition.Top));
38515
+ let endY = cy + this.y + tabBarRenderer.getNoteY(this._beat.minStringNote, NoteYPosition.Bottom);
38391
38516
  let arrowX = (cx + this.x + this.width / 2) | 0;
38392
38517
  let arrowSize = 8 * this.scale;
38393
38518
  if (this._beat.brushType !== BrushType.None) {
@@ -40759,6 +40884,11 @@ class Environment {
40759
40884
  Document.prototype.replaceChildren = Element.prototype.replaceChildren;
40760
40885
  DocumentFragment.prototype.replaceChildren = Element.prototype.replaceChildren;
40761
40886
  }
40887
+ if (!('replaceAll' in String.prototype)) {
40888
+ String.prototype.replaceAll = function (str, newStr) {
40889
+ return this.replace(new RegExp(str, 'g'), newStr);
40890
+ };
40891
+ }
40762
40892
  }
40763
40893
  }
40764
40894
  /**
@@ -40833,7 +40963,7 @@ Environment.scriptFile = Environment.detectScriptFile();
40833
40963
  /**
40834
40964
  * @target web
40835
40965
  */
40836
- Environment.bravuraFontChecker = new FontLoadingChecker('alphaTab');
40966
+ Environment.bravuraFontChecker = new FontLoadingChecker(['alphaTab']);
40837
40967
  Environment.renderEngines = Environment.createDefaultRenderEngines();
40838
40968
  Environment.layoutEngines = Environment.createDefaultLayoutEngines();
40839
40969
  Environment.staveProfiles = Environment.createDefaultStaveProfiles();
@@ -40978,8 +41108,8 @@ class CoreSettings {
40978
41108
  // </auto-generated>
40979
41109
  class VersionInfo {
40980
41110
  }
40981
- VersionInfo.version = '1.3.0-alpha.369';
40982
- VersionInfo.date = '2022-08-23T01:00:18.004Z';
41111
+ VersionInfo.version = '1.3.0-alpha.376';
41112
+ VersionInfo.date = '2022-08-30T01:01:41.651Z';
40983
41113
 
40984
41114
  var index$5 = /*#__PURE__*/Object.freeze({
40985
41115
  __proto__: null,
@@ -44043,13 +44173,18 @@ var index$1 = /*#__PURE__*/Object.freeze({
44043
44173
  var index = /*#__PURE__*/Object.freeze({
44044
44174
  __proto__: null,
44045
44175
  AlphaSynth: AlphaSynth,
44176
+ CircularSampleBuffer: CircularSampleBuffer,
44046
44177
  PlaybackRange: PlaybackRange,
44047
44178
  get PlayerState () { return PlayerState; },
44048
44179
  PlayerStateChangedEventArgs: PlayerStateChangedEventArgs,
44049
44180
  PlaybackRangeChangedEventArgs: PlaybackRangeChangedEventArgs,
44050
44181
  PositionChangedEventArgs: PositionChangedEventArgs,
44182
+ MidiEventsPlayedEventArgs: MidiEventsPlayedEventArgs,
44051
44183
  ActiveBeatsChangedEventArgs: ActiveBeatsChangedEventArgs,
44052
- AlphaSynthWebWorkerApi: AlphaSynthWebWorkerApi
44184
+ AlphaSynthWebWorkerApi: AlphaSynthWebWorkerApi,
44185
+ AlphaSynthWebAudioOutputBase: AlphaSynthWebAudioOutputBase,
44186
+ AlphaSynthScriptProcessorOutput: AlphaSynthScriptProcessorOutput,
44187
+ AlphaSynthAudioWorkletOutput: AlphaSynthAudioWorkletOutput
44053
44188
  });
44054
44189
 
44055
44190
  export { AlphaTabApi, AlphaTabError, AlphaTabErrorType, CoreSettings, DisplaySettings, FileLoadError, FingeringMode, FormatError, ImporterSettings, LayoutMode, LogLevel, Logger, NotationMode, NotationSettings, PlayerSettings, ProgressEventArgs, RenderingResources, ResizeEventArgs, ScrollMode, Settings, StaveProfile, TabRhythmMode, VibratoPlaybackSettings, index$4 as exporter, index$5 as importer, VersionInfo as meta, index$3 as midi, index$2 as model, index$1 as rendering, index as synth };