@coderline/alphatab 1.3.0-alpha.133 → 1.3.0-alpha.137

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.133 (develop, build 133)
2
+ * alphaTab v1.3.0-alpha.137 (develop, build 137)
3
3
  *
4
4
  * Copyright © 2021, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -14,30 +14,48 @@
14
14
  * Copyright (C) 2012 Steve Folta (https://github.com/stevefolta/SFZero)
15
15
  */
16
16
 
17
- var AlphaTabErrorType;
18
- (function (AlphaTabErrorType) {
19
- AlphaTabErrorType[AlphaTabErrorType["General"] = 0] = "General";
20
- AlphaTabErrorType[AlphaTabErrorType["Format"] = 1] = "Format";
21
- AlphaTabErrorType[AlphaTabErrorType["AlphaTex"] = 2] = "AlphaTex";
22
- })(AlphaTabErrorType || (AlphaTabErrorType = {}));
23
- class AlphaTabError extends Error {
24
- constructor(type, message = "", inner) {
25
- super(message);
26
- this.type = type;
27
- this.inner = inner !== null && inner !== void 0 ? inner : null;
28
- Object.setPrototypeOf(this, AlphaTabError.prototype);
29
- }
30
- }
17
+ /**
18
+ * Lists all layout modes that are supported.
19
+ */
20
+ var LayoutMode;
21
+ (function (LayoutMode) {
22
+ /**
23
+ * Bars are aligned in rows using a fixed width.
24
+ */
25
+ LayoutMode[LayoutMode["Page"] = 0] = "Page";
26
+ /**
27
+ * Bars are aligned horizontally in one row
28
+ */
29
+ LayoutMode[LayoutMode["Horizontal"] = 1] = "Horizontal";
30
+ })(LayoutMode || (LayoutMode = {}));
31
31
 
32
32
  /**
33
- * An invalid input format was detected (e.g. invalid setting values, file formats,...)
33
+ * Lists all stave profiles controlling which staves are shown.
34
34
  */
35
- class FormatError extends AlphaTabError {
36
- constructor(message) {
37
- super(AlphaTabErrorType.Format, message);
38
- Object.setPrototypeOf(this, FormatError.prototype);
39
- }
40
- }
35
+ var StaveProfile;
36
+ (function (StaveProfile) {
37
+ /**
38
+ * The profile is auto detected by the track configurations.
39
+ */
40
+ StaveProfile[StaveProfile["Default"] = 0] = "Default";
41
+ /**
42
+ * Standard music notation and guitar tablature are rendered.
43
+ */
44
+ StaveProfile[StaveProfile["ScoreTab"] = 1] = "ScoreTab";
45
+ /**
46
+ * Only standard music notation is rendered.
47
+ */
48
+ StaveProfile[StaveProfile["Score"] = 2] = "Score";
49
+ /**
50
+ * Only guitar tablature is rendered.
51
+ */
52
+ StaveProfile[StaveProfile["Tab"] = 3] = "Tab";
53
+ /**
54
+ * Only guitar tablature is rendered, but also rests and time signatures are not shown.
55
+ * This profile is typically used in multi-track scenarios.
56
+ */
57
+ StaveProfile[StaveProfile["TabMixed"] = 4] = "TabMixed";
58
+ })(StaveProfile || (StaveProfile = {}));
41
59
 
42
60
  /**
43
61
  * This public class provides names for all general midi instruments.
@@ -93,2161 +111,1154 @@ GeneralMidi._values = new Map([
93
111
  ]);
94
112
 
95
113
  /**
96
- * Lists all fingers.
114
+ * This is the base public class for creating new song importers which
115
+ * enable reading scores from any binary datasource
97
116
  */
98
- var Fingers;
99
- (function (Fingers) {
100
- /**
101
- * Unknown type (not documented)
102
- */
103
- Fingers[Fingers["Unknown"] = -2] = "Unknown";
104
- /**
105
- * No finger, dead note
106
- */
107
- Fingers[Fingers["NoOrDead"] = -1] = "NoOrDead";
108
- /**
109
- * The thumb
110
- */
111
- Fingers[Fingers["Thumb"] = 0] = "Thumb";
112
- /**
113
- * The index finger
114
- */
115
- Fingers[Fingers["IndexFinger"] = 1] = "IndexFinger";
116
- /**
117
- * The middle finger
118
- */
119
- Fingers[Fingers["MiddleFinger"] = 2] = "MiddleFinger";
120
- /**
121
- * The annular finger
122
- */
123
- Fingers[Fingers["AnnularFinger"] = 3] = "AnnularFinger";
117
+ class ScoreImporter {
124
118
  /**
125
- * The little finger
119
+ * Initializes the importer with the given data and settings.
126
120
  */
127
- Fingers[Fingers["LittleFinger"] = 4] = "LittleFinger";
128
- })(Fingers || (Fingers = {}));
121
+ init(data, settings) {
122
+ this.data = data;
123
+ this.settings = settings;
124
+ }
125
+ }
126
+
127
+ var AlphaTabErrorType;
128
+ (function (AlphaTabErrorType) {
129
+ AlphaTabErrorType[AlphaTabErrorType["General"] = 0] = "General";
130
+ AlphaTabErrorType[AlphaTabErrorType["Format"] = 1] = "Format";
131
+ AlphaTabErrorType[AlphaTabErrorType["AlphaTex"] = 2] = "AlphaTex";
132
+ })(AlphaTabErrorType || (AlphaTabErrorType = {}));
133
+ class AlphaTabError extends Error {
134
+ constructor(type, message = "", inner) {
135
+ super(message);
136
+ this.type = type;
137
+ this.inner = inner !== null && inner !== void 0 ? inner : null;
138
+ Object.setPrototypeOf(this, AlphaTabError.prototype);
139
+ }
140
+ }
129
141
 
130
142
  /**
131
- * Lists the different modes on how rhythm notation is shown on the tab staff.
143
+ * The exception thrown by a {@link ScoreImporter} in case the
144
+ * binary data does not contain a reader compatible structure.
132
145
  */
133
- var TabRhythmMode;
134
- (function (TabRhythmMode) {
146
+ class UnsupportedFormatError extends AlphaTabError {
147
+ constructor(message = 'Unsupported format', inner = null) {
148
+ super(AlphaTabErrorType.Format, message);
149
+ this.inner = inner;
150
+ Object.setPrototypeOf(this, UnsupportedFormatError.prototype);
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Lists all types of note acceuntations
156
+ */
157
+ var AccentuationType;
158
+ (function (AccentuationType) {
135
159
  /**
136
- * Rhythm notation is hidden.
160
+ * No accentuation
137
161
  */
138
- TabRhythmMode[TabRhythmMode["Hidden"] = 0] = "Hidden";
162
+ AccentuationType[AccentuationType["None"] = 0] = "None";
139
163
  /**
140
- * Rhythm notation is shown with individual beams per beat.
164
+ * Normal accentuation
141
165
  */
142
- TabRhythmMode[TabRhythmMode["ShowWithBeams"] = 1] = "ShowWithBeams";
166
+ AccentuationType[AccentuationType["Normal"] = 1] = "Normal";
143
167
  /**
144
- * Rhythm notation is shown and behaves like normal score notation with connected bars.
168
+ * Heavy accentuation
145
169
  */
146
- TabRhythmMode[TabRhythmMode["ShowWithBars"] = 2] = "ShowWithBars";
147
- })(TabRhythmMode || (TabRhythmMode = {}));
170
+ AccentuationType[AccentuationType["Heavy"] = 2] = "Heavy";
171
+ })(AccentuationType || (AccentuationType = {}));
172
+
148
173
  /**
149
- * Lists all modes on how fingerings should be displayed.
174
+ * This public enumeration lists all types of automations.
150
175
  */
151
- var FingeringMode;
152
- (function (FingeringMode) {
176
+ var AutomationType;
177
+ (function (AutomationType) {
153
178
  /**
154
- * Fingerings will be shown in the standard notation staff.
179
+ * Tempo change.
155
180
  */
156
- FingeringMode[FingeringMode["ScoreDefault"] = 0] = "ScoreDefault";
181
+ AutomationType[AutomationType["Tempo"] = 0] = "Tempo";
157
182
  /**
158
- * Fingerings will be shown in the standard notation staff. Piano finger style is enforced, where
159
- * fingers are rendered as 1-5 instead of p,i,m,a,c and T,1,2,3,4.
183
+ * Colume change.
160
184
  */
161
- FingeringMode[FingeringMode["ScoreForcePiano"] = 1] = "ScoreForcePiano";
185
+ AutomationType[AutomationType["Volume"] = 1] = "Volume";
162
186
  /**
163
- * Fingerings will be shown in a effect band above the tabs in case
164
- * they have only a single note on the beat.
187
+ * Instrument change.
165
188
  */
166
- FingeringMode[FingeringMode["SingleNoteEffectBand"] = 2] = "SingleNoteEffectBand";
189
+ AutomationType[AutomationType["Instrument"] = 2] = "Instrument";
167
190
  /**
168
- * Fingerings will be shown in a effect band above the tabs in case
169
- * they have only a single note on the beat. Piano finger style is enforced, where
170
- * fingers are rendered as 1-5 instead of p,i,m,a,c and T,1,2,3,4.
191
+ * Balance change.
171
192
  */
172
- FingeringMode[FingeringMode["SingleNoteEffectBandForcePiano"] = 3] = "SingleNoteEffectBandForcePiano";
173
- })(FingeringMode || (FingeringMode = {}));
193
+ AutomationType[AutomationType["Balance"] = 3] = "Balance";
194
+ })(AutomationType || (AutomationType = {}));
174
195
  /**
175
- * Lists all modes on how alphaTab can handle the display and playback of music notation.
196
+ * Automations are used to change the behaviour of a song.
197
+ * @cloneable
198
+ * @json
176
199
  */
177
- var NotationMode;
178
- (function (NotationMode) {
179
- /**
180
- * Music elements will be displayed and played as in Guitar Pro.
181
- */
182
- NotationMode[NotationMode["GuitarPro"] = 0] = "GuitarPro";
183
- /**
184
- * Music elements will be displayed and played as in traditional songbooks.
185
- * Changes:
186
- * 1. Bends
187
- * For bends additional grace beats are introduced.
188
- * Bends are categorized into gradual and fast bends.
189
- * - Gradual bends are indicated by beat text "grad" or "grad.". Bend will sound along the beat duration.
190
- * - Fast bends are done right before the next note. If the next note is tied even on-beat of the next note.
191
- * 2. Whammy Bars
192
- * Dips are shown as simple annotation over the beats
193
- * Whammy Bars are categorized into gradual and fast.
194
- * - Gradual whammys are indicated by beat text "grad" or "grad.". Whammys will sound along the beat duration.
195
- * - Fast whammys are done right the beat.
196
- * 3. Let Ring
197
- * Tied notes with let ring are not shown in standard notation
198
- * Let ring does not cause a longer playback, duration is defined via tied notes.
199
- */
200
- NotationMode[NotationMode["SongBook"] = 1] = "SongBook";
201
- })(NotationMode || (NotationMode = {}));
200
+ class Automation {
201
+ constructor() {
202
+ /**
203
+ * Gets or sets whether the automation is applied linear.
204
+ */
205
+ this.isLinear = false;
206
+ /**
207
+ * Gets or sets the type of the automation.
208
+ */
209
+ this.type = AutomationType.Tempo;
210
+ /**
211
+ * Gets or sets the target value of the automation.
212
+ */
213
+ this.value = 0;
214
+ /**
215
+ * Gets or sets the relative position of of the automation.
216
+ */
217
+ this.ratioPosition = 0;
218
+ /**
219
+ * Gets or sets the additional text of the automation.
220
+ */
221
+ this.text = '';
222
+ }
223
+ static buildTempoAutomation(isLinear, ratioPosition, value, reference) {
224
+ if (reference < 1 || reference > 5) {
225
+ reference = 2;
226
+ }
227
+ let references = new Float32Array([1, 0.5, 1.0, 1.5, 2.0, 3.0]);
228
+ let automation = new Automation();
229
+ automation.type = AutomationType.Tempo;
230
+ automation.isLinear = isLinear;
231
+ automation.ratioPosition = ratioPosition;
232
+ automation.value = value * references[reference];
233
+ return automation;
234
+ }
235
+ static buildInstrumentAutomation(isLinear, ratioPosition, value) {
236
+ let automation = new Automation();
237
+ automation.type = AutomationType.Instrument;
238
+ automation.isLinear = isLinear;
239
+ automation.ratioPosition = ratioPosition;
240
+ automation.value = value;
241
+ return automation;
242
+ }
243
+ }
244
+
202
245
  /**
203
- * Lists all major music notation elements that are part
204
- * of the music sheet and can be dynamically controlled to be shown
205
- * or hidden.
246
+ * This public enumeration lists all supported Clefs.
206
247
  */
207
- var NotationElement;
208
- (function (NotationElement) {
209
- /**
210
- * The score title shown at the start of the music sheet.
211
- */
212
- NotationElement[NotationElement["ScoreTitle"] = 0] = "ScoreTitle";
213
- /**
214
- * The score subtitle shown at the start of the music sheet.
215
- */
216
- NotationElement[NotationElement["ScoreSubTitle"] = 1] = "ScoreSubTitle";
217
- /**
218
- * The score artist shown at the start of the music sheet.
219
- */
220
- NotationElement[NotationElement["ScoreArtist"] = 2] = "ScoreArtist";
221
- /**
222
- * The score album shown at the start of the music sheet.
223
- */
224
- NotationElement[NotationElement["ScoreAlbum"] = 3] = "ScoreAlbum";
225
- /**
226
- * The score words author shown at the start of the music sheet.
227
- */
228
- NotationElement[NotationElement["ScoreWords"] = 4] = "ScoreWords";
229
- /**
230
- * The score music author shown at the start of the music sheet.
231
- */
232
- NotationElement[NotationElement["ScoreMusic"] = 5] = "ScoreMusic";
233
- /**
234
- * The score words&music author shown at the start of the music sheet.
235
- */
236
- NotationElement[NotationElement["ScoreWordsAndMusic"] = 6] = "ScoreWordsAndMusic";
237
- /**
238
- * The score copyright owner shown at the start of the music sheet.
239
- */
240
- NotationElement[NotationElement["ScoreCopyright"] = 7] = "ScoreCopyright";
241
- /**
242
- * The tuning information of the guitar shown
243
- * above the staves.
244
- */
245
- NotationElement[NotationElement["GuitarTuning"] = 8] = "GuitarTuning";
246
- /**
247
- * The track names which are shown in the accolade.
248
- */
249
- NotationElement[NotationElement["TrackNames"] = 9] = "TrackNames";
250
- /**
251
- * The chord diagrams for guitars. Usually shown
252
- * below the score info.
253
- */
254
- NotationElement[NotationElement["ChordDiagrams"] = 10] = "ChordDiagrams";
255
- /**
256
- * Parenthesis that are shown for tied bends
257
- * if they are preceeded by bends.
258
- */
259
- NotationElement[NotationElement["ParenthesisOnTiedBends"] = 11] = "ParenthesisOnTiedBends";
260
- /**
261
- * The tab number for tied notes if the
262
- * bend of a note is increased at that point.
263
- */
264
- NotationElement[NotationElement["TabNotesOnTiedBends"] = 12] = "TabNotesOnTiedBends";
265
- /**
266
- * Zero tab numbers on "dive whammys".
267
- */
268
- NotationElement[NotationElement["ZerosOnDiveWhammys"] = 13] = "ZerosOnDiveWhammys";
269
- /**
270
- * The alternate endings information on repeats shown above the staff.
271
- */
272
- NotationElement[NotationElement["EffectAlternateEndings"] = 14] = "EffectAlternateEndings";
273
- /**
274
- * The information about the fret on which the capo is placed shown above the staff.
275
- */
276
- NotationElement[NotationElement["EffectCapo"] = 15] = "EffectCapo";
277
- /**
278
- * The chord names shown above beats shown above the staff.
279
- */
280
- NotationElement[NotationElement["EffectChordNames"] = 16] = "EffectChordNames";
281
- /**
282
- * The crescendo/decrescendo angle shown above the staff.
283
- */
284
- NotationElement[NotationElement["EffectCrescendo"] = 17] = "EffectCrescendo";
285
- /**
286
- * The beat dynamics shown above the staff.
287
- */
288
- NotationElement[NotationElement["EffectDynamics"] = 18] = "EffectDynamics";
289
- /**
290
- * The curved angle for fade in/out effects shown above the staff.
291
- */
292
- NotationElement[NotationElement["EffectFadeIn"] = 19] = "EffectFadeIn";
293
- /**
294
- * The fermata symbol shown above the staff.
295
- */
296
- NotationElement[NotationElement["EffectFermata"] = 20] = "EffectFermata";
297
- /**
298
- * The fingering information.
299
- */
300
- NotationElement[NotationElement["EffectFingering"] = 21] = "EffectFingering";
301
- /**
302
- * The harmonics names shown above the staff.
303
- * (does not represent the harmonic note heads)
304
- */
305
- NotationElement[NotationElement["EffectHarmonics"] = 22] = "EffectHarmonics";
306
- /**
307
- * The let ring name and line above the staff.
308
- */
309
- NotationElement[NotationElement["EffectLetRing"] = 23] = "EffectLetRing";
310
- /**
311
- * The lyrics of the track shown above the staff.
312
- */
313
- NotationElement[NotationElement["EffectLyrics"] = 24] = "EffectLyrics";
314
- /**
315
- * The section markers shown above the staff.
316
- */
317
- NotationElement[NotationElement["EffectMarker"] = 25] = "EffectMarker";
318
- /**
319
- * The ottava symbol and lines shown above the staff.
320
- */
321
- NotationElement[NotationElement["EffectOttavia"] = 26] = "EffectOttavia";
248
+ var Clef;
249
+ (function (Clef) {
322
250
  /**
323
- * The palm mute name and line shown above the staff.
251
+ * Neutral clef.
324
252
  */
325
- NotationElement[NotationElement["EffectPalmMute"] = 27] = "EffectPalmMute";
253
+ Clef[Clef["Neutral"] = 0] = "Neutral";
326
254
  /**
327
- * The pick slide information shown above the staff.
328
- * (does not control the pick slide lines)
255
+ * C3 clef
329
256
  */
330
- NotationElement[NotationElement["EffectPickSlide"] = 28] = "EffectPickSlide";
257
+ Clef[Clef["C3"] = 1] = "C3";
331
258
  /**
332
- * The pick stroke symbols shown above the staff.
259
+ * C4 clef
333
260
  */
334
- NotationElement[NotationElement["EffectPickStroke"] = 29] = "EffectPickStroke";
261
+ Clef[Clef["C4"] = 2] = "C4";
335
262
  /**
336
- * The slight beat vibrato waves shown above the staff.
263
+ * F4 clef
337
264
  */
338
- NotationElement[NotationElement["EffectSlightBeatVibrato"] = 30] = "EffectSlightBeatVibrato";
265
+ Clef[Clef["F4"] = 3] = "F4";
339
266
  /**
340
- * The slight note vibrato waves shown above the staff.
267
+ * G2 clef
341
268
  */
342
- NotationElement[NotationElement["EffectSlightNoteVibrato"] = 31] = "EffectSlightNoteVibrato";
269
+ Clef[Clef["G2"] = 4] = "G2";
270
+ })(Clef || (Clef = {}));
271
+
272
+ /**
273
+ * Lists all ottavia.
274
+ */
275
+ var Ottavia;
276
+ (function (Ottavia) {
343
277
  /**
344
- * The tap/slap/pop effect names shown above the staff.
278
+ * 2 octaves higher
345
279
  */
346
- NotationElement[NotationElement["EffectTap"] = 32] = "EffectTap";
280
+ Ottavia[Ottavia["_15ma"] = 0] = "_15ma";
347
281
  /**
348
- * The tempo information shown above the staff.
282
+ * 1 octave higher
349
283
  */
350
- NotationElement[NotationElement["EffectTempo"] = 33] = "EffectTempo";
284
+ Ottavia[Ottavia["_8va"] = 1] = "_8va";
351
285
  /**
352
- * The additional beat text shown above the staff.
286
+ * Normal
353
287
  */
354
- NotationElement[NotationElement["EffectText"] = 34] = "EffectText";
288
+ Ottavia[Ottavia["Regular"] = 2] = "Regular";
355
289
  /**
356
- * The trill name and waves shown above the staff.
290
+ * 1 octave lower
357
291
  */
358
- NotationElement[NotationElement["EffectTrill"] = 35] = "EffectTrill";
292
+ Ottavia[Ottavia["_8vb"] = 3] = "_8vb";
359
293
  /**
360
- * The triplet feel symbol shown above the staff.
294
+ * 2 octaves lower.
361
295
  */
362
- NotationElement[NotationElement["EffectTripletFeel"] = 36] = "EffectTripletFeel";
296
+ Ottavia[Ottavia["_15mb"] = 4] = "_15mb";
297
+ })(Ottavia || (Ottavia = {}));
298
+
299
+ /**
300
+ * Lists all simile mark types as they are assigned to bars.
301
+ */
302
+ var SimileMark;
303
+ (function (SimileMark) {
363
304
  /**
364
- * The whammy bar information shown above the staff.
365
- * (does not control the whammy lines shown within the staff)
305
+ * No simile mark is applied
366
306
  */
367
- NotationElement[NotationElement["EffectWhammyBar"] = 37] = "EffectWhammyBar";
307
+ SimileMark[SimileMark["None"] = 0] = "None";
368
308
  /**
369
- * The wide beat vibrato waves shown above the staff.
309
+ * A simple simile mark. The previous bar is repeated.
370
310
  */
371
- NotationElement[NotationElement["EffectWideBeatVibrato"] = 38] = "EffectWideBeatVibrato";
311
+ SimileMark[SimileMark["Simple"] = 1] = "Simple";
372
312
  /**
373
- * The wide note vibrato waves shown above the staff.
313
+ * A double simile mark. This value is assigned to the first
314
+ * bar of the 2 repeat bars.
374
315
  */
375
- NotationElement[NotationElement["EffectWideNoteVibrato"] = 39] = "EffectWideNoteVibrato";
316
+ SimileMark[SimileMark["FirstOfDouble"] = 2] = "FirstOfDouble";
376
317
  /**
377
- * The left hand tap symbol shown above the staff.
318
+ * A double simile mark. This value is assigned to the second
319
+ * bar of the 2 repeat bars.
378
320
  */
379
- NotationElement[NotationElement["EffectLeftHandTap"] = 40] = "EffectLeftHandTap";
380
- })(NotationElement || (NotationElement = {}));
321
+ SimileMark[SimileMark["SecondOfDouble"] = 3] = "SecondOfDouble";
322
+ })(SimileMark || (SimileMark = {}));
323
+
381
324
  /**
382
- * The notation settings control how various music notation elements are shown and behaving
325
+ * A bar is a single block within a track, also known as Measure.
383
326
  * @json
384
327
  */
385
- class NotationSettings {
328
+ class Bar {
386
329
  constructor() {
387
330
  /**
388
- * Gets or sets the mode to use for display and play music notation elements.
389
- */
390
- this.notationMode = NotationMode.GuitarPro;
391
- /**
392
- * Gets or sets the fingering mode to use.
393
- */
394
- this.fingeringMode = FingeringMode.ScoreDefault;
395
- /**
396
- * Gets or sets the configuration on whether music notation elements are visible or not.
397
- * If notation elements are not specified, the default configuration will be applied.
331
+ * Gets or sets the unique id of this bar.
398
332
  */
399
- this.elements = new Map();
333
+ this.id = Bar._globalBarId++;
400
334
  /**
401
- * Whether to show rhythm notation in the guitar tablature.
335
+ * Gets or sets the zero-based index of this bar within the staff.
336
+ * @json_ignore
402
337
  */
403
- this.rhythmMode = TabRhythmMode.Hidden;
338
+ this.index = 0;
404
339
  /**
405
- * The height of the rythm bars.
340
+ * Gets or sets the next bar that comes after this bar.
341
+ * @json_ignore
406
342
  */
407
- this.rhythmHeight = 15;
343
+ this.nextBar = null;
408
344
  /**
409
- * The transposition pitch offsets for the individual tracks.
410
- * They apply to rendering and playback.
345
+ * Gets or sets the previous bar that comes before this bar.
346
+ * @json_ignore
411
347
  */
412
- this.transpositionPitches = [];
348
+ this.previousBar = null;
413
349
  /**
414
- * The transposition pitch offsets for the individual tracks.
415
- * They apply to rendering only.
350
+ * Gets or sets the clef on this bar.
416
351
  */
417
- this.displayTranspositionPitches = [];
352
+ this.clef = Clef.G2;
418
353
  /**
419
- * If set to true the guitar tabs on grace beats are rendered smaller.
354
+ * Gets or sets the ottava applied to the clef.
420
355
  */
421
- this.smallGraceTabNotes = true;
356
+ this.clefOttava = Ottavia.Regular;
422
357
  /**
423
- * If set to true bend arrows expand to the end of the last tied note
424
- * of the string. Otherwise they end on the next beat.
358
+ * Gets or sets the list of voices contained in this bar.
359
+ * @json_add addVoice
425
360
  */
426
- this.extendBendArrowsOnTiedNotes = true;
361
+ this.voices = [];
427
362
  /**
428
- * If set to true, line effects (like w/bar, let-ring etc)
429
- * are drawn until the end of the beat instead of the start.
363
+ * Gets or sets the simile mark on this bar.
430
364
  */
431
- this.extendLineEffectsToBeatEnd = false;
365
+ this.simileMark = SimileMark.None;
432
366
  /**
433
- * Gets or sets the height for slurs. The factor is multiplied with the a logarithmic distance
434
- * between slur start and end.
367
+ * Gets a value indicating whether this bar contains multiple voices with notes.
368
+ * @json_ignore
435
369
  */
436
- this.slurHeight = 5.0;
370
+ this.isMultiVoice = false;
437
371
  }
438
- /**
439
- * Gets whether the given music notation element should be shown
440
- * @param element the element to check
441
- * @returns true if the element should be shown, otherwise false.
442
- */
443
- isNotationElementVisible(element) {
444
- if (this.elements.has(element)) {
445
- return this.elements.get(element);
446
- }
447
- if (NotationSettings.defaultElements.has(element)) {
448
- return NotationSettings.defaultElements.get(element);
449
- }
450
- return true;
451
- }
452
- }
453
- /**
454
- * Gets the default configuration of the {@see notationElements} setting. Do not modify
455
- * this map as it might not result in the expected side effects.
456
- * If items are not listed explicitly in this list, they are considered visible.
457
- */
458
- NotationSettings.defaultElements = new Map([
459
- [NotationElement.ZerosOnDiveWhammys, false]
460
- ]);
461
-
462
- class TuningParseResult {
463
- constructor() {
464
- this.note = null;
465
- this.noteValue = 0;
466
- this.octave = 0;
467
- }
468
- get realValue() {
469
- return this.octave * 12 + this.noteValue;
372
+ get masterBar() {
373
+ return this.staff.track.score.masterBars[this.index];
470
374
  }
471
- }
472
- /**
473
- * This public class contains some utilities for working with model public classes
474
- */
475
- class ModelUtils {
476
- static getIndex(duration) {
477
- let index = 0;
478
- let value = duration;
479
- if (value < 0) {
480
- return index;
375
+ get isEmpty() {
376
+ for (let i = 0, j = this.voices.length; i < j; i++) {
377
+ if (!this.voices[i].isEmpty) {
378
+ return false;
379
+ }
481
380
  }
482
- return Math.log2(duration) | 0;
483
- }
484
- static keySignatureIsFlat(ks) {
485
- return ks < 0;
486
- }
487
- static keySignatureIsNatural(ks) {
488
- return ks === 0;
381
+ return true;
489
382
  }
490
- static keySignatureIsSharp(ks) {
491
- return ks > 0;
383
+ addVoice(voice) {
384
+ voice.bar = this;
385
+ voice.index = this.voices.length;
386
+ this.voices.push(voice);
492
387
  }
493
- static applyPitchOffsets(settings, score) {
494
- for (let i = 0; i < score.tracks.length; i++) {
495
- if (i < settings.notation.displayTranspositionPitches.length) {
496
- for (let staff of score.tracks[i].staves) {
497
- staff.displayTranspositionPitch = -settings.notation.displayTranspositionPitches[i];
498
- }
499
- }
500
- if (i < settings.notation.transpositionPitches.length) {
501
- for (let staff of score.tracks[i].staves) {
502
- staff.transpositionPitch = -settings.notation.transpositionPitches[i];
503
- }
388
+ finish(settings) {
389
+ this.isMultiVoice = false;
390
+ for (let i = 0, j = this.voices.length; i < j; i++) {
391
+ let voice = this.voices[i];
392
+ voice.finish(settings);
393
+ if (i > 0 && !voice.isEmpty) {
394
+ this.isMultiVoice = true;
504
395
  }
505
396
  }
506
397
  }
507
- static fingerToString(settings, beat, finger, leftHand) {
508
- if (settings.notation.fingeringMode === FingeringMode.ScoreForcePiano ||
509
- settings.notation.fingeringMode === FingeringMode.SingleNoteEffectBandForcePiano ||
510
- GeneralMidi.isPiano(beat.voice.bar.staff.track.playbackInfo.program)) {
511
- switch (finger) {
512
- case Fingers.Unknown:
513
- case Fingers.NoOrDead:
514
- return null;
515
- case Fingers.Thumb:
516
- return '1';
517
- case Fingers.IndexFinger:
518
- return '2';
519
- case Fingers.MiddleFinger:
520
- return '3';
521
- case Fingers.AnnularFinger:
522
- return '4';
523
- case Fingers.LittleFinger:
524
- return '5';
525
- default:
526
- return null;
527
- }
528
- }
529
- if (leftHand) {
530
- switch (finger) {
531
- case Fingers.Unknown:
532
- case Fingers.NoOrDead:
533
- return '0';
534
- case Fingers.Thumb:
535
- return 'T';
536
- case Fingers.IndexFinger:
537
- return '1';
538
- case Fingers.MiddleFinger:
539
- return '2';
540
- case Fingers.AnnularFinger:
541
- return '3';
542
- case Fingers.LittleFinger:
543
- return '4';
544
- default:
545
- return null;
398
+ calculateDuration() {
399
+ let duration = 0;
400
+ for (let voice of this.voices) {
401
+ let voiceDuration = voice.calculateDuration();
402
+ if (voiceDuration > duration) {
403
+ duration = voiceDuration;
546
404
  }
547
405
  }
548
- switch (finger) {
549
- case Fingers.Unknown:
550
- case Fingers.NoOrDead:
551
- return null;
552
- case Fingers.Thumb:
553
- return 'p';
554
- case Fingers.IndexFinger:
555
- return 'i';
556
- case Fingers.MiddleFinger:
557
- return 'm';
558
- case Fingers.AnnularFinger:
559
- return 'a';
560
- case Fingers.LittleFinger:
561
- return 'c';
562
- default:
563
- return null;
564
- }
406
+ return duration;
565
407
  }
408
+ }
409
+ Bar._globalBarId = 0;
410
+
411
+ class MidiUtils {
566
412
  /**
567
- * Checks if the given string is a tuning inticator.
568
- * @param name
569
- * @returns
413
+ * Converts the given midi tick duration into milliseconds.
414
+ * @param ticks The duration in midi ticks
415
+ * @param tempo The current tempo in BPM.
416
+ * @returns The converted duration in milliseconds.
570
417
  */
571
- static isTuning(name) {
572
- return !!ModelUtils.parseTuning(name);
418
+ static ticksToMillis(ticks, tempo) {
419
+ return (ticks * (60000.0 / (tempo * MidiUtils.QuarterTime))) | 0;
573
420
  }
574
- static parseTuning(name) {
575
- let note = '';
576
- let octave = '';
577
- for (let i = 0; i < name.length; i++) {
578
- let c = name.charCodeAt(i);
579
- if (c >= 0x30 && c <= 0x39) {
580
- // number without note?
581
- if (!note) {
582
- return null;
583
- }
584
- octave += String.fromCharCode(c);
585
- }
586
- else if ((c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) || c === 0x23) {
587
- note += String.fromCharCode(c);
588
- }
589
- else {
590
- return null;
591
- }
592
- }
593
- if (!octave || !note) {
594
- return null;
595
- }
596
- let result = new TuningParseResult();
597
- result.octave = parseInt(octave) + 1;
598
- result.note = note.toLowerCase();
599
- result.noteValue = ModelUtils.getToneForText(result.note);
600
- return result;
421
+ /**
422
+ * Converts the given midi tick duration into milliseconds.
423
+ * @param millis The duration in milliseconds
424
+ * @param tempo The current tempo in BPM.
425
+ * @returns The converted duration in midi ticks.
426
+ */
427
+ static millisToTicks(millis, tempo) {
428
+ return (millis / (60000.0 / (tempo * MidiUtils.QuarterTime))) | 0;
601
429
  }
602
- static getTuningForText(str) {
603
- let result = ModelUtils.parseTuning(str);
604
- if (!result) {
605
- return -1;
430
+ /**
431
+ * Converts a duration value to its ticks equivalent.
432
+ */
433
+ static toTicks(duration) {
434
+ return MidiUtils.valueToTicks(duration);
435
+ }
436
+ /**
437
+ * Converts a numerical value to its ticks equivalent.
438
+ * @param duration the numerical proportion to convert. (i.E. timesignature denominator, note duration,...)
439
+ */
440
+ static valueToTicks(duration) {
441
+ let denomninator = duration;
442
+ if (denomninator < 0) {
443
+ denomninator = 1 / -denomninator;
606
444
  }
607
- return result.realValue;
445
+ return (MidiUtils.QuarterTime * (4.0 / denomninator)) | 0;
608
446
  }
609
- static getToneForText(note) {
610
- let b = 0;
611
- switch (note.toLowerCase()) {
612
- case 'c':
613
- b = 0;
614
- break;
615
- case 'c#':
616
- case 'db':
617
- b = 1;
618
- break;
619
- case 'd':
620
- b = 2;
621
- break;
622
- case 'd#':
623
- case 'eb':
624
- b = 3;
625
- break;
626
- case 'e':
627
- b = 4;
628
- break;
629
- case 'f':
630
- b = 5;
631
- break;
632
- case 'f#':
633
- case 'gb':
634
- b = 6;
635
- break;
636
- case 'g':
637
- b = 7;
638
- break;
639
- case 'g#':
640
- case 'ab':
641
- b = 8;
642
- break;
643
- case 'a':
644
- b = 9;
645
- break;
646
- case 'a#':
647
- case 'bb':
648
- b = 10;
649
- break;
650
- case 'b':
651
- b = 11;
652
- break;
653
- default:
654
- return 0;
447
+ static applyDot(ticks, doubleDotted) {
448
+ if (doubleDotted) {
449
+ return ticks + ((ticks / 4) | 0) * 3;
655
450
  }
656
- return b;
451
+ return ticks + ((ticks / 2) | 0);
657
452
  }
658
- static newGuid() {
659
- return (Math.floor((1 + Math.random()) * 0x10000)
660
- .toString(16)
661
- .substring(1) +
662
- Math.floor((1 + Math.random()) * 0x10000)
663
- .toString(16)
664
- .substring(1) +
665
- '-' +
666
- Math.floor((1 + Math.random()) * 0x10000)
667
- .toString(16)
668
- .substring(1) +
669
- '-' +
670
- Math.floor((1 + Math.random()) * 0x10000)
671
- .toString(16)
672
- .substring(1) +
673
- '-' +
674
- Math.floor((1 + Math.random()) * 0x10000)
675
- .toString(16)
676
- .substring(1) +
677
- '-' +
678
- Math.floor((1 + Math.random()) * 0x10000)
679
- .toString(16)
680
- .substring(1) +
681
- Math.floor((1 + Math.random()) * 0x10000)
682
- .toString(16)
683
- .substring(1) +
684
- Math.floor((1 + Math.random()) * 0x10000)
685
- .toString(16)
686
- .substring(1));
453
+ static applyTuplet(ticks, numerator, denominator) {
454
+ return ((ticks * denominator) / numerator) | 0;
687
455
  }
688
- static isAlmostEqualTo(a, b) {
689
- return Math.abs(a - b) < 0.00001;
456
+ static removeTuplet(ticks, numerator, denominator) {
457
+ return ((ticks * numerator) / denominator) | 0;
690
458
  }
691
- static toHexString(n, digits = 0) {
692
- let s = '';
693
- let hexChars = '0123456789ABCDEF';
694
- do {
695
- s = String.fromCharCode(hexChars.charCodeAt(n & 15)) + s;
696
- n = n >> 4;
697
- } while (n > 0);
698
- while (s.length < digits) {
699
- s = '0' + s;
700
- }
701
- return s;
459
+ static dynamicToVelocity(dyn) {
460
+ return MidiUtils.MinVelocity + dyn * MidiUtils.VelocityIncrement;
702
461
  }
703
- }
462
+ }
463
+ MidiUtils.QuarterTime = 960;
464
+ MidiUtils.MinVelocity = 15;
465
+ MidiUtils.VelocityIncrement = 16;
704
466
 
705
467
  /**
706
- * @json_immutable
468
+ * A single point of a bending graph. Used to
469
+ * describe WhammyBar and String Bending effects.
470
+ * @cloneable
471
+ * @json
707
472
  */
708
- class Color {
473
+ class BendPoint {
709
474
  /**
710
- * Initializes a new instance of the {@link Color} class.
711
- * @param r The red component.
712
- * @param g The green component.
713
- * @param b The blue component.
714
- * @param a The alpha component.
475
+ * Initializes a new instance of the {@link BendPoint} class.
476
+ * @param offset The offset.
477
+ * @param value The value.
715
478
  */
716
- constructor(r, g, b, a = 0xff) {
717
- /**
718
- * Gets or sets the raw RGBA value.
719
- */
720
- this.raw = 0;
721
- this.raw = ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
722
- this.updateRgba();
723
- }
724
- updateRgba() {
725
- if (this.a === 0xff) {
726
- this.rgba =
727
- '#' +
728
- ModelUtils.toHexString(this.r, 2) +
729
- ModelUtils.toHexString(this.g, 2) +
730
- ModelUtils.toHexString(this.b, 2);
731
- }
732
- else {
733
- this.rgba = `rgba(${this.r},${this.g},${this.b},${this.a / 255.0})`;
734
- }
735
- }
736
- get a() {
737
- return (this.raw >> 24) & 0xff;
738
- }
739
- get r() {
740
- return (this.raw >> 16) & 0xff;
741
- }
742
- get g() {
743
- return (this.raw >> 8) & 0xff;
744
- }
745
- get b() {
746
- return this.raw & 0xff;
747
- }
748
- static random(opacity = 100) {
749
- return new Color((Math.random() * 255) | 0, (Math.random() * 255) | 0, (Math.random() * 255) | 0, opacity);
750
- }
751
- static fromJson(v) {
752
- switch (typeof v) {
753
- case 'number':
754
- {
755
- const c = new Color(0, 0, 0, 0);
756
- c.raw = v;
757
- c.updateRgba();
758
- return c;
759
- }
760
- case 'string':
761
- {
762
- const json = v;
763
- if (json.startsWith('#')) {
764
- if (json.length === 4) {
765
- // #RGB
766
- return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17);
767
- }
768
- if (json.length === 5) {
769
- // #RGBA
770
- return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17, parseInt(json.substring(4, 1), 16) * 17);
771
- }
772
- if (json.length === 7) {
773
- // #RRGGBB
774
- return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16));
775
- }
776
- if (json.length === 9) {
777
- // #RRGGBBAA
778
- return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16), parseInt(json.substring(7, 2), 16));
779
- }
780
- }
781
- else if (json.startsWith('rgba') || json.startsWith('rgb')) {
782
- const start = json.indexOf('(');
783
- const end = json.lastIndexOf(')');
784
- if (start === -1 || end === -1) {
785
- throw new FormatError('No values specified for rgb/rgba function');
786
- }
787
- const numbers = json.substring(start + 1, end).split(',');
788
- if (numbers.length === 3) {
789
- return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]));
790
- }
791
- if (numbers.length === 4) {
792
- return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]), parseFloat(numbers[3]) * 255);
793
- }
794
- }
795
- return null;
796
- }
797
- }
798
- throw new FormatError('Unsupported format for color');
799
- }
800
- static toJson(obj) {
801
- return obj.raw;
479
+ constructor(offset = 0, value = 0) {
480
+ this.offset = offset;
481
+ this.value = value;
802
482
  }
803
483
  }
804
- Color.BlackRgb = '#000000';
484
+ BendPoint.MaxPosition = 60;
485
+ BendPoint.MaxValue = 12;
805
486
 
806
487
  /**
807
- * @partial
488
+ * Lists the different bend styles
808
489
  */
809
- class JsonHelper {
490
+ var BendStyle;
491
+ (function (BendStyle) {
810
492
  /**
811
- * @target web
812
- * @partial
493
+ * The bends are as described by the bend points
813
494
  */
814
- static parseEnum(s, enumType) {
815
- switch (typeof s) {
816
- case 'string':
817
- const num = parseInt(s);
818
- return isNaN(num)
819
- ? enumType[Object.keys(enumType).find(k => k.toLowerCase() === s.toLowerCase())]
820
- : num;
821
- case 'number':
822
- return s;
823
- case 'undefined':
824
- case 'object':
825
- return null;
826
- }
827
- throw new AlphaTabError(AlphaTabErrorType.Format, `Could not parse enum value '${s}'`);
828
- }
495
+ BendStyle[BendStyle["Default"] = 0] = "Default";
829
496
  /**
830
- * @target web
831
- * @partial
497
+ * The bends are gradual over the beat duration.
832
498
  */
833
- static forEach(s, func) {
834
- if (s instanceof Map) {
835
- s.forEach(func);
836
- }
837
- else if (typeof s === 'object') {
838
- for (const k in s) {
839
- func(s[k], k);
840
- }
841
- }
842
- // skip
843
- }
844
- }
499
+ BendStyle[BendStyle["Gradual"] = 1] = "Gradual";
500
+ /**
501
+ * The bends are done fast before the next note.
502
+ */
503
+ BendStyle[BendStyle["Fast"] = 2] = "Fast";
504
+ })(BendStyle || (BendStyle = {}));
845
505
 
846
506
  /**
847
- * A very basic font parser which parses the fields according to
848
- * https://www.w3.org/TR/CSS21/fonts.html#propdef-font
507
+ * Lists all types of bends
849
508
  */
850
- class FontParserToken {
851
- constructor(text, startPos, endPos) {
852
- this.text = text;
853
- this.startPos = startPos;
854
- this.endPos = endPos;
855
- }
856
- }
857
- class FontParser {
858
- constructor(input) {
859
- this.style = 'normal';
860
- this.variant = 'normal';
861
- this.weight = 'normal';
862
- this.stretch = 'normal';
863
- this.lineHeight = 'normal';
864
- this.size = '1rem';
865
- this.families = [];
866
- this._currentTokenIndex = -1;
867
- this._input = '';
868
- this._currentToken = null;
869
- this._input = input;
870
- this._tokens = this.splitToTokens(input);
871
- }
872
- splitToTokens(input) {
873
- const tokens = [];
874
- let startPos = 0;
875
- while (startPos < input.length) {
876
- let endPos = startPos;
877
- while (endPos < input.length && input.charAt(endPos) !== ' ') {
878
- endPos++;
879
- }
880
- if (endPos > startPos) {
881
- tokens.push(new FontParserToken(input.substring(startPos, endPos), startPos, endPos));
882
- }
883
- startPos = endPos + 1;
884
- }
885
- return tokens;
886
- }
887
- parse() {
888
- var _a;
889
- this.reset();
890
- // default font flags
891
- if (this._tokens.length === 1) {
892
- switch ((_a = this._currentToken) === null || _a === void 0 ? void 0 : _a.text) {
893
- case 'caption':
894
- case 'icon':
895
- case 'menu':
896
- case 'message-box':
897
- case 'small-caption':
898
- case 'status-bar':
899
- case 'inherit':
900
- return;
901
- }
902
- }
903
- this.fontStyleVariantWeight();
904
- this.fontSizeLineHeight();
905
- this.fontFamily();
906
- }
907
- fontFamily() {
908
- if (!this._currentToken) {
909
- throw new Error(`Missing font list`);
910
- }
911
- const familyListInput = this._input.substr(this._currentToken.startPos).trim();
912
- let pos = 0;
913
- while (pos < familyListInput.length) {
914
- let c = familyListInput.charAt(pos);
915
- if (c === ' ' || c == ',') {
916
- // skip whitespace and quotes
917
- pos++;
918
- }
919
- else if (c === '"' || c === "'") {
920
- // quoted
921
- const endOfString = this.findEndOfQuote(familyListInput, pos + 1, c);
922
- this.families.push(familyListInput
923
- .substring(pos + 1, endOfString)
924
- .split('\\' + c)
925
- .join(c));
926
- pos = endOfString + 1;
927
- }
928
- else {
929
- // until comma
930
- const endOfString = this.findEndOfQuote(familyListInput, pos + 1, ',');
931
- this.families.push(familyListInput.substring(pos, endOfString).trim());
932
- pos = endOfString + 1;
933
- }
934
- }
935
- }
936
- findEndOfQuote(s, pos, quoteChar) {
937
- let escaped = false;
938
- while (pos < s.length) {
939
- const c = s.charAt(pos);
940
- if (!escaped && c === quoteChar) {
941
- return pos;
942
- }
943
- if (!escaped && c === '\\') {
944
- escaped = true;
945
- }
946
- else {
947
- escaped = false;
948
- }
949
- pos += 1;
950
- }
951
- return s.length;
952
- }
953
- fontSizeLineHeight() {
954
- if (!this._currentToken) {
955
- throw new Error(`Missing font size`);
956
- }
957
- const parts = this._currentToken.text.split('/');
958
- if (parts.length >= 3) {
959
- throw new Error(`Invalid font size '${this._currentToken}' specified`);
960
- }
961
- this.nextToken();
962
- if (parts.length >= 2) {
963
- if (parts[1] === '/') {
964
- // size/ line-height (space after slash)
965
- if (!this._currentToken) {
966
- throw new Error('Missing line-height after font size');
967
- }
968
- this.lineHeight = this._currentToken.text;
969
- this.nextToken();
970
- }
971
- else {
972
- // size/line-height (no spaces)
973
- this.size = parts[0];
974
- this.lineHeight = parts[1];
975
- }
976
- }
977
- else if (parts.length >= 1) {
978
- this.size = parts[0];
979
- if (this._currentToken &&
980
- this._currentToken.text.indexOf('/') === 0) {
981
- // size / line-height (with spaces befor and after slash)
982
- if (this._currentToken.text === '/') {
983
- this.nextToken();
984
- if (!this._currentToken) {
985
- throw new Error('Missing line-height after font size');
986
- }
987
- this.lineHeight = this._currentToken.text;
988
- this.nextToken();
989
- }
990
- else {
991
- this.lineHeight = this._currentToken.text.substr(1);
992
- this.nextToken();
993
- }
994
- }
995
- }
996
- else {
997
- throw new Error(`Missing font size`);
998
- }
999
- }
1000
- nextToken() {
1001
- this._currentTokenIndex++;
1002
- if (this._currentTokenIndex < this._tokens.length) {
1003
- this._currentToken = this._tokens[this._currentTokenIndex];
1004
- }
1005
- else {
1006
- this._currentToken = null;
1007
- }
1008
- }
1009
- fontStyleVariantWeight() {
1010
- let hasStyle = false;
1011
- let hasVariant = false;
1012
- let hasWeight = false;
1013
- let valuesNeeded = 3;
1014
- let ambiguous = [];
1015
- while (true) {
1016
- if (!this._currentToken) {
1017
- return;
1018
- }
1019
- let text = this._currentToken.text;
1020
- switch (text) {
1021
- // ambiguous
1022
- case 'normal':
1023
- case 'inherit':
1024
- ambiguous.push(text);
1025
- valuesNeeded--;
1026
- this.nextToken();
1027
- break;
1028
- // style
1029
- case 'italic':
1030
- case 'oblique':
1031
- this.style = text;
1032
- hasStyle = true;
1033
- valuesNeeded--;
1034
- this.nextToken();
1035
- break;
1036
- // variant
1037
- case 'small-caps':
1038
- this.variant = text;
1039
- hasVariant = true;
1040
- valuesNeeded--;
1041
- this.nextToken();
1042
- break;
1043
- // weight
1044
- case 'bold':
1045
- case 'bolder':
1046
- case 'lighter':
1047
- case '100':
1048
- case '200':
1049
- case '300':
1050
- case '400':
1051
- case '500':
1052
- case '600':
1053
- case '700':
1054
- case '800':
1055
- case '900':
1056
- this.weight = text;
1057
- hasWeight = true;
1058
- valuesNeeded--;
1059
- this.nextToken();
1060
- break;
1061
- default:
1062
- // unknown token -> done with this part
1063
- return;
1064
- }
1065
- if (valuesNeeded === 0) {
1066
- break;
1067
- }
1068
- }
1069
- while (ambiguous.length > 0) {
1070
- const v = ambiguous.pop();
1071
- if (!hasWeight) {
1072
- this.weight = v;
1073
- }
1074
- else if (!hasVariant) {
1075
- this.variant = v;
1076
- }
1077
- else if (!hasStyle) {
1078
- this.style = v;
1079
- }
1080
- }
1081
- }
1082
- reset() {
1083
- this._currentTokenIndex = -1;
1084
- this.nextToken();
1085
- }
1086
- }
509
+ var BendType;
510
+ (function (BendType) {
511
+ /**
512
+ * No bend at all
513
+ */
514
+ BendType[BendType["None"] = 0] = "None";
515
+ /**
516
+ * Individual points define the bends in a flexible manner.
517
+ * This system was mainly used in Guitar Pro 3-5
518
+ */
519
+ BendType[BendType["Custom"] = 1] = "Custom";
520
+ /**
521
+ * Simple Bend from an unbended string to a higher note.
522
+ */
523
+ BendType[BendType["Bend"] = 2] = "Bend";
524
+ /**
525
+ * Release of a bend that was started on an earlier note.
526
+ */
527
+ BendType[BendType["Release"] = 3] = "Release";
528
+ /**
529
+ * A bend that starts from an unbended string,
530
+ * and also releases the bend after some time.
531
+ */
532
+ BendType[BendType["BendRelease"] = 4] = "BendRelease";
533
+ /**
534
+ * Holds a bend that was started on an earlier note
535
+ */
536
+ BendType[BendType["Hold"] = 5] = "Hold";
537
+ /**
538
+ * A bend that is already started before the note is played then it is held until the end.
539
+ */
540
+ BendType[BendType["Prebend"] = 6] = "Prebend";
541
+ /**
542
+ * A bend that is already started before the note is played and
543
+ * bends even further, then it is held until the end.
544
+ */
545
+ BendType[BendType["PrebendBend"] = 7] = "PrebendBend";
546
+ /**
547
+ * A bend that is already started before the note is played and
548
+ * then releases the bend to a lower note where it is held until the end.
549
+ */
550
+ BendType[BendType["PrebendRelease"] = 8] = "PrebendRelease";
551
+ })(BendType || (BendType = {}));
552
+
1087
553
  /**
1088
- * Lists all flags for font styles.
554
+ * Lists all types of how to brush multiple notes on a beat.
1089
555
  */
1090
- var FontStyle;
1091
- (function (FontStyle) {
556
+ var BrushType;
557
+ (function (BrushType) {
1092
558
  /**
1093
- * No flags.
559
+ * No brush.
1094
560
  */
1095
- FontStyle[FontStyle["Plain"] = 0] = "Plain";
561
+ BrushType[BrushType["None"] = 0] = "None";
1096
562
  /**
1097
- * Font is italic.
563
+ * Normal brush up.
1098
564
  */
1099
- FontStyle[FontStyle["Italic"] = 1] = "Italic";
1100
- })(FontStyle || (FontStyle = {}));
565
+ BrushType[BrushType["BrushUp"] = 1] = "BrushUp";
566
+ /**
567
+ * Normal brush down.
568
+ */
569
+ BrushType[BrushType["BrushDown"] = 2] = "BrushDown";
570
+ /**
571
+ * Arpeggio up.
572
+ */
573
+ BrushType[BrushType["ArpeggioUp"] = 3] = "ArpeggioUp";
574
+ /**
575
+ * Arpeggio down.
576
+ */
577
+ BrushType[BrushType["ArpeggioDown"] = 4] = "ArpeggioDown";
578
+ })(BrushType || (BrushType = {}));
579
+
1101
580
  /**
1102
- * Lists all font weight values.
581
+ * Lists all Crescendo and Decrescendo types.
1103
582
  */
1104
- var FontWeight;
1105
- (function (FontWeight) {
583
+ var CrescendoType;
584
+ (function (CrescendoType) {
1106
585
  /**
1107
- * Not bold
586
+ * No crescendo applied.
1108
587
  */
1109
- FontWeight[FontWeight["Regular"] = 0] = "Regular";
588
+ CrescendoType[CrescendoType["None"] = 0] = "None";
1110
589
  /**
1111
- * Font is bold
590
+ * Normal crescendo applied.
1112
591
  */
1113
- FontWeight[FontWeight["Bold"] = 1] = "Bold";
1114
- })(FontWeight || (FontWeight = {}));
592
+ CrescendoType[CrescendoType["Crescendo"] = 1] = "Crescendo";
593
+ /**
594
+ * Normal decrescendo applied.
595
+ */
596
+ CrescendoType[CrescendoType["Decrescendo"] = 2] = "Decrescendo";
597
+ })(CrescendoType || (CrescendoType = {}));
598
+
1115
599
  /**
1116
- * @json_immutable
600
+ * Lists all durations of a beat.
1117
601
  */
1118
- class Font {
602
+ var Duration;
603
+ (function (Duration) {
1119
604
  /**
1120
- * Initializes a new instance of the {@link Font} class.
1121
- * @param family The family.
1122
- * @param size The size.
1123
- * @param style The style.
1124
- * @param weight The weight.
605
+ * A quadruple whole note duration
1125
606
  */
1126
- constructor(family, size, style = FontStyle.Plain, weight = FontWeight.Regular) {
1127
- this._cssScale = 0.0;
1128
- this._family = family;
1129
- this._size = size;
1130
- this._style = style;
1131
- this._weight = weight;
1132
- this._css = this.toCssString();
1133
- }
1134
- reset() {
1135
- this._cssScale = 0;
1136
- this._css = this.toCssString();
1137
- }
607
+ Duration[Duration["QuadrupleWhole"] = -4] = "QuadrupleWhole";
1138
608
  /**
1139
- * Gets the font family name.
609
+ * A double whole note duration
1140
610
  */
1141
- get family() {
1142
- return this._family;
1143
- }
611
+ Duration[Duration["DoubleWhole"] = -2] = "DoubleWhole";
1144
612
  /**
1145
- * Sets the font family name.
613
+ * A whole note duration
1146
614
  */
1147
- set family(value) {
1148
- this._family = value;
1149
- this.reset();
1150
- }
615
+ Duration[Duration["Whole"] = 1] = "Whole";
1151
616
  /**
1152
- * Gets the font size in pixels.
617
+ * A 1/2 note duration
1153
618
  */
1154
- get size() {
1155
- return this._size;
1156
- }
619
+ Duration[Duration["Half"] = 2] = "Half";
1157
620
  /**
1158
- * Sets the font size in pixels.
621
+ * A 1/4 note duration
1159
622
  */
1160
- set size(value) {
1161
- this._size = value;
1162
- this.reset();
1163
- }
623
+ Duration[Duration["Quarter"] = 4] = "Quarter";
1164
624
  /**
1165
- * Gets the font style.
625
+ * A 1/8 note duration
1166
626
  */
1167
- get style() {
1168
- return this._style;
1169
- }
627
+ Duration[Duration["Eighth"] = 8] = "Eighth";
1170
628
  /**
1171
- * Sets the font style.
629
+ * A 1/16 note duration
1172
630
  */
1173
- set style(value) {
1174
- this._style = value;
1175
- this.reset();
1176
- }
631
+ Duration[Duration["Sixteenth"] = 16] = "Sixteenth";
1177
632
  /**
1178
- * Gets the font weight.
633
+ * A 1/32 note duration
1179
634
  */
1180
- get weight() {
1181
- return this._weight;
1182
- }
635
+ Duration[Duration["ThirtySecond"] = 32] = "ThirtySecond";
1183
636
  /**
1184
- * Gets or sets the font weight.
637
+ * A 1/64 note duration
1185
638
  */
1186
- set weight(value) {
1187
- this._weight = value;
1188
- this.reset();
1189
- }
1190
- get isBold() {
1191
- return this.weight === FontWeight.Bold;
1192
- }
1193
- get isItalic() {
1194
- return this.style === FontStyle.Italic;
1195
- }
1196
- toCssString(scale = 1) {
1197
- if (!this._css || !(Math.abs(scale - this._cssScale) < 0.01)) {
1198
- let buf = '';
1199
- if (this.isBold) {
1200
- buf += 'bold ';
1201
- }
1202
- if (this.isItalic) {
1203
- buf += 'italic ';
1204
- }
1205
- buf += this.size * scale;
1206
- buf += 'px ';
1207
- buf += "'";
1208
- buf += this.family;
1209
- buf += "'";
1210
- this._css = buf;
1211
- this._cssScale = scale;
1212
- }
1213
- return this._css;
1214
- }
1215
- static fromJson(v) {
1216
- switch (typeof v) {
1217
- case 'undefined':
1218
- return null;
1219
- case 'object': {
1220
- const m = v;
1221
- let family = m.get('family');
1222
- // tslint:disable-next-line: no-unnecessary-type-assertion
1223
- let size = m.get('size');
1224
- let style = JsonHelper.parseEnum(m.get('style'), FontStyle);
1225
- let weight = JsonHelper.parseEnum(m.get('weight'), FontWeight);
1226
- return new Font(family, size, style, weight);
1227
- }
1228
- case 'string': {
1229
- const parser = new FontParser(v);
1230
- parser.parse();
1231
- let family = parser.families[0];
1232
- if ((family.startsWith("'") && family.endsWith("'")) ||
1233
- (family.startsWith('"') && family.endsWith('"'))) {
1234
- family = family.substr(1, family.length - 2);
1235
- }
1236
- let fontSizeString = parser.size.toLowerCase();
1237
- let fontSize = 0;
1238
- // as per https://websemantics.uk/articles/font-size-conversion/
1239
- switch (fontSizeString) {
1240
- case 'xx-small':
1241
- fontSize = 7;
1242
- break;
1243
- case 'x-small':
1244
- fontSize = 10;
1245
- break;
1246
- case 'small':
1247
- case 'smaller':
1248
- fontSize = 13;
1249
- break;
1250
- case 'medium':
1251
- fontSize = 16;
1252
- break;
1253
- case 'large':
1254
- case 'larger':
1255
- fontSize = 18;
1256
- break;
1257
- case 'x-large':
1258
- fontSize = 24;
1259
- break;
1260
- case 'xx-large':
1261
- fontSize = 32;
1262
- break;
1263
- default:
1264
- try {
1265
- if (fontSizeString.endsWith('em')) {
1266
- fontSize = parseFloat(fontSizeString.substr(0, fontSizeString.length - 2)) * 16;
1267
- }
1268
- else if (fontSizeString.endsWith('pt')) {
1269
- fontSize =
1270
- (parseFloat(fontSizeString.substr(0, fontSizeString.length - 2)) * 16.0) / 12.0;
1271
- }
1272
- else if (fontSizeString.endsWith('px')) {
1273
- fontSize = parseFloat(fontSizeString.substr(0, fontSizeString.length - 2));
1274
- }
1275
- else {
1276
- fontSize = 12;
1277
- }
1278
- }
1279
- catch (e) {
1280
- fontSize = 12;
1281
- }
1282
- break;
1283
- }
1284
- let fontStyle = FontStyle.Plain;
1285
- if (parser.style === 'italic') {
1286
- fontStyle = FontStyle.Italic;
1287
- }
1288
- let fontWeight = FontWeight.Regular;
1289
- let fontWeightString = parser.weight.toLowerCase();
1290
- switch (fontWeightString) {
1291
- case 'normal':
1292
- case 'lighter':
1293
- break;
1294
- default:
1295
- fontWeight = FontWeight.Bold;
1296
- break;
1297
- }
1298
- return new Font(family, fontSize, fontStyle, fontWeight);
1299
- }
1300
- default:
1301
- return null;
1302
- }
1303
- }
1304
- static toJson(font) {
1305
- const o = new Map();
1306
- o.set('family', font.family);
1307
- o.set('size', font.size);
1308
- o.set('style', font.style);
1309
- o.set('weight', font.weight);
1310
- return o;
1311
- }
1312
- }
639
+ Duration[Duration["SixtyFourth"] = 64] = "SixtyFourth";
640
+ /**
641
+ * A 1/128 note duration
642
+ */
643
+ Duration[Duration["OneHundredTwentyEighth"] = 128] = "OneHundredTwentyEighth";
644
+ /**
645
+ * A 1/256 note duration
646
+ */
647
+ Duration[Duration["TwoHundredFiftySixth"] = 256] = "TwoHundredFiftySixth";
648
+ })(Duration || (Duration = {}));
1313
649
 
1314
650
  /**
1315
- * This public class contains central definitions for controlling the visual appearance.
1316
- * @json
651
+ * Lists all dynamics.
1317
652
  */
1318
- class RenderingResources {
1319
- constructor() {
1320
- /**
1321
- * Gets or sets the font to use for displaying the songs copyright information in the header of the music sheet.
1322
- */
1323
- this.copyrightFont = new Font(RenderingResources.sansFont, 12, FontStyle.Plain, FontWeight.Bold);
1324
- /**
1325
- * Gets or sets the font to use for displaying the songs title in the header of the music sheet.
1326
- */
1327
- this.titleFont = new Font(RenderingResources.serifFont, 32, FontStyle.Plain);
1328
- /**
1329
- * Gets or sets the font to use for displaying the songs subtitle in the header of the music sheet.
1330
- */
1331
- this.subTitleFont = new Font(RenderingResources.serifFont, 20, FontStyle.Plain);
1332
- /**
1333
- * Gets or sets the font to use for displaying the lyrics information in the header of the music sheet.
1334
- */
1335
- this.wordsFont = new Font(RenderingResources.serifFont, 15, FontStyle.Plain);
1336
- /**
1337
- * Gets or sets the font to use for displaying certain effect related elements in the music sheet.
1338
- */
1339
- this.effectFont = new Font(RenderingResources.serifFont, 12, FontStyle.Italic);
1340
- /**
1341
- * Gets or sets the font to use for displaying the fretboard numbers in chord diagrams.
1342
- */
1343
- this.fretboardNumberFont = new Font(RenderingResources.sansFont, 11, FontStyle.Plain);
1344
- /**
1345
- * Gets or sets the font to use for displaying the guitar tablature numbers in the music sheet.
1346
- */
1347
- this.tablatureFont = new Font(RenderingResources.sansFont, 13, FontStyle.Plain);
1348
- /**
1349
- * Gets or sets the font to use for grace notation related texts in the music sheet.
1350
- */
1351
- this.graceFont = new Font(RenderingResources.sansFont, 11, FontStyle.Plain);
1352
- /**
1353
- * Gets or sets the color to use for rendering the lines of staves.
1354
- */
1355
- this.staffLineColor = new Color(165, 165, 165, 0xff);
1356
- /**
1357
- * Gets or sets the color to use for rendering bar separators, the accolade and repeat signs.
1358
- */
1359
- this.barSeparatorColor = new Color(34, 34, 17, 0xff);
1360
- /**
1361
- * Gets or sets the font to use for displaying the bar numbers above the music sheet.
1362
- */
1363
- this.barNumberFont = new Font(RenderingResources.sansFont, 11, FontStyle.Plain);
1364
- /**
1365
- * Gets or sets the color to use for displaying the bar numbers above the music sheet.
1366
- */
1367
- this.barNumberColor = new Color(200, 0, 0, 0xff);
1368
- /**
1369
- * Gets or sets the font to use for displaying finger information in the music sheet.
1370
- */
1371
- this.fingeringFont = new Font(RenderingResources.serifFont, 14, FontStyle.Plain);
1372
- /**
1373
- * Gets or sets the font to use for section marker labels shown above the music sheet.
1374
- */
1375
- this.markerFont = new Font(RenderingResources.serifFont, 14, FontStyle.Plain, FontWeight.Bold);
1376
- /**
1377
- * Gets or sets the color to use for music notation elements of the primary voice.
1378
- */
1379
- this.mainGlyphColor = new Color(0, 0, 0, 0xff);
1380
- /**
1381
- * Gets or sets the color to use for music notation elements of the secondary voices.
1382
- */
1383
- this.secondaryGlyphColor = new Color(0, 0, 0, 100);
1384
- /**
1385
- * Gets or sets the color to use for displaying the song information above the music sheet.
1386
- */
1387
- this.scoreInfoColor = new Color(0, 0, 0, 0xff);
1388
- }
1389
- }
1390
- RenderingResources.sansFont = 'Arial';
1391
- RenderingResources.serifFont = 'Georgia';
1392
-
1393
- /**
1394
- * Lists all stave profiles controlling which staves are shown.
1395
- */
1396
- var StaveProfile;
1397
- (function (StaveProfile) {
653
+ var DynamicValue;
654
+ (function (DynamicValue) {
1398
655
  /**
1399
- * The profile is auto detected by the track configurations.
656
+ * pianississimo (very very soft)
1400
657
  */
1401
- StaveProfile[StaveProfile["Default"] = 0] = "Default";
658
+ DynamicValue[DynamicValue["PPP"] = 0] = "PPP";
1402
659
  /**
1403
- * Standard music notation and guitar tablature are rendered.
660
+ * pianissimo (very soft)
1404
661
  */
1405
- StaveProfile[StaveProfile["ScoreTab"] = 1] = "ScoreTab";
662
+ DynamicValue[DynamicValue["PP"] = 1] = "PP";
1406
663
  /**
1407
- * Only standard music notation is rendered.
664
+ * piano (soft)
1408
665
  */
1409
- StaveProfile[StaveProfile["Score"] = 2] = "Score";
666
+ DynamicValue[DynamicValue["P"] = 2] = "P";
1410
667
  /**
1411
- * Only guitar tablature is rendered.
668
+ * mezzo-piano (half soft)
1412
669
  */
1413
- StaveProfile[StaveProfile["Tab"] = 3] = "Tab";
670
+ DynamicValue[DynamicValue["MP"] = 3] = "MP";
1414
671
  /**
1415
- * Only guitar tablature is rendered, but also rests and time signatures are not shown.
1416
- * This profile is typically used in multi-track scenarios.
672
+ * mezzo-forte (half loud)
1417
673
  */
1418
- StaveProfile[StaveProfile["TabMixed"] = 4] = "TabMixed";
1419
- })(StaveProfile || (StaveProfile = {}));
1420
- /**
1421
- * Lists all layout modes that are supported.
1422
- */
1423
- var LayoutMode;
1424
- (function (LayoutMode) {
674
+ DynamicValue[DynamicValue["MF"] = 4] = "MF";
1425
675
  /**
1426
- * Bars are aligned in rows using a fixed width.
676
+ * forte (loud)
1427
677
  */
1428
- LayoutMode[LayoutMode["Page"] = 0] = "Page";
678
+ DynamicValue[DynamicValue["F"] = 5] = "F";
1429
679
  /**
1430
- * Bars are aligned horizontally in one row
680
+ * fortissimo (very loud)
1431
681
  */
1432
- LayoutMode[LayoutMode["Horizontal"] = 1] = "Horizontal";
1433
- })(LayoutMode || (LayoutMode = {}));
1434
- /**
1435
- * The display settings control how the general layout and display of alphaTab is done.
1436
- * @json
1437
- */
1438
- class DisplaySettings {
1439
- constructor() {
1440
- /**
1441
- * Sets the zoom level of the rendered notation
1442
- */
1443
- this.scale = 1.0;
1444
- /**
1445
- * The default stretch force to use for layouting.
1446
- */
1447
- this.stretchForce = 1.0;
1448
- /**
1449
- * The layouting mode used to arrange the the notation.
1450
- */
1451
- this.layoutMode = LayoutMode.Page;
1452
- /**
1453
- * The stave profile to use.
1454
- */
1455
- this.staveProfile = StaveProfile.Default;
1456
- /**
1457
- * Limit the displayed bars per row.
1458
- */
1459
- this.barsPerRow = -1;
1460
- /**
1461
- * The bar start number to start layouting with. Note that this is the bar number and not an index!
1462
- */
1463
- this.startBar = 1;
1464
- /**
1465
- * The amount of bars to render overall.
1466
- */
1467
- this.barCount = -1;
1468
- /**
1469
- * The number of bars that should be rendered per partial. This setting is not used by all layouts.
1470
- */
1471
- this.barCountPerPartial = 10;
1472
- /**
1473
- * Gets or sets the resources used during rendering. This defines all fonts and colors used.
1474
- * @json_partial_names
1475
- */
1476
- this.resources = new RenderingResources();
1477
- /**
1478
- * Gets or sets the padding between the music notation and the border.
1479
- */
1480
- this.padding = null;
1481
- }
1482
- }
1483
-
1484
- /**
1485
- * This is the base public class for creating new song importers which
1486
- * enable reading scores from any binary datasource
1487
- */
1488
- class ScoreImporter {
682
+ DynamicValue[DynamicValue["FF"] = 6] = "FF";
1489
683
  /**
1490
- * Initializes the importer with the given data and settings.
684
+ * fortississimo (very very loud)
1491
685
  */
1492
- init(data, settings) {
1493
- this.data = data;
1494
- this.settings = settings;
1495
- }
1496
- }
1497
-
1498
- /**
1499
- * The exception thrown by a {@link ScoreImporter} in case the
1500
- * binary data does not contain a reader compatible structure.
1501
- */
1502
- class UnsupportedFormatError extends AlphaTabError {
1503
- constructor(message = 'Unsupported format', inner = null) {
1504
- super(AlphaTabErrorType.Format, message);
1505
- this.inner = inner;
1506
- Object.setPrototypeOf(this, UnsupportedFormatError.prototype);
1507
- }
1508
- }
686
+ DynamicValue[DynamicValue["FFF"] = 7] = "FFF";
687
+ })(DynamicValue || (DynamicValue = {}));
1509
688
 
1510
689
  /**
1511
- * Lists all types of note acceuntations
690
+ * Lists all types of grace notes
1512
691
  */
1513
- var AccentuationType;
1514
- (function (AccentuationType) {
692
+ var GraceType;
693
+ (function (GraceType) {
1515
694
  /**
1516
- * No accentuation
695
+ * No grace, normal beat.
1517
696
  */
1518
- AccentuationType[AccentuationType["None"] = 0] = "None";
697
+ GraceType[GraceType["None"] = 0] = "None";
1519
698
  /**
1520
- * Normal accentuation
699
+ * The beat contains on-beat grace notes.
1521
700
  */
1522
- AccentuationType[AccentuationType["Normal"] = 1] = "Normal";
701
+ GraceType[GraceType["OnBeat"] = 1] = "OnBeat";
1523
702
  /**
1524
- * Heavy accentuation
703
+ * The beat contains before-beat grace notes.
1525
704
  */
1526
- AccentuationType[AccentuationType["Heavy"] = 2] = "Heavy";
1527
- })(AccentuationType || (AccentuationType = {}));
705
+ GraceType[GraceType["BeforeBeat"] = 2] = "BeforeBeat";
706
+ /**
707
+ * The beat contains very special bend-grace notes used in SongBook style displays.
708
+ */
709
+ GraceType[GraceType["BendGrace"] = 3] = "BendGrace";
710
+ })(GraceType || (GraceType = {}));
1528
711
 
1529
712
  /**
1530
- * This public enumeration lists all types of automations.
713
+ * Lists all fingers.
1531
714
  */
1532
- var AutomationType;
1533
- (function (AutomationType) {
715
+ var Fingers;
716
+ (function (Fingers) {
1534
717
  /**
1535
- * Tempo change.
718
+ * Unknown type (not documented)
1536
719
  */
1537
- AutomationType[AutomationType["Tempo"] = 0] = "Tempo";
720
+ Fingers[Fingers["Unknown"] = -2] = "Unknown";
1538
721
  /**
1539
- * Colume change.
722
+ * No finger, dead note
1540
723
  */
1541
- AutomationType[AutomationType["Volume"] = 1] = "Volume";
724
+ Fingers[Fingers["NoOrDead"] = -1] = "NoOrDead";
1542
725
  /**
1543
- * Instrument change.
726
+ * The thumb
1544
727
  */
1545
- AutomationType[AutomationType["Instrument"] = 2] = "Instrument";
728
+ Fingers[Fingers["Thumb"] = 0] = "Thumb";
1546
729
  /**
1547
- * Balance change.
730
+ * The index finger
1548
731
  */
1549
- AutomationType[AutomationType["Balance"] = 3] = "Balance";
1550
- })(AutomationType || (AutomationType = {}));
1551
- /**
1552
- * Automations are used to change the behaviour of a song.
1553
- * @cloneable
1554
- * @json
1555
- */
1556
- class Automation {
1557
- constructor() {
1558
- /**
1559
- * Gets or sets whether the automation is applied linear.
1560
- */
1561
- this.isLinear = false;
1562
- /**
1563
- * Gets or sets the type of the automation.
1564
- */
1565
- this.type = AutomationType.Tempo;
1566
- /**
1567
- * Gets or sets the target value of the automation.
1568
- */
1569
- this.value = 0;
1570
- /**
1571
- * Gets or sets the relative position of of the automation.
1572
- */
1573
- this.ratioPosition = 0;
1574
- /**
1575
- * Gets or sets the additional text of the automation.
1576
- */
1577
- this.text = '';
1578
- }
1579
- static buildTempoAutomation(isLinear, ratioPosition, value, reference) {
1580
- if (reference < 1 || reference > 5) {
1581
- reference = 2;
1582
- }
1583
- let references = new Float32Array([1, 0.5, 1.0, 1.5, 2.0, 3.0]);
1584
- let automation = new Automation();
1585
- automation.type = AutomationType.Tempo;
1586
- automation.isLinear = isLinear;
1587
- automation.ratioPosition = ratioPosition;
1588
- automation.value = value * references[reference];
1589
- return automation;
1590
- }
1591
- static buildInstrumentAutomation(isLinear, ratioPosition, value) {
1592
- let automation = new Automation();
1593
- automation.type = AutomationType.Instrument;
1594
- automation.isLinear = isLinear;
1595
- automation.ratioPosition = ratioPosition;
1596
- automation.value = value;
1597
- return automation;
1598
- }
1599
- }
732
+ Fingers[Fingers["IndexFinger"] = 1] = "IndexFinger";
733
+ /**
734
+ * The middle finger
735
+ */
736
+ Fingers[Fingers["MiddleFinger"] = 2] = "MiddleFinger";
737
+ /**
738
+ * The annular finger
739
+ */
740
+ Fingers[Fingers["AnnularFinger"] = 3] = "AnnularFinger";
741
+ /**
742
+ * The little finger
743
+ */
744
+ Fingers[Fingers["LittleFinger"] = 4] = "LittleFinger";
745
+ })(Fingers || (Fingers = {}));
1600
746
 
1601
747
  /**
1602
- * This public enumeration lists all supported Clefs.
748
+ * Lists all harmonic types.
1603
749
  */
1604
- var Clef;
1605
- (function (Clef) {
750
+ var HarmonicType;
751
+ (function (HarmonicType) {
1606
752
  /**
1607
- * Neutral clef.
753
+ * No harmonics.
1608
754
  */
1609
- Clef[Clef["Neutral"] = 0] = "Neutral";
755
+ HarmonicType[HarmonicType["None"] = 0] = "None";
1610
756
  /**
1611
- * C3 clef
757
+ * Natural harmonic
1612
758
  */
1613
- Clef[Clef["C3"] = 1] = "C3";
759
+ HarmonicType[HarmonicType["Natural"] = 1] = "Natural";
1614
760
  /**
1615
- * C4 clef
761
+ * Artificial harmonic
1616
762
  */
1617
- Clef[Clef["C4"] = 2] = "C4";
763
+ HarmonicType[HarmonicType["Artificial"] = 2] = "Artificial";
1618
764
  /**
1619
- * F4 clef
765
+ * Pinch harmonics
1620
766
  */
1621
- Clef[Clef["F4"] = 3] = "F4";
767
+ HarmonicType[HarmonicType["Pinch"] = 3] = "Pinch";
1622
768
  /**
1623
- * G2 clef
769
+ * Tap harmonics
1624
770
  */
1625
- Clef[Clef["G2"] = 4] = "G2";
1626
- })(Clef || (Clef = {}));
771
+ HarmonicType[HarmonicType["Tap"] = 4] = "Tap";
772
+ /**
773
+ * Semi harmonics
774
+ */
775
+ HarmonicType[HarmonicType["Semi"] = 5] = "Semi";
776
+ /**
777
+ * Feedback harmonics
778
+ */
779
+ HarmonicType[HarmonicType["Feedback"] = 6] = "Feedback";
780
+ })(HarmonicType || (HarmonicType = {}));
1627
781
 
1628
782
  /**
1629
- * Lists all ottavia.
783
+ * Lists the modes how accidentals are handled for notes
1630
784
  */
1631
- var Ottavia;
1632
- (function (Ottavia) {
785
+ var NoteAccidentalMode;
786
+ (function (NoteAccidentalMode) {
1633
787
  /**
1634
- * 2 octaves higher
788
+ * Accidentals are calculated automatically.
1635
789
  */
1636
- Ottavia[Ottavia["_15ma"] = 0] = "_15ma";
790
+ NoteAccidentalMode[NoteAccidentalMode["Default"] = 0] = "Default";
1637
791
  /**
1638
- * 1 octave higher
792
+ * This will try to ensure that no accidental is shown.
1639
793
  */
1640
- Ottavia[Ottavia["_8va"] = 1] = "_8va";
794
+ NoteAccidentalMode[NoteAccidentalMode["ForceNone"] = 1] = "ForceNone";
1641
795
  /**
1642
- * Normal
796
+ * This will move the note one line down and applies a Naturalize.
1643
797
  */
1644
- Ottavia[Ottavia["Regular"] = 2] = "Regular";
798
+ NoteAccidentalMode[NoteAccidentalMode["ForceNatural"] = 2] = "ForceNatural";
1645
799
  /**
1646
- * 1 octave lower
800
+ * This will move the note one line down and applies a Sharp.
1647
801
  */
1648
- Ottavia[Ottavia["_8vb"] = 3] = "_8vb";
802
+ NoteAccidentalMode[NoteAccidentalMode["ForceSharp"] = 3] = "ForceSharp";
1649
803
  /**
1650
- * 2 octaves lower.
804
+ * This will move the note to be shown 2 half-notes deeper with a double sharp symbol
1651
805
  */
1652
- Ottavia[Ottavia["_15mb"] = 4] = "_15mb";
1653
- })(Ottavia || (Ottavia = {}));
806
+ NoteAccidentalMode[NoteAccidentalMode["ForceDoubleSharp"] = 4] = "ForceDoubleSharp";
807
+ /**
808
+ * This will move the note one line up and applies a Flat.
809
+ */
810
+ NoteAccidentalMode[NoteAccidentalMode["ForceFlat"] = 5] = "ForceFlat";
811
+ /**
812
+ * This will move the note two half notes up with a double flag symbol.
813
+ */
814
+ NoteAccidentalMode[NoteAccidentalMode["ForceDoubleFlat"] = 6] = "ForceDoubleFlat";
815
+ })(NoteAccidentalMode || (NoteAccidentalMode = {}));
1654
816
 
1655
817
  /**
1656
- * Lists all simile mark types as they are assigned to bars.
818
+ * This public enum lists all different types of finger slide-ins on a string.
1657
819
  */
1658
- var SimileMark;
1659
- (function (SimileMark) {
1660
- /**
1661
- * No simile mark is applied
1662
- */
1663
- SimileMark[SimileMark["None"] = 0] = "None";
820
+ var SlideInType;
821
+ (function (SlideInType) {
1664
822
  /**
1665
- * A simple simile mark. The previous bar is repeated.
823
+ * No slide.
1666
824
  */
1667
- SimileMark[SimileMark["Simple"] = 1] = "Simple";
825
+ SlideInType[SlideInType["None"] = 0] = "None";
1668
826
  /**
1669
- * A double simile mark. This value is assigned to the first
1670
- * bar of the 2 repeat bars.
827
+ * Slide into the note from below on the same string.
1671
828
  */
1672
- SimileMark[SimileMark["FirstOfDouble"] = 2] = "FirstOfDouble";
829
+ SlideInType[SlideInType["IntoFromBelow"] = 1] = "IntoFromBelow";
1673
830
  /**
1674
- * A double simile mark. This value is assigned to the second
1675
- * bar of the 2 repeat bars.
831
+ * Slide into the note from above on the same string.
1676
832
  */
1677
- SimileMark[SimileMark["SecondOfDouble"] = 3] = "SecondOfDouble";
1678
- })(SimileMark || (SimileMark = {}));
833
+ SlideInType[SlideInType["IntoFromAbove"] = 2] = "IntoFromAbove";
834
+ })(SlideInType || (SlideInType = {}));
1679
835
 
1680
836
  /**
1681
- * A bar is a single block within a track, also known as Measure.
1682
- * @json
837
+ * This public enum lists all different types of finger slide-outs on a string.
1683
838
  */
1684
- class Bar {
1685
- constructor() {
1686
- /**
1687
- * Gets or sets the unique id of this bar.
1688
- */
1689
- this.id = Bar._globalBarId++;
1690
- /**
1691
- * Gets or sets the zero-based index of this bar within the staff.
1692
- * @json_ignore
1693
- */
1694
- this.index = 0;
1695
- /**
1696
- * Gets or sets the next bar that comes after this bar.
1697
- * @json_ignore
1698
- */
1699
- this.nextBar = null;
1700
- /**
1701
- * Gets or sets the previous bar that comes before this bar.
1702
- * @json_ignore
1703
- */
1704
- this.previousBar = null;
1705
- /**
1706
- * Gets or sets the clef on this bar.
1707
- */
1708
- this.clef = Clef.G2;
1709
- /**
1710
- * Gets or sets the ottava applied to the clef.
1711
- */
1712
- this.clefOttava = Ottavia.Regular;
1713
- /**
1714
- * Gets or sets the list of voices contained in this bar.
1715
- * @json_add addVoice
1716
- */
1717
- this.voices = [];
1718
- /**
1719
- * Gets or sets the simile mark on this bar.
1720
- */
1721
- this.simileMark = SimileMark.None;
1722
- /**
1723
- * Gets a value indicating whether this bar contains multiple voices with notes.
1724
- * @json_ignore
1725
- */
1726
- this.isMultiVoice = false;
1727
- }
1728
- get masterBar() {
1729
- return this.staff.track.score.masterBars[this.index];
1730
- }
1731
- get isEmpty() {
1732
- for (let i = 0, j = this.voices.length; i < j; i++) {
1733
- if (!this.voices[i].isEmpty) {
1734
- return false;
1735
- }
1736
- }
1737
- return true;
1738
- }
1739
- addVoice(voice) {
1740
- voice.bar = this;
1741
- voice.index = this.voices.length;
1742
- this.voices.push(voice);
1743
- }
1744
- finish(settings) {
1745
- this.isMultiVoice = false;
1746
- for (let i = 0, j = this.voices.length; i < j; i++) {
1747
- let voice = this.voices[i];
1748
- voice.finish(settings);
1749
- if (i > 0 && !voice.isEmpty) {
1750
- this.isMultiVoice = true;
1751
- }
1752
- }
1753
- }
1754
- calculateDuration() {
1755
- let duration = 0;
1756
- for (let voice of this.voices) {
1757
- let voiceDuration = voice.calculateDuration();
1758
- if (voiceDuration > duration) {
1759
- duration = voiceDuration;
1760
- }
1761
- }
1762
- return duration;
1763
- }
1764
- }
1765
- Bar._globalBarId = 0;
1766
-
1767
- class MidiUtils {
839
+ var SlideOutType;
840
+ (function (SlideOutType) {
1768
841
  /**
1769
- * Converts the given midi tick duration into milliseconds.
1770
- * @param ticks The duration in midi ticks
1771
- * @param tempo The current tempo in BPM.
1772
- * @returns The converted duration in milliseconds.
842
+ * No slide.
1773
843
  */
1774
- static ticksToMillis(ticks, tempo) {
1775
- return (ticks * (60000.0 / (tempo * MidiUtils.QuarterTime))) | 0;
1776
- }
844
+ SlideOutType[SlideOutType["None"] = 0] = "None";
1777
845
  /**
1778
- * Converts the given midi tick duration into milliseconds.
1779
- * @param millis The duration in milliseconds
1780
- * @param tempo The current tempo in BPM.
1781
- * @returns The converted duration in midi ticks.
846
+ * Shift slide to next note on same string
1782
847
  */
1783
- static millisToTicks(millis, tempo) {
1784
- return (millis / (60000.0 / (tempo * MidiUtils.QuarterTime))) | 0;
1785
- }
848
+ SlideOutType[SlideOutType["Shift"] = 1] = "Shift";
1786
849
  /**
1787
- * Converts a duration value to its ticks equivalent.
850
+ * Legato slide to next note on same string.
1788
851
  */
1789
- static toTicks(duration) {
1790
- return MidiUtils.valueToTicks(duration);
1791
- }
852
+ SlideOutType[SlideOutType["Legato"] = 2] = "Legato";
1792
853
  /**
1793
- * Converts a numerical value to its ticks equivalent.
1794
- * @param duration the numerical proportion to convert. (i.E. timesignature denominator, note duration,...)
854
+ * Slide out from the note from upwards on the same string.
1795
855
  */
1796
- static valueToTicks(duration) {
1797
- let denomninator = duration;
1798
- if (denomninator < 0) {
1799
- denomninator = 1 / -denomninator;
1800
- }
1801
- return (MidiUtils.QuarterTime * (4.0 / denomninator)) | 0;
1802
- }
1803
- static applyDot(ticks, doubleDotted) {
1804
- if (doubleDotted) {
1805
- return ticks + ((ticks / 4) | 0) * 3;
1806
- }
1807
- return ticks + ((ticks / 2) | 0);
1808
- }
1809
- static applyTuplet(ticks, numerator, denominator) {
1810
- return ((ticks * denominator) / numerator) | 0;
1811
- }
1812
- static removeTuplet(ticks, numerator, denominator) {
1813
- return ((ticks * numerator) / denominator) | 0;
1814
- }
1815
- static dynamicToVelocity(dyn) {
1816
- return MidiUtils.MinVelocity + dyn * MidiUtils.VelocityIncrement;
1817
- }
1818
- }
1819
- MidiUtils.QuarterTime = 960;
1820
- MidiUtils.MinVelocity = 15;
1821
- MidiUtils.VelocityIncrement = 16;
1822
-
1823
- /**
1824
- * A single point of a bending graph. Used to
1825
- * describe WhammyBar and String Bending effects.
1826
- * @cloneable
1827
- * @json
1828
- */
1829
- class BendPoint {
856
+ SlideOutType[SlideOutType["OutUp"] = 3] = "OutUp";
1830
857
  /**
1831
- * Initializes a new instance of the {@link BendPoint} class.
1832
- * @param offset The offset.
1833
- * @param value The value.
858
+ * Slide out from the note from downwards on the same string.
1834
859
  */
1835
- constructor(offset = 0, value = 0) {
1836
- this.offset = offset;
1837
- this.value = value;
1838
- }
1839
- }
1840
- BendPoint.MaxPosition = 60;
1841
- BendPoint.MaxValue = 12;
860
+ SlideOutType[SlideOutType["OutDown"] = 4] = "OutDown";
861
+ /**
862
+ * Pickslide down on this note
863
+ */
864
+ SlideOutType[SlideOutType["PickSlideDown"] = 5] = "PickSlideDown";
865
+ /**
866
+ * Pickslide up on this note
867
+ */
868
+ SlideOutType[SlideOutType["PickSlideUp"] = 6] = "PickSlideUp";
869
+ })(SlideOutType || (SlideOutType = {}));
1842
870
 
1843
871
  /**
1844
- * Lists the different bend styles
872
+ * This public enum lists all vibrato types that can be performed.
1845
873
  */
1846
- var BendStyle;
1847
- (function (BendStyle) {
874
+ var VibratoType;
875
+ (function (VibratoType) {
1848
876
  /**
1849
- * The bends are as described by the bend points
877
+ * No vibrato.
1850
878
  */
1851
- BendStyle[BendStyle["Default"] = 0] = "Default";
879
+ VibratoType[VibratoType["None"] = 0] = "None";
1852
880
  /**
1853
- * The bends are gradual over the beat duration.
881
+ * A slight vibrato.
1854
882
  */
1855
- BendStyle[BendStyle["Gradual"] = 1] = "Gradual";
883
+ VibratoType[VibratoType["Slight"] = 1] = "Slight";
1856
884
  /**
1857
- * The bends are done fast before the next note.
885
+ * A wide vibrato.
1858
886
  */
1859
- BendStyle[BendStyle["Fast"] = 2] = "Fast";
1860
- })(BendStyle || (BendStyle = {}));
887
+ VibratoType[VibratoType["Wide"] = 2] = "Wide";
888
+ })(VibratoType || (VibratoType = {}));
1861
889
 
1862
890
  /**
1863
- * Lists all types of bends
891
+ * Lists the different modes on how rhythm notation is shown on the tab staff.
1864
892
  */
1865
- var BendType;
1866
- (function (BendType) {
1867
- /**
1868
- * No bend at all
1869
- */
1870
- BendType[BendType["None"] = 0] = "None";
1871
- /**
1872
- * Individual points define the bends in a flexible manner.
1873
- * This system was mainly used in Guitar Pro 3-5
1874
- */
1875
- BendType[BendType["Custom"] = 1] = "Custom";
893
+ var TabRhythmMode;
894
+ (function (TabRhythmMode) {
1876
895
  /**
1877
- * Simple Bend from an unbended string to a higher note.
896
+ * Rhythm notation is hidden.
1878
897
  */
1879
- BendType[BendType["Bend"] = 2] = "Bend";
898
+ TabRhythmMode[TabRhythmMode["Hidden"] = 0] = "Hidden";
1880
899
  /**
1881
- * Release of a bend that was started on an earlier note.
900
+ * Rhythm notation is shown with individual beams per beat.
1882
901
  */
1883
- BendType[BendType["Release"] = 3] = "Release";
902
+ TabRhythmMode[TabRhythmMode["ShowWithBeams"] = 1] = "ShowWithBeams";
1884
903
  /**
1885
- * A bend that starts from an unbended string,
1886
- * and also releases the bend after some time.
904
+ * Rhythm notation is shown and behaves like normal score notation with connected bars.
1887
905
  */
1888
- BendType[BendType["BendRelease"] = 4] = "BendRelease";
906
+ TabRhythmMode[TabRhythmMode["ShowWithBars"] = 2] = "ShowWithBars";
907
+ })(TabRhythmMode || (TabRhythmMode = {}));
908
+ /**
909
+ * Lists all modes on how fingerings should be displayed.
910
+ */
911
+ var FingeringMode;
912
+ (function (FingeringMode) {
1889
913
  /**
1890
- * Holds a bend that was started on an earlier note
914
+ * Fingerings will be shown in the standard notation staff.
1891
915
  */
1892
- BendType[BendType["Hold"] = 5] = "Hold";
916
+ FingeringMode[FingeringMode["ScoreDefault"] = 0] = "ScoreDefault";
1893
917
  /**
1894
- * A bend that is already started before the note is played then it is held until the end.
918
+ * Fingerings will be shown in the standard notation staff. Piano finger style is enforced, where
919
+ * fingers are rendered as 1-5 instead of p,i,m,a,c and T,1,2,3,4.
1895
920
  */
1896
- BendType[BendType["Prebend"] = 6] = "Prebend";
921
+ FingeringMode[FingeringMode["ScoreForcePiano"] = 1] = "ScoreForcePiano";
1897
922
  /**
1898
- * A bend that is already started before the note is played and
1899
- * bends even further, then it is held until the end.
923
+ * Fingerings will be shown in a effect band above the tabs in case
924
+ * they have only a single note on the beat.
1900
925
  */
1901
- BendType[BendType["PrebendBend"] = 7] = "PrebendBend";
926
+ FingeringMode[FingeringMode["SingleNoteEffectBand"] = 2] = "SingleNoteEffectBand";
1902
927
  /**
1903
- * A bend that is already started before the note is played and
1904
- * then releases the bend to a lower note where it is held until the end.
928
+ * Fingerings will be shown in a effect band above the tabs in case
929
+ * they have only a single note on the beat. Piano finger style is enforced, where
930
+ * fingers are rendered as 1-5 instead of p,i,m,a,c and T,1,2,3,4.
1905
931
  */
1906
- BendType[BendType["PrebendRelease"] = 8] = "PrebendRelease";
1907
- })(BendType || (BendType = {}));
1908
-
932
+ FingeringMode[FingeringMode["SingleNoteEffectBandForcePiano"] = 3] = "SingleNoteEffectBandForcePiano";
933
+ })(FingeringMode || (FingeringMode = {}));
1909
934
  /**
1910
- * Lists all types of how to brush multiple notes on a beat.
935
+ * Lists all modes on how alphaTab can handle the display and playback of music notation.
1911
936
  */
1912
- var BrushType;
1913
- (function (BrushType) {
1914
- /**
1915
- * No brush.
1916
- */
1917
- BrushType[BrushType["None"] = 0] = "None";
937
+ var NotationMode;
938
+ (function (NotationMode) {
1918
939
  /**
1919
- * Normal brush up.
940
+ * Music elements will be displayed and played as in Guitar Pro.
1920
941
  */
1921
- BrushType[BrushType["BrushUp"] = 1] = "BrushUp";
942
+ NotationMode[NotationMode["GuitarPro"] = 0] = "GuitarPro";
1922
943
  /**
1923
- * Normal brush down.
944
+ * Music elements will be displayed and played as in traditional songbooks.
945
+ * Changes:
946
+ * 1. Bends
947
+ * For bends additional grace beats are introduced.
948
+ * Bends are categorized into gradual and fast bends.
949
+ * - Gradual bends are indicated by beat text "grad" or "grad.". Bend will sound along the beat duration.
950
+ * - Fast bends are done right before the next note. If the next note is tied even on-beat of the next note.
951
+ * 2. Whammy Bars
952
+ * Dips are shown as simple annotation over the beats
953
+ * Whammy Bars are categorized into gradual and fast.
954
+ * - Gradual whammys are indicated by beat text "grad" or "grad.". Whammys will sound along the beat duration.
955
+ * - Fast whammys are done right the beat.
956
+ * 3. Let Ring
957
+ * Tied notes with let ring are not shown in standard notation
958
+ * Let ring does not cause a longer playback, duration is defined via tied notes.
1924
959
  */
1925
- BrushType[BrushType["BrushDown"] = 2] = "BrushDown";
960
+ NotationMode[NotationMode["SongBook"] = 1] = "SongBook";
961
+ })(NotationMode || (NotationMode = {}));
962
+ /**
963
+ * Lists all major music notation elements that are part
964
+ * of the music sheet and can be dynamically controlled to be shown
965
+ * or hidden.
966
+ */
967
+ var NotationElement;
968
+ (function (NotationElement) {
1926
969
  /**
1927
- * Arpeggio up.
970
+ * The score title shown at the start of the music sheet.
1928
971
  */
1929
- BrushType[BrushType["ArpeggioUp"] = 3] = "ArpeggioUp";
972
+ NotationElement[NotationElement["ScoreTitle"] = 0] = "ScoreTitle";
1930
973
  /**
1931
- * Arpeggio down.
974
+ * The score subtitle shown at the start of the music sheet.
1932
975
  */
1933
- BrushType[BrushType["ArpeggioDown"] = 4] = "ArpeggioDown";
1934
- })(BrushType || (BrushType = {}));
1935
-
1936
- /**
1937
- * Lists all Crescendo and Decrescendo types.
1938
- */
1939
- var CrescendoType;
1940
- (function (CrescendoType) {
976
+ NotationElement[NotationElement["ScoreSubTitle"] = 1] = "ScoreSubTitle";
1941
977
  /**
1942
- * No crescendo applied.
978
+ * The score artist shown at the start of the music sheet.
1943
979
  */
1944
- CrescendoType[CrescendoType["None"] = 0] = "None";
980
+ NotationElement[NotationElement["ScoreArtist"] = 2] = "ScoreArtist";
1945
981
  /**
1946
- * Normal crescendo applied.
982
+ * The score album shown at the start of the music sheet.
1947
983
  */
1948
- CrescendoType[CrescendoType["Crescendo"] = 1] = "Crescendo";
984
+ NotationElement[NotationElement["ScoreAlbum"] = 3] = "ScoreAlbum";
1949
985
  /**
1950
- * Normal decrescendo applied.
986
+ * The score words author shown at the start of the music sheet.
1951
987
  */
1952
- CrescendoType[CrescendoType["Decrescendo"] = 2] = "Decrescendo";
1953
- })(CrescendoType || (CrescendoType = {}));
1954
-
1955
- /**
1956
- * Lists all durations of a beat.
1957
- */
1958
- var Duration;
1959
- (function (Duration) {
988
+ NotationElement[NotationElement["ScoreWords"] = 4] = "ScoreWords";
1960
989
  /**
1961
- * A quadruple whole note duration
990
+ * The score music author shown at the start of the music sheet.
1962
991
  */
1963
- Duration[Duration["QuadrupleWhole"] = -4] = "QuadrupleWhole";
992
+ NotationElement[NotationElement["ScoreMusic"] = 5] = "ScoreMusic";
1964
993
  /**
1965
- * A double whole note duration
994
+ * The score words&music author shown at the start of the music sheet.
1966
995
  */
1967
- Duration[Duration["DoubleWhole"] = -2] = "DoubleWhole";
996
+ NotationElement[NotationElement["ScoreWordsAndMusic"] = 6] = "ScoreWordsAndMusic";
1968
997
  /**
1969
- * A whole note duration
998
+ * The score copyright owner shown at the start of the music sheet.
1970
999
  */
1971
- Duration[Duration["Whole"] = 1] = "Whole";
1000
+ NotationElement[NotationElement["ScoreCopyright"] = 7] = "ScoreCopyright";
1972
1001
  /**
1973
- * A 1/2 note duration
1002
+ * The tuning information of the guitar shown
1003
+ * above the staves.
1974
1004
  */
1975
- Duration[Duration["Half"] = 2] = "Half";
1005
+ NotationElement[NotationElement["GuitarTuning"] = 8] = "GuitarTuning";
1976
1006
  /**
1977
- * A 1/4 note duration
1007
+ * The track names which are shown in the accolade.
1978
1008
  */
1979
- Duration[Duration["Quarter"] = 4] = "Quarter";
1009
+ NotationElement[NotationElement["TrackNames"] = 9] = "TrackNames";
1980
1010
  /**
1981
- * A 1/8 note duration
1011
+ * The chord diagrams for guitars. Usually shown
1012
+ * below the score info.
1982
1013
  */
1983
- Duration[Duration["Eighth"] = 8] = "Eighth";
1014
+ NotationElement[NotationElement["ChordDiagrams"] = 10] = "ChordDiagrams";
1984
1015
  /**
1985
- * A 1/16 note duration
1016
+ * Parenthesis that are shown for tied bends
1017
+ * if they are preceeded by bends.
1986
1018
  */
1987
- Duration[Duration["Sixteenth"] = 16] = "Sixteenth";
1019
+ NotationElement[NotationElement["ParenthesisOnTiedBends"] = 11] = "ParenthesisOnTiedBends";
1988
1020
  /**
1989
- * A 1/32 note duration
1021
+ * The tab number for tied notes if the
1022
+ * bend of a note is increased at that point.
1990
1023
  */
1991
- Duration[Duration["ThirtySecond"] = 32] = "ThirtySecond";
1024
+ NotationElement[NotationElement["TabNotesOnTiedBends"] = 12] = "TabNotesOnTiedBends";
1992
1025
  /**
1993
- * A 1/64 note duration
1026
+ * Zero tab numbers on "dive whammys".
1994
1027
  */
1995
- Duration[Duration["SixtyFourth"] = 64] = "SixtyFourth";
1028
+ NotationElement[NotationElement["ZerosOnDiveWhammys"] = 13] = "ZerosOnDiveWhammys";
1996
1029
  /**
1997
- * A 1/128 note duration
1030
+ * The alternate endings information on repeats shown above the staff.
1998
1031
  */
1999
- Duration[Duration["OneHundredTwentyEighth"] = 128] = "OneHundredTwentyEighth";
1032
+ NotationElement[NotationElement["EffectAlternateEndings"] = 14] = "EffectAlternateEndings";
2000
1033
  /**
2001
- * A 1/256 note duration
1034
+ * The information about the fret on which the capo is placed shown above the staff.
2002
1035
  */
2003
- Duration[Duration["TwoHundredFiftySixth"] = 256] = "TwoHundredFiftySixth";
2004
- })(Duration || (Duration = {}));
2005
-
2006
- /**
2007
- * Lists all dynamics.
2008
- */
2009
- var DynamicValue;
2010
- (function (DynamicValue) {
1036
+ NotationElement[NotationElement["EffectCapo"] = 15] = "EffectCapo";
2011
1037
  /**
2012
- * pianississimo (very very soft)
1038
+ * The chord names shown above beats shown above the staff.
2013
1039
  */
2014
- DynamicValue[DynamicValue["PPP"] = 0] = "PPP";
1040
+ NotationElement[NotationElement["EffectChordNames"] = 16] = "EffectChordNames";
2015
1041
  /**
2016
- * pianissimo (very soft)
1042
+ * The crescendo/decrescendo angle shown above the staff.
2017
1043
  */
2018
- DynamicValue[DynamicValue["PP"] = 1] = "PP";
1044
+ NotationElement[NotationElement["EffectCrescendo"] = 17] = "EffectCrescendo";
2019
1045
  /**
2020
- * piano (soft)
1046
+ * The beat dynamics shown above the staff.
2021
1047
  */
2022
- DynamicValue[DynamicValue["P"] = 2] = "P";
1048
+ NotationElement[NotationElement["EffectDynamics"] = 18] = "EffectDynamics";
2023
1049
  /**
2024
- * mezzo-piano (half soft)
1050
+ * The curved angle for fade in/out effects shown above the staff.
2025
1051
  */
2026
- DynamicValue[DynamicValue["MP"] = 3] = "MP";
1052
+ NotationElement[NotationElement["EffectFadeIn"] = 19] = "EffectFadeIn";
2027
1053
  /**
2028
- * mezzo-forte (half loud)
1054
+ * The fermata symbol shown above the staff.
2029
1055
  */
2030
- DynamicValue[DynamicValue["MF"] = 4] = "MF";
1056
+ NotationElement[NotationElement["EffectFermata"] = 20] = "EffectFermata";
2031
1057
  /**
2032
- * forte (loud)
1058
+ * The fingering information.
2033
1059
  */
2034
- DynamicValue[DynamicValue["F"] = 5] = "F";
1060
+ NotationElement[NotationElement["EffectFingering"] = 21] = "EffectFingering";
2035
1061
  /**
2036
- * fortissimo (very loud)
1062
+ * The harmonics names shown above the staff.
1063
+ * (does not represent the harmonic note heads)
2037
1064
  */
2038
- DynamicValue[DynamicValue["FF"] = 6] = "FF";
1065
+ NotationElement[NotationElement["EffectHarmonics"] = 22] = "EffectHarmonics";
2039
1066
  /**
2040
- * fortississimo (very very loud)
1067
+ * The let ring name and line above the staff.
2041
1068
  */
2042
- DynamicValue[DynamicValue["FFF"] = 7] = "FFF";
2043
- })(DynamicValue || (DynamicValue = {}));
2044
-
2045
- /**
2046
- * Lists all types of grace notes
2047
- */
2048
- var GraceType;
2049
- (function (GraceType) {
1069
+ NotationElement[NotationElement["EffectLetRing"] = 23] = "EffectLetRing";
2050
1070
  /**
2051
- * No grace, normal beat.
1071
+ * The lyrics of the track shown above the staff.
2052
1072
  */
2053
- GraceType[GraceType["None"] = 0] = "None";
1073
+ NotationElement[NotationElement["EffectLyrics"] = 24] = "EffectLyrics";
2054
1074
  /**
2055
- * The beat contains on-beat grace notes.
1075
+ * The section markers shown above the staff.
2056
1076
  */
2057
- GraceType[GraceType["OnBeat"] = 1] = "OnBeat";
1077
+ NotationElement[NotationElement["EffectMarker"] = 25] = "EffectMarker";
2058
1078
  /**
2059
- * The beat contains before-beat grace notes.
1079
+ * The ottava symbol and lines shown above the staff.
2060
1080
  */
2061
- GraceType[GraceType["BeforeBeat"] = 2] = "BeforeBeat";
1081
+ NotationElement[NotationElement["EffectOttavia"] = 26] = "EffectOttavia";
2062
1082
  /**
2063
- * The beat contains very special bend-grace notes used in SongBook style displays.
1083
+ * The palm mute name and line shown above the staff.
2064
1084
  */
2065
- GraceType[GraceType["BendGrace"] = 3] = "BendGrace";
2066
- })(GraceType || (GraceType = {}));
2067
-
2068
- /**
2069
- * Lists all harmonic types.
2070
- */
2071
- var HarmonicType;
2072
- (function (HarmonicType) {
1085
+ NotationElement[NotationElement["EffectPalmMute"] = 27] = "EffectPalmMute";
2073
1086
  /**
2074
- * No harmonics.
1087
+ * The pick slide information shown above the staff.
1088
+ * (does not control the pick slide lines)
2075
1089
  */
2076
- HarmonicType[HarmonicType["None"] = 0] = "None";
1090
+ NotationElement[NotationElement["EffectPickSlide"] = 28] = "EffectPickSlide";
2077
1091
  /**
2078
- * Natural harmonic
1092
+ * The pick stroke symbols shown above the staff.
2079
1093
  */
2080
- HarmonicType[HarmonicType["Natural"] = 1] = "Natural";
1094
+ NotationElement[NotationElement["EffectPickStroke"] = 29] = "EffectPickStroke";
2081
1095
  /**
2082
- * Artificial harmonic
1096
+ * The slight beat vibrato waves shown above the staff.
2083
1097
  */
2084
- HarmonicType[HarmonicType["Artificial"] = 2] = "Artificial";
1098
+ NotationElement[NotationElement["EffectSlightBeatVibrato"] = 30] = "EffectSlightBeatVibrato";
2085
1099
  /**
2086
- * Pinch harmonics
1100
+ * The slight note vibrato waves shown above the staff.
2087
1101
  */
2088
- HarmonicType[HarmonicType["Pinch"] = 3] = "Pinch";
1102
+ NotationElement[NotationElement["EffectSlightNoteVibrato"] = 31] = "EffectSlightNoteVibrato";
2089
1103
  /**
2090
- * Tap harmonics
1104
+ * The tap/slap/pop effect names shown above the staff.
2091
1105
  */
2092
- HarmonicType[HarmonicType["Tap"] = 4] = "Tap";
1106
+ NotationElement[NotationElement["EffectTap"] = 32] = "EffectTap";
2093
1107
  /**
2094
- * Semi harmonics
1108
+ * The tempo information shown above the staff.
2095
1109
  */
2096
- HarmonicType[HarmonicType["Semi"] = 5] = "Semi";
1110
+ NotationElement[NotationElement["EffectTempo"] = 33] = "EffectTempo";
2097
1111
  /**
2098
- * Feedback harmonics
1112
+ * The additional beat text shown above the staff.
2099
1113
  */
2100
- HarmonicType[HarmonicType["Feedback"] = 6] = "Feedback";
2101
- })(HarmonicType || (HarmonicType = {}));
2102
-
2103
- /**
2104
- * Lists the modes how accidentals are handled for notes
2105
- */
2106
- var NoteAccidentalMode;
2107
- (function (NoteAccidentalMode) {
1114
+ NotationElement[NotationElement["EffectText"] = 34] = "EffectText";
2108
1115
  /**
2109
- * Accidentals are calculated automatically.
1116
+ * The trill name and waves shown above the staff.
2110
1117
  */
2111
- NoteAccidentalMode[NoteAccidentalMode["Default"] = 0] = "Default";
1118
+ NotationElement[NotationElement["EffectTrill"] = 35] = "EffectTrill";
2112
1119
  /**
2113
- * This will try to ensure that no accidental is shown.
1120
+ * The triplet feel symbol shown above the staff.
2114
1121
  */
2115
- NoteAccidentalMode[NoteAccidentalMode["ForceNone"] = 1] = "ForceNone";
1122
+ NotationElement[NotationElement["EffectTripletFeel"] = 36] = "EffectTripletFeel";
2116
1123
  /**
2117
- * This will move the note one line down and applies a Naturalize.
1124
+ * The whammy bar information shown above the staff.
1125
+ * (does not control the whammy lines shown within the staff)
2118
1126
  */
2119
- NoteAccidentalMode[NoteAccidentalMode["ForceNatural"] = 2] = "ForceNatural";
1127
+ NotationElement[NotationElement["EffectWhammyBar"] = 37] = "EffectWhammyBar";
2120
1128
  /**
2121
- * This will move the note one line down and applies a Sharp.
1129
+ * The wide beat vibrato waves shown above the staff.
2122
1130
  */
2123
- NoteAccidentalMode[NoteAccidentalMode["ForceSharp"] = 3] = "ForceSharp";
1131
+ NotationElement[NotationElement["EffectWideBeatVibrato"] = 38] = "EffectWideBeatVibrato";
2124
1132
  /**
2125
- * This will move the note to be shown 2 half-notes deeper with a double sharp symbol
1133
+ * The wide note vibrato waves shown above the staff.
2126
1134
  */
2127
- NoteAccidentalMode[NoteAccidentalMode["ForceDoubleSharp"] = 4] = "ForceDoubleSharp";
1135
+ NotationElement[NotationElement["EffectWideNoteVibrato"] = 39] = "EffectWideNoteVibrato";
2128
1136
  /**
2129
- * This will move the note one line up and applies a Flat.
1137
+ * The left hand tap symbol shown above the staff.
2130
1138
  */
2131
- NoteAccidentalMode[NoteAccidentalMode["ForceFlat"] = 5] = "ForceFlat";
1139
+ NotationElement[NotationElement["EffectLeftHandTap"] = 40] = "EffectLeftHandTap";
1140
+ })(NotationElement || (NotationElement = {}));
1141
+ /**
1142
+ * The notation settings control how various music notation elements are shown and behaving
1143
+ * @json
1144
+ */
1145
+ class NotationSettings {
1146
+ constructor() {
1147
+ /**
1148
+ * Gets or sets the mode to use for display and play music notation elements.
1149
+ */
1150
+ this.notationMode = NotationMode.GuitarPro;
1151
+ /**
1152
+ * Gets or sets the fingering mode to use.
1153
+ */
1154
+ this.fingeringMode = FingeringMode.ScoreDefault;
1155
+ /**
1156
+ * Gets or sets the configuration on whether music notation elements are visible or not.
1157
+ * If notation elements are not specified, the default configuration will be applied.
1158
+ */
1159
+ this.elements = new Map();
1160
+ /**
1161
+ * Whether to show rhythm notation in the guitar tablature.
1162
+ */
1163
+ this.rhythmMode = TabRhythmMode.Hidden;
1164
+ /**
1165
+ * The height of the rythm bars.
1166
+ */
1167
+ this.rhythmHeight = 15;
1168
+ /**
1169
+ * The transposition pitch offsets for the individual tracks.
1170
+ * They apply to rendering and playback.
1171
+ */
1172
+ this.transpositionPitches = [];
1173
+ /**
1174
+ * The transposition pitch offsets for the individual tracks.
1175
+ * They apply to rendering only.
1176
+ */
1177
+ this.displayTranspositionPitches = [];
1178
+ /**
1179
+ * If set to true the guitar tabs on grace beats are rendered smaller.
1180
+ */
1181
+ this.smallGraceTabNotes = true;
1182
+ /**
1183
+ * If set to true bend arrows expand to the end of the last tied note
1184
+ * of the string. Otherwise they end on the next beat.
1185
+ */
1186
+ this.extendBendArrowsOnTiedNotes = true;
1187
+ /**
1188
+ * If set to true, line effects (like w/bar, let-ring etc)
1189
+ * are drawn until the end of the beat instead of the start.
1190
+ */
1191
+ this.extendLineEffectsToBeatEnd = false;
1192
+ /**
1193
+ * Gets or sets the height for slurs. The factor is multiplied with the a logarithmic distance
1194
+ * between slur start and end.
1195
+ */
1196
+ this.slurHeight = 5.0;
1197
+ }
2132
1198
  /**
2133
- * This will move the note two half notes up with a double flag symbol.
1199
+ * Gets whether the given music notation element should be shown
1200
+ * @param element the element to check
1201
+ * @returns true if the element should be shown, otherwise false.
2134
1202
  */
2135
- NoteAccidentalMode[NoteAccidentalMode["ForceDoubleFlat"] = 6] = "ForceDoubleFlat";
2136
- })(NoteAccidentalMode || (NoteAccidentalMode = {}));
1203
+ isNotationElementVisible(element) {
1204
+ if (this.elements.has(element)) {
1205
+ return this.elements.get(element);
1206
+ }
1207
+ if (NotationSettings.defaultElements.has(element)) {
1208
+ return NotationSettings.defaultElements.get(element);
1209
+ }
1210
+ return true;
1211
+ }
1212
+ }
1213
+ /**
1214
+ * Gets the default configuration of the {@see notationElements} setting. Do not modify
1215
+ * this map as it might not result in the expected side effects.
1216
+ * If items are not listed explicitly in this list, they are considered visible.
1217
+ */
1218
+ NotationSettings.defaultElements = new Map([
1219
+ [NotationElement.ZerosOnDiveWhammys, false]
1220
+ ]);
2137
1221
 
2138
1222
  /**
2139
- * This public enum lists all different types of finger slide-ins on a string.
1223
+ * @target web
2140
1224
  */
2141
- var SlideInType;
2142
- (function (SlideInType) {
2143
- /**
2144
- * No slide.
2145
- */
2146
- SlideInType[SlideInType["None"] = 0] = "None";
2147
- /**
2148
- * Slide into the note from below on the same string.
2149
- */
2150
- SlideInType[SlideInType["IntoFromBelow"] = 1] = "IntoFromBelow";
2151
- /**
2152
- * Slide into the note from above on the same string.
2153
- */
2154
- SlideInType[SlideInType["IntoFromAbove"] = 2] = "IntoFromAbove";
2155
- })(SlideInType || (SlideInType = {}));
1225
+ class Lazy {
1226
+ constructor(factory) {
1227
+ this._value = undefined;
1228
+ this._factory = factory;
1229
+ }
1230
+ get value() {
1231
+ if (this._value === undefined) {
1232
+ this._value = this._factory();
1233
+ }
1234
+ return this._value;
1235
+ }
1236
+ }
2156
1237
 
2157
1238
  /**
2158
- * This public enum lists all different types of finger slide-outs on a string.
1239
+ * Defines all loglevels.
1240
+ * @json
2159
1241
  */
2160
- var SlideOutType;
2161
- (function (SlideOutType) {
1242
+ var LogLevel;
1243
+ (function (LogLevel) {
2162
1244
  /**
2163
- * No slide.
1245
+ * No logging
2164
1246
  */
2165
- SlideOutType[SlideOutType["None"] = 0] = "None";
1247
+ LogLevel[LogLevel["None"] = 0] = "None";
2166
1248
  /**
2167
- * Shift slide to next note on same string
1249
+ * Debug level (internal details are displayed).
2168
1250
  */
2169
- SlideOutType[SlideOutType["Shift"] = 1] = "Shift";
1251
+ LogLevel[LogLevel["Debug"] = 1] = "Debug";
2170
1252
  /**
2171
- * Legato slide to next note on same string.
1253
+ * Info level (only important details are shown)
2172
1254
  */
2173
- SlideOutType[SlideOutType["Legato"] = 2] = "Legato";
1255
+ LogLevel[LogLevel["Info"] = 2] = "Info";
2174
1256
  /**
2175
- * Slide out from the note from upwards on the same string.
1257
+ * Warning level
2176
1258
  */
2177
- SlideOutType[SlideOutType["OutUp"] = 3] = "OutUp";
1259
+ LogLevel[LogLevel["Warning"] = 3] = "Warning";
2178
1260
  /**
2179
- * Slide out from the note from downwards on the same string.
2180
- */
2181
- SlideOutType[SlideOutType["OutDown"] = 4] = "OutDown";
2182
- /**
2183
- * Pickslide down on this note
2184
- */
2185
- SlideOutType[SlideOutType["PickSlideDown"] = 5] = "PickSlideDown";
2186
- /**
2187
- * Pickslide up on this note
2188
- */
2189
- SlideOutType[SlideOutType["PickSlideUp"] = 6] = "PickSlideUp";
2190
- })(SlideOutType || (SlideOutType = {}));
2191
-
2192
- /**
2193
- * This public enum lists all vibrato types that can be performed.
2194
- */
2195
- var VibratoType;
2196
- (function (VibratoType) {
2197
- /**
2198
- * No vibrato.
2199
- */
2200
- VibratoType[VibratoType["None"] = 0] = "None";
2201
- /**
2202
- * A slight vibrato.
2203
- */
2204
- VibratoType[VibratoType["Slight"] = 1] = "Slight";
2205
- /**
2206
- * A wide vibrato.
2207
- */
2208
- VibratoType[VibratoType["Wide"] = 2] = "Wide";
2209
- })(VibratoType || (VibratoType = {}));
2210
-
2211
- /**
2212
- * @target web
2213
- */
2214
- class Lazy {
2215
- constructor(factory) {
2216
- this._value = undefined;
2217
- this._factory = factory;
2218
- }
2219
- get value() {
2220
- if (this._value === undefined) {
2221
- this._value = this._factory();
2222
- }
2223
- return this._value;
2224
- }
2225
- }
2226
-
2227
- /**
2228
- * Defines all loglevels.
2229
- * @json
2230
- */
2231
- var LogLevel;
2232
- (function (LogLevel) {
2233
- /**
2234
- * No logging
2235
- */
2236
- LogLevel[LogLevel["None"] = 0] = "None";
2237
- /**
2238
- * Debug level (internal details are displayed).
2239
- */
2240
- LogLevel[LogLevel["Debug"] = 1] = "Debug";
2241
- /**
2242
- * Info level (only important details are shown)
2243
- */
2244
- LogLevel[LogLevel["Info"] = 2] = "Info";
2245
- /**
2246
- * Warning level
2247
- */
2248
- LogLevel[LogLevel["Warning"] = 3] = "Warning";
2249
- /**
2250
- * Error level.
1261
+ * Error level.
2251
1262
  */
2252
1263
  LogLevel[LogLevel["Error"] = 4] = "Error";
2253
1264
  })(LogLevel || (LogLevel = {}));
@@ -2298,6 +1309,249 @@ class Logger {
2298
1309
  Logger.logLevel = LogLevel.Info;
2299
1310
  Logger.log = new ConsoleLogger();
2300
1311
 
1312
+ class TuningParseResult {
1313
+ constructor() {
1314
+ this.note = null;
1315
+ this.noteValue = 0;
1316
+ this.octave = 0;
1317
+ }
1318
+ get realValue() {
1319
+ return this.octave * 12 + this.noteValue;
1320
+ }
1321
+ }
1322
+ /**
1323
+ * This public class contains some utilities for working with model public classes
1324
+ */
1325
+ class ModelUtils {
1326
+ static getIndex(duration) {
1327
+ let index = 0;
1328
+ let value = duration;
1329
+ if (value < 0) {
1330
+ return index;
1331
+ }
1332
+ return Math.log2(duration) | 0;
1333
+ }
1334
+ static keySignatureIsFlat(ks) {
1335
+ return ks < 0;
1336
+ }
1337
+ static keySignatureIsNatural(ks) {
1338
+ return ks === 0;
1339
+ }
1340
+ static keySignatureIsSharp(ks) {
1341
+ return ks > 0;
1342
+ }
1343
+ static applyPitchOffsets(settings, score) {
1344
+ for (let i = 0; i < score.tracks.length; i++) {
1345
+ if (i < settings.notation.displayTranspositionPitches.length) {
1346
+ for (let staff of score.tracks[i].staves) {
1347
+ staff.displayTranspositionPitch = -settings.notation.displayTranspositionPitches[i];
1348
+ }
1349
+ }
1350
+ if (i < settings.notation.transpositionPitches.length) {
1351
+ for (let staff of score.tracks[i].staves) {
1352
+ staff.transpositionPitch = -settings.notation.transpositionPitches[i];
1353
+ }
1354
+ }
1355
+ }
1356
+ }
1357
+ static fingerToString(settings, beat, finger, leftHand) {
1358
+ if (settings.notation.fingeringMode === FingeringMode.ScoreForcePiano ||
1359
+ settings.notation.fingeringMode === FingeringMode.SingleNoteEffectBandForcePiano ||
1360
+ GeneralMidi.isPiano(beat.voice.bar.staff.track.playbackInfo.program)) {
1361
+ switch (finger) {
1362
+ case Fingers.Unknown:
1363
+ case Fingers.NoOrDead:
1364
+ return null;
1365
+ case Fingers.Thumb:
1366
+ return '1';
1367
+ case Fingers.IndexFinger:
1368
+ return '2';
1369
+ case Fingers.MiddleFinger:
1370
+ return '3';
1371
+ case Fingers.AnnularFinger:
1372
+ return '4';
1373
+ case Fingers.LittleFinger:
1374
+ return '5';
1375
+ default:
1376
+ return null;
1377
+ }
1378
+ }
1379
+ if (leftHand) {
1380
+ switch (finger) {
1381
+ case Fingers.Unknown:
1382
+ case Fingers.NoOrDead:
1383
+ return '0';
1384
+ case Fingers.Thumb:
1385
+ return 'T';
1386
+ case Fingers.IndexFinger:
1387
+ return '1';
1388
+ case Fingers.MiddleFinger:
1389
+ return '2';
1390
+ case Fingers.AnnularFinger:
1391
+ return '3';
1392
+ case Fingers.LittleFinger:
1393
+ return '4';
1394
+ default:
1395
+ return null;
1396
+ }
1397
+ }
1398
+ switch (finger) {
1399
+ case Fingers.Unknown:
1400
+ case Fingers.NoOrDead:
1401
+ return null;
1402
+ case Fingers.Thumb:
1403
+ return 'p';
1404
+ case Fingers.IndexFinger:
1405
+ return 'i';
1406
+ case Fingers.MiddleFinger:
1407
+ return 'm';
1408
+ case Fingers.AnnularFinger:
1409
+ return 'a';
1410
+ case Fingers.LittleFinger:
1411
+ return 'c';
1412
+ default:
1413
+ return null;
1414
+ }
1415
+ }
1416
+ /**
1417
+ * Checks if the given string is a tuning inticator.
1418
+ * @param name
1419
+ * @returns
1420
+ */
1421
+ static isTuning(name) {
1422
+ return !!ModelUtils.parseTuning(name);
1423
+ }
1424
+ static parseTuning(name) {
1425
+ let note = '';
1426
+ let octave = '';
1427
+ for (let i = 0; i < name.length; i++) {
1428
+ let c = name.charCodeAt(i);
1429
+ if (c >= 0x30 && c <= 0x39) {
1430
+ // number without note?
1431
+ if (!note) {
1432
+ return null;
1433
+ }
1434
+ octave += String.fromCharCode(c);
1435
+ }
1436
+ else if ((c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) || c === 0x23) {
1437
+ note += String.fromCharCode(c);
1438
+ }
1439
+ else {
1440
+ return null;
1441
+ }
1442
+ }
1443
+ if (!octave || !note) {
1444
+ return null;
1445
+ }
1446
+ let result = new TuningParseResult();
1447
+ result.octave = parseInt(octave) + 1;
1448
+ result.note = note.toLowerCase();
1449
+ result.noteValue = ModelUtils.getToneForText(result.note);
1450
+ return result;
1451
+ }
1452
+ static getTuningForText(str) {
1453
+ let result = ModelUtils.parseTuning(str);
1454
+ if (!result) {
1455
+ return -1;
1456
+ }
1457
+ return result.realValue;
1458
+ }
1459
+ static getToneForText(note) {
1460
+ let b = 0;
1461
+ switch (note.toLowerCase()) {
1462
+ case 'c':
1463
+ b = 0;
1464
+ break;
1465
+ case 'c#':
1466
+ case 'db':
1467
+ b = 1;
1468
+ break;
1469
+ case 'd':
1470
+ b = 2;
1471
+ break;
1472
+ case 'd#':
1473
+ case 'eb':
1474
+ b = 3;
1475
+ break;
1476
+ case 'e':
1477
+ b = 4;
1478
+ break;
1479
+ case 'f':
1480
+ b = 5;
1481
+ break;
1482
+ case 'f#':
1483
+ case 'gb':
1484
+ b = 6;
1485
+ break;
1486
+ case 'g':
1487
+ b = 7;
1488
+ break;
1489
+ case 'g#':
1490
+ case 'ab':
1491
+ b = 8;
1492
+ break;
1493
+ case 'a':
1494
+ b = 9;
1495
+ break;
1496
+ case 'a#':
1497
+ case 'bb':
1498
+ b = 10;
1499
+ break;
1500
+ case 'b':
1501
+ b = 11;
1502
+ break;
1503
+ default:
1504
+ return 0;
1505
+ }
1506
+ return b;
1507
+ }
1508
+ static newGuid() {
1509
+ return (Math.floor((1 + Math.random()) * 0x10000)
1510
+ .toString(16)
1511
+ .substring(1) +
1512
+ Math.floor((1 + Math.random()) * 0x10000)
1513
+ .toString(16)
1514
+ .substring(1) +
1515
+ '-' +
1516
+ Math.floor((1 + Math.random()) * 0x10000)
1517
+ .toString(16)
1518
+ .substring(1) +
1519
+ '-' +
1520
+ Math.floor((1 + Math.random()) * 0x10000)
1521
+ .toString(16)
1522
+ .substring(1) +
1523
+ '-' +
1524
+ Math.floor((1 + Math.random()) * 0x10000)
1525
+ .toString(16)
1526
+ .substring(1) +
1527
+ '-' +
1528
+ Math.floor((1 + Math.random()) * 0x10000)
1529
+ .toString(16)
1530
+ .substring(1) +
1531
+ Math.floor((1 + Math.random()) * 0x10000)
1532
+ .toString(16)
1533
+ .substring(1) +
1534
+ Math.floor((1 + Math.random()) * 0x10000)
1535
+ .toString(16)
1536
+ .substring(1));
1537
+ }
1538
+ static isAlmostEqualTo(a, b) {
1539
+ return Math.abs(a - b) < 0.00001;
1540
+ }
1541
+ static toHexString(n, digits = 0) {
1542
+ let s = '';
1543
+ let hexChars = '0123456789ABCDEF';
1544
+ do {
1545
+ s = String.fromCharCode(hexChars.charCodeAt(n & 15)) + s;
1546
+ n = n >> 4;
1547
+ } while (n > 0);
1548
+ while (s.length < digits) {
1549
+ s = '0' + s;
1550
+ }
1551
+ return s;
1552
+ }
1553
+ }
1554
+
2301
1555
  /**
2302
1556
  * Lists all types of pick strokes.
2303
1557
  */
@@ -5258,6 +4512,117 @@ class Section {
5258
4512
  }
5259
4513
  }
5260
4514
 
4515
+ /**
4516
+ * An invalid input format was detected (e.g. invalid setting values, file formats,...)
4517
+ */
4518
+ class FormatError extends AlphaTabError {
4519
+ constructor(message) {
4520
+ super(AlphaTabErrorType.Format, message);
4521
+ Object.setPrototypeOf(this, FormatError.prototype);
4522
+ }
4523
+ }
4524
+
4525
+ /**
4526
+ * @json_immutable
4527
+ */
4528
+ class Color {
4529
+ /**
4530
+ * Initializes a new instance of the {@link Color} class.
4531
+ * @param r The red component.
4532
+ * @param g The green component.
4533
+ * @param b The blue component.
4534
+ * @param a The alpha component.
4535
+ */
4536
+ constructor(r, g, b, a = 0xff) {
4537
+ /**
4538
+ * Gets or sets the raw RGBA value.
4539
+ */
4540
+ this.raw = 0;
4541
+ this.raw = ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
4542
+ this.updateRgba();
4543
+ }
4544
+ updateRgba() {
4545
+ if (this.a === 0xff) {
4546
+ this.rgba =
4547
+ '#' +
4548
+ ModelUtils.toHexString(this.r, 2) +
4549
+ ModelUtils.toHexString(this.g, 2) +
4550
+ ModelUtils.toHexString(this.b, 2);
4551
+ }
4552
+ else {
4553
+ this.rgba = `rgba(${this.r},${this.g},${this.b},${this.a / 255.0})`;
4554
+ }
4555
+ }
4556
+ get a() {
4557
+ return (this.raw >> 24) & 0xff;
4558
+ }
4559
+ get r() {
4560
+ return (this.raw >> 16) & 0xff;
4561
+ }
4562
+ get g() {
4563
+ return (this.raw >> 8) & 0xff;
4564
+ }
4565
+ get b() {
4566
+ return this.raw & 0xff;
4567
+ }
4568
+ static random(opacity = 100) {
4569
+ return new Color((Math.random() * 255) | 0, (Math.random() * 255) | 0, (Math.random() * 255) | 0, opacity);
4570
+ }
4571
+ static fromJson(v) {
4572
+ switch (typeof v) {
4573
+ case 'number':
4574
+ {
4575
+ const c = new Color(0, 0, 0, 0);
4576
+ c.raw = v;
4577
+ c.updateRgba();
4578
+ return c;
4579
+ }
4580
+ case 'string':
4581
+ {
4582
+ const json = v;
4583
+ if (json.startsWith('#')) {
4584
+ if (json.length === 4) {
4585
+ // #RGB
4586
+ return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17);
4587
+ }
4588
+ if (json.length === 5) {
4589
+ // #RGBA
4590
+ return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17, parseInt(json.substring(4, 1), 16) * 17);
4591
+ }
4592
+ if (json.length === 7) {
4593
+ // #RRGGBB
4594
+ return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16));
4595
+ }
4596
+ if (json.length === 9) {
4597
+ // #RRGGBBAA
4598
+ return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16), parseInt(json.substring(7, 2), 16));
4599
+ }
4600
+ }
4601
+ else if (json.startsWith('rgba') || json.startsWith('rgb')) {
4602
+ const start = json.indexOf('(');
4603
+ const end = json.lastIndexOf(')');
4604
+ if (start === -1 || end === -1) {
4605
+ throw new FormatError('No values specified for rgb/rgba function');
4606
+ }
4607
+ const numbers = json.substring(start + 1, end).split(',');
4608
+ if (numbers.length === 3) {
4609
+ return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]));
4610
+ }
4611
+ if (numbers.length === 4) {
4612
+ return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]), parseFloat(numbers[3]) * 255);
4613
+ }
4614
+ }
4615
+ return null;
4616
+ }
4617
+ }
4618
+ throw new FormatError('Unsupported format for color');
4619
+ }
4620
+ static toJson(obj) {
4621
+ return obj.raw;
4622
+ }
4623
+ }
4624
+ Color.BlackRgb = '#000000';
4625
+
5261
4626
  /**
5262
4627
  * This public class stores the midi specific information of a track needed
5263
4628
  * for playback.
@@ -7555,6 +6920,9 @@ class AlphaTexImporter extends ScoreImporter {
7555
6920
  break;
7556
6921
  }
7557
6922
  }
6923
+ isNoteText(txt) {
6924
+ return txt === 'x' || txt === '-' || txt === 'r';
6925
+ }
7558
6926
  note(beat) {
7559
6927
  // fret.string
7560
6928
  let isDead = false;
@@ -7957,7 +7325,7 @@ class AlphaTexImporter extends ScoreImporter {
7957
7325
  let text = this._syData;
7958
7326
  this._sy = this.newSy();
7959
7327
  let marker = '';
7960
- if (this._sy === AlphaTexSymbols.String) {
7328
+ if (this._sy === AlphaTexSymbols.String && !this.isNoteText(this._syData.toLowerCase())) {
7961
7329
  marker = text;
7962
7330
  text = this._syData;
7963
7331
  this._sy = this.newSy();
@@ -17878,6 +17246,7 @@ class AlphaSynth {
17878
17246
  set masterVolume(value) {
17879
17247
  value = Math.max(value, SynthConstants.MinVolume);
17880
17248
  this._synthesizer.masterVolume = value;
17249
+ this.onAudioSettingsUpdate();
17881
17250
  }
17882
17251
  get metronomeVolume() {
17883
17252
  return this._metronomeVolume;
@@ -17886,6 +17255,7 @@ class AlphaSynth {
17886
17255
  value = Math.max(value, SynthConstants.MinVolume);
17887
17256
  this._metronomeVolume = value;
17888
17257
  this._synthesizer.metronomeVolume = value;
17258
+ this.onAudioSettingsUpdate();
17889
17259
  }
17890
17260
  get countInVolume() {
17891
17261
  return this._countInVolume;
@@ -17907,7 +17277,7 @@ class AlphaSynth {
17907
17277
  value = SynthHelper.clamp(value, SynthConstants.MinPlaybackSpeed, SynthConstants.MaxPlaybackSpeed);
17908
17278
  let oldSpeed = this._sequencer.playbackSpeed;
17909
17279
  this._sequencer.playbackSpeed = value;
17910
- this.updateTimePosition(this._timePosition * (oldSpeed / value), true);
17280
+ this.timePosition = this.timePosition * (oldSpeed / value);
17911
17281
  }
17912
17282
  get tickPosition() {
17913
17283
  return this._tickPosition;
@@ -18031,242 +17401,888 @@ class AlphaSynth {
18031
17401
  this.soundFontLoadFailed.trigger(e);
18032
17402
  }
18033
17403
  }
18034
- checkReadyForPlayback() {
18035
- if (this.isReadyForPlayback) {
18036
- this._synthesizer.setupMetronomeChannel(this.metronomeVolume);
18037
- this.readyForPlayback.trigger();
18038
- }
17404
+ checkReadyForPlayback() {
17405
+ if (this.isReadyForPlayback) {
17406
+ this._synthesizer.setupMetronomeChannel(this.metronomeVolume);
17407
+ this.readyForPlayback.trigger();
17408
+ }
17409
+ }
17410
+ /**
17411
+ * Loads the given midi file for playback.
17412
+ * @param midi The midi file to load
17413
+ */
17414
+ loadMidiFile(midi) {
17415
+ this.stop();
17416
+ try {
17417
+ Logger.debug('AlphaSynth', 'Loading midi from model');
17418
+ this._sequencer.loadMidi(midi);
17419
+ this._isMidiLoaded = true;
17420
+ this.midiLoaded.trigger(new PositionChangedEventArgs(0, this._sequencer.endTime, 0, this._sequencer.endTick, false));
17421
+ Logger.debug('AlphaSynth', 'Midi successfully loaded');
17422
+ this.checkReadyForPlayback();
17423
+ this.tickPosition = 0;
17424
+ }
17425
+ catch (e) {
17426
+ Logger.error('AlphaSynth', 'Could not load midi from model ' + e);
17427
+ this.midiLoadFailed.trigger(e);
17428
+ }
17429
+ }
17430
+ setChannelMute(channel, mute) {
17431
+ this._synthesizer.channelSetMute(channel, mute);
17432
+ this.onAudioSettingsUpdate();
17433
+ }
17434
+ resetChannelStates() {
17435
+ this._synthesizer.resetChannelStates();
17436
+ }
17437
+ setChannelSolo(channel, solo) {
17438
+ this._synthesizer.channelSetSolo(channel, solo);
17439
+ this.onAudioSettingsUpdate();
17440
+ }
17441
+ setChannelVolume(channel, volume) {
17442
+ volume = Math.max(volume, SynthConstants.MinVolume);
17443
+ this._synthesizer.channelSetMixVolume(channel, volume);
17444
+ this.onAudioSettingsUpdate();
17445
+ }
17446
+ onAudioSettingsUpdate() {
17447
+ // seeking to the currently known position, will ensure we
17448
+ // clear all audio buffers and re-generate the audio
17449
+ // which was not actually played yet.
17450
+ this.timePosition = this.timePosition;
17451
+ }
17452
+ onSamplesPlayed(sampleCount) {
17453
+ let playedMillis = (sampleCount / this._synthesizer.outSampleRate) * 1000;
17454
+ this.updateTimePosition(this._timePosition + playedMillis, false);
17455
+ this.checkForFinish();
17456
+ }
17457
+ checkForFinish() {
17458
+ let startTick = 0;
17459
+ let endTick = 0;
17460
+ if (this.playbackRange) {
17461
+ startTick = this.playbackRange.startTick;
17462
+ endTick = this.playbackRange.endTick;
17463
+ }
17464
+ else {
17465
+ endTick = this._sequencer.endTick;
17466
+ }
17467
+ if (this._tickPosition >= endTick) {
17468
+ Logger.debug('AlphaSynth', 'Finished playback');
17469
+ if (this._sequencer.isPlayingCountIn) {
17470
+ this._sequencer.resetCountIn();
17471
+ this.timePosition = this._sequencer.currentTime;
17472
+ this.playInternal();
17473
+ }
17474
+ else if (this._sequencer.isPlayingOneTimeMidi) {
17475
+ this._sequencer.resetOneTimeMidi();
17476
+ this.state = PlayerState.Paused;
17477
+ this.output.pause();
17478
+ this._synthesizer.noteOffAll(false);
17479
+ }
17480
+ else {
17481
+ this.finished.trigger();
17482
+ if (this.isLooping) {
17483
+ this.tickPosition = startTick;
17484
+ }
17485
+ else {
17486
+ this.stop();
17487
+ }
17488
+ }
17489
+ }
17490
+ }
17491
+ updateTimePosition(timePosition, isSeek) {
17492
+ // update the real positions
17493
+ const currentTime = timePosition;
17494
+ this._timePosition = currentTime;
17495
+ const currentTick = this._sequencer.timePositionToTickPosition(currentTime);
17496
+ this._tickPosition = currentTick;
17497
+ const endTime = this._sequencer.endTime;
17498
+ const endTick = this._sequencer.endTick;
17499
+ if (!this._sequencer.isPlayingOneTimeMidi && !this._sequencer.isPlayingCountIn) {
17500
+ Logger.debug('AlphaSynth', `Position changed: (time: ${currentTime}/${endTime}, tick: ${currentTick}/${endTick}, Active Voices: ${this._synthesizer.activeVoiceCount}`);
17501
+ this.positionChanged.trigger(new PositionChangedEventArgs(currentTime, endTime, currentTick, endTick, isSeek));
17502
+ }
17503
+ // build events which were actually played
17504
+ if (isSeek) {
17505
+ this._playedEventsQueue.clear();
17506
+ }
17507
+ else {
17508
+ const playedEvents = new Queue();
17509
+ while (!this._playedEventsQueue.isEmpty && this._playedEventsQueue.peek().time < currentTime) {
17510
+ const synthEvent = this._playedEventsQueue.dequeue();
17511
+ playedEvents.enqueue(synthEvent.event);
17512
+ }
17513
+ if (!playedEvents.isEmpty) {
17514
+ this.midiEventsPlayed.trigger(new MidiEventsPlayedEventArgs(playedEvents.toArray()));
17515
+ }
17516
+ }
17517
+ }
17518
+ }
17519
+
17520
+ /**
17521
+ * Represents a midi file with a single track that can be played via {@link AlphaSynth}
17522
+ */
17523
+ class MidiFile {
17524
+ constructor() {
17525
+ /**
17526
+ * Gets or sets the division per quarter notes.
17527
+ */
17528
+ this.division = MidiUtils.QuarterTime;
17529
+ /**
17530
+ * Gets a list of midi events sorted by time.
17531
+ */
17532
+ this.events = [];
17533
+ }
17534
+ /**
17535
+ * Adds the given midi event a the correct time position into the file.
17536
+ */
17537
+ addEvent(e) {
17538
+ if (this.events.length === 0) {
17539
+ this.events.push(e);
17540
+ }
17541
+ else {
17542
+ let insertPos = this.events.length;
17543
+ while (insertPos > 0) {
17544
+ const prevItem = this.events[insertPos - 1];
17545
+ if (prevItem.tick > e.tick) {
17546
+ insertPos--;
17547
+ }
17548
+ else {
17549
+ break;
17550
+ }
17551
+ }
17552
+ this.events.splice(insertPos, 0, e);
17553
+ }
17554
+ }
17555
+ /**
17556
+ * Writes the midi file into a binary format.
17557
+ * @returns The binary midi file.
17558
+ */
17559
+ toBinary() {
17560
+ let data = ByteBuffer.empty();
17561
+ this.writeTo(data);
17562
+ return data.toArray();
17563
+ }
17564
+ /**
17565
+ * Writes the midi file as binary into the given stream.
17566
+ * @returns The stream to write to.
17567
+ */
17568
+ writeTo(s) {
17569
+ // magic number "MThd" (0x4D546864)
17570
+ let b = new Uint8Array([0x4d, 0x54, 0x68, 0x64]);
17571
+ s.write(b, 0, b.length);
17572
+ // Header Length 6 (0x00000006)
17573
+ b = new Uint8Array([0x00, 0x00, 0x00, 0x06]);
17574
+ s.write(b, 0, b.length);
17575
+ // format
17576
+ b = new Uint8Array([0x00, 0x00]);
17577
+ s.write(b, 0, b.length);
17578
+ // number of tracks
17579
+ let v = 1;
17580
+ b = new Uint8Array([(v >> 8) & 0xff, v & 0xff]);
17581
+ s.write(b, 0, b.length);
17582
+ v = this.division;
17583
+ b = new Uint8Array([(v >> 8) & 0xff, v & 0xff]);
17584
+ s.write(b, 0, b.length);
17585
+ // build track data first
17586
+ let trackData = ByteBuffer.empty();
17587
+ let previousTick = 0;
17588
+ for (let midiEvent of this.events) {
17589
+ let delta = midiEvent.tick - previousTick;
17590
+ MidiFile.writeVariableInt(trackData, delta);
17591
+ midiEvent.writeTo(trackData);
17592
+ previousTick = midiEvent.tick;
17593
+ }
17594
+ // end of track
17595
+ // magic number "MTrk" (0x4D54726B)
17596
+ b = new Uint8Array([0x4d, 0x54, 0x72, 0x6b]);
17597
+ s.write(b, 0, b.length);
17598
+ // size as integer
17599
+ let data = trackData.toArray();
17600
+ let l = data.length;
17601
+ b = new Uint8Array([(l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff]);
17602
+ s.write(b, 0, b.length);
17603
+ s.write(data, 0, data.length);
17604
+ }
17605
+ static writeVariableInt(s, value) {
17606
+ let array = new Uint8Array(4);
17607
+ let n = 0;
17608
+ do {
17609
+ array[n++] = value & 0x7f;
17610
+ value >>= 7;
17611
+ } while (value > 0);
17612
+ while (n > 0) {
17613
+ n--;
17614
+ if (n > 0) {
17615
+ s.writeByte(array[n] | 0x80);
17616
+ }
17617
+ else {
17618
+ s.writeByte(array[n]);
17619
+ }
17620
+ }
17621
+ }
17622
+ }
17623
+
17624
+ class MetaDataEvent extends MetaEvent {
17625
+ constructor(track, delta, status, metaId, data) {
17626
+ super(track, delta, status, metaId, 0);
17627
+ this.data = data;
17628
+ }
17629
+ writeTo(s) {
17630
+ s.writeByte(0xff);
17631
+ s.writeByte(this.metaStatus);
17632
+ let l = this.data.length;
17633
+ MidiFile.writeVariableInt(s, l);
17634
+ s.write(this.data, 0, this.data.length);
17635
+ }
17636
+ }
17637
+
17638
+ class MetaNumberEvent extends MetaEvent {
17639
+ constructor(track, delta, status, metaId, value) {
17640
+ super(track, delta, status, metaId, 0);
17641
+ this.value = value;
17642
+ }
17643
+ writeTo(s) {
17644
+ s.writeByte(0xff);
17645
+ s.writeByte(this.metaStatus);
17646
+ MidiFile.writeVariableInt(s, 3);
17647
+ let b = new Uint8Array([(this.value >> 16) & 0xff, (this.value >> 8) & 0xff, this.value & 0xff]);
17648
+ s.write(b, 0, b.length);
17649
+ }
17650
+ }
17651
+
17652
+ /**
17653
+ * @partial
17654
+ */
17655
+ class JsonHelper {
17656
+ /**
17657
+ * @target web
17658
+ * @partial
17659
+ */
17660
+ static parseEnum(s, enumType) {
17661
+ switch (typeof s) {
17662
+ case 'string':
17663
+ const num = parseInt(s);
17664
+ return isNaN(num)
17665
+ ? enumType[Object.keys(enumType).find(k => k.toLowerCase() === s.toLowerCase())]
17666
+ : num;
17667
+ case 'number':
17668
+ return s;
17669
+ case 'undefined':
17670
+ case 'object':
17671
+ return null;
17672
+ }
17673
+ throw new AlphaTabError(AlphaTabErrorType.Format, `Could not parse enum value '${s}'`);
17674
+ }
17675
+ /**
17676
+ * @target web
17677
+ * @partial
17678
+ */
17679
+ static forEach(s, func) {
17680
+ if (s instanceof Map) {
17681
+ s.forEach(func);
17682
+ }
17683
+ else if (typeof s === 'object') {
17684
+ for (const k in s) {
17685
+ func(s[k], k);
17686
+ }
17687
+ }
17688
+ // skip
17689
+ }
17690
+ }
17691
+
17692
+ /**
17693
+ * A very basic font parser which parses the fields according to
17694
+ * https://www.w3.org/TR/CSS21/fonts.html#propdef-font
17695
+ */
17696
+ class FontParserToken {
17697
+ constructor(text, startPos, endPos) {
17698
+ this.text = text;
17699
+ this.startPos = startPos;
17700
+ this.endPos = endPos;
17701
+ }
17702
+ }
17703
+ class FontParser {
17704
+ constructor(input) {
17705
+ this.style = 'normal';
17706
+ this.variant = 'normal';
17707
+ this.weight = 'normal';
17708
+ this.stretch = 'normal';
17709
+ this.lineHeight = 'normal';
17710
+ this.size = '1rem';
17711
+ this.families = [];
17712
+ this._currentTokenIndex = -1;
17713
+ this._input = '';
17714
+ this._currentToken = null;
17715
+ this._input = input;
17716
+ this._tokens = this.splitToTokens(input);
17717
+ }
17718
+ splitToTokens(input) {
17719
+ const tokens = [];
17720
+ let startPos = 0;
17721
+ while (startPos < input.length) {
17722
+ let endPos = startPos;
17723
+ while (endPos < input.length && input.charAt(endPos) !== ' ') {
17724
+ endPos++;
17725
+ }
17726
+ if (endPos > startPos) {
17727
+ tokens.push(new FontParserToken(input.substring(startPos, endPos), startPos, endPos));
17728
+ }
17729
+ startPos = endPos + 1;
17730
+ }
17731
+ return tokens;
17732
+ }
17733
+ parse() {
17734
+ var _a;
17735
+ this.reset();
17736
+ // default font flags
17737
+ if (this._tokens.length === 1) {
17738
+ switch ((_a = this._currentToken) === null || _a === void 0 ? void 0 : _a.text) {
17739
+ case 'caption':
17740
+ case 'icon':
17741
+ case 'menu':
17742
+ case 'message-box':
17743
+ case 'small-caption':
17744
+ case 'status-bar':
17745
+ case 'inherit':
17746
+ return;
17747
+ }
17748
+ }
17749
+ this.fontStyleVariantWeight();
17750
+ this.fontSizeLineHeight();
17751
+ this.fontFamily();
17752
+ }
17753
+ fontFamily() {
17754
+ if (!this._currentToken) {
17755
+ throw new Error(`Missing font list`);
17756
+ }
17757
+ const familyListInput = this._input.substr(this._currentToken.startPos).trim();
17758
+ let pos = 0;
17759
+ while (pos < familyListInput.length) {
17760
+ let c = familyListInput.charAt(pos);
17761
+ if (c === ' ' || c == ',') {
17762
+ // skip whitespace and quotes
17763
+ pos++;
17764
+ }
17765
+ else if (c === '"' || c === "'") {
17766
+ // quoted
17767
+ const endOfString = this.findEndOfQuote(familyListInput, pos + 1, c);
17768
+ this.families.push(familyListInput
17769
+ .substring(pos + 1, endOfString)
17770
+ .split('\\' + c)
17771
+ .join(c));
17772
+ pos = endOfString + 1;
17773
+ }
17774
+ else {
17775
+ // until comma
17776
+ const endOfString = this.findEndOfQuote(familyListInput, pos + 1, ',');
17777
+ this.families.push(familyListInput.substring(pos, endOfString).trim());
17778
+ pos = endOfString + 1;
17779
+ }
17780
+ }
17781
+ }
17782
+ findEndOfQuote(s, pos, quoteChar) {
17783
+ let escaped = false;
17784
+ while (pos < s.length) {
17785
+ const c = s.charAt(pos);
17786
+ if (!escaped && c === quoteChar) {
17787
+ return pos;
17788
+ }
17789
+ if (!escaped && c === '\\') {
17790
+ escaped = true;
17791
+ }
17792
+ else {
17793
+ escaped = false;
17794
+ }
17795
+ pos += 1;
17796
+ }
17797
+ return s.length;
17798
+ }
17799
+ fontSizeLineHeight() {
17800
+ if (!this._currentToken) {
17801
+ throw new Error(`Missing font size`);
17802
+ }
17803
+ const parts = this._currentToken.text.split('/');
17804
+ if (parts.length >= 3) {
17805
+ throw new Error(`Invalid font size '${this._currentToken}' specified`);
17806
+ }
17807
+ this.nextToken();
17808
+ if (parts.length >= 2) {
17809
+ if (parts[1] === '/') {
17810
+ // size/ line-height (space after slash)
17811
+ if (!this._currentToken) {
17812
+ throw new Error('Missing line-height after font size');
17813
+ }
17814
+ this.lineHeight = this._currentToken.text;
17815
+ this.nextToken();
17816
+ }
17817
+ else {
17818
+ // size/line-height (no spaces)
17819
+ this.size = parts[0];
17820
+ this.lineHeight = parts[1];
17821
+ }
17822
+ }
17823
+ else if (parts.length >= 1) {
17824
+ this.size = parts[0];
17825
+ if (this._currentToken &&
17826
+ this._currentToken.text.indexOf('/') === 0) {
17827
+ // size / line-height (with spaces befor and after slash)
17828
+ if (this._currentToken.text === '/') {
17829
+ this.nextToken();
17830
+ if (!this._currentToken) {
17831
+ throw new Error('Missing line-height after font size');
17832
+ }
17833
+ this.lineHeight = this._currentToken.text;
17834
+ this.nextToken();
17835
+ }
17836
+ else {
17837
+ this.lineHeight = this._currentToken.text.substr(1);
17838
+ this.nextToken();
17839
+ }
17840
+ }
17841
+ }
17842
+ else {
17843
+ throw new Error(`Missing font size`);
17844
+ }
17845
+ }
17846
+ nextToken() {
17847
+ this._currentTokenIndex++;
17848
+ if (this._currentTokenIndex < this._tokens.length) {
17849
+ this._currentToken = this._tokens[this._currentTokenIndex];
17850
+ }
17851
+ else {
17852
+ this._currentToken = null;
17853
+ }
17854
+ }
17855
+ fontStyleVariantWeight() {
17856
+ let hasStyle = false;
17857
+ let hasVariant = false;
17858
+ let hasWeight = false;
17859
+ let valuesNeeded = 3;
17860
+ let ambiguous = [];
17861
+ while (true) {
17862
+ if (!this._currentToken) {
17863
+ return;
17864
+ }
17865
+ let text = this._currentToken.text;
17866
+ switch (text) {
17867
+ // ambiguous
17868
+ case 'normal':
17869
+ case 'inherit':
17870
+ ambiguous.push(text);
17871
+ valuesNeeded--;
17872
+ this.nextToken();
17873
+ break;
17874
+ // style
17875
+ case 'italic':
17876
+ case 'oblique':
17877
+ this.style = text;
17878
+ hasStyle = true;
17879
+ valuesNeeded--;
17880
+ this.nextToken();
17881
+ break;
17882
+ // variant
17883
+ case 'small-caps':
17884
+ this.variant = text;
17885
+ hasVariant = true;
17886
+ valuesNeeded--;
17887
+ this.nextToken();
17888
+ break;
17889
+ // weight
17890
+ case 'bold':
17891
+ case 'bolder':
17892
+ case 'lighter':
17893
+ case '100':
17894
+ case '200':
17895
+ case '300':
17896
+ case '400':
17897
+ case '500':
17898
+ case '600':
17899
+ case '700':
17900
+ case '800':
17901
+ case '900':
17902
+ this.weight = text;
17903
+ hasWeight = true;
17904
+ valuesNeeded--;
17905
+ this.nextToken();
17906
+ break;
17907
+ default:
17908
+ // unknown token -> done with this part
17909
+ return;
17910
+ }
17911
+ if (valuesNeeded === 0) {
17912
+ break;
17913
+ }
17914
+ }
17915
+ while (ambiguous.length > 0) {
17916
+ const v = ambiguous.pop();
17917
+ if (!hasWeight) {
17918
+ this.weight = v;
17919
+ }
17920
+ else if (!hasVariant) {
17921
+ this.variant = v;
17922
+ }
17923
+ else if (!hasStyle) {
17924
+ this.style = v;
17925
+ }
17926
+ }
17927
+ }
17928
+ reset() {
17929
+ this._currentTokenIndex = -1;
17930
+ this.nextToken();
17931
+ }
17932
+ }
17933
+ /**
17934
+ * Lists all flags for font styles.
17935
+ */
17936
+ var FontStyle;
17937
+ (function (FontStyle) {
17938
+ /**
17939
+ * No flags.
17940
+ */
17941
+ FontStyle[FontStyle["Plain"] = 0] = "Plain";
17942
+ /**
17943
+ * Font is italic.
17944
+ */
17945
+ FontStyle[FontStyle["Italic"] = 1] = "Italic";
17946
+ })(FontStyle || (FontStyle = {}));
17947
+ /**
17948
+ * Lists all font weight values.
17949
+ */
17950
+ var FontWeight;
17951
+ (function (FontWeight) {
17952
+ /**
17953
+ * Not bold
17954
+ */
17955
+ FontWeight[FontWeight["Regular"] = 0] = "Regular";
17956
+ /**
17957
+ * Font is bold
17958
+ */
17959
+ FontWeight[FontWeight["Bold"] = 1] = "Bold";
17960
+ })(FontWeight || (FontWeight = {}));
17961
+ /**
17962
+ * @json_immutable
17963
+ */
17964
+ class Font {
17965
+ /**
17966
+ * Initializes a new instance of the {@link Font} class.
17967
+ * @param family The family.
17968
+ * @param size The size.
17969
+ * @param style The style.
17970
+ * @param weight The weight.
17971
+ */
17972
+ constructor(family, size, style = FontStyle.Plain, weight = FontWeight.Regular) {
17973
+ this._cssScale = 0.0;
17974
+ this._family = family;
17975
+ this._size = size;
17976
+ this._style = style;
17977
+ this._weight = weight;
17978
+ this._css = this.toCssString();
17979
+ }
17980
+ reset() {
17981
+ this._cssScale = 0;
17982
+ this._css = this.toCssString();
17983
+ }
17984
+ /**
17985
+ * Gets the font family name.
17986
+ */
17987
+ get family() {
17988
+ return this._family;
17989
+ }
17990
+ /**
17991
+ * Sets the font family name.
17992
+ */
17993
+ set family(value) {
17994
+ this._family = value;
17995
+ this.reset();
18039
17996
  }
18040
17997
  /**
18041
- * Loads the given midi file for playback.
18042
- * @param midi The midi file to load
17998
+ * Gets the font size in pixels.
18043
17999
  */
18044
- loadMidiFile(midi) {
18045
- this.stop();
18046
- try {
18047
- Logger.debug('AlphaSynth', 'Loading midi from model');
18048
- this._sequencer.loadMidi(midi);
18049
- this._isMidiLoaded = true;
18050
- this.midiLoaded.trigger(new PositionChangedEventArgs(0, this._sequencer.endTime, 0, this._sequencer.endTick, false));
18051
- Logger.debug('AlphaSynth', 'Midi successfully loaded');
18052
- this.checkReadyForPlayback();
18053
- this.tickPosition = 0;
18054
- }
18055
- catch (e) {
18056
- Logger.error('AlphaSynth', 'Could not load midi from model ' + e);
18057
- this.midiLoadFailed.trigger(e);
18058
- }
18000
+ get size() {
18001
+ return this._size;
18059
18002
  }
18060
- setChannelMute(channel, mute) {
18061
- this._synthesizer.channelSetMute(channel, mute);
18003
+ /**
18004
+ * Sets the font size in pixels.
18005
+ */
18006
+ set size(value) {
18007
+ this._size = value;
18008
+ this.reset();
18062
18009
  }
18063
- resetChannelStates() {
18064
- this._synthesizer.resetChannelStates();
18010
+ /**
18011
+ * Gets the font style.
18012
+ */
18013
+ get style() {
18014
+ return this._style;
18065
18015
  }
18066
- setChannelSolo(channel, solo) {
18067
- this._synthesizer.channelSetSolo(channel, solo);
18016
+ /**
18017
+ * Sets the font style.
18018
+ */
18019
+ set style(value) {
18020
+ this._style = value;
18021
+ this.reset();
18068
18022
  }
18069
- setChannelVolume(channel, volume) {
18070
- volume = Math.max(volume, SynthConstants.MinVolume);
18071
- this._synthesizer.channelSetMixVolume(channel, volume);
18023
+ /**
18024
+ * Gets the font weight.
18025
+ */
18026
+ get weight() {
18027
+ return this._weight;
18072
18028
  }
18073
- onSamplesPlayed(sampleCount) {
18074
- let playedMillis = (sampleCount / this._synthesizer.outSampleRate) * 1000;
18075
- this.updateTimePosition(this._timePosition + playedMillis, false);
18076
- this.checkForFinish();
18029
+ /**
18030
+ * Gets or sets the font weight.
18031
+ */
18032
+ set weight(value) {
18033
+ this._weight = value;
18034
+ this.reset();
18077
18035
  }
18078
- checkForFinish() {
18079
- let startTick = 0;
18080
- let endTick = 0;
18081
- if (this.playbackRange) {
18082
- startTick = this.playbackRange.startTick;
18083
- endTick = this.playbackRange.endTick;
18084
- }
18085
- else {
18086
- endTick = this._sequencer.endTick;
18087
- }
18088
- if (this._tickPosition >= endTick) {
18089
- Logger.debug('AlphaSynth', 'Finished playback');
18090
- if (this._sequencer.isPlayingCountIn) {
18091
- this._sequencer.resetCountIn();
18092
- this.timePosition = this._sequencer.currentTime;
18093
- this.playInternal();
18094
- }
18095
- else if (this._sequencer.isPlayingOneTimeMidi) {
18096
- this._sequencer.resetOneTimeMidi();
18097
- this.state = PlayerState.Paused;
18098
- this.output.pause();
18099
- this._synthesizer.noteOffAll(false);
18036
+ get isBold() {
18037
+ return this.weight === FontWeight.Bold;
18038
+ }
18039
+ get isItalic() {
18040
+ return this.style === FontStyle.Italic;
18041
+ }
18042
+ toCssString(scale = 1) {
18043
+ if (!this._css || !(Math.abs(scale - this._cssScale) < 0.01)) {
18044
+ let buf = '';
18045
+ if (this.isBold) {
18046
+ buf += 'bold ';
18100
18047
  }
18101
- else {
18102
- this.finished.trigger();
18103
- if (this.isLooping) {
18104
- this.tickPosition = startTick;
18105
- }
18106
- else {
18107
- this.stop();
18108
- }
18048
+ if (this.isItalic) {
18049
+ buf += 'italic ';
18109
18050
  }
18051
+ buf += this.size * scale;
18052
+ buf += 'px ';
18053
+ buf += "'";
18054
+ buf += this.family;
18055
+ buf += "'";
18056
+ this._css = buf;
18057
+ this._cssScale = scale;
18110
18058
  }
18059
+ return this._css;
18111
18060
  }
18112
- updateTimePosition(timePosition, isSeek) {
18113
- // update the real positions
18114
- const currentTime = timePosition;
18115
- this._timePosition = currentTime;
18116
- const currentTick = this._sequencer.timePositionToTickPosition(currentTime);
18117
- this._tickPosition = currentTick;
18118
- const endTime = this._sequencer.endTime;
18119
- const endTick = this._sequencer.endTick;
18120
- if (!this._sequencer.isPlayingOneTimeMidi && !this._sequencer.isPlayingCountIn) {
18121
- Logger.debug('AlphaSynth', `Position changed: (time: ${currentTime}/${endTime}, tick: ${currentTick}/${endTick}, Active Voices: ${this._synthesizer.activeVoiceCount}`);
18122
- this.positionChanged.trigger(new PositionChangedEventArgs(currentTime, endTime, currentTick, endTick, isSeek));
18123
- }
18124
- // build events which were actually played
18125
- if (isSeek) {
18126
- this._playedEventsQueue.clear();
18127
- }
18128
- else {
18129
- const playedEvents = new Queue();
18130
- while (!this._playedEventsQueue.isEmpty && this._playedEventsQueue.peek().time < currentTime) {
18131
- const synthEvent = this._playedEventsQueue.dequeue();
18132
- playedEvents.enqueue(synthEvent.event);
18061
+ static fromJson(v) {
18062
+ switch (typeof v) {
18063
+ case 'undefined':
18064
+ return null;
18065
+ case 'object': {
18066
+ const m = v;
18067
+ let family = m.get('family');
18068
+ // tslint:disable-next-line: no-unnecessary-type-assertion
18069
+ let size = m.get('size');
18070
+ let style = JsonHelper.parseEnum(m.get('style'), FontStyle);
18071
+ let weight = JsonHelper.parseEnum(m.get('weight'), FontWeight);
18072
+ return new Font(family, size, style, weight);
18133
18073
  }
18134
- if (!playedEvents.isEmpty) {
18135
- this.midiEventsPlayed.trigger(new MidiEventsPlayedEventArgs(playedEvents.toArray()));
18074
+ case 'string': {
18075
+ const parser = new FontParser(v);
18076
+ parser.parse();
18077
+ let family = parser.families[0];
18078
+ if ((family.startsWith("'") && family.endsWith("'")) ||
18079
+ (family.startsWith('"') && family.endsWith('"'))) {
18080
+ family = family.substr(1, family.length - 2);
18081
+ }
18082
+ let fontSizeString = parser.size.toLowerCase();
18083
+ let fontSize = 0;
18084
+ // as per https://websemantics.uk/articles/font-size-conversion/
18085
+ switch (fontSizeString) {
18086
+ case 'xx-small':
18087
+ fontSize = 7;
18088
+ break;
18089
+ case 'x-small':
18090
+ fontSize = 10;
18091
+ break;
18092
+ case 'small':
18093
+ case 'smaller':
18094
+ fontSize = 13;
18095
+ break;
18096
+ case 'medium':
18097
+ fontSize = 16;
18098
+ break;
18099
+ case 'large':
18100
+ case 'larger':
18101
+ fontSize = 18;
18102
+ break;
18103
+ case 'x-large':
18104
+ fontSize = 24;
18105
+ break;
18106
+ case 'xx-large':
18107
+ fontSize = 32;
18108
+ break;
18109
+ default:
18110
+ try {
18111
+ if (fontSizeString.endsWith('em')) {
18112
+ fontSize = parseFloat(fontSizeString.substr(0, fontSizeString.length - 2)) * 16;
18113
+ }
18114
+ else if (fontSizeString.endsWith('pt')) {
18115
+ fontSize =
18116
+ (parseFloat(fontSizeString.substr(0, fontSizeString.length - 2)) * 16.0) / 12.0;
18117
+ }
18118
+ else if (fontSizeString.endsWith('px')) {
18119
+ fontSize = parseFloat(fontSizeString.substr(0, fontSizeString.length - 2));
18120
+ }
18121
+ else {
18122
+ fontSize = 12;
18123
+ }
18124
+ }
18125
+ catch (e) {
18126
+ fontSize = 12;
18127
+ }
18128
+ break;
18129
+ }
18130
+ let fontStyle = FontStyle.Plain;
18131
+ if (parser.style === 'italic') {
18132
+ fontStyle = FontStyle.Italic;
18133
+ }
18134
+ let fontWeight = FontWeight.Regular;
18135
+ let fontWeightString = parser.weight.toLowerCase();
18136
+ switch (fontWeightString) {
18137
+ case 'normal':
18138
+ case 'lighter':
18139
+ break;
18140
+ default:
18141
+ fontWeight = FontWeight.Bold;
18142
+ break;
18143
+ }
18144
+ return new Font(family, fontSize, fontStyle, fontWeight);
18136
18145
  }
18146
+ default:
18147
+ return null;
18137
18148
  }
18138
18149
  }
18150
+ static toJson(font) {
18151
+ const o = new Map();
18152
+ o.set('family', font.family);
18153
+ o.set('size', font.size);
18154
+ o.set('style', font.style);
18155
+ o.set('weight', font.weight);
18156
+ return o;
18157
+ }
18139
18158
  }
18140
18159
 
18141
18160
  /**
18142
- * Represents a midi file with a single track that can be played via {@link AlphaSynth}
18161
+ * This public class contains central definitions for controlling the visual appearance.
18162
+ * @json
18143
18163
  */
18144
- class MidiFile {
18164
+ class RenderingResources {
18145
18165
  constructor() {
18146
18166
  /**
18147
- * Gets or sets the division per quarter notes.
18167
+ * Gets or sets the font to use for displaying the songs copyright information in the header of the music sheet.
18148
18168
  */
18149
- this.division = MidiUtils.QuarterTime;
18169
+ this.copyrightFont = new Font(RenderingResources.sansFont, 12, FontStyle.Plain, FontWeight.Bold);
18150
18170
  /**
18151
- * Gets a list of midi events sorted by time.
18171
+ * Gets or sets the font to use for displaying the songs title in the header of the music sheet.
18152
18172
  */
18153
- this.events = [];
18154
- }
18155
- /**
18156
- * Adds the given midi event a the correct time position into the file.
18157
- */
18158
- addEvent(e) {
18159
- if (this.events.length === 0) {
18160
- this.events.push(e);
18161
- }
18162
- else {
18163
- let insertPos = this.events.length;
18164
- while (insertPos > 0) {
18165
- const prevItem = this.events[insertPos - 1];
18166
- if (prevItem.tick > e.tick) {
18167
- insertPos--;
18168
- }
18169
- else {
18170
- break;
18171
- }
18172
- }
18173
- this.events.splice(insertPos, 0, e);
18174
- }
18175
- }
18176
- /**
18177
- * Writes the midi file into a binary format.
18178
- * @returns The binary midi file.
18179
- */
18180
- toBinary() {
18181
- let data = ByteBuffer.empty();
18182
- this.writeTo(data);
18183
- return data.toArray();
18184
- }
18185
- /**
18186
- * Writes the midi file as binary into the given stream.
18187
- * @returns The stream to write to.
18188
- */
18189
- writeTo(s) {
18190
- // magic number "MThd" (0x4D546864)
18191
- let b = new Uint8Array([0x4d, 0x54, 0x68, 0x64]);
18192
- s.write(b, 0, b.length);
18193
- // Header Length 6 (0x00000006)
18194
- b = new Uint8Array([0x00, 0x00, 0x00, 0x06]);
18195
- s.write(b, 0, b.length);
18196
- // format
18197
- b = new Uint8Array([0x00, 0x00]);
18198
- s.write(b, 0, b.length);
18199
- // number of tracks
18200
- let v = 1;
18201
- b = new Uint8Array([(v >> 8) & 0xff, v & 0xff]);
18202
- s.write(b, 0, b.length);
18203
- v = this.division;
18204
- b = new Uint8Array([(v >> 8) & 0xff, v & 0xff]);
18205
- s.write(b, 0, b.length);
18206
- // build track data first
18207
- let trackData = ByteBuffer.empty();
18208
- let previousTick = 0;
18209
- for (let midiEvent of this.events) {
18210
- let delta = midiEvent.tick - previousTick;
18211
- MidiFile.writeVariableInt(trackData, delta);
18212
- midiEvent.writeTo(trackData);
18213
- previousTick = midiEvent.tick;
18214
- }
18215
- // end of track
18216
- // magic number "MTrk" (0x4D54726B)
18217
- b = new Uint8Array([0x4d, 0x54, 0x72, 0x6b]);
18218
- s.write(b, 0, b.length);
18219
- // size as integer
18220
- let data = trackData.toArray();
18221
- let l = data.length;
18222
- b = new Uint8Array([(l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff]);
18223
- s.write(b, 0, b.length);
18224
- s.write(data, 0, data.length);
18225
- }
18226
- static writeVariableInt(s, value) {
18227
- let array = new Uint8Array(4);
18228
- let n = 0;
18229
- do {
18230
- array[n++] = value & 0x7f;
18231
- value >>= 7;
18232
- } while (value > 0);
18233
- while (n > 0) {
18234
- n--;
18235
- if (n > 0) {
18236
- s.writeByte(array[n] | 0x80);
18237
- }
18238
- else {
18239
- s.writeByte(array[n]);
18240
- }
18241
- }
18242
- }
18243
- }
18244
-
18245
- class MetaDataEvent extends MetaEvent {
18246
- constructor(track, delta, status, metaId, data) {
18247
- super(track, delta, status, metaId, 0);
18248
- this.data = data;
18249
- }
18250
- writeTo(s) {
18251
- s.writeByte(0xff);
18252
- s.writeByte(this.metaStatus);
18253
- let l = this.data.length;
18254
- MidiFile.writeVariableInt(s, l);
18255
- s.write(this.data, 0, this.data.length);
18173
+ this.titleFont = new Font(RenderingResources.serifFont, 32, FontStyle.Plain);
18174
+ /**
18175
+ * Gets or sets the font to use for displaying the songs subtitle in the header of the music sheet.
18176
+ */
18177
+ this.subTitleFont = new Font(RenderingResources.serifFont, 20, FontStyle.Plain);
18178
+ /**
18179
+ * Gets or sets the font to use for displaying the lyrics information in the header of the music sheet.
18180
+ */
18181
+ this.wordsFont = new Font(RenderingResources.serifFont, 15, FontStyle.Plain);
18182
+ /**
18183
+ * Gets or sets the font to use for displaying certain effect related elements in the music sheet.
18184
+ */
18185
+ this.effectFont = new Font(RenderingResources.serifFont, 12, FontStyle.Italic);
18186
+ /**
18187
+ * Gets or sets the font to use for displaying the fretboard numbers in chord diagrams.
18188
+ */
18189
+ this.fretboardNumberFont = new Font(RenderingResources.sansFont, 11, FontStyle.Plain);
18190
+ /**
18191
+ * Gets or sets the font to use for displaying the guitar tablature numbers in the music sheet.
18192
+ */
18193
+ this.tablatureFont = new Font(RenderingResources.sansFont, 13, FontStyle.Plain);
18194
+ /**
18195
+ * Gets or sets the font to use for grace notation related texts in the music sheet.
18196
+ */
18197
+ this.graceFont = new Font(RenderingResources.sansFont, 11, FontStyle.Plain);
18198
+ /**
18199
+ * Gets or sets the color to use for rendering the lines of staves.
18200
+ */
18201
+ this.staffLineColor = new Color(165, 165, 165, 0xff);
18202
+ /**
18203
+ * Gets or sets the color to use for rendering bar separators, the accolade and repeat signs.
18204
+ */
18205
+ this.barSeparatorColor = new Color(34, 34, 17, 0xff);
18206
+ /**
18207
+ * Gets or sets the font to use for displaying the bar numbers above the music sheet.
18208
+ */
18209
+ this.barNumberFont = new Font(RenderingResources.sansFont, 11, FontStyle.Plain);
18210
+ /**
18211
+ * Gets or sets the color to use for displaying the bar numbers above the music sheet.
18212
+ */
18213
+ this.barNumberColor = new Color(200, 0, 0, 0xff);
18214
+ /**
18215
+ * Gets or sets the font to use for displaying finger information in the music sheet.
18216
+ */
18217
+ this.fingeringFont = new Font(RenderingResources.serifFont, 14, FontStyle.Plain);
18218
+ /**
18219
+ * Gets or sets the font to use for section marker labels shown above the music sheet.
18220
+ */
18221
+ this.markerFont = new Font(RenderingResources.serifFont, 14, FontStyle.Plain, FontWeight.Bold);
18222
+ /**
18223
+ * Gets or sets the color to use for music notation elements of the primary voice.
18224
+ */
18225
+ this.mainGlyphColor = new Color(0, 0, 0, 0xff);
18226
+ /**
18227
+ * Gets or sets the color to use for music notation elements of the secondary voices.
18228
+ */
18229
+ this.secondaryGlyphColor = new Color(0, 0, 0, 100);
18230
+ /**
18231
+ * Gets or sets the color to use for displaying the song information above the music sheet.
18232
+ */
18233
+ this.scoreInfoColor = new Color(0, 0, 0, 0xff);
18256
18234
  }
18257
- }
18235
+ }
18236
+ RenderingResources.sansFont = 'Arial';
18237
+ RenderingResources.serifFont = 'Georgia';
18258
18238
 
18259
- class MetaNumberEvent extends MetaEvent {
18260
- constructor(track, delta, status, metaId, value) {
18261
- super(track, delta, status, metaId, 0);
18262
- this.value = value;
18263
- }
18264
- writeTo(s) {
18265
- s.writeByte(0xff);
18266
- s.writeByte(this.metaStatus);
18267
- MidiFile.writeVariableInt(s, 3);
18268
- let b = new Uint8Array([(this.value >> 16) & 0xff, (this.value >> 8) & 0xff, this.value & 0xff]);
18269
- s.write(b, 0, b.length);
18239
+ /**
18240
+ * The display settings control how the general layout and display of alphaTab is done.
18241
+ * @json
18242
+ */
18243
+ class DisplaySettings {
18244
+ constructor() {
18245
+ /**
18246
+ * Sets the zoom level of the rendered notation
18247
+ */
18248
+ this.scale = 1.0;
18249
+ /**
18250
+ * The default stretch force to use for layouting.
18251
+ */
18252
+ this.stretchForce = 1.0;
18253
+ /**
18254
+ * The layouting mode used to arrange the the notation.
18255
+ */
18256
+ this.layoutMode = LayoutMode.Page;
18257
+ /**
18258
+ * The stave profile to use.
18259
+ */
18260
+ this.staveProfile = StaveProfile.Default;
18261
+ /**
18262
+ * Limit the displayed bars per row.
18263
+ */
18264
+ this.barsPerRow = -1;
18265
+ /**
18266
+ * The bar start number to start layouting with. Note that this is the bar number and not an index!
18267
+ */
18268
+ this.startBar = 1;
18269
+ /**
18270
+ * The amount of bars to render overall.
18271
+ */
18272
+ this.barCount = -1;
18273
+ /**
18274
+ * The number of bars that should be rendered per partial. This setting is not used by all layouts.
18275
+ */
18276
+ this.barCountPerPartial = 10;
18277
+ /**
18278
+ * Gets or sets the resources used during rendering. This defines all fonts and colors used.
18279
+ * @json_partial_names
18280
+ */
18281
+ this.resources = new RenderingResources();
18282
+ /**
18283
+ * Gets or sets the padding between the music notation and the border.
18284
+ */
18285
+ this.padding = null;
18270
18286
  }
18271
18287
  }
18272
18288
 
@@ -21393,7 +21409,7 @@ class ScoreRenderer {
21393
21409
  }
21394
21410
  recreateCanvas() {
21395
21411
  if (this._currentRenderEngine !== this.settings.core.engine) {
21396
- this.canvas = Environment.getRenderEngineFactory(this.settings).createCanvas();
21412
+ this.canvas = Environment.getRenderEngineFactory(this.settings.core.engine).createCanvas();
21397
21413
  this._currentRenderEngine = this.settings.core.engine;
21398
21414
  return true;
21399
21415
  }
@@ -21401,7 +21417,7 @@ class ScoreRenderer {
21401
21417
  }
21402
21418
  recreateLayout() {
21403
21419
  if (!this.layout || this._currentLayoutMode !== this.settings.display.layoutMode) {
21404
- this.layout = Environment.getLayoutEngineFactory(this.settings).createLayout(this);
21420
+ this.layout = Environment.getLayoutEngineFactory(this.settings.display.layoutMode).createLayout(this);
21405
21421
  this._currentLayoutMode = this.settings.display.layoutMode;
21406
21422
  return true;
21407
21423
  }
@@ -23898,7 +23914,7 @@ class AlphaTabApiBase {
23898
23914
  this.container.appendChild(this.canvasElement);
23899
23915
  if (this.settings.core.useWorkers &&
23900
23916
  this.uiFacade.areWorkersSupported &&
23901
- Environment.getRenderEngineFactory(this.settings).supportsWorkers) {
23917
+ Environment.getRenderEngineFactory(this.settings.core.engine).supportsWorkers) {
23902
23918
  this.renderer = this.uiFacade.createWorkerRenderer();
23903
23919
  }
23904
23920
  else {
@@ -24585,7 +24601,7 @@ class AlphaTabApiBase {
24585
24601
  }
24586
24602
  if (!this._beatMouseDown && this.settings.player.scrollMode !== ScrollMode.Off) {
24587
24603
  let scrollElement = this.uiFacade.getScrollContainer();
24588
- let isVertical = Environment.getLayoutEngineFactory(this.settings).vertical;
24604
+ let isVertical = Environment.getLayoutEngineFactory(this.settings.display.layoutMode).vertical;
24589
24605
  let mode = this.settings.player.scrollMode;
24590
24606
  if (isVertical) {
24591
24607
  // when scrolling on the y-axis, we preliminary check if the new beat/bar have
@@ -25539,6 +25555,21 @@ class AlphaSynthScriptProcessorOutput extends AlphaSynthWebAudioOutputBase {
25539
25555
  }
25540
25556
  }
25541
25557
 
25558
+ /**
25559
+ * Represents the progress of any data being loaded.
25560
+ */
25561
+ class ProgressEventArgs {
25562
+ /**
25563
+ * Initializes a new instance of the {@link ProgressEventArgs} class.
25564
+ * @param loaded
25565
+ * @param total
25566
+ */
25567
+ constructor(loaded, total) {
25568
+ this.loaded = loaded;
25569
+ this.total = total;
25570
+ }
25571
+ }
25572
+
25542
25573
  /**
25543
25574
  * a WebWorker based alphaSynth which uses the given player as output.
25544
25575
  * @target web
@@ -39854,20 +39885,17 @@ class Environment {
39854
39885
  jquery.fn.alphaTab.fn = api;
39855
39886
  }
39856
39887
  }
39857
- static createScoreRenderer(settings) {
39858
- return new ScoreRenderer(settings);
39859
- }
39860
- static getRenderEngineFactory(settings) {
39861
- if (!settings.core.engine || !Environment.renderEngines.has(settings.core.engine)) {
39888
+ static getRenderEngineFactory(engine) {
39889
+ if (!engine || !Environment.renderEngines.has(engine)) {
39862
39890
  return Environment.renderEngines.get('default');
39863
39891
  }
39864
- return Environment.renderEngines.get(settings.core.engine);
39892
+ return Environment.renderEngines.get(engine);
39865
39893
  }
39866
- static getLayoutEngineFactory(settings) {
39867
- if (!settings.display.layoutMode || !Environment.layoutEngines.has(settings.display.layoutMode)) {
39894
+ static getLayoutEngineFactory(layoutMode) {
39895
+ if (!layoutMode || !Environment.layoutEngines.has(layoutMode)) {
39868
39896
  return Environment.layoutEngines.get(LayoutMode.Page);
39869
39897
  }
39870
- return Environment.layoutEngines.get(settings.display.layoutMode);
39898
+ return Environment.layoutEngines.get(layoutMode);
39871
39899
  }
39872
39900
  /**
39873
39901
  * Gets all default ScoreImporters
@@ -40251,21 +40279,6 @@ class CoreSettings {
40251
40279
  }
40252
40280
  }
40253
40281
 
40254
- /**
40255
- * Represents the progress of any data being loaded.
40256
- */
40257
- class ProgressEventArgs {
40258
- /**
40259
- * Initializes a new instance of the {@link ProgressEventArgs} class.
40260
- * @param loaded
40261
- * @param total
40262
- */
40263
- constructor(loaded, total) {
40264
- this.loaded = loaded;
40265
- this.total = total;
40266
- }
40267
- }
40268
-
40269
40282
  // <auto-generated>
40270
40283
  // This code was auto-generated.
40271
40284
  // Changes to this file may cause incorrect behavior and will be lost if
@@ -40273,8 +40286,15 @@ class ProgressEventArgs {
40273
40286
  // </auto-generated>
40274
40287
  class VersionInfo {
40275
40288
  }
40276
- VersionInfo.version = '1.3.0-alpha.133';
40277
- VersionInfo.date = '2021-11-07T12:07:10.004Z';
40289
+ VersionInfo.version = '1.3.0-alpha.137';
40290
+ VersionInfo.date = '2021-11-28T18:13:01.688Z';
40291
+
40292
+ var index$5 = /*#__PURE__*/Object.freeze({
40293
+ __proto__: null,
40294
+ ScoreImporter: ScoreImporter,
40295
+ ScoreLoader: ScoreLoader,
40296
+ UnsupportedFormatError: UnsupportedFormatError
40297
+ });
40278
40298
 
40279
40299
  /**
40280
40300
  * This is the base class for creating new song exporters which
@@ -43228,106 +43248,109 @@ class Gp7Exporter extends ScoreExporter {
43228
43248
  }
43229
43249
  }
43230
43250
 
43231
- const meta = VersionInfo;
43232
- const importer = {
43233
- ScoreImporter,
43234
- ScoreLoader,
43235
- UnsupportedFormatError
43236
- };
43237
- const exporter = {
43238
- ScoreExporter,
43239
- Gp7Exporter
43240
- };
43241
- const midi = {
43242
- BeatTickLookup,
43243
- MasterBarTickLookup,
43244
- MidiTickLookup,
43245
- MidiTickLookupFindBeatResult,
43246
- MidiFile,
43247
- ControllerType,
43248
- MetaDataEvent,
43249
- MetaEvent,
43250
- MetaEventType,
43251
- MetaNumberEvent,
43252
- MidiEvent,
43253
- MidiEventType,
43254
- Midi20PerNotePitchBendEvent,
43255
- SystemCommonEvent,
43256
- SystemCommonType,
43257
- SystemExclusiveEvent,
43258
- MidiFileGenerator,
43259
- AlphaSynthMidiFileHandler
43260
- };
43261
- const model = {
43262
- AccentuationType,
43263
- AccidentalType,
43264
- AutomationType,
43265
- Automation,
43266
- Bar,
43267
- Beat,
43268
- BendPoint,
43269
- BendStyle,
43270
- BendType,
43271
- BrushType,
43272
- Chord,
43273
- Clef,
43274
- Color,
43275
- CrescendoType,
43276
- Duration,
43277
- DynamicValue,
43278
- FermataType,
43279
- Fermata,
43280
- Fingers,
43281
- FontStyle,
43282
- Font,
43283
- GraceType,
43284
- HarmonicType,
43285
- InstrumentArticulation,
43286
- JsonConverter,
43287
- KeySignature,
43288
- KeySignatureType,
43289
- Lyrics,
43290
- MasterBar,
43291
- MusicFontSymbol,
43292
- Note,
43293
- NoteAccidentalMode,
43294
- Ottavia,
43295
- PickStroke,
43296
- PlaybackInformation,
43297
- RenderStylesheet,
43298
- RepeatGroup,
43299
- Score,
43300
- Section,
43301
- SimileMark,
43302
- SlideInType,
43303
- SlideOutType,
43304
- Staff,
43305
- Track,
43306
- TripletFeel,
43307
- Tuning,
43308
- TupletGroup,
43309
- VibratoType,
43310
- Voice: Voice$1,
43311
- WhammyType
43312
- };
43313
- const rendering = {
43314
- ScoreRenderer,
43315
- RenderFinishedEventArgs,
43316
- BarBounds,
43317
- BeatBounds,
43318
- Bounds,
43319
- BoundsLookup,
43320
- MasterBarBounds,
43321
- NoteBounds,
43322
- StaveGroupBounds
43323
- };
43324
- const synth = {
43325
- AlphaSynth,
43326
- PlaybackRange,
43327
- PlayerState,
43328
- PlayerStateChangedEventArgs,
43329
- PositionChangedEventArgs,
43330
- AlphaSynthWebWorkerApi
43331
- };
43332
-
43333
- export { AlphaTabApi, AlphaTabError, AlphaTabErrorType, CoreSettings, DisplaySettings, FileLoadError, FingeringMode, FormatError, ImporterSettings, LayoutMode, LogLevel, Logger, NotationMode, NotationSettings, PlayerSettings, ProgressEventArgs, RenderingResources, ResizeEventArgs, ScrollMode, Settings, StaveProfile, TabRhythmMode, VibratoPlaybackSettings, exporter, importer, meta, midi, model, rendering, synth };
43251
+ var index$4 = /*#__PURE__*/Object.freeze({
43252
+ __proto__: null,
43253
+ ScoreExporter: ScoreExporter,
43254
+ Gp7Exporter: Gp7Exporter
43255
+ });
43256
+
43257
+ var index$3 = /*#__PURE__*/Object.freeze({
43258
+ __proto__: null,
43259
+ BeatTickLookup: BeatTickLookup,
43260
+ MasterBarTickLookup: MasterBarTickLookup,
43261
+ MidiTickLookup: MidiTickLookup,
43262
+ MidiTickLookupFindBeatResult: MidiTickLookupFindBeatResult,
43263
+ MidiFile: MidiFile,
43264
+ get ControllerType () { return ControllerType; },
43265
+ MetaDataEvent: MetaDataEvent,
43266
+ MetaEvent: MetaEvent,
43267
+ get MetaEventType () { return MetaEventType; },
43268
+ MetaNumberEvent: MetaNumberEvent,
43269
+ MidiEvent: MidiEvent,
43270
+ get MidiEventType () { return MidiEventType; },
43271
+ Midi20PerNotePitchBendEvent: Midi20PerNotePitchBendEvent,
43272
+ SystemCommonEvent: SystemCommonEvent,
43273
+ get SystemCommonType () { return SystemCommonType; },
43274
+ SystemExclusiveEvent: SystemExclusiveEvent,
43275
+ MidiFileGenerator: MidiFileGenerator,
43276
+ AlphaSynthMidiFileHandler: AlphaSynthMidiFileHandler
43277
+ });
43278
+
43279
+ var index$2 = /*#__PURE__*/Object.freeze({
43280
+ __proto__: null,
43281
+ get AccentuationType () { return AccentuationType; },
43282
+ get AccidentalType () { return AccidentalType; },
43283
+ get AutomationType () { return AutomationType; },
43284
+ Automation: Automation,
43285
+ Bar: Bar,
43286
+ Beat: Beat,
43287
+ BendPoint: BendPoint,
43288
+ get BendStyle () { return BendStyle; },
43289
+ get BendType () { return BendType; },
43290
+ get BrushType () { return BrushType; },
43291
+ Chord: Chord,
43292
+ get Clef () { return Clef; },
43293
+ Color: Color,
43294
+ get CrescendoType () { return CrescendoType; },
43295
+ get Duration () { return Duration; },
43296
+ get DynamicValue () { return DynamicValue; },
43297
+ get FermataType () { return FermataType; },
43298
+ Fermata: Fermata,
43299
+ get Fingers () { return Fingers; },
43300
+ get FontStyle () { return FontStyle; },
43301
+ Font: Font,
43302
+ get GraceType () { return GraceType; },
43303
+ get HarmonicType () { return HarmonicType; },
43304
+ InstrumentArticulation: InstrumentArticulation,
43305
+ JsonConverter: JsonConverter,
43306
+ get KeySignature () { return KeySignature; },
43307
+ get KeySignatureType () { return KeySignatureType; },
43308
+ Lyrics: Lyrics,
43309
+ MasterBar: MasterBar,
43310
+ get MusicFontSymbol () { return MusicFontSymbol; },
43311
+ Note: Note,
43312
+ get NoteAccidentalMode () { return NoteAccidentalMode; },
43313
+ get Ottavia () { return Ottavia; },
43314
+ get PickStroke () { return PickStroke; },
43315
+ PlaybackInformation: PlaybackInformation,
43316
+ RenderStylesheet: RenderStylesheet,
43317
+ RepeatGroup: RepeatGroup,
43318
+ Score: Score,
43319
+ Section: Section,
43320
+ get SimileMark () { return SimileMark; },
43321
+ get SlideInType () { return SlideInType; },
43322
+ get SlideOutType () { return SlideOutType; },
43323
+ Staff: Staff,
43324
+ Track: Track,
43325
+ get TripletFeel () { return TripletFeel; },
43326
+ Tuning: Tuning,
43327
+ TupletGroup: TupletGroup,
43328
+ get VibratoType () { return VibratoType; },
43329
+ Voice: Voice$1,
43330
+ get WhammyType () { return WhammyType; }
43331
+ });
43332
+
43333
+ var index$1 = /*#__PURE__*/Object.freeze({
43334
+ __proto__: null,
43335
+ RenderFinishedEventArgs: RenderFinishedEventArgs,
43336
+ ScoreRenderer: ScoreRenderer,
43337
+ BarBounds: BarBounds,
43338
+ BeatBounds: BeatBounds,
43339
+ Bounds: Bounds,
43340
+ BoundsLookup: BoundsLookup,
43341
+ MasterBarBounds: MasterBarBounds,
43342
+ NoteBounds: NoteBounds,
43343
+ StaveGroupBounds: StaveGroupBounds
43344
+ });
43345
+
43346
+ var index = /*#__PURE__*/Object.freeze({
43347
+ __proto__: null,
43348
+ AlphaSynth: AlphaSynth,
43349
+ PlaybackRange: PlaybackRange,
43350
+ get PlayerState () { return PlayerState; },
43351
+ PlayerStateChangedEventArgs: PlayerStateChangedEventArgs,
43352
+ PositionChangedEventArgs: PositionChangedEventArgs,
43353
+ AlphaSynthWebWorkerApi: AlphaSynthWebWorkerApi
43354
+ });
43355
+
43356
+ 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 };