@coderline/alphatab 1.7.0-alpha.1568 → 1.7.0-alpha.1574

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * alphaTab v1.7.0-alpha.1568 (develop, build 1568)
2
+ * alphaTab v1.7.0-alpha.1574 (develop, build 1574)
3
3
  *
4
4
  * Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -197,9 +197,9 @@ class VersionInfo {
197
197
  print(`build date: ${VersionInfo.date}`);
198
198
  }
199
199
  }
200
- VersionInfo.version = '1.7.0-alpha.1568';
201
- VersionInfo.date = '2025-10-07T01:57:28.773Z';
202
- VersionInfo.commit = '74a7b1503601f5a61437e95ba242fc411e55052a';
200
+ VersionInfo.version = '1.7.0-alpha.1574';
201
+ VersionInfo.date = '2025-10-13T02:06:10.997Z';
202
+ VersionInfo.commit = '870f57e8775bddacc5a91b00ccb39c598babb881';
203
203
 
204
204
  /**
205
205
  * This public class provides names for all general midi instruments.
@@ -1481,8 +1481,13 @@ class Automation {
1481
1481
  * Gets or sets the additional text of the automation.
1482
1482
  */
1483
1483
  this.text = '';
1484
+ /**
1485
+ * Whether this automation should be visible. (not all automation types are shown,
1486
+ * e.g. tempo changes shown in the score while volume changes are not).
1487
+ */
1488
+ this.isVisible = true;
1484
1489
  }
1485
- static buildTempoAutomation(isLinear, ratioPosition, value, reference) {
1490
+ static buildTempoAutomation(isLinear, ratioPosition, value, reference, isVisible = true) {
1486
1491
  if (reference < 1 || reference > 5) {
1487
1492
  reference = 2;
1488
1493
  }
@@ -1492,6 +1497,7 @@ class Automation {
1492
1497
  automation.isLinear = isLinear;
1493
1498
  automation.ratioPosition = ratioPosition;
1494
1499
  automation.value = value * references[reference];
1500
+ automation.isVisible = isVisible;
1495
1501
  return automation;
1496
1502
  }
1497
1503
  static buildInstrumentAutomation(isLinear, ratioPosition, value) {
@@ -3898,6 +3904,19 @@ class ModelUtils {
3898
3904
  }
3899
3905
  }
3900
3906
  }
3907
+ // ensure first masterbar has a tempo automation for score tempo
3908
+ if (score.masterBars.length > 0) {
3909
+ const firstTempoAutomation = score.masterBars[0].tempoAutomations.find(a => a.type === AutomationType.Tempo && a.ratioPosition === 0);
3910
+ if (!firstTempoAutomation) {
3911
+ const tempoAutomation = new Automation();
3912
+ tempoAutomation.isLinear = false;
3913
+ tempoAutomation.type = AutomationType.Tempo;
3914
+ tempoAutomation.value = score.tempo;
3915
+ tempoAutomation.text = score.tempoLabel;
3916
+ tempoAutomation.isVisible = false;
3917
+ score.masterBars[0].tempoAutomations.push(tempoAutomation);
3918
+ }
3919
+ }
3901
3920
  }
3902
3921
  /**
3903
3922
  * Trims any empty bars at the end of the song.
@@ -6228,6 +6247,7 @@ class AutomationCloner {
6228
6247
  clone.syncPointValue = original.syncPointValue ? SyncPointDataCloner.clone(original.syncPointValue) : undefined;
6229
6248
  clone.ratioPosition = original.ratioPosition;
6230
6249
  clone.text = original.text;
6250
+ clone.isVisible = original.isVisible;
6231
6251
  return clone;
6232
6252
  }
6233
6253
  }
@@ -7628,14 +7648,6 @@ class Score {
7628
7648
  * The author of this tablature.
7629
7649
  */
7630
7650
  this.tab = '';
