@coderline/alphatab 1.6.0-alpha.1448 → 1.6.0-alpha.1450
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/alphaTab.core.min.mjs +2 -2
- package/dist/alphaTab.core.mjs +75 -13
- package/dist/alphaTab.d.ts +8 -1
- package/dist/alphaTab.js +75 -13
- package/dist/alphaTab.min.js +2 -2
- package/dist/alphaTab.min.mjs +1 -1
- package/dist/alphaTab.mjs +1 -1
- package/dist/alphaTab.vite.js +1 -1
- package/dist/alphaTab.vite.mjs +1 -1
- package/dist/alphaTab.webpack.js +1 -1
- package/dist/alphaTab.webpack.mjs +1 -1
- package/dist/alphaTab.worker.min.mjs +1 -1
- package/dist/alphaTab.worker.mjs +1 -1
- package/dist/alphaTab.worklet.min.mjs +1 -1
- package/dist/alphaTab.worklet.mjs +1 -1
- package/package.json +1 -1
package/dist/alphaTab.core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* alphaTab v1.6.0-alpha.
|
|
2
|
+
* alphaTab v1.6.0-alpha.1450 (develop, build 1450)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -22887,6 +22887,9 @@ class MidiFileSequencer {
|
|
|
22887
22887
|
if (tempoChangeIndex !== state.tempoChangeIndex) {
|
|
22888
22888
|
state.tempoChangeIndex = tempoChangeIndex;
|
|
22889
22889
|
state.currentTempo = state.tempoChanges[state.tempoChangeIndex].bpm;
|
|
22890
|
+
if (state.syncPoints.length === 0) {
|
|
22891
|
+
state.syncPointTempo = state.currentTempo;
|
|
22892
|
+
}
|
|
22890
22893
|
}
|
|
22891
22894
|
}
|
|
22892
22895
|
currentUpdateSyncPoints(timePosition) {
|
|
@@ -36331,6 +36334,7 @@ class PlayThroughContext {
|
|
|
36331
36334
|
this.synthTime = 0;
|
|
36332
36335
|
this.currentTempo = 0;
|
|
36333
36336
|
this.automationToSyncPoint = new Map();
|
|
36337
|
+
this.createNewSyncPoints = false;
|
|
36334
36338
|
}
|
|
36335
36339
|
}
|
|
36336
36340
|
/**
|
|
@@ -36383,7 +36387,7 @@ class MidiFileGenerator {
|
|
|
36383
36387
|
}
|
|
36384
36388
|
Logger.debug('Midi', 'Begin midi generation');
|
|
36385
36389
|
this.syncPoints = [];
|
|
36386
|
-
MidiFileGenerator.playThroughSong(this._score, this.syncPoints, (bar, previousMasterBar, currentTick, currentTempo, occurence) => {
|
|
36390
|
+
MidiFileGenerator.playThroughSong(this._score, this.syncPoints, false, (bar, previousMasterBar, currentTick, currentTempo, occurence) => {
|
|
36387
36391
|
this.generateMasterBar(bar, previousMasterBar, currentTick, currentTempo, occurence);
|
|
36388
36392
|
}, (index, currentTick, currentTempo) => {
|
|
36389
36393
|
for (const track of this._score.tracks) {
|
|
@@ -36449,11 +36453,12 @@ class MidiFileGenerator {
|
|
|
36449
36453
|
* It correctly handles repeats and places sync points accoridng to their absolute midi tick when they
|
|
36450
36454
|
* need to be considered for synchronization.
|
|
36451
36455
|
* @param score The song for which to regenerate the sync points.
|
|
36456
|
+
* @param createNew Whether a new set of sync points should be generated for the sync (start, stop and tempo changes).
|
|
36452
36457
|
* @returns The generated sync points for usage in the backing track playback.
|
|
36453
36458
|
*/
|
|
36454
|
-
static generateSyncPoints(score) {
|
|
36459
|
+
static generateSyncPoints(score, createNew = false) {
|
|
36455
36460
|
const syncPoints = [];
|
|
36456
|
-
MidiFileGenerator.playThroughSong(score, syncPoints, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36461
|
+
MidiFileGenerator.playThroughSong(score, syncPoints, createNew, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36457
36462
|
}, (_barIndex, _currentTick, _currentTempo) => {
|
|
36458
36463
|
}, _endTick => {
|
|
36459
36464
|
});
|
|
@@ -36464,17 +36469,18 @@ class MidiFileGenerator {
|
|
|
36464
36469
|
*/
|
|
36465
36470
|
static buildModifiedTempoLookup(score) {
|
|
36466
36471
|
const syncPoints = [];
|
|
36467
|
-
const context = MidiFileGenerator.playThroughSong(score, syncPoints, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36472
|
+
const context = MidiFileGenerator.playThroughSong(score, syncPoints, false, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36468
36473
|
}, (_barIndex, _currentTick, _currentTempo) => {
|
|
36469
36474
|
}, _endTick => {
|
|
36470
36475
|
});
|
|
36471
36476
|
return context.automationToSyncPoint;
|
|
36472
36477
|
}
|
|
36473
|
-
static playThroughSong(score, syncPoints, generateMasterBar, generateTracks, finish) {
|
|
36478
|
+
static playThroughSong(score, syncPoints, createNewSyncPoints, generateMasterBar, generateTracks, finish) {
|
|
36474
36479
|
const controller = new MidiPlaybackController(score);
|
|
36475
36480
|
const playContext = new PlayThroughContext();
|
|
36476
36481
|
playContext.currentTempo = score.tempo;
|
|
36477
36482
|
playContext.syncPoints = syncPoints;
|
|
36483
|
+
playContext.createNewSyncPoints = createNewSyncPoints;
|
|
36478
36484
|
let previousMasterBar = null;
|
|
36479
36485
|
// store the previous played bar for repeats
|
|
36480
36486
|
const barOccurence = new Map();
|
|
@@ -36512,14 +36518,24 @@ class MidiFileGenerator {
|
|
|
36512
36518
|
// we need to assume some BPM for the last interpolated point.
|
|
36513
36519
|
// if we have more than just a start point, we keep the BPM before the last manual sync point
|
|
36514
36520
|
// otherwise we have no customized sync BPM known and keep the synthesizer one.
|
|
36515
|
-
|
|
36516
|
-
|
|
36521
|
+
if (playContext.createNewSyncPoints) {
|
|
36522
|
+
backingTrackSyncPoint.syncBpm = lastSyncPoint.synthBpm;
|
|
36523
|
+
backingTrackSyncPoint.synthBpm = lastSyncPoint.synthBpm;
|
|
36524
|
+
}
|
|
36525
|
+
else if (syncPoints.length === 1) {
|
|
36526
|
+
backingTrackSyncPoint.syncBpm = lastSyncPoint.synthBpm;
|
|
36527
|
+
}
|
|
36528
|
+
else {
|
|
36529
|
+
backingTrackSyncPoint.syncBpm = syncPoints[syncPoints.length - 2].syncBpm;
|
|
36530
|
+
}
|
|
36517
36531
|
backingTrackSyncPoint.synthTime =
|
|
36518
36532
|
lastSyncPoint.synthTime + MidiUtils.ticksToMillis(remainingTicks, lastSyncPoint.synthBpm);
|
|
36519
36533
|
backingTrackSyncPoint.syncTime =
|
|
36520
36534
|
lastSyncPoint.syncTime + MidiUtils.ticksToMillis(remainingTicks, backingTrackSyncPoint.syncBpm);
|
|
36521
36535
|
// update the previous sync point according to the new time
|
|
36522
|
-
|
|
36536
|
+
if (!playContext.createNewSyncPoints) {
|
|
36537
|
+
lastSyncPoint.updateSyncBpm(backingTrackSyncPoint.synthTime, backingTrackSyncPoint.syncTime);
|
|
36538
|
+
}
|
|
36523
36539
|
syncPoints.push(backingTrackSyncPoint);
|
|
36524
36540
|
}
|
|
36525
36541
|
}
|
|
@@ -36530,7 +36546,10 @@ class MidiFileGenerator {
|
|
|
36530
36546
|
const duration = bar.calculateDuration();
|
|
36531
36547
|
const barSyncPoints = bar.syncPoints;
|
|
36532
36548
|
const barStartTick = context.synthTick;
|
|
36533
|
-
if (
|
|
36549
|
+
if (context.createNewSyncPoints) {
|
|
36550
|
+
MidiFileGenerator.processBarTimeWithNewSyncPoints(bar, occurence, context);
|
|
36551
|
+
}
|
|
36552
|
+
else if (barSyncPoints) {
|
|
36534
36553
|
MidiFileGenerator.processBarTimeWithSyncPoints(bar, occurence, context);
|
|
36535
36554
|
}
|
|
36536
36555
|
else {
|
|
@@ -36544,6 +36563,44 @@ class MidiFileGenerator {
|
|
|
36544
36563
|
context.synthTick = endTick;
|
|
36545
36564
|
}
|
|
36546
36565
|
}
|
|
36566
|
+
static processBarTimeWithNewSyncPoints(bar, occurence, context) {
|
|
36567
|
+
// start marker
|
|
36568
|
+
const barStartTick = context.synthTick;
|
|
36569
|
+
if (bar.index === 0 && occurence === 0) {
|
|
36570
|
+
context.currentTempo = bar.score.tempo;
|
|
36571
|
+
const backingTrackSyncPoint = new BackingTrackSyncPoint();
|
|
36572
|
+
backingTrackSyncPoint.masterBarIndex = bar.index;
|
|
36573
|
+
backingTrackSyncPoint.masterBarOccurence = occurence;
|
|
36574
|
+
backingTrackSyncPoint.synthTick = barStartTick;
|
|
36575
|
+
backingTrackSyncPoint.synthBpm = context.currentTempo;
|
|
36576
|
+
backingTrackSyncPoint.synthTime = context.synthTime;
|
|
36577
|
+
backingTrackSyncPoint.syncBpm = context.currentTempo;
|
|
36578
|
+
backingTrackSyncPoint.syncTime = context.synthTime;
|
|
36579
|
+
context.syncPoints.push(backingTrackSyncPoint);
|
|
36580
|
+
}
|
|
36581
|
+
// walk tempo changes and create points
|
|
36582
|
+
const duration = bar.calculateDuration();
|
|
36583
|
+
for (const change of bar.tempoAutomations) {
|
|
36584
|
+
const absoluteTick = barStartTick + change.ratioPosition * duration;
|
|
36585
|
+
const tickOffset = absoluteTick - context.synthTick;
|
|
36586
|
+
if (tickOffset > 0) {
|
|
36587
|
+
context.synthTick = absoluteTick;
|
|
36588
|
+
context.synthTime += MidiUtils.ticksToMillis(tickOffset, context.currentTempo);
|
|
36589
|
+
}
|
|
36590
|
+
if (change.value !== context.currentTempo) {
|
|
36591
|
+
context.currentTempo = change.value;
|
|
36592
|
+
const backingTrackSyncPoint = new BackingTrackSyncPoint();
|
|
36593
|
+
backingTrackSyncPoint.masterBarIndex = bar.index;
|
|
36594
|
+
backingTrackSyncPoint.masterBarOccurence = occurence;
|
|
36595
|
+
backingTrackSyncPoint.synthTick = absoluteTick;
|
|
36596
|
+
backingTrackSyncPoint.synthBpm = context.currentTempo;
|
|
36597
|
+
backingTrackSyncPoint.synthTime = context.synthTime;
|
|
36598
|
+
backingTrackSyncPoint.syncBpm = context.currentTempo;
|
|
36599
|
+
backingTrackSyncPoint.syncTime = context.synthTime;
|
|
36600
|
+
context.syncPoints.push(backingTrackSyncPoint);
|
|
36601
|
+
}
|
|
36602
|
+
}
|
|
36603
|
+
}
|
|
36547
36604
|
static processBarTimeWithSyncPoints(bar, occurence, context) {
|
|
36548
36605
|
const barStartTick = context.synthTick;
|
|
36549
36606
|
const duration = bar.calculateDuration();
|
|
@@ -42881,7 +42938,12 @@ class AlphaTabApiBase {
|
|
|
42881
42938
|
* @remarks
|
|
42882
42939
|
* This will not export or use any backing track media but will always use the synthesizer to generate the output.
|
|
42883
42940
|
* This method works with any PlayerMode active but changing the mode during export can lead to unexpected side effects.
|
|
42941
|
+
*
|
|
42942
|
+
* See [Audio Export](https://www.alphatab.net/docs/guides/audio-export) for further guidance how to use this feature.
|
|
42943
|
+
*
|
|
42884
42944
|
* @param options The export options.
|
|
42945
|
+
* @category Methods - Player
|
|
42946
|
+
* @since 1.6.0
|
|
42885
42947
|
* @returns An exporter instance to export the audio in a streaming fashion.
|
|
42886
42948
|
*/
|
|
42887
42949
|
async exportAudio(options) {
|
|
@@ -61727,9 +61789,9 @@ class VersionInfo {
|
|
|
61727
61789
|
print(`build date: ${VersionInfo.date}`);
|
|
61728
61790
|
}
|
|
61729
61791
|
}
|
|
61730
|
-
VersionInfo.version = '1.6.0-alpha.
|
|
61731
|
-
VersionInfo.date = '2025-06-
|
|
61732
|
-
VersionInfo.commit = '
|
|
61792
|
+
VersionInfo.version = '1.6.0-alpha.1450';
|
|
61793
|
+
VersionInfo.date = '2025-06-15T01:20:26.410Z';
|
|
61794
|
+
VersionInfo.commit = 'a7639d9604a6fcdedff2883864b1008daae5cc64';
|
|
61733
61795
|
|
|
61734
61796
|
/**
|
|
61735
61797
|
* A factory for custom layout engines.
|
package/dist/alphaTab.d.ts
CHANGED
|
@@ -2965,7 +2965,12 @@ export declare class AlphaTabApiBase<TSettings> {
|
|
|
2965
2965
|
* @remarks
|
|
2966
2966
|
* This will not export or use any backing track media but will always use the synthesizer to generate the output.
|
|
2967
2967
|
* This method works with any PlayerMode active but changing the mode during export can lead to unexpected side effects.
|
|
2968
|
+
*
|
|
2969
|
+
* See [Audio Export](https://www.alphatab.net/docs/guides/audio-export) for further guidance how to use this feature.
|
|
2970
|
+
*
|
|
2968
2971
|
* @param options The export options.
|
|
2972
|
+
* @category Methods - Player
|
|
2973
|
+
* @since 1.6.0
|
|
2969
2974
|
* @returns An exporter instance to export the audio in a streaming fashion.
|
|
2970
2975
|
*/
|
|
2971
2976
|
exportAudio(options: AudioExportOptions): Promise<IAudioExporter>;
|
|
@@ -9628,12 +9633,14 @@ declare class MidiFileGenerator {
|
|
|
9628
9633
|
* It correctly handles repeats and places sync points accoridng to their absolute midi tick when they
|
|
9629
9634
|
* need to be considered for synchronization.
|
|
9630
9635
|
* @param score The song for which to regenerate the sync points.
|
|
9636
|
+
* @param createNew Whether a new set of sync points should be generated for the sync (start, stop and tempo changes).
|
|
9631
9637
|
* @returns The generated sync points for usage in the backing track playback.
|
|
9632
9638
|
*/
|
|
9633
|
-
static generateSyncPoints(score: Score): BackingTrackSyncPoint[];
|
|
9639
|
+
static generateSyncPoints(score: Score, createNew?: boolean): BackingTrackSyncPoint[];
|
|
9634
9640
|
/* Excluded from this release type: buildModifiedTempoLookup */
|
|
9635
9641
|
private static playThroughSong;
|
|
9636
9642
|
private static processBarTime;
|
|
9643
|
+
private static processBarTimeWithNewSyncPoints;
|
|
9637
9644
|
private static processBarTimeWithSyncPoints;
|
|
9638
9645
|
private static processBarTimeNoSyncPoints;
|
|
9639
9646
|
private static toChannelShort;
|
package/dist/alphaTab.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* alphaTab v1.6.0-alpha.
|
|
2
|
+
* alphaTab v1.6.0-alpha.1450 (develop, build 1450)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -22893,6 +22893,9 @@
|
|
|
22893
22893
|
if (tempoChangeIndex !== state.tempoChangeIndex) {
|
|
22894
22894
|
state.tempoChangeIndex = tempoChangeIndex;
|
|
22895
22895
|
state.currentTempo = state.tempoChanges[state.tempoChangeIndex].bpm;
|
|
22896
|
+
if (state.syncPoints.length === 0) {
|
|
22897
|
+
state.syncPointTempo = state.currentTempo;
|
|
22898
|
+
}
|
|
22896
22899
|
}
|
|
22897
22900
|
}
|
|
22898
22901
|
currentUpdateSyncPoints(timePosition) {
|
|
@@ -36337,6 +36340,7 @@
|
|
|
36337
36340
|
this.synthTime = 0;
|
|
36338
36341
|
this.currentTempo = 0;
|
|
36339
36342
|
this.automationToSyncPoint = new Map();
|
|
36343
|
+
this.createNewSyncPoints = false;
|
|
36340
36344
|
}
|
|
36341
36345
|
}
|
|
36342
36346
|
/**
|
|
@@ -36389,7 +36393,7 @@
|
|
|
36389
36393
|
}
|
|
36390
36394
|
Logger.debug('Midi', 'Begin midi generation');
|
|
36391
36395
|
this.syncPoints = [];
|
|
36392
|
-
MidiFileGenerator.playThroughSong(this._score, this.syncPoints, (bar, previousMasterBar, currentTick, currentTempo, occurence) => {
|
|
36396
|
+
MidiFileGenerator.playThroughSong(this._score, this.syncPoints, false, (bar, previousMasterBar, currentTick, currentTempo, occurence) => {
|
|
36393
36397
|
this.generateMasterBar(bar, previousMasterBar, currentTick, currentTempo, occurence);
|
|
36394
36398
|
}, (index, currentTick, currentTempo) => {
|
|
36395
36399
|
for (const track of this._score.tracks) {
|
|
@@ -36455,11 +36459,12 @@
|
|
|
36455
36459
|
* It correctly handles repeats and places sync points accoridng to their absolute midi tick when they
|
|
36456
36460
|
* need to be considered for synchronization.
|
|
36457
36461
|
* @param score The song for which to regenerate the sync points.
|
|
36462
|
+
* @param createNew Whether a new set of sync points should be generated for the sync (start, stop and tempo changes).
|
|
36458
36463
|
* @returns The generated sync points for usage in the backing track playback.
|
|
36459
36464
|
*/
|
|
36460
|
-
static generateSyncPoints(score) {
|
|
36465
|
+
static generateSyncPoints(score, createNew = false) {
|
|
36461
36466
|
const syncPoints = [];
|
|
36462
|
-
MidiFileGenerator.playThroughSong(score, syncPoints, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36467
|
+
MidiFileGenerator.playThroughSong(score, syncPoints, createNew, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36463
36468
|
}, (_barIndex, _currentTick, _currentTempo) => {
|
|
36464
36469
|
}, _endTick => {
|
|
36465
36470
|
});
|
|
@@ -36470,17 +36475,18 @@
|
|
|
36470
36475
|
*/
|
|
36471
36476
|
static buildModifiedTempoLookup(score) {
|
|
36472
36477
|
const syncPoints = [];
|
|
36473
|
-
const context = MidiFileGenerator.playThroughSong(score, syncPoints, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36478
|
+
const context = MidiFileGenerator.playThroughSong(score, syncPoints, false, (_masterBar, _previousMasterBar, _currentTick, _currentTempo, _barOccurence) => {
|
|
36474
36479
|
}, (_barIndex, _currentTick, _currentTempo) => {
|
|
36475
36480
|
}, _endTick => {
|
|
36476
36481
|
});
|
|
36477
36482
|
return context.automationToSyncPoint;
|
|
36478
36483
|
}
|
|
36479
|
-
static playThroughSong(score, syncPoints, generateMasterBar, generateTracks, finish) {
|
|
36484
|
+
static playThroughSong(score, syncPoints, createNewSyncPoints, generateMasterBar, generateTracks, finish) {
|
|
36480
36485
|
const controller = new MidiPlaybackController(score);
|
|
36481
36486
|
const playContext = new PlayThroughContext();
|
|
36482
36487
|
playContext.currentTempo = score.tempo;
|
|
36483
36488
|
playContext.syncPoints = syncPoints;
|
|
36489
|
+
playContext.createNewSyncPoints = createNewSyncPoints;
|
|
36484
36490
|
let previousMasterBar = null;
|
|
36485
36491
|
// store the previous played bar for repeats
|
|
36486
36492
|
const barOccurence = new Map();
|
|
@@ -36518,14 +36524,24 @@
|
|
|
36518
36524
|
// we need to assume some BPM for the last interpolated point.
|
|
36519
36525
|
// if we have more than just a start point, we keep the BPM before the last manual sync point
|
|
36520
36526
|
// otherwise we have no customized sync BPM known and keep the synthesizer one.
|
|
36521
|
-
|
|
36522
|
-
|
|
36527
|
+
if (playContext.createNewSyncPoints) {
|
|
36528
|
+
backingTrackSyncPoint.syncBpm = lastSyncPoint.synthBpm;
|
|
36529
|
+
backingTrackSyncPoint.synthBpm = lastSyncPoint.synthBpm;
|
|
36530
|
+
}
|
|
36531
|
+
else if (syncPoints.length === 1) {
|
|
36532
|
+
backingTrackSyncPoint.syncBpm = lastSyncPoint.synthBpm;
|
|
36533
|
+
}
|
|
36534
|
+
else {
|
|
36535
|
+
backingTrackSyncPoint.syncBpm = syncPoints[syncPoints.length - 2].syncBpm;
|
|
36536
|
+
}
|
|
36523
36537
|
backingTrackSyncPoint.synthTime =
|
|
36524
36538
|
lastSyncPoint.synthTime + MidiUtils.ticksToMillis(remainingTicks, lastSyncPoint.synthBpm);
|
|
36525
36539
|
backingTrackSyncPoint.syncTime =
|
|
36526
36540
|
lastSyncPoint.syncTime + MidiUtils.ticksToMillis(remainingTicks, backingTrackSyncPoint.syncBpm);
|
|
36527
36541
|
// update the previous sync point according to the new time
|
|
36528
|
-
|
|
36542
|
+
if (!playContext.createNewSyncPoints) {
|
|
36543
|
+
lastSyncPoint.updateSyncBpm(backingTrackSyncPoint.synthTime, backingTrackSyncPoint.syncTime);
|
|
36544
|
+
}
|
|
36529
36545
|
syncPoints.push(backingTrackSyncPoint);
|
|
36530
36546
|
}
|
|
36531
36547
|
}
|
|
@@ -36536,7 +36552,10 @@
|
|
|
36536
36552
|
const duration = bar.calculateDuration();
|
|
36537
36553
|
const barSyncPoints = bar.syncPoints;
|
|
36538
36554
|
const barStartTick = context.synthTick;
|
|
36539
|
-
if (
|
|
36555
|
+
if (context.createNewSyncPoints) {
|
|
36556
|
+
MidiFileGenerator.processBarTimeWithNewSyncPoints(bar, occurence, context);
|
|
36557
|
+
}
|
|
36558
|
+
else if (barSyncPoints) {
|
|
36540
36559
|
MidiFileGenerator.processBarTimeWithSyncPoints(bar, occurence, context);
|
|
36541
36560
|
}
|
|
36542
36561
|
else {
|
|
@@ -36550,6 +36569,44 @@
|
|
|
36550
36569
|
context.synthTick = endTick;
|
|
36551
36570
|
}
|
|
36552
36571
|
}
|
|
36572
|
+
static processBarTimeWithNewSyncPoints(bar, occurence, context) {
|
|
36573
|
+
// start marker
|
|
36574
|
+
const barStartTick = context.synthTick;
|
|
36575
|
+
if (bar.index === 0 && occurence === 0) {
|
|
36576
|
+
context.currentTempo = bar.score.tempo;
|
|
36577
|
+
const backingTrackSyncPoint = new BackingTrackSyncPoint();
|
|
36578
|
+
backingTrackSyncPoint.masterBarIndex = bar.index;
|
|
36579
|
+
backingTrackSyncPoint.masterBarOccurence = occurence;
|
|
36580
|
+
backingTrackSyncPoint.synthTick = barStartTick;
|
|
36581
|
+
backingTrackSyncPoint.synthBpm = context.currentTempo;
|
|
36582
|
+
backingTrackSyncPoint.synthTime = context.synthTime;
|
|
36583
|
+
backingTrackSyncPoint.syncBpm = context.currentTempo;
|
|
36584
|
+
backingTrackSyncPoint.syncTime = context.synthTime;
|
|
36585
|
+
context.syncPoints.push(backingTrackSyncPoint);
|
|
36586
|
+
}
|
|
36587
|
+
// walk tempo changes and create points
|
|
36588
|
+
const duration = bar.calculateDuration();
|
|
36589
|
+
for (const change of bar.tempoAutomations) {
|
|
36590
|
+
const absoluteTick = barStartTick + change.ratioPosition * duration;
|
|
36591
|
+
const tickOffset = absoluteTick - context.synthTick;
|
|
36592
|
+
if (tickOffset > 0) {
|
|
36593
|
+
context.synthTick = absoluteTick;
|
|
36594
|
+
context.synthTime += MidiUtils.ticksToMillis(tickOffset, context.currentTempo);
|
|
36595
|
+
}
|
|
36596
|
+
if (change.value !== context.currentTempo) {
|
|
36597
|
+
context.currentTempo = change.value;
|
|
36598
|
+
const backingTrackSyncPoint = new BackingTrackSyncPoint();
|
|
36599
|
+
backingTrackSyncPoint.masterBarIndex = bar.index;
|
|
36600
|
+
backingTrackSyncPoint.masterBarOccurence = occurence;
|
|
36601
|
+
backingTrackSyncPoint.synthTick = absoluteTick;
|
|
36602
|
+
backingTrackSyncPoint.synthBpm = context.currentTempo;
|
|
36603
|
+
backingTrackSyncPoint.synthTime = context.synthTime;
|
|
36604
|
+
backingTrackSyncPoint.syncBpm = context.currentTempo;
|
|
36605
|
+
backingTrackSyncPoint.syncTime = context.synthTime;
|
|
36606
|
+
context.syncPoints.push(backingTrackSyncPoint);
|
|
36607
|
+
}
|
|
36608
|
+
}
|
|
36609
|
+
}
|
|
36553
36610
|
static processBarTimeWithSyncPoints(bar, occurence, context) {
|
|
36554
36611
|
const barStartTick = context.synthTick;
|
|
36555
36612
|
const duration = bar.calculateDuration();
|
|
@@ -42887,7 +42944,12 @@
|
|
|
42887
42944
|
* @remarks
|
|
42888
42945
|
* This will not export or use any backing track media but will always use the synthesizer to generate the output.
|
|
42889
42946
|
* This method works with any PlayerMode active but changing the mode during export can lead to unexpected side effects.
|
|
42947
|
+
*
|
|
42948
|
+
* See [Audio Export](https://www.alphatab.net/docs/guides/audio-export) for further guidance how to use this feature.
|
|
42949
|
+
*
|
|
42890
42950
|
* @param options The export options.
|
|
42951
|
+
* @category Methods - Player
|
|
42952
|
+
* @since 1.6.0
|
|
42891
42953
|
* @returns An exporter instance to export the audio in a streaming fashion.
|
|
42892
42954
|
*/
|
|
42893
42955
|
async exportAudio(options) {
|
|
@@ -61733,9 +61795,9 @@
|
|
|
61733
61795
|
print(`build date: ${VersionInfo.date}`);
|
|
61734
61796
|
}
|
|
61735
61797
|
}
|
|
61736
|
-
VersionInfo.version = '1.6.0-alpha.
|
|
61737
|
-
VersionInfo.date = '2025-06-
|
|
61738
|
-
VersionInfo.commit = '
|
|
61798
|
+
VersionInfo.version = '1.6.0-alpha.1450';
|
|
61799
|
+
VersionInfo.date = '2025-06-15T01:20:26.410Z';
|
|
61800
|
+
VersionInfo.commit = 'a7639d9604a6fcdedff2883864b1008daae5cc64';
|
|
61739
61801
|
|
|
61740
61802
|
/**
|
|
61741
61803
|
* A factory for custom layout engines.
|