@coderline/alphatab 1.4.0 → 1.5.0-alpha.1331
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 +1 -1
- package/dist/alphaTab.core.mjs +159 -4
- package/dist/alphaTab.d.ts +120 -58
- package/dist/alphaTab.js +159 -4
- package/dist/alphaTab.min.js +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.mjs +1 -1
- package/dist/alphaTab.worklet.mjs +1 -1
- package/dist/font/Bravura-FONTLOG.txt +345 -345
- package/dist/font/Bravura-OFL-FAQ.txt +369 -369
- package/dist/font/Bravura-OFL.txt +94 -94
- package/dist/font/Bravura.svg +3864 -3864
- package/dist/soundfont/LICENSE +10 -10
- package/dist/soundfont/README.md +19 -19
- package/package.json +1 -1
package/dist/alphaTab.core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* alphaTab v1.
|
|
2
|
+
* alphaTab v1.5.0-alpha.1331 (develop, build 1331)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -27073,6 +27073,9 @@ class PlaybackRangeChangedEventArgs {
|
|
|
27073
27073
|
* play a {@link MidiFile} via a {@link ISynthOutput}.
|
|
27074
27074
|
*/
|
|
27075
27075
|
class AlphaSynth {
|
|
27076
|
+
get output() {
|
|
27077
|
+
return this._output;
|
|
27078
|
+
}
|
|
27076
27079
|
get isReadyForPlayback() {
|
|
27077
27080
|
return this.isReady && this._isSoundFontLoaded && this._isMidiLoaded;
|
|
27078
27081
|
}
|
|
@@ -27193,7 +27196,7 @@ class AlphaSynth {
|
|
|
27193
27196
|
Logger.debug('AlphaSynth', 'Initializing player');
|
|
27194
27197
|
this.state = PlayerState.Paused;
|
|
27195
27198
|
Logger.debug('AlphaSynth', 'Creating output');
|
|
27196
|
-
this.
|
|
27199
|
+
this._output = output;
|
|
27197
27200
|
Logger.debug('AlphaSynth', 'Creating synthesizer');
|
|
27198
27201
|
this._synthesizer = new TinySoundFont(this.output.sampleRate);
|
|
27199
27202
|
this._sequencer = new MidiFileSequencer(this._synthesizer);
|
|
@@ -27566,6 +27569,13 @@ class AlphaSynthWorkerSynthOutput {
|
|
|
27566
27569
|
activate() {
|
|
27567
27570
|
// nothing to do
|
|
27568
27571
|
}
|
|
27572
|
+
async enumerateOutputDevices() {
|
|
27573
|
+
return [];
|
|
27574
|
+
}
|
|
27575
|
+
async setOutputDevice(device) { }
|
|
27576
|
+
async getOutputDevice() {
|
|
27577
|
+
return null;
|
|
27578
|
+
}
|
|
27569
27579
|
}
|
|
27570
27580
|
AlphaSynthWorkerSynthOutput.CmdOutputPrefix = 'alphaSynth.output.';
|
|
27571
27581
|
AlphaSynthWorkerSynthOutput.CmdOutputAddSamples = AlphaSynthWorkerSynthOutput.CmdOutputPrefix + 'addSamples';
|
|
@@ -33383,6 +33393,37 @@ class AlphaTabApiBase {
|
|
|
33383
33393
|
this.settingsUpdated.trigger();
|
|
33384
33394
|
this.uiFacade.triggerEvent(this.container, 'settingsUpdated', null);
|
|
33385
33395
|
}
|
|
33396
|
+
/**
|
|
33397
|
+
* Loads and lists the available output devices which can be used by the player. Will request permissions if needed.
|
|
33398
|
+
* @returns the list of available devices or an empty list if there are no permissions, or the player is not enabled.
|
|
33399
|
+
*/
|
|
33400
|
+
async enumerateOutputDevices() {
|
|
33401
|
+
if (this.player) {
|
|
33402
|
+
return await this.player.output.enumerateOutputDevices();
|
|
33403
|
+
}
|
|
33404
|
+
return [];
|
|
33405
|
+
}
|
|
33406
|
+
/**
|
|
33407
|
+
* Changes the output device which should be used for playing the audio (player must be enabled).
|
|
33408
|
+
* @param device The output device to use, or null to switch to the default device.
|
|
33409
|
+
*/
|
|
33410
|
+
async setOutputDevice(device) {
|
|
33411
|
+
if (this.player) {
|
|
33412
|
+
await this.player.output.setOutputDevice(device);
|
|
33413
|
+
}
|
|
33414
|
+
}
|
|
33415
|
+
/**
|
|
33416
|
+
* The currently configured output device if changed via {@link setOutputDevice}.
|
|
33417
|
+
* @returns The custom configured output device which was set via {@link setOutputDevice} or `null`
|
|
33418
|
+
* if the default outputDevice is used.
|
|
33419
|
+
* The output device might change dynamically if devices are connected/disconnected (e.g. bluetooth headset).
|
|
33420
|
+
*/
|
|
33421
|
+
async getOutputDevice() {
|
|
33422
|
+
if (this.player) {
|
|
33423
|
+
return await this.player.output.getOutputDevice();
|
|
33424
|
+
}
|
|
33425
|
+
return null;
|
|
33426
|
+
}
|
|
33386
33427
|
}
|
|
33387
33428
|
|
|
33388
33429
|
/**
|
|
@@ -33845,6 +33886,21 @@ class CircularSampleBuffer {
|
|
|
33845
33886
|
}
|
|
33846
33887
|
}
|
|
33847
33888
|
|
|
33889
|
+
/**
|
|
33890
|
+
* @target web
|
|
33891
|
+
*/
|
|
33892
|
+
class AlphaSynthWebAudioSynthOutputDevice {
|
|
33893
|
+
constructor(device) {
|
|
33894
|
+
this.isDefault = false;
|
|
33895
|
+
this.device = device;
|
|
33896
|
+
}
|
|
33897
|
+
get deviceId() {
|
|
33898
|
+
return this.device.deviceId;
|
|
33899
|
+
}
|
|
33900
|
+
get label() {
|
|
33901
|
+
return this.device.label;
|
|
33902
|
+
}
|
|
33903
|
+
}
|
|
33848
33904
|
/**
|
|
33849
33905
|
* @target web
|
|
33850
33906
|
*/
|
|
@@ -33856,6 +33912,7 @@ class AlphaSynthWebAudioOutputBase {
|
|
|
33856
33912
|
this.ready = new EventEmitter();
|
|
33857
33913
|
this.samplesPlayed = new EventEmitterOfT();
|
|
33858
33914
|
this.sampleRequest = new EventEmitter();
|
|
33915
|
+
this._knownDevices = [];
|
|
33859
33916
|
}
|
|
33860
33917
|
get sampleRate() {
|
|
33861
33918
|
return this._context ? this._context.sampleRate : AlphaSynthWebAudioOutputBase.PreferredSampleRate;
|
|
@@ -33954,6 +34011,101 @@ class AlphaSynthWebAudioOutputBase {
|
|
|
33954
34011
|
onReady() {
|
|
33955
34012
|
this.ready.trigger();
|
|
33956
34013
|
}
|
|
34014
|
+
async checkSinkIdSupport() {
|
|
34015
|
+
// https://caniuse.com/mdn-api_audiocontext_sinkid
|
|
34016
|
+
const context = this._context ?? this.createAudioContext();
|
|
34017
|
+
if (!('setSinkId' in context)) {
|
|
34018
|
+
Logger.warning('WebAudio', 'Browser does not support changing the output device');
|
|
34019
|
+
return false;
|
|
34020
|
+
}
|
|
34021
|
+
return true;
|
|
34022
|
+
}
|
|
34023
|
+
async enumerateOutputDevices() {
|
|
34024
|
+
try {
|
|
34025
|
+
if (!(await this.checkSinkIdSupport())) {
|
|
34026
|
+
return [];
|
|
34027
|
+
}
|
|
34028
|
+
// Request permissions
|
|
34029
|
+
try {
|
|
34030
|
+
await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
34031
|
+
}
|
|
34032
|
+
catch (e) {
|
|
34033
|
+
// sometimes we get an error but can still enumerate, e.g. if microphone access is denied,
|
|
34034
|
+
// we can still load the output devices in some cases.
|
|
34035
|
+
Logger.warning('WebAudio', 'Output device permission rejected', e);
|
|
34036
|
+
}
|
|
34037
|
+
// load devices
|
|
34038
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
34039
|
+
// default device candidates
|
|
34040
|
+
let defaultDeviceGroupId = '';
|
|
34041
|
+
let defaultDeviceId = '';
|
|
34042
|
+
const realDevices = new Map();
|
|
34043
|
+
for (const device of devices) {
|
|
34044
|
+
if (device.kind === 'audiooutput') {
|
|
34045
|
+
realDevices.set(device.groupId, new AlphaSynthWebAudioSynthOutputDevice(device));
|
|
34046
|
+
// chromium has the default device as deviceID: 'default'
|
|
34047
|
+
// the standard defines empty-string as default
|
|
34048
|
+
if (device.deviceId === 'default' || device.deviceId === '') {
|
|
34049
|
+
defaultDeviceGroupId = device.groupId;
|
|
34050
|
+
defaultDeviceId = device.deviceId;
|
|
34051
|
+
}
|
|
34052
|
+
}
|
|
34053
|
+
}
|
|
34054
|
+
const final = Array.from(realDevices.values());
|
|
34055
|
+
// flag default device
|
|
34056
|
+
let defaultDevice = final.find(d => d.deviceId === defaultDeviceId);
|
|
34057
|
+
if (!defaultDevice) {
|
|
34058
|
+
defaultDevice = final.find(d => d.device.groupId === defaultDeviceGroupId);
|
|
34059
|
+
}
|
|
34060
|
+
if (!defaultDevice && final.length > 0) {
|
|
34061
|
+
defaultDevice = final[0];
|
|
34062
|
+
}
|
|
34063
|
+
if (defaultDevice) {
|
|
34064
|
+
defaultDevice.isDefault = true;
|
|
34065
|
+
}
|
|
34066
|
+
this._knownDevices = final;
|
|
34067
|
+
return final;
|
|
34068
|
+
}
|
|
34069
|
+
catch (e) {
|
|
34070
|
+
Logger.error('WebAudio', 'Failed to enumerate output devices', e);
|
|
34071
|
+
return [];
|
|
34072
|
+
}
|
|
34073
|
+
}
|
|
34074
|
+
async setOutputDevice(device) {
|
|
34075
|
+
if (!(await this.checkSinkIdSupport())) {
|
|
34076
|
+
return;
|
|
34077
|
+
}
|
|
34078
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId
|
|
34079
|
+
if (!device) {
|
|
34080
|
+
await this._context.setSinkId('');
|
|
34081
|
+
}
|
|
34082
|
+
else {
|
|
34083
|
+
await this._context.setSinkId(device.deviceId);
|
|
34084
|
+
}
|
|
34085
|
+
}
|
|
34086
|
+
async getOutputDevice() {
|
|
34087
|
+
if (!(await this.checkSinkIdSupport())) {
|
|
34088
|
+
return null;
|
|
34089
|
+
}
|
|
34090
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/sinkId
|
|
34091
|
+
const sinkId = this._context.sinkId;
|
|
34092
|
+
if (typeof sinkId !== 'string' || sinkId === '' || sinkId === 'default') {
|
|
34093
|
+
return null;
|
|
34094
|
+
}
|
|
34095
|
+
// fast path -> cached devices list
|
|
34096
|
+
let device = this._knownDevices.find(d => d.deviceId === sinkId);
|
|
34097
|
+
if (device) {
|
|
34098
|
+
return device;
|
|
34099
|
+
}
|
|
34100
|
+
// slow path -> enumerate devices
|
|
34101
|
+
const allDevices = await this.enumerateOutputDevices();
|
|
34102
|
+
device = allDevices.find(d => d.deviceId === sinkId);
|
|
34103
|
+
if (device) {
|
|
34104
|
+
return device;
|
|
34105
|
+
}
|
|
34106
|
+
Logger.warning('WebAudio', 'Could not find output device in device list', sinkId, allDevices);
|
|
34107
|
+
return null;
|
|
34108
|
+
}
|
|
33957
34109
|
}
|
|
33958
34110
|
AlphaSynthWebAudioOutputBase.BufferSize = 4096;
|
|
33959
34111
|
AlphaSynthWebAudioOutputBase.PreferredSampleRate = 44100;
|
|
@@ -34070,6 +34222,9 @@ class ProgressEventArgs {
|
|
|
34070
34222
|
* @target web
|
|
34071
34223
|
*/
|
|
34072
34224
|
class AlphaSynthWebWorkerApi {
|
|
34225
|
+
get output() {
|
|
34226
|
+
return this._output;
|
|
34227
|
+
}
|
|
34073
34228
|
get isReady() {
|
|
34074
34229
|
return this._workerIsReady && this._outputIsReady;
|
|
34075
34230
|
}
|
|
@@ -52127,8 +52282,8 @@ class CoreSettings {
|
|
|
52127
52282
|
// </auto-generated>
|
|
52128
52283
|
class VersionInfo {
|
|
52129
52284
|
}
|
|
52130
|
-
VersionInfo.version = '1.
|
|
52131
|
-
VersionInfo.date = '2025-03-
|
|
52285
|
+
VersionInfo.version = '1.5.0-alpha.1331';
|
|
52286
|
+
VersionInfo.date = '2025-03-03T01:56:53.590Z';
|
|
52132
52287
|
|
|
52133
52288
|
var index$4 = /*#__PURE__*/Object.freeze({
|
|
52134
52289
|
__proto__: null,
|
package/dist/alphaTab.d.ts
CHANGED
|
@@ -7299,6 +7299,95 @@ declare class MidiEventsPlayedEventArgs {
|
|
|
7299
7299
|
constructor(events: MidiEvent[]);
|
|
7300
7300
|
}
|
|
7301
7301
|
|
|
7302
|
+
/**
|
|
7303
|
+
* Represents a output device on which the synth can send the audio to.
|
|
7304
|
+
*/
|
|
7305
|
+
interface ISynthOutputDevice {
|
|
7306
|
+
/**
|
|
7307
|
+
* The ID to uniquely identify the device.
|
|
7308
|
+
*/
|
|
7309
|
+
readonly deviceId: string;
|
|
7310
|
+
/**
|
|
7311
|
+
* A string describing the device.
|
|
7312
|
+
*/
|
|
7313
|
+
readonly label: string;
|
|
7314
|
+
/**
|
|
7315
|
+
* Gets a value indicating whether the device is the default output device.
|
|
7316
|
+
*/
|
|
7317
|
+
readonly isDefault: boolean;
|
|
7318
|
+
}
|
|
7319
|
+
/**
|
|
7320
|
+
* This is the base interface for output devices which can
|
|
7321
|
+
* request and playback audio samples.
|
|
7322
|
+
* @csharp_public
|
|
7323
|
+
*/
|
|
7324
|
+
interface ISynthOutput {
|
|
7325
|
+
/**
|
|
7326
|
+
* Gets the sample rate required by the output.
|
|
7327
|
+
*/
|
|
7328
|
+
readonly sampleRate: number;
|
|
7329
|
+
/**
|
|
7330
|
+
* Called when the output should be opened.
|
|
7331
|
+
*/
|
|
7332
|
+
open(bufferTimeInMilliseconds: number): void;
|
|
7333
|
+
/**
|
|
7334
|
+
* Called when the output should start the playback.
|
|
7335
|
+
*/
|
|
7336
|
+
play(): void;
|
|
7337
|
+
/**
|
|
7338
|
+
* Requests the output to destroy itself.
|
|
7339
|
+
*/
|
|
7340
|
+
destroy(): void;
|
|
7341
|
+
/**
|
|
7342
|
+
* Called when the output should stop the playback.
|
|
7343
|
+
*/
|
|
7344
|
+
pause(): void;
|
|
7345
|
+
/**
|
|
7346
|
+
* Called when samples have been synthesized and should be added to the playback buffer.
|
|
7347
|
+
* @param samples
|
|
7348
|
+
*/
|
|
7349
|
+
addSamples(samples: Float32Array): void;
|
|
7350
|
+
/**
|
|
7351
|
+
* Called when the samples in the output buffer should be reset. This is neeed for instance when seeking to another position.
|
|
7352
|
+
*/
|
|
7353
|
+
resetSamples(): void;
|
|
7354
|
+
/**
|
|
7355
|
+
* Activates the output component.
|
|
7356
|
+
*/
|
|
7357
|
+
activate(): void;
|
|
7358
|
+
/**
|
|
7359
|
+
* Fired when the output has been successfully opened and is ready to play samples.
|
|
7360
|
+
*/
|
|
7361
|
+
readonly ready: IEventEmitter;
|
|
7362
|
+
/**
|
|
7363
|
+
* Fired when a certain number of samples have been played.
|
|
7364
|
+
*/
|
|
7365
|
+
readonly samplesPlayed: IEventEmitterOfT<number>;
|
|
7366
|
+
/**
|
|
7367
|
+
* Fired when the output needs more samples to be played.
|
|
7368
|
+
*/
|
|
7369
|
+
readonly sampleRequest: IEventEmitter;
|
|
7370
|
+
/**
|
|
7371
|
+
* Loads and lists the available output devices. Will request permissions if needed.
|
|
7372
|
+
* @async
|
|
7373
|
+
*/
|
|
7374
|
+
enumerateOutputDevices(): Promise<ISynthOutputDevice[]>;
|
|
7375
|
+
/**
|
|
7376
|
+
* Changes the output device which should be used for playing the audio.
|
|
7377
|
+
* @async
|
|
7378
|
+
* @param device The output device to use, or null to switch to the default device.
|
|
7379
|
+
*/
|
|
7380
|
+
setOutputDevice(device: ISynthOutputDevice | null): Promise<void>;
|
|
7381
|
+
/**
|
|
7382
|
+
* The currently configured output device if changed via {@link setOutputDevice}.
|
|
7383
|
+
* @async
|
|
7384
|
+
* @returns The custom configured output device which was set via {@link setOutputDevice} or `null`
|
|
7385
|
+
* if the default outputDevice is used.
|
|
7386
|
+
* The output device might change dynamically if devices are connected/disconnected (e.g. bluetooth headset).
|
|
7387
|
+
*/
|
|
7388
|
+
getOutputDevice(): Promise<ISynthOutputDevice | null>;
|
|
7389
|
+
}
|
|
7390
|
+
|
|
7302
7391
|
/**
|
|
7303
7392
|
* The public API interface for interacting with the synthesizer.
|
|
7304
7393
|
*/
|
|
@@ -7356,6 +7445,10 @@ interface IAlphaSynth {
|
|
|
7356
7445
|
* Gets or sets the midi events which will trigger the `midiEventsPlayed` event.
|
|
7357
7446
|
*/
|
|
7358
7447
|
midiEventsPlayedFilter: MidiEventType[];
|
|
7448
|
+
/**
|
|
7449
|
+
* Gets the output used by alphaSynth.
|
|
7450
|
+
*/
|
|
7451
|
+
readonly output: ISynthOutput;
|
|
7359
7452
|
/**
|
|
7360
7453
|
* Destroys the synthesizer and all related components
|
|
7361
7454
|
*/
|
|
@@ -8039,6 +8132,23 @@ declare class AlphaTabApiBase<TSettings> {
|
|
|
8039
8132
|
*/
|
|
8040
8133
|
settingsUpdated: IEventEmitter;
|
|
8041
8134
|
private onSettingsUpdated;
|
|
8135
|
+
/**
|
|
8136
|
+
* Loads and lists the available output devices which can be used by the player. Will request permissions if needed.
|
|
8137
|
+
* @returns the list of available devices or an empty list if there are no permissions, or the player is not enabled.
|
|
8138
|
+
*/
|
|
8139
|
+
enumerateOutputDevices(): Promise<ISynthOutputDevice[]>;
|
|
8140
|
+
/**
|
|
8141
|
+
* Changes the output device which should be used for playing the audio (player must be enabled).
|
|
8142
|
+
* @param device The output device to use, or null to switch to the default device.
|
|
8143
|
+
*/
|
|
8144
|
+
setOutputDevice(device: ISynthOutputDevice | null): Promise<void>;
|
|
8145
|
+
/**
|
|
8146
|
+
* The currently configured output device if changed via {@link setOutputDevice}.
|
|
8147
|
+
* @returns The custom configured output device which was set via {@link setOutputDevice} or `null`
|
|
8148
|
+
* if the default outputDevice is used.
|
|
8149
|
+
* The output device might change dynamically if devices are connected/disconnected (e.g. bluetooth headset).
|
|
8150
|
+
*/
|
|
8151
|
+
getOutputDevice(): Promise<ISynthOutputDevice | null>;
|
|
8042
8152
|
}
|
|
8043
8153
|
|
|
8044
8154
|
/**
|
|
@@ -8542,59 +8652,6 @@ declare namespace index_d$1 {
|
|
|
8542
8652
|
export { index_d$1_CssFontSvgCanvas as CssFontSvgCanvas, index_d$1_Cursors as Cursors, index_d$1_FontSizes as FontSizes, type index_d$1_ICanvas as ICanvas, type index_d$1_IContainer as IContainer, type index_d$1_IMouseEventArgs as IMouseEventArgs, type index_d$1_IUiFacade as IUiFacade, index_d$1_SvgCanvas as SvgCanvas, index_d$1_TextAlign as TextAlign, index_d$1_TextBaseline as TextBaseline };
|
|
8543
8653
|
}
|
|
8544
8654
|
|
|
8545
|
-
/**
|
|
8546
|
-
* This is the base interface for output devices which can
|
|
8547
|
-
* request and playback audio samples.
|
|
8548
|
-
* @csharp_public
|
|
8549
|
-
*/
|
|
8550
|
-
interface ISynthOutput {
|
|
8551
|
-
/**
|
|
8552
|
-
* Gets the sample rate required by the output.
|
|
8553
|
-
*/
|
|
8554
|
-
readonly sampleRate: number;
|
|
8555
|
-
/**
|
|
8556
|
-
* Called when the output should be opened.
|
|
8557
|
-
*/
|
|
8558
|
-
open(bufferTimeInMilliseconds: number): void;
|
|
8559
|
-
/**
|
|
8560
|
-
* Called when the output should start the playback.
|
|
8561
|
-
*/
|
|
8562
|
-
play(): void;
|
|
8563
|
-
/**
|
|
8564
|
-
* Requests the output to destroy itself.
|
|
8565
|
-
*/
|
|
8566
|
-
destroy(): void;
|
|
8567
|
-
/**
|
|
8568
|
-
* Called when the output should stop the playback.
|
|
8569
|
-
*/
|
|
8570
|
-
pause(): void;
|
|
8571
|
-
/**
|
|
8572
|
-
* Called when samples have been synthesized and should be added to the playback buffer.
|
|
8573
|
-
* @param samples
|
|
8574
|
-
*/
|
|
8575
|
-
addSamples(samples: Float32Array): void;
|
|
8576
|
-
/**
|
|
8577
|
-
* Called when the samples in the output buffer should be reset. This is neeed for instance when seeking to another position.
|
|
8578
|
-
*/
|
|
8579
|
-
resetSamples(): void;
|
|
8580
|
-
/**
|
|
8581
|
-
* Activates the output component.
|
|
8582
|
-
*/
|
|
8583
|
-
activate(): void;
|
|
8584
|
-
/**
|
|
8585
|
-
* Fired when the output has been successfully opened and is ready to play samples.
|
|
8586
|
-
*/
|
|
8587
|
-
readonly ready: IEventEmitter;
|
|
8588
|
-
/**
|
|
8589
|
-
* Fired when a certain number of samples have been played.
|
|
8590
|
-
*/
|
|
8591
|
-
readonly samplesPlayed: IEventEmitterOfT<number>;
|
|
8592
|
-
/**
|
|
8593
|
-
* Fired when the output needs more samples to be played.
|
|
8594
|
-
*/
|
|
8595
|
-
readonly sampleRequest: IEventEmitter;
|
|
8596
|
-
}
|
|
8597
|
-
|
|
8598
8655
|
/**
|
|
8599
8656
|
* This is the main synthesizer component which can be used to
|
|
8600
8657
|
* play a {@link MidiFile} via a {@link ISynthOutput}.
|
|
@@ -8612,10 +8669,8 @@ declare class AlphaSynth implements IAlphaSynth {
|
|
|
8612
8669
|
private _midiEventsPlayedFilter;
|
|
8613
8670
|
private _notPlayedSamples;
|
|
8614
8671
|
private _synthStopping;
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
*/
|
|
8618
|
-
readonly output: ISynthOutput;
|
|
8672
|
+
private _output;
|
|
8673
|
+
get output(): ISynthOutput;
|
|
8619
8674
|
isReady: boolean;
|
|
8620
8675
|
get isReadyForPlayback(): boolean;
|
|
8621
8676
|
state: PlayerState;
|
|
@@ -8750,6 +8805,7 @@ declare class AlphaSynthWebWorkerApi implements IAlphaSynth {
|
|
|
8750
8805
|
private _isLooping;
|
|
8751
8806
|
private _playbackRange;
|
|
8752
8807
|
private _midiEventsPlayedFilter;
|
|
8808
|
+
get output(): ISynthOutput;
|
|
8753
8809
|
get isReady(): boolean;
|
|
8754
8810
|
get isReadyForPlayback(): boolean;
|
|
8755
8811
|
get state(): PlayerState;
|
|
@@ -8837,6 +8893,11 @@ declare abstract class AlphaSynthWebAudioOutputBase implements ISynthOutput {
|
|
|
8837
8893
|
protected onSamplesPlayed(numberOfSamples: number): void;
|
|
8838
8894
|
protected onSampleRequest(): void;
|
|
8839
8895
|
protected onReady(): void;
|
|
8896
|
+
private checkSinkIdSupport;
|
|
8897
|
+
private _knownDevices;
|
|
8898
|
+
enumerateOutputDevices(): Promise<ISynthOutputDevice[]>;
|
|
8899
|
+
setOutputDevice(device: ISynthOutputDevice | null): Promise<void>;
|
|
8900
|
+
getOutputDevice(): Promise<ISynthOutputDevice | null>;
|
|
8840
8901
|
}
|
|
8841
8902
|
|
|
8842
8903
|
/**
|
|
@@ -8893,6 +8954,7 @@ type index_d_CircularSampleBuffer = CircularSampleBuffer;
|
|
|
8893
8954
|
declare const index_d_CircularSampleBuffer: typeof CircularSampleBuffer;
|
|
8894
8955
|
type index_d_IAlphaSynth = IAlphaSynth;
|
|
8895
8956
|
type index_d_ISynthOutput = ISynthOutput;
|
|
8957
|
+
type index_d_ISynthOutputDevice = ISynthOutputDevice;
|
|
8896
8958
|
type index_d_MidiEventsPlayedEventArgs = MidiEventsPlayedEventArgs;
|
|
8897
8959
|
declare const index_d_MidiEventsPlayedEventArgs: typeof MidiEventsPlayedEventArgs;
|
|
8898
8960
|
type index_d_PlaybackRange = PlaybackRange;
|
|
@@ -8906,7 +8968,7 @@ declare const index_d_PlayerStateChangedEventArgs: typeof PlayerStateChangedEven
|
|
|
8906
8968
|
type index_d_PositionChangedEventArgs = PositionChangedEventArgs;
|
|
8907
8969
|
declare const index_d_PositionChangedEventArgs: typeof PositionChangedEventArgs;
|
|
8908
8970
|
declare namespace index_d {
|
|
8909
|
-
export { index_d_ActiveBeatsChangedEventArgs as ActiveBeatsChangedEventArgs, index_d_AlphaSynth as AlphaSynth, index_d_AlphaSynthAudioWorkletOutput as AlphaSynthAudioWorkletOutput, index_d_AlphaSynthScriptProcessorOutput as AlphaSynthScriptProcessorOutput, index_d_AlphaSynthWebAudioOutputBase as AlphaSynthWebAudioOutputBase, index_d_AlphaSynthWebWorkerApi as AlphaSynthWebWorkerApi, index_d_CircularSampleBuffer as CircularSampleBuffer, type index_d_IAlphaSynth as IAlphaSynth, type index_d_ISynthOutput as ISynthOutput, index_d_MidiEventsPlayedEventArgs as MidiEventsPlayedEventArgs, index_d_PlaybackRange as PlaybackRange, index_d_PlaybackRangeChangedEventArgs as PlaybackRangeChangedEventArgs, index_d_PlayerState as PlayerState, index_d_PlayerStateChangedEventArgs as PlayerStateChangedEventArgs, index_d_PositionChangedEventArgs as PositionChangedEventArgs };
|
|
8971
|
+
export { index_d_ActiveBeatsChangedEventArgs as ActiveBeatsChangedEventArgs, index_d_AlphaSynth as AlphaSynth, index_d_AlphaSynthAudioWorkletOutput as AlphaSynthAudioWorkletOutput, index_d_AlphaSynthScriptProcessorOutput as AlphaSynthScriptProcessorOutput, index_d_AlphaSynthWebAudioOutputBase as AlphaSynthWebAudioOutputBase, index_d_AlphaSynthWebWorkerApi as AlphaSynthWebWorkerApi, index_d_CircularSampleBuffer as CircularSampleBuffer, type index_d_IAlphaSynth as IAlphaSynth, type index_d_ISynthOutput as ISynthOutput, type index_d_ISynthOutputDevice as ISynthOutputDevice, index_d_MidiEventsPlayedEventArgs as MidiEventsPlayedEventArgs, index_d_PlaybackRange as PlaybackRange, index_d_PlaybackRangeChangedEventArgs as PlaybackRangeChangedEventArgs, index_d_PlayerState as PlayerState, index_d_PlayerStateChangedEventArgs as PlayerStateChangedEventArgs, index_d_PositionChangedEventArgs as PositionChangedEventArgs };
|
|
8910
8972
|
}
|
|
8911
8973
|
|
|
8912
8974
|
type json_d_CoreSettingsJson = CoreSettingsJson;
|
package/dist/alphaTab.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* alphaTab v1.
|
|
2
|
+
* alphaTab v1.5.0-alpha.1331 (develop, build 1331)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -27079,6 +27079,9 @@
|
|
|
27079
27079
|
* play a {@link MidiFile} via a {@link ISynthOutput}.
|
|
27080
27080
|
*/
|
|
27081
27081
|
class AlphaSynth {
|
|
27082
|
+
get output() {
|
|
27083
|
+
return this._output;
|
|
27084
|
+
}
|
|
27082
27085
|
get isReadyForPlayback() {
|
|
27083
27086
|
return this.isReady && this._isSoundFontLoaded && this._isMidiLoaded;
|
|
27084
27087
|
}
|
|
@@ -27199,7 +27202,7 @@
|
|
|
27199
27202
|
Logger.debug('AlphaSynth', 'Initializing player');
|
|
27200
27203
|
this.state = PlayerState.Paused;
|
|
27201
27204
|
Logger.debug('AlphaSynth', 'Creating output');
|
|
27202
|
-
this.
|
|
27205
|
+
this._output = output;
|
|
27203
27206
|
Logger.debug('AlphaSynth', 'Creating synthesizer');
|
|
27204
27207
|
this._synthesizer = new TinySoundFont(this.output.sampleRate);
|
|
27205
27208
|
this._sequencer = new MidiFileSequencer(this._synthesizer);
|
|
@@ -27572,6 +27575,13 @@
|
|
|
27572
27575
|
activate() {
|
|
27573
27576
|
// nothing to do
|
|
27574
27577
|
}
|
|
27578
|
+
async enumerateOutputDevices() {
|
|
27579
|
+
return [];
|
|
27580
|
+
}
|
|
27581
|
+
async setOutputDevice(device) { }
|
|
27582
|
+
async getOutputDevice() {
|
|
27583
|
+
return null;
|
|
27584
|
+
}
|
|
27575
27585
|
}
|
|
27576
27586
|
AlphaSynthWorkerSynthOutput.CmdOutputPrefix = 'alphaSynth.output.';
|
|
27577
27587
|
AlphaSynthWorkerSynthOutput.CmdOutputAddSamples = AlphaSynthWorkerSynthOutput.CmdOutputPrefix + 'addSamples';
|
|
@@ -33389,6 +33399,37 @@
|
|
|
33389
33399
|
this.settingsUpdated.trigger();
|
|
33390
33400
|
this.uiFacade.triggerEvent(this.container, 'settingsUpdated', null);
|
|
33391
33401
|
}
|
|
33402
|
+
/**
|
|
33403
|
+
* Loads and lists the available output devices which can be used by the player. Will request permissions if needed.
|
|
33404
|
+
* @returns the list of available devices or an empty list if there are no permissions, or the player is not enabled.
|
|
33405
|
+
*/
|
|
33406
|
+
async enumerateOutputDevices() {
|
|
33407
|
+
if (this.player) {
|
|
33408
|
+
return await this.player.output.enumerateOutputDevices();
|
|
33409
|
+
}
|
|
33410
|
+
return [];
|
|
33411
|
+
}
|
|
33412
|
+
/**
|
|
33413
|
+
* Changes the output device which should be used for playing the audio (player must be enabled).
|
|
33414
|
+
* @param device The output device to use, or null to switch to the default device.
|
|
33415
|
+
*/
|
|
33416
|
+
async setOutputDevice(device) {
|
|
33417
|
+
if (this.player) {
|
|
33418
|
+
await this.player.output.setOutputDevice(device);
|
|
33419
|
+
}
|
|
33420
|
+
}
|
|
33421
|
+
/**
|
|
33422
|
+
* The currently configured output device if changed via {@link setOutputDevice}.
|
|
33423
|
+
* @returns The custom configured output device which was set via {@link setOutputDevice} or `null`
|
|
33424
|
+
* if the default outputDevice is used.
|
|
33425
|
+
* The output device might change dynamically if devices are connected/disconnected (e.g. bluetooth headset).
|
|
33426
|
+
*/
|
|
33427
|
+
async getOutputDevice() {
|
|
33428
|
+
if (this.player) {
|
|
33429
|
+
return await this.player.output.getOutputDevice();
|
|
33430
|
+
}
|
|
33431
|
+
return null;
|
|
33432
|
+
}
|
|
33392
33433
|
}
|
|
33393
33434
|
|
|
33394
33435
|
/**
|
|
@@ -33851,6 +33892,21 @@
|
|
|
33851
33892
|
}
|
|
33852
33893
|
}
|
|
33853
33894
|
|
|
33895
|
+
/**
|
|
33896
|
+
* @target web
|
|
33897
|
+
*/
|
|
33898
|
+
class AlphaSynthWebAudioSynthOutputDevice {
|
|
33899
|
+
constructor(device) {
|
|
33900
|
+
this.isDefault = false;
|
|
33901
|
+
this.device = device;
|
|
33902
|
+
}
|
|
33903
|
+
get deviceId() {
|
|
33904
|
+
return this.device.deviceId;
|
|
33905
|
+
}
|
|
33906
|
+
get label() {
|
|
33907
|
+
return this.device.label;
|
|
33908
|
+
}
|
|
33909
|
+
}
|
|
33854
33910
|
/**
|
|
33855
33911
|
* @target web
|
|
33856
33912
|
*/
|
|
@@ -33862,6 +33918,7 @@
|
|
|
33862
33918
|
this.ready = new EventEmitter();
|
|
33863
33919
|
this.samplesPlayed = new EventEmitterOfT();
|
|
33864
33920
|
this.sampleRequest = new EventEmitter();
|
|
33921
|
+
this._knownDevices = [];
|
|
33865
33922
|
}
|
|
33866
33923
|
get sampleRate() {
|
|
33867
33924
|
return this._context ? this._context.sampleRate : AlphaSynthWebAudioOutputBase.PreferredSampleRate;
|
|
@@ -33960,6 +34017,101 @@
|
|
|
33960
34017
|
onReady() {
|
|
33961
34018
|
this.ready.trigger();
|
|
33962
34019
|
}
|
|
34020
|
+
async checkSinkIdSupport() {
|
|
34021
|
+
// https://caniuse.com/mdn-api_audiocontext_sinkid
|
|
34022
|
+
const context = this._context ?? this.createAudioContext();
|
|
34023
|
+
if (!('setSinkId' in context)) {
|
|
34024
|
+
Logger.warning('WebAudio', 'Browser does not support changing the output device');
|
|
34025
|
+
return false;
|
|
34026
|
+
}
|
|
34027
|
+
return true;
|
|
34028
|
+
}
|
|
34029
|
+
async enumerateOutputDevices() {
|
|
34030
|
+
try {
|
|
34031
|
+
if (!(await this.checkSinkIdSupport())) {
|
|
34032
|
+
return [];
|
|
34033
|
+
}
|
|
34034
|
+
// Request permissions
|
|
34035
|
+
try {
|
|
34036
|
+
await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
34037
|
+
}
|
|
34038
|
+
catch (e) {
|
|
34039
|
+
// sometimes we get an error but can still enumerate, e.g. if microphone access is denied,
|
|
34040
|
+
// we can still load the output devices in some cases.
|
|
34041
|
+
Logger.warning('WebAudio', 'Output device permission rejected', e);
|
|
34042
|
+
}
|
|
34043
|
+
// load devices
|
|
34044
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
34045
|
+
// default device candidates
|
|
34046
|
+
let defaultDeviceGroupId = '';
|
|
34047
|
+
let defaultDeviceId = '';
|
|
34048
|
+
const realDevices = new Map();
|
|
34049
|
+
for (const device of devices) {
|
|
34050
|
+
if (device.kind === 'audiooutput') {
|
|
34051
|
+
realDevices.set(device.groupId, new AlphaSynthWebAudioSynthOutputDevice(device));
|
|
34052
|
+
// chromium has the default device as deviceID: 'default'
|
|
34053
|
+
// the standard defines empty-string as default
|
|
34054
|
+
if (device.deviceId === 'default' || device.deviceId === '') {
|
|
34055
|
+
defaultDeviceGroupId = device.groupId;
|
|
34056
|
+
defaultDeviceId = device.deviceId;
|
|
34057
|
+
}
|
|
34058
|
+
}
|
|
34059
|
+
}
|
|
34060
|
+
const final = Array.from(realDevices.values());
|
|
34061
|
+
// flag default device
|
|
34062
|
+
let defaultDevice = final.find(d => d.deviceId === defaultDeviceId);
|
|
34063
|
+
if (!defaultDevice) {
|
|
34064
|
+
defaultDevice = final.find(d => d.device.groupId === defaultDeviceGroupId);
|
|
34065
|
+
}
|
|
34066
|
+
if (!defaultDevice && final.length > 0) {
|
|
34067
|
+
defaultDevice = final[0];
|
|
34068
|
+
}
|
|
34069
|
+
if (defaultDevice) {
|
|
34070
|
+
defaultDevice.isDefault = true;
|
|
34071
|
+
}
|
|
34072
|
+
this._knownDevices = final;
|
|
34073
|
+
return final;
|
|
34074
|
+
}
|
|
34075
|
+
catch (e) {
|
|
34076
|
+
Logger.error('WebAudio', 'Failed to enumerate output devices', e);
|
|
34077
|
+
return [];
|
|
34078
|
+
}
|
|
34079
|
+
}
|
|
34080
|
+
async setOutputDevice(device) {
|
|
34081
|
+
if (!(await this.checkSinkIdSupport())) {
|
|
34082
|
+
return;
|
|
34083
|
+
}
|
|
34084
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId
|
|
34085
|
+
if (!device) {
|
|
34086
|
+
await this._context.setSinkId('');
|
|
34087
|
+
}
|
|
34088
|
+
else {
|
|
34089
|
+
await this._context.setSinkId(device.deviceId);
|
|
34090
|
+
}
|
|
34091
|
+
}
|
|
34092
|
+
async getOutputDevice() {
|
|
34093
|
+
if (!(await this.checkSinkIdSupport())) {
|
|
34094
|
+
return null;
|
|
34095
|
+
}
|
|
34096
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/sinkId
|
|
34097
|
+
const sinkId = this._context.sinkId;
|
|
34098
|
+
if (typeof sinkId !== 'string' || sinkId === '' || sinkId === 'default') {
|
|
34099
|
+
return null;
|
|
34100
|
+
}
|
|
34101
|
+
// fast path -> cached devices list
|
|
34102
|
+
let device = this._knownDevices.find(d => d.deviceId === sinkId);
|
|
34103
|
+
if (device) {
|
|
34104
|
+
return device;
|
|
34105
|
+
}
|
|
34106
|
+
// slow path -> enumerate devices
|
|
34107
|
+
const allDevices = await this.enumerateOutputDevices();
|
|
34108
|
+
device = allDevices.find(d => d.deviceId === sinkId);
|
|
34109
|
+
if (device) {
|
|
34110
|
+
return device;
|
|
34111
|
+
}
|
|
34112
|
+
Logger.warning('WebAudio', 'Could not find output device in device list', sinkId, allDevices);
|
|
34113
|
+
return null;
|
|
34114
|
+
}
|
|
33963
34115
|
}
|
|
33964
34116
|
AlphaSynthWebAudioOutputBase.BufferSize = 4096;
|
|
33965
34117
|
AlphaSynthWebAudioOutputBase.PreferredSampleRate = 44100;
|
|
@@ -34076,6 +34228,9 @@
|
|
|
34076
34228
|
* @target web
|
|
34077
34229
|
*/
|
|
34078
34230
|
class AlphaSynthWebWorkerApi {
|
|
34231
|
+
get output() {
|
|
34232
|
+
return this._output;
|
|
34233
|
+
}
|
|
34079
34234
|
get isReady() {
|
|
34080
34235
|
return this._workerIsReady && this._outputIsReady;
|
|
34081
34236
|
}
|
|
@@ -52133,8 +52288,8 @@
|
|
|
52133
52288
|
// </auto-generated>
|
|
52134
52289
|
class VersionInfo {
|
|
52135
52290
|
}
|
|
52136
|
-
VersionInfo.version = '1.
|
|
52137
|
-
VersionInfo.date = '2025-03-
|
|
52291
|
+
VersionInfo.version = '1.5.0-alpha.1331';
|
|
52292
|
+
VersionInfo.date = '2025-03-03T01:56:53.590Z';
|
|
52138
52293
|
|
|
52139
52294
|
var index$4 = /*#__PURE__*/Object.freeze({
|
|
52140
52295
|
__proto__: null,
|