7631
- /**
7632
- * Gets or sets the global tempo of the song in BPM. The tempo might change via {@link MasterBar.tempoAutomations}.
7633
- */
7634
- this.tempo = 120;
7635
- /**
7636
- * Gets or sets the name/label of the tempo.
7637
- */
7638
- this.tempoLabel = '';
7639
7651
  /**
7640
7652
  * Gets or sets a list of all masterbars contained in this song.
7641
7653
  * @json_add addMasterBar
@@ -7670,6 +7682,22 @@ class Score {
7670
7682
  Voice$1.resetIds();
7671
7683
  Note.resetIds();
7672
7684
  }
7685
+ /**
7686
+ * The initial tempo of the song in BPM. The tempo might change via {@link MasterBar.tempoAutomations}.
7687
+ */
7688
+ get tempo() {
7689
+ return this.masterBars.length && this.masterBars[0].tempoAutomations.length > 0
7690
+ ? this.masterBars[0].tempoAutomations[0].value
7691
+ : 120;
7692
+ }
7693
+ /**
7694
+ * The name/label of the initial tempo.
7695
+ */
7696
+ get tempoLabel() {
7697
+ return this.masterBars.length && this.masterBars[0].tempoAutomations.length > 0
7698
+ ? this.masterBars[0].tempoAutomations[0].text
7699
+ : '';
7700
+ }
7673
7701
  rebuildRepeatGroups() {
7674
7702
  this._currentRepeatGroup = null;
7675
7703
  this._openedRepeatGroups = [];
@@ -9515,6 +9543,7 @@ class AlphaTexImporter extends ScoreImporter {
9515
9543
  this._trackChannel = 0;
9516
9544
  this._barIndex = 0;
9517
9545
  this._voiceIndex = 0;
9546
+ this._initialTempo = Automation.buildTempoAutomation(false, 0, 120, 0);
9518
9547
  // Last known position that had valid syntax/symbols
9519
9548
  this._currentDuration = Duration.QuadrupleWhole;
9520
9549
  this._currentDynamics = DynamicValue.PPP;
@@ -9682,8 +9711,6 @@ class AlphaTexImporter extends ScoreImporter {
9682
9711
  */
9683
9712
  createDefaultScore() {
9684
9713
  this._score = new Score();
9685
- this._score.tempo = 120;
9686
- this._score.tempoLabel = '';
9687
9714
  this.newTrack();
9688
9715
  }
9689
9716
  newTrack() {
@@ -9971,14 +9998,14 @@ class AlphaTexImporter extends ScoreImporter {
9971
9998
  case 'tempo':
9972
9999
  this.sy = this.newSy(true);
9973
10000
  if (this.sy === AlphaTexSymbols.Number) {
9974
- this._score.tempo = this.syData;
10001
+ this._initialTempo.value = this.syData;
9975
10002
  }
9976
10003
  else {
9977
10004
  this.error('tempo', AlphaTexSymbols.Number, true);
9978
10005
  }
9979
10006
  this.sy = this.newSy();
9980
10007
  if (this.sy === AlphaTexSymbols.String) {
9981
- this._score.tempoLabel = this.syData;
10008
+ this._initialTempo.text = this.syData;
9982
10009
  this.sy = this.newSy();
9983
10010
  }
9984
10011
  anyTopLevelMeta = true;
@@ -10740,6 +10767,9 @@ class AlphaTexImporter extends ScoreImporter {
10740
10767
  master.timeSignatureNumerator = master.previousMasterBar.timeSignatureNumerator;
10741
10768
  master.tripletFeel = master.previousMasterBar.tripletFeel;
10742
10769
  }
10770
+ else {
10771
+ master.tempoAutomations.push(this._initialTempo);
10772
+ }
10743
10773
  }
10744
10774
  const anyBarMeta = this.barMeta(bar);
10745
10775
  // detect tuning for staff
@@ -11233,6 +11263,15 @@ class AlphaTexImporter extends ScoreImporter {
11233
11263
  else if (syData === 'tempo') {
11234
11264
  // NOTE: playbackRatio is calculated on score finish when playback positions are known
11235
11265
  const tempoAutomation = this.readTempoAutomation(false);
11266
+ if (beat.index === 0) {
11267
+ const existing = beat.voice.bar.masterBar.tempoAutomations.find(a => a.ratioPosition === 0);
11268
+ if (existing) {
11269
+ existing.value = tempoAutomation.value;
11270
+ existing.text = tempoAutomation.text;
11271
+ beat.automations.push(existing);
11272
+ return true;
11273
+ }
11274
+ }
11236
11275
  beat.automations.push(tempoAutomation);
11237
11276
  beat.voice.bar.masterBar.tempoAutomations.push(tempoAutomation);
11238
11277
  return true;
@@ -12223,7 +12262,15 @@ class AlphaTexImporter extends ScoreImporter {
12223
12262
  }
12224
12263
  else if (syData === 'tempo') {
12225
12264
  const tempoAutomation = this.readTempoAutomation(true);
12226
- master.tempoAutomations.push(tempoAutomation);
12265
+ const existing = master.tempoAutomations.find(a => a.ratioPosition === tempoAutomation.ratioPosition);
12266
+ if (existing) {
12267
+ existing.value = tempoAutomation.value;
12268
+ existing.text = tempoAutomation.text;
12269
+ existing.isVisible = tempoAutomation.isVisible;
12270
+ }
12271
+ else {
12272
+ master.tempoAutomations.push(tempoAutomation);
12273
+ }
12227
12274
  }
12228
12275
  else if (syData === 'section') {
12229
12276
  this.sy = this.newSy();
@@ -12511,7 +12558,7 @@ class AlphaTexImporter extends ScoreImporter {
12511
12558
  const tempoAutomation = new Automation();
12512
12559
  tempoAutomation.isLinear = false;
12513
12560
  tempoAutomation.type = AutomationType.Tempo;
12514
- if (this.sy === AlphaTexSymbols.LBrace && withPosition) {
12561
+ if (this.sy === AlphaTexSymbols.LParensis && withPosition) {
12515
12562
  this.sy = this.newSy(true);
12516
12563
  if (this.sy !== AlphaTexSymbols.Number) {
12517
12564
  this.error('tempo', AlphaTexSymbols.Number, true);
@@ -12527,8 +12574,12 @@ class AlphaTexImporter extends ScoreImporter {
12527
12574
  }
12528
12575
  tempoAutomation.ratioPosition = this.syData;
12529
12576
  this.sy = this.newSy();
12530
- if (this.sy !== AlphaTexSymbols.RBrace) {
12531
- this.error('tempo', AlphaTexSymbols.RBrace, true);
12577
+ if (this.sy === AlphaTexSymbols.String && this.syData === 'hide') {
12578
+ tempoAutomation.isVisible = false;
12579
+ this.sy = this.newSy();
12580
+ }
12581
+ if (this.sy !== AlphaTexSymbols.RParensis) {
12582
+ this.error('tempo', AlphaTexSymbols.RParensis, true);
12532
12583
  }
12533
12584
  this.sy = this.newSy();
12534
12585
  }
@@ -14003,6 +14054,7 @@ class CapellaParser {
14003
14054
  this._trackChannel = 0;
14004
14055
  this._beamingMode = BeatBeamingMode.Auto;
14005
14056
  this._isFirstSystem = true;
14057
+ this._initialTempo = -1;
14006
14058
  this._staffLookup = new Map();
14007
14059
  this._brackets = [];
14008
14060
  this._staffLayoutLookup = new Map();
@@ -14065,7 +14117,6 @@ class CapellaParser {
14065
14117
  }
14066
14118
  if (root.localName === 'score') {
14067
14119
  this.score = new Score();
14068
- this.score.tempo = 120;
14069
14120
  // parse all children
14070
14121
  for (const n of root.childElements()) {
14071
14122
  switch (n.localName) {
@@ -14239,7 +14290,7 @@ class CapellaParser {
14239
14290
  parseSystem(element) {
14240
14291
  if (element.attributes.has('tempo')) {
14241
14292
  if (this.score.masterBars.length === 0) {
14242
- this.score.tempo = Number.parseInt(element.attributes.get('tempo'), 10);
14293
+ this._initialTempo = Number.parseInt(element.attributes.get('tempo'), 10);
14243
14294
  }
14244
14295
  }
14245
14296
  if (element.getAttribute('beamGrouping') === '0') {
@@ -14346,6 +14397,9 @@ class CapellaParser {
14346
14397
  if (master.index > 0) {
14347
14398
  master.tripletFeel = master.previousMasterBar.tripletFeel;
14348
14399
  }
14400
+ else if (this._initialTempo > 0) {
14401
+ master.tempoAutomations.push(Automation.buildTempoAutomation(false, 0, this._initialTempo, 0));
14402
+ }
14349
14403
  master.timeSignatureDenominator = this._timeSignature.timeSignatureDenominator;
14350
14404
  master.timeSignatureNumerator = this._timeSignature.timeSignatureNumerator;
14351
14405
  master.timeSignatureCommon = this._timeSignature.timeSignatureCommon;
@@ -15121,12 +15175,13 @@ class Gp3To5Importer extends ScoreImporter {
15121
15175
  this.data.skip(19);
15122
15176
  }
15123
15177
  // page setup since GP5
15178
+ this._initialTempo = Automation.buildTempoAutomation(false, 0, 0, 0);
15124
15179
  if (this._versionNumber >= 500) {
15125
15180
  this.readPageSetup();
15126
- this._score.tempoLabel = GpBinaryHelpers.gpReadStringIntByte(this.data, this.settings.importer.encoding);
15181
+ this._initialTempo.text = GpBinaryHelpers.gpReadStringIntByte(this.data, this.settings.importer.encoding);
15127
15182
  }
15128
15183
  // tempo stuff
15129
- this._score.tempo = IOHelper.readInt32LE(this.data);
15184
+ this._initialTempo.value = IOHelper.readInt32LE(this.data);
15130
15185
  if (this._versionNumber >= 510) {
15131
15186
  GpBinaryHelpers.gpReadBool(this.data); // hide tempo?
15132
15187
  }
@@ -15205,7 +15260,8 @@ class Gp3To5Importer extends ScoreImporter {
15205
15260
  }
15206
15261
  version = version.substr(Gp3To5Importer.VersionString.length + 1);
15207
15262
  const dot = version.indexOf(String.fromCharCode(46));
15208
- this._versionNumber = 100 * Number.parseInt(version.substr(0, dot), 10) + Number.parseInt(version.substr(dot + 1), 10);
15263
+ this._versionNumber =
15264
+ 100 * Number.parseInt(version.substr(0, dot), 10) + Number.parseInt(version.substr(dot + 1), 10);
15209
15265
  Logger.debug(this.name, `Guitar Pro version ${version} detected`);
15210
15266
  }
15211
15267
  readScoreInformation() {
@@ -15315,6 +15371,9 @@ class Gp3To5Importer extends ScoreImporter {
15315
15371
  previousMasterBar = this._score.masterBars[this._score.masterBars.length - 1];
15316
15372
  }
15317
15373
  const newMasterBar = new MasterBar();
15374
+ if (!previousMasterBar && this._initialTempo.value > 0) {
15375
+ newMasterBar.tempoAutomations.push(this._initialTempo);
15376
+ }
15318
15377
  const flags = this.data.readByte();
15319
15378
  // time signature
15320
15379
  if ((flags & 0x01) !== 0) {
@@ -17327,6 +17386,7 @@ class GpifParser {
17327
17386
  let reference = 0;
17328
17387
  let text = null;
17329
17388
  let syncPointValue = undefined;
17389
+ let isVisible = true;
17330
17390
  for (const c of node.childElements()) {
17331
17391
  switch (c.localName) {
17332
17392
  case 'Type':
@@ -17381,6 +17441,9 @@ class GpifParser {
17381
17441
  case 'Text':
17382
17442
  text = c.innerText;
17383
17443
  break;
17444
+ case 'Visible':
17445
+ isVisible = c.innerText.toLowerCase() === 'true';
17446
+ break;
17384
17447
  }
17385
17448
  }
17386
17449
  if (!type) {
@@ -17389,7 +17452,7 @@ class GpifParser {
17389
17452
  const newAutomations = [];
17390
17453
  switch (type) {
17391
17454
  case 'Tempo':
17392
- newAutomations.push(Automation.buildTempoAutomation(isLinear, ratioPosition, numberValue, reference));
17455
+ newAutomations.push(Automation.buildTempoAutomation(isLinear, ratioPosition, numberValue, reference, isVisible));
17393
17456
  break;
17394
17457
  case 'SyncPoint':
17395
17458
  const syncPoint = new Automation();
@@ -17397,6 +17460,7 @@ class GpifParser {
17397
17460
  syncPoint.isLinear = isLinear;
17398
17461
  syncPoint.ratioPosition = ratioPosition;
17399
17462
  syncPoint.syncPointValue = syncPointValue;
17463
+ syncPoint.isVisible = isVisible;
17400
17464
  newAutomations.push(syncPoint);
17401
17465
  break;
17402
17466
  case 'Sound':
@@ -17405,6 +17469,7 @@ class GpifParser {
17405
17469
  bankChange.type = AutomationType.Bank;
17406
17470
  bankChange.ratioPosition = ratioPosition;
17407
17471
  bankChange.value = sounds.get(textValue).bank;
17472
+ bankChange.isVisible = isVisible;
17408
17473
  newAutomations.push(bankChange);
17409
17474
  const programChange = Automation.buildInstrumentAutomation(isLinear, ratioPosition, sounds.get(textValue).program);
17410
17475
  newAutomations.push(programChange);
@@ -19545,12 +19610,6 @@ class GpifParser {
19545
19610
  const automation = automations[i];
19546
19611
  switch (automation.type) {
19547
19612
  case AutomationType.Tempo:
19548
- if (barNumber === 0) {
19549
- this.score.tempo = automation.value | 0;
19550
- if (automation.text) {
19551
- this.score.tempoLabel = automation.text;
19552
- }
19553
- }
19554
19613
  masterBar.tempoAutomations.push(automation);
19555
19614
  break;
19556
19615
  case AutomationType.SyncPoint:
@@ -20654,7 +20713,6 @@ class MusicXmlImporter extends ScoreImporter {
20654
20713
  throw new UnsupportedFormatError('Unsupported format', e);
20655
20714
  }
20656
20715
  this._score = new Score();
20657
- this._score.tempo = 120;
20658
20716
  this._score.stylesheet.hideDynamics = true;
20659
20717
  this.parseDom(dom);
20660
20718
  ModelUtils.consolidate(this._score);
@@ -22296,9 +22354,6 @@ class MusicXmlImporter extends ScoreImporter {
22296
22354
  tempoAutomation.ratioPosition = getRatioPosition();
22297
22355
  if (!this.hasSameTempo(masterBar, tempoAutomation)) {
22298
22356
  masterBar.tempoAutomations.push(tempoAutomation);
22299
- if (masterBar.index === 0) {
22300
- masterBar.score.tempo = tempoAutomation.value;
22301
- }
22302
22357
  }
22303
22358
  }
22304
22359
  let previousWords = '';
@@ -22444,9 +22499,6 @@ class MusicXmlImporter extends ScoreImporter {
22444
22499
  tempoAutomation.ratioPosition = ratioPosition;
22445
22500
  if (!this.hasSameTempo(masterBar, tempoAutomation)) {
22446
22501
  masterBar.tempoAutomations.push(tempoAutomation);
22447
- if (masterBar.index === 0) {
22448
- masterBar.score.tempo = tempoAutomation.value;
22449
- }
22450
22502
  }
22451
22503
  }
22452
22504
  }
@@ -36912,6 +36964,7 @@ class AutomationSerializer {
36912
36964
  }
36913
36965
  o.set("ratioposition", obj.ratioPosition);
36914
36966
  o.set("text", obj.text);
36967
+ o.set("isvisible", obj.isVisible);
36915
36968
  return o;
36916
36969
  }
36917
36970
  static setProperty(obj, property, v) {
@@ -36940,6 +36993,9 @@ class AutomationSerializer {
36940
36993
  case "text":
36941
36994
  obj.text = v;
36942
36995
  return true;
36996
+ case "isvisible":
36997
+ obj.isVisible = v;
36998
+ return true;
36943
36999
  }
36944
37000
  return false;
36945
37001
  }
@@ -38496,8 +38552,6 @@ class ScoreSerializer {
38496
38552
  o.set("title", obj.title);
38497
38553
  o.set("words", obj.words);
38498
38554
  o.set("tab", obj.tab);
38499
- o.set("tempo", obj.tempo);
38500
- o.set("tempolabel", obj.tempoLabel);
38501
38555
  o.set("masterbars", obj.masterBars.map(i => MasterBarSerializer.toJson(i)));
38502
38556
  o.set("tracks", obj.tracks.map(i => TrackSerializer.toJson(i)));
38503
38557
  o.set("defaultsystemslayout", obj.defaultSystemsLayout);
@@ -38543,12 +38597,6 @@ class ScoreSerializer {
38543
38597
  case "tab":
38544
38598
  obj.tab = v;
38545
38599
  return true;
38546
- case "tempo":
38547
- obj.tempo = v;
38548
- return true;
38549
- case "tempolabel":
38550
- obj.tempoLabel = v;
38551
- return true;
38552
38600
  case "masterbars":
38553
38601
  obj.masterBars = [];
38554
38602
  for (const o of v) {
@@ -56839,10 +56887,10 @@ class TempoEffectInfo extends EffectBarRendererInfo {
56839
56887
  return (beat.voice.bar.staff.index === 0 &&
56840
56888
  beat.voice.index === 0 &&
56841
56889
  beat.index === 0 &&
56842
- beat.voice.bar.masterBar.tempoAutomations.length > 0);
56890
+ beat.voice.bar.masterBar.tempoAutomations.some(t => t.isVisible));
56843
56891
  }
56844
56892
  createNewGlyph(_renderer, beat) {
56845
- return new BarTempoGlyph(beat.voice.bar.masterBar.tempoAutomations);
56893
+ return new BarTempoGlyph(beat.voice.bar.masterBar.tempoAutomations.filter(a => a.isVisible));
56846
56894
  }
56847
56895
  canExpand(_from, _to) {
56848
56896
  return true;
@@ -66960,11 +67008,15 @@ class AlphaTexExporter extends ScoreExporter {
66960
67008
  }
66961
67009
  }
66962
67010
  for (const a of masterBar.tempoAutomations) {
66963
- writer.write(`\\tempo { ${a.value} `);
67011
+ writer.write(`\\tempo ( ${a.value} `);
66964
67012
  if (a.text) {
66965
67013
  writer.writeString(a.text);
66966
67014
  }
66967
- writer.writeLine(`${a.ratioPosition} }`);
67015
+ writer.write(`${a.ratioPosition} `);
67016
+ if (!a.isVisible) {
67017
+ writer.writeLine('hide ');
67018
+ }
67019
+ writer.writeLine(`)`);
66968
67020
  }
66969
67021
  writer.dropSingleLineComment();
66970
67022
  }
@@ -68381,7 +68433,7 @@ class GpifWriter {
68381
68433
  tempoAutomation.addElement('Linear').innerText = automation.isLinear ? 'true' : 'false';
68382
68434
  tempoAutomation.addElement('Bar').innerText = mb.index.toString();
68383
68435
  tempoAutomation.addElement('Position').innerText = automation.ratioPosition.toString();
68384
- tempoAutomation.addElement('Visible').innerText = 'true';
68436
+ tempoAutomation.addElement('Visible').innerText = automation.isVisible ? 'true' : 'false';
68385
68437
  tempoAutomation.addElement('Value').innerText = `${automation.value} 2`;
68386
68438
  if (automation.text) {
68387
68439
  tempoAutomation.addElement('Text').innerText = automation.text;
@@ -3110,6 +3110,7 @@ declare class AlphaTexImporter extends ScoreImporter {
3110
3110
  private _currentStaff;
3111
3111
  private _barIndex;
3112
3112
  private _voiceIndex;
3113
+ private _initialTempo;
3113
3114
  private _currentDuration;
3114
3115
  private _currentDynamics;
3115
3116
  private _currentTuplet;
@@ -3337,7 +3338,12 @@ declare class Automation {
3337
3338
  * Gets or sets the additional text of the automation.
3338
3339
  */
3339
3340
  text: string;
3340
- static buildTempoAutomation(isLinear: boolean, ratioPosition: number, value: number, reference: number): Automation;
3341
+ /**
3342
+ * Whether this automation should be visible. (not all automation types are shown,
3343
+ * e.g. tempo changes shown in the score while volume changes are not).
3344
+ */
3345
+ isVisible: boolean;
3346
+ static buildTempoAutomation(isLinear: boolean, ratioPosition: number, value: number, reference: number, isVisible?: boolean): Automation;
3341
3347
  static buildInstrumentAutomation(isLinear: boolean, ratioPosition: number, value: number): Automation;
3342
3348
  }
3343
3349
 
@@ -14163,13 +14169,13 @@ declare class Score {
14163
14169
  */
14164
14170
  tab: string;
14165
14171
  /**
14166
- * Gets or sets the global tempo of the song in BPM. The tempo might change via {@link MasterBar.tempoAutomations}.
14172
+ * The initial tempo of the song in BPM. The tempo might change via {@link MasterBar.tempoAutomations}.
14167
14173
  */
14168
- tempo: number;
14174
+ get tempo(): number;
14169
14175
  /**
14170
- * Gets or sets the name/label of the tempo.
14176
+ * The name/label of the initial tempo.
14171
14177
  */
14172
- tempoLabel: string;
14178
+ get tempoLabel(): string;
14173
14179
  /**
14174
14180
  * Gets or sets a list of all masterbars contained in this song.
14175
14181
  * @json_add addMasterBar