@waveform-playlist/playout 9.5.2 → 10.1.0
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/index.d.mts +5 -37
- package/dist/index.d.ts +5 -37
- package/dist/index.js +97 -170
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -163
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Gain, ToneAudioNode, SynthOptions, Volume, BaseContext, Context } from 'tone';
|
|
2
2
|
import { Fade, Track, MidiNoteData } from '@waveform-playlist/core';
|
|
3
|
+
export { FadeConfig, FadeType, applyFadeIn, applyFadeOut } from '@waveform-playlist/core';
|
|
3
4
|
import { ZoneMap, Generator, GeneratorType } from 'soundfont2';
|
|
4
5
|
import { PlayoutAdapter } from '@waveform-playlist/engine';
|
|
5
6
|
|
|
@@ -536,44 +537,11 @@ declare function releaseMediaStreamSource(stream: MediaStream): void;
|
|
|
536
537
|
declare function hasMediaStreamSource(stream: MediaStream): boolean;
|
|
537
538
|
|
|
538
539
|
/**
|
|
539
|
-
* Fade utilities
|
|
540
|
-
*
|
|
541
|
-
* Applies fade in/out envelopes to AudioParam (typically gain)
|
|
542
|
-
* using various curve types.
|
|
540
|
+
* Fade utilities — re-exports from @waveform-playlist/core
|
|
541
|
+
* plus Tone.js-specific helpers
|
|
543
542
|
*/
|
|
543
|
+
|
|
544
544
|
declare function getUnderlyingAudioParam(signal: unknown): AudioParam | undefined;
|
|
545
|
-
type FadeType = 'linear' | 'logarithmic' | 'exponential' | 'sCurve';
|
|
546
|
-
/**
|
|
547
|
-
* Simple fade configuration - just duration and type
|
|
548
|
-
*/
|
|
549
|
-
interface FadeConfig {
|
|
550
|
-
/** Duration of the fade in seconds */
|
|
551
|
-
duration: number;
|
|
552
|
-
/** Type of fade curve (default: 'linear') */
|
|
553
|
-
type?: FadeType;
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* Apply a fade in to an AudioParam
|
|
557
|
-
*
|
|
558
|
-
* @param param - The AudioParam to apply the fade to (usually gain)
|
|
559
|
-
* @param startTime - When the fade starts (in seconds, AudioContext time)
|
|
560
|
-
* @param duration - Duration of the fade in seconds
|
|
561
|
-
* @param type - Type of fade curve
|
|
562
|
-
* @param startValue - Starting value (default: 0)
|
|
563
|
-
* @param endValue - Ending value (default: 1)
|
|
564
|
-
*/
|
|
565
|
-
declare function applyFadeIn(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
|
|
566
|
-
/**
|
|
567
|
-
* Apply a fade out to an AudioParam
|
|
568
|
-
*
|
|
569
|
-
* @param param - The AudioParam to apply the fade to (usually gain)
|
|
570
|
-
* @param startTime - When the fade starts (in seconds, AudioContext time)
|
|
571
|
-
* @param duration - Duration of the fade in seconds
|
|
572
|
-
* @param type - Type of fade curve
|
|
573
|
-
* @param startValue - Starting value (default: 1)
|
|
574
|
-
* @param endValue - Ending value (default: 0)
|
|
575
|
-
*/
|
|
576
|
-
declare function applyFadeOut(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
|
|
577
545
|
|
|
578
546
|
interface ToneAdapterOptions {
|
|
579
547
|
effects?: EffectsFunction;
|
|
@@ -582,4 +550,4 @@ interface ToneAdapterOptions {
|
|
|
582
550
|
}
|
|
583
551
|
declare function createToneAdapter(options?: ToneAdapterOptions): PlayoutAdapter;
|
|
584
552
|
|
|
585
|
-
export { type EffectsFunction, type
|
|
553
|
+
export { type EffectsFunction, type LoopAndEnvelopeParams, type MidiClipInfo, MidiToneTrack, type MidiToneTrackOptions, type PlayableTrack, type PlaybackRateParams, SoundFontCache, type SoundFontSample, SoundFontToneTrack, type SoundFontToneTrackOptions, type ToneAdapterOptions, TonePlayout, type TonePlayoutOptions, ToneTrack, type ToneTrackOptions, type TrackEffectsFunction, calculatePlaybackRate, closeGlobalAudioContext, createToneAdapter, extractLoopAndEnvelope, getGeneratorValue, getGlobalAudioContext, getGlobalAudioContextState, getGlobalContext, getGlobalToneContext, getMediaStreamSource, getUnderlyingAudioParam, hasMediaStreamSource, int16ToFloat32, releaseMediaStreamSource, resumeGlobalAudioContext, timecentsToSeconds };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Gain, ToneAudioNode, SynthOptions, Volume, BaseContext, Context } from 'tone';
|
|
2
2
|
import { Fade, Track, MidiNoteData } from '@waveform-playlist/core';
|
|
3
|
+
export { FadeConfig, FadeType, applyFadeIn, applyFadeOut } from '@waveform-playlist/core';
|
|
3
4
|
import { ZoneMap, Generator, GeneratorType } from 'soundfont2';
|
|
4
5
|
import { PlayoutAdapter } from '@waveform-playlist/engine';
|
|
5
6
|
|
|
@@ -536,44 +537,11 @@ declare function releaseMediaStreamSource(stream: MediaStream): void;
|
|
|
536
537
|
declare function hasMediaStreamSource(stream: MediaStream): boolean;
|
|
537
538
|
|
|
538
539
|
/**
|
|
539
|
-
* Fade utilities
|
|
540
|
-
*
|
|
541
|
-
* Applies fade in/out envelopes to AudioParam (typically gain)
|
|
542
|
-
* using various curve types.
|
|
540
|
+
* Fade utilities — re-exports from @waveform-playlist/core
|
|
541
|
+
* plus Tone.js-specific helpers
|
|
543
542
|
*/
|
|
543
|
+
|
|
544
544
|
declare function getUnderlyingAudioParam(signal: unknown): AudioParam | undefined;
|
|
545
|
-
type FadeType = 'linear' | 'logarithmic' | 'exponential' | 'sCurve';
|
|
546
|
-
/**
|
|
547
|
-
* Simple fade configuration - just duration and type
|
|
548
|
-
*/
|
|
549
|
-
interface FadeConfig {
|
|
550
|
-
/** Duration of the fade in seconds */
|
|
551
|
-
duration: number;
|
|
552
|
-
/** Type of fade curve (default: 'linear') */
|
|
553
|
-
type?: FadeType;
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* Apply a fade in to an AudioParam
|
|
557
|
-
*
|
|
558
|
-
* @param param - The AudioParam to apply the fade to (usually gain)
|
|
559
|
-
* @param startTime - When the fade starts (in seconds, AudioContext time)
|
|
560
|
-
* @param duration - Duration of the fade in seconds
|
|
561
|
-
* @param type - Type of fade curve
|
|
562
|
-
* @param startValue - Starting value (default: 0)
|
|
563
|
-
* @param endValue - Ending value (default: 1)
|
|
564
|
-
*/
|
|
565
|
-
declare function applyFadeIn(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
|
|
566
|
-
/**
|
|
567
|
-
* Apply a fade out to an AudioParam
|
|
568
|
-
*
|
|
569
|
-
* @param param - The AudioParam to apply the fade to (usually gain)
|
|
570
|
-
* @param startTime - When the fade starts (in seconds, AudioContext time)
|
|
571
|
-
* @param duration - Duration of the fade in seconds
|
|
572
|
-
* @param type - Type of fade curve
|
|
573
|
-
* @param startValue - Starting value (default: 1)
|
|
574
|
-
* @param endValue - Ending value (default: 0)
|
|
575
|
-
*/
|
|
576
|
-
declare function applyFadeOut(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
|
|
577
545
|
|
|
578
546
|
interface ToneAdapterOptions {
|
|
579
547
|
effects?: EffectsFunction;
|
|
@@ -582,4 +550,4 @@ interface ToneAdapterOptions {
|
|
|
582
550
|
}
|
|
583
551
|
declare function createToneAdapter(options?: ToneAdapterOptions): PlayoutAdapter;
|
|
584
552
|
|
|
585
|
-
export { type EffectsFunction, type
|
|
553
|
+
export { type EffectsFunction, type LoopAndEnvelopeParams, type MidiClipInfo, MidiToneTrack, type MidiToneTrackOptions, type PlayableTrack, type PlaybackRateParams, SoundFontCache, type SoundFontSample, SoundFontToneTrack, type SoundFontToneTrackOptions, type ToneAdapterOptions, TonePlayout, type TonePlayoutOptions, ToneTrack, type ToneTrackOptions, type TrackEffectsFunction, calculatePlaybackRate, closeGlobalAudioContext, createToneAdapter, extractLoopAndEnvelope, getGeneratorValue, getGlobalAudioContext, getGlobalAudioContextState, getGlobalContext, getGlobalToneContext, getMediaStreamSource, getUnderlyingAudioParam, hasMediaStreamSource, int16ToFloat32, releaseMediaStreamSource, resumeGlobalAudioContext, timecentsToSeconds };
|
package/dist/index.js
CHANGED
|
@@ -25,8 +25,8 @@ __export(index_exports, {
|
|
|
25
25
|
SoundFontToneTrack: () => SoundFontToneTrack,
|
|
26
26
|
TonePlayout: () => TonePlayout,
|
|
27
27
|
ToneTrack: () => ToneTrack,
|
|
28
|
-
applyFadeIn: () => applyFadeIn,
|
|
29
|
-
applyFadeOut: () => applyFadeOut,
|
|
28
|
+
applyFadeIn: () => import_core.applyFadeIn,
|
|
29
|
+
applyFadeOut: () => import_core.applyFadeOut,
|
|
30
30
|
calculatePlaybackRate: () => calculatePlaybackRate,
|
|
31
31
|
closeGlobalAudioContext: () => closeGlobalAudioContext,
|
|
32
32
|
createToneAdapter: () => createToneAdapter,
|
|
@@ -53,6 +53,7 @@ var import_tone4 = require("tone");
|
|
|
53
53
|
var import_tone = require("tone");
|
|
54
54
|
|
|
55
55
|
// src/fades.ts
|
|
56
|
+
var import_core = require("@waveform-playlist/core");
|
|
56
57
|
var hasWarned = false;
|
|
57
58
|
function getUnderlyingAudioParam(signal) {
|
|
58
59
|
const param = signal._param;
|
|
@@ -64,92 +65,6 @@ function getUnderlyingAudioParam(signal) {
|
|
|
64
65
|
}
|
|
65
66
|
return param;
|
|
66
67
|
}
|
|
67
|
-
function linearCurve(length, fadeIn) {
|
|
68
|
-
const curve = new Float32Array(length);
|
|
69
|
-
const scale = length - 1;
|
|
70
|
-
for (let i = 0; i < length; i++) {
|
|
71
|
-
const x = i / scale;
|
|
72
|
-
curve[i] = fadeIn ? x : 1 - x;
|
|
73
|
-
}
|
|
74
|
-
return curve;
|
|
75
|
-
}
|
|
76
|
-
function exponentialCurve(length, fadeIn) {
|
|
77
|
-
const curve = new Float32Array(length);
|
|
78
|
-
const scale = length - 1;
|
|
79
|
-
for (let i = 0; i < length; i++) {
|
|
80
|
-
const x = i / scale;
|
|
81
|
-
const index = fadeIn ? i : length - 1 - i;
|
|
82
|
-
curve[index] = Math.exp(2 * x - 1) / Math.E;
|
|
83
|
-
}
|
|
84
|
-
return curve;
|
|
85
|
-
}
|
|
86
|
-
function sCurveCurve(length, fadeIn) {
|
|
87
|
-
const curve = new Float32Array(length);
|
|
88
|
-
const phase = fadeIn ? Math.PI / 2 : -Math.PI / 2;
|
|
89
|
-
for (let i = 0; i < length; i++) {
|
|
90
|
-
curve[i] = Math.sin(Math.PI * i / length - phase) / 2 + 0.5;
|
|
91
|
-
}
|
|
92
|
-
return curve;
|
|
93
|
-
}
|
|
94
|
-
function logarithmicCurve(length, fadeIn, base = 10) {
|
|
95
|
-
const curve = new Float32Array(length);
|
|
96
|
-
for (let i = 0; i < length; i++) {
|
|
97
|
-
const index = fadeIn ? i : length - 1 - i;
|
|
98
|
-
const x = i / length;
|
|
99
|
-
curve[index] = Math.log(1 + base * x) / Math.log(1 + base);
|
|
100
|
-
}
|
|
101
|
-
return curve;
|
|
102
|
-
}
|
|
103
|
-
function generateCurve(type, length, fadeIn) {
|
|
104
|
-
switch (type) {
|
|
105
|
-
case "linear":
|
|
106
|
-
return linearCurve(length, fadeIn);
|
|
107
|
-
case "exponential":
|
|
108
|
-
return exponentialCurve(length, fadeIn);
|
|
109
|
-
case "sCurve":
|
|
110
|
-
return sCurveCurve(length, fadeIn);
|
|
111
|
-
case "logarithmic":
|
|
112
|
-
return logarithmicCurve(length, fadeIn);
|
|
113
|
-
default:
|
|
114
|
-
return linearCurve(length, fadeIn);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
function applyFadeIn(param, startTime, duration, type = "linear", startValue = 0, endValue = 1) {
|
|
118
|
-
if (duration <= 0) return;
|
|
119
|
-
if (type === "linear") {
|
|
120
|
-
param.setValueAtTime(startValue, startTime);
|
|
121
|
-
param.linearRampToValueAtTime(endValue, startTime + duration);
|
|
122
|
-
} else if (type === "exponential") {
|
|
123
|
-
param.setValueAtTime(Math.max(startValue, 1e-3), startTime);
|
|
124
|
-
param.exponentialRampToValueAtTime(Math.max(endValue, 1e-3), startTime + duration);
|
|
125
|
-
} else {
|
|
126
|
-
const curve = generateCurve(type, 1e4, true);
|
|
127
|
-
const scaledCurve = new Float32Array(curve.length);
|
|
128
|
-
const range = endValue - startValue;
|
|
129
|
-
for (let i = 0; i < curve.length; i++) {
|
|
130
|
-
scaledCurve[i] = startValue + curve[i] * range;
|
|
131
|
-
}
|
|
132
|
-
param.setValueCurveAtTime(scaledCurve, startTime, duration);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function applyFadeOut(param, startTime, duration, type = "linear", startValue = 1, endValue = 0) {
|
|
136
|
-
if (duration <= 0) return;
|
|
137
|
-
if (type === "linear") {
|
|
138
|
-
param.setValueAtTime(startValue, startTime);
|
|
139
|
-
param.linearRampToValueAtTime(endValue, startTime + duration);
|
|
140
|
-
} else if (type === "exponential") {
|
|
141
|
-
param.setValueAtTime(Math.max(startValue, 1e-3), startTime);
|
|
142
|
-
param.exponentialRampToValueAtTime(Math.max(endValue, 1e-3), startTime + duration);
|
|
143
|
-
} else {
|
|
144
|
-
const curve = generateCurve(type, 1e4, false);
|
|
145
|
-
const scaledCurve = new Float32Array(curve.length);
|
|
146
|
-
const range = startValue - endValue;
|
|
147
|
-
for (let i = 0; i < curve.length; i++) {
|
|
148
|
-
scaledCurve[i] = endValue + curve[i] * range;
|
|
149
|
-
}
|
|
150
|
-
param.setValueCurveAtTime(scaledCurve, startTime, duration);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
68
|
|
|
154
69
|
// src/ToneTrack.ts
|
|
155
70
|
var ToneTrack = class {
|
|
@@ -164,7 +79,7 @@ var ToneTrack = class {
|
|
|
164
79
|
this._scheduleGuardOffset = 0;
|
|
165
80
|
this.track = options.track;
|
|
166
81
|
this.volumeNode = new import_tone.Volume(this.gainToDb(options.track.gain));
|
|
167
|
-
this.panNode = new import_tone.Panner(options.track.stereoPan);
|
|
82
|
+
this.panNode = new import_tone.Panner({ pan: options.track.stereoPan, channelCount: 2 });
|
|
168
83
|
this.muteGain = new import_tone.Gain(options.track.muted ? 0 : 1);
|
|
169
84
|
this.volumeNode.chain(this.panNode, this.muteGain);
|
|
170
85
|
const destination = options.destination || (0, import_tone.getDestination)();
|
|
@@ -291,7 +206,7 @@ var ToneTrack = class {
|
|
|
291
206
|
if (clipInfo.fadeIn && skipTime < clipInfo.fadeIn.duration) {
|
|
292
207
|
const fadeInDuration = clipInfo.fadeIn.duration;
|
|
293
208
|
if (skipTime <= 0) {
|
|
294
|
-
applyFadeIn(
|
|
209
|
+
(0, import_core.applyFadeIn)(
|
|
295
210
|
audioParam,
|
|
296
211
|
clipStartTime2,
|
|
297
212
|
fadeInDuration,
|
|
@@ -303,7 +218,7 @@ var ToneTrack = class {
|
|
|
303
218
|
const remainingFadeDuration = fadeInDuration - skipTime;
|
|
304
219
|
const fadeProgress = skipTime / fadeInDuration;
|
|
305
220
|
const startValue = clipInfo.gain * fadeProgress;
|
|
306
|
-
applyFadeIn(
|
|
221
|
+
(0, import_core.applyFadeIn)(
|
|
307
222
|
audioParam,
|
|
308
223
|
clipStartTime2,
|
|
309
224
|
remainingFadeDuration,
|
|
@@ -320,7 +235,7 @@ var ToneTrack = class {
|
|
|
320
235
|
const fadeOutStartInClip = fadeOutStart - skipTime;
|
|
321
236
|
if (fadeOutStartInClip > 0) {
|
|
322
237
|
const absoluteFadeOutStart = clipStartTime2 + fadeOutStartInClip;
|
|
323
|
-
applyFadeOut(
|
|
238
|
+
(0, import_core.applyFadeOut)(
|
|
324
239
|
audioParam,
|
|
325
240
|
absoluteFadeOutStart,
|
|
326
241
|
clipInfo.fadeOut.duration,
|
|
@@ -333,7 +248,7 @@ var ToneTrack = class {
|
|
|
333
248
|
const remainingFadeDuration = clipInfo.fadeOut.duration - elapsedFadeOut;
|
|
334
249
|
const fadeProgress = elapsedFadeOut / clipInfo.fadeOut.duration;
|
|
335
250
|
const startValue = clipInfo.gain * (1 - fadeProgress);
|
|
336
|
-
applyFadeOut(
|
|
251
|
+
(0, import_core.applyFadeOut)(
|
|
337
252
|
audioParam,
|
|
338
253
|
clipStartTime2,
|
|
339
254
|
remainingFadeDuration,
|
|
@@ -1543,7 +1458,7 @@ function hasMediaStreamSource(stream) {
|
|
|
1543
1458
|
}
|
|
1544
1459
|
|
|
1545
1460
|
// src/TonePlayoutAdapter.ts
|
|
1546
|
-
var
|
|
1461
|
+
var import_core2 = require("@waveform-playlist/core");
|
|
1547
1462
|
var import_tone7 = require("tone");
|
|
1548
1463
|
function createToneAdapter(options) {
|
|
1549
1464
|
let playout = null;
|
|
@@ -1553,6 +1468,84 @@ function createToneAdapter(options) {
|
|
|
1553
1468
|
let _loopStart = 0;
|
|
1554
1469
|
let _loopEnd = 0;
|
|
1555
1470
|
let _audioInitialized = false;
|
|
1471
|
+
function addTrackToPlayout(p, track) {
|
|
1472
|
+
const audioClips = track.clips.filter((c) => c.audioBuffer && !c.midiNotes);
|
|
1473
|
+
const midiClips = track.clips.filter((c) => c.midiNotes && c.midiNotes.length > 0);
|
|
1474
|
+
if (audioClips.length > 0) {
|
|
1475
|
+
const startTime = Math.min(...audioClips.map(import_core2.clipStartTime));
|
|
1476
|
+
const endTime = Math.max(...audioClips.map(import_core2.clipEndTime));
|
|
1477
|
+
const trackObj = {
|
|
1478
|
+
id: track.id,
|
|
1479
|
+
name: track.name,
|
|
1480
|
+
gain: track.volume,
|
|
1481
|
+
muted: track.muted,
|
|
1482
|
+
soloed: track.soloed,
|
|
1483
|
+
stereoPan: track.pan,
|
|
1484
|
+
startTime,
|
|
1485
|
+
endTime
|
|
1486
|
+
};
|
|
1487
|
+
const clipInfos = audioClips.map((clip) => ({
|
|
1488
|
+
buffer: clip.audioBuffer,
|
|
1489
|
+
startTime: (0, import_core2.clipStartTime)(clip) - startTime,
|
|
1490
|
+
duration: (0, import_core2.clipDurationTime)(clip),
|
|
1491
|
+
offset: (0, import_core2.clipOffsetTime)(clip),
|
|
1492
|
+
fadeIn: clip.fadeIn,
|
|
1493
|
+
fadeOut: clip.fadeOut,
|
|
1494
|
+
gain: clip.gain
|
|
1495
|
+
}));
|
|
1496
|
+
p.addTrack({
|
|
1497
|
+
clips: clipInfos,
|
|
1498
|
+
track: trackObj,
|
|
1499
|
+
effects: track.effects
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
if (midiClips.length > 0) {
|
|
1503
|
+
const startTime = Math.min(...midiClips.map(import_core2.clipStartTime));
|
|
1504
|
+
const endTime = Math.max(...midiClips.map(import_core2.clipEndTime));
|
|
1505
|
+
const trackId = audioClips.length > 0 ? `${track.id}:midi` : track.id;
|
|
1506
|
+
const trackObj = {
|
|
1507
|
+
id: trackId,
|
|
1508
|
+
name: track.name,
|
|
1509
|
+
gain: track.volume,
|
|
1510
|
+
muted: track.muted,
|
|
1511
|
+
soloed: track.soloed,
|
|
1512
|
+
stereoPan: track.pan,
|
|
1513
|
+
startTime,
|
|
1514
|
+
endTime
|
|
1515
|
+
};
|
|
1516
|
+
const midiClipInfos = midiClips.map((clip) => ({
|
|
1517
|
+
notes: clip.midiNotes,
|
|
1518
|
+
startTime: (0, import_core2.clipStartTime)(clip) - startTime,
|
|
1519
|
+
duration: (0, import_core2.clipDurationTime)(clip),
|
|
1520
|
+
offset: (0, import_core2.clipOffsetTime)(clip)
|
|
1521
|
+
}));
|
|
1522
|
+
if (options?.soundFontCache?.isLoaded) {
|
|
1523
|
+
const firstClip = midiClips[0];
|
|
1524
|
+
const midiChannel = firstClip.midiChannel;
|
|
1525
|
+
const isPercussion = midiChannel === 9;
|
|
1526
|
+
const programNumber = firstClip.midiProgram ?? 0;
|
|
1527
|
+
p.addSoundFontTrack({
|
|
1528
|
+
clips: midiClipInfos,
|
|
1529
|
+
track: trackObj,
|
|
1530
|
+
soundFontCache: options.soundFontCache,
|
|
1531
|
+
programNumber,
|
|
1532
|
+
isPercussion,
|
|
1533
|
+
effects: track.effects
|
|
1534
|
+
});
|
|
1535
|
+
} else {
|
|
1536
|
+
if (options?.soundFontCache) {
|
|
1537
|
+
console.warn(
|
|
1538
|
+
`[waveform-playlist] SoundFont not loaded for track "${track.name}" \u2014 falling back to PolySynth.`
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
p.addMidiTrack({
|
|
1542
|
+
clips: midiClipInfos,
|
|
1543
|
+
track: trackObj,
|
|
1544
|
+
effects: track.effects
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1556
1549
|
function buildPlayout(tracks) {
|
|
1557
1550
|
if (playout) {
|
|
1558
1551
|
try {
|
|
@@ -1577,82 +1570,7 @@ function createToneAdapter(options) {
|
|
|
1577
1570
|
});
|
|
1578
1571
|
}
|
|
1579
1572
|
for (const track of tracks) {
|
|
1580
|
-
|
|
1581
|
-
const midiClips = track.clips.filter((c) => c.midiNotes && c.midiNotes.length > 0);
|
|
1582
|
-
if (audioClips.length > 0) {
|
|
1583
|
-
const startTime = Math.min(...audioClips.map(import_core.clipStartTime));
|
|
1584
|
-
const endTime = Math.max(...audioClips.map(import_core.clipEndTime));
|
|
1585
|
-
const trackObj = {
|
|
1586
|
-
id: track.id,
|
|
1587
|
-
name: track.name,
|
|
1588
|
-
gain: track.volume,
|
|
1589
|
-
muted: track.muted,
|
|
1590
|
-
soloed: track.soloed,
|
|
1591
|
-
stereoPan: track.pan,
|
|
1592
|
-
startTime,
|
|
1593
|
-
endTime
|
|
1594
|
-
};
|
|
1595
|
-
const clipInfos = audioClips.map((clip) => ({
|
|
1596
|
-
buffer: clip.audioBuffer,
|
|
1597
|
-
startTime: (0, import_core.clipStartTime)(clip) - startTime,
|
|
1598
|
-
duration: (0, import_core.clipDurationTime)(clip),
|
|
1599
|
-
offset: (0, import_core.clipOffsetTime)(clip),
|
|
1600
|
-
fadeIn: clip.fadeIn,
|
|
1601
|
-
fadeOut: clip.fadeOut,
|
|
1602
|
-
gain: clip.gain
|
|
1603
|
-
}));
|
|
1604
|
-
playout.addTrack({
|
|
1605
|
-
clips: clipInfos,
|
|
1606
|
-
track: trackObj,
|
|
1607
|
-
effects: track.effects
|
|
1608
|
-
});
|
|
1609
|
-
}
|
|
1610
|
-
if (midiClips.length > 0) {
|
|
1611
|
-
const startTime = Math.min(...midiClips.map(import_core.clipStartTime));
|
|
1612
|
-
const endTime = Math.max(...midiClips.map(import_core.clipEndTime));
|
|
1613
|
-
const trackId = audioClips.length > 0 ? `${track.id}:midi` : track.id;
|
|
1614
|
-
const trackObj = {
|
|
1615
|
-
id: trackId,
|
|
1616
|
-
name: track.name,
|
|
1617
|
-
gain: track.volume,
|
|
1618
|
-
muted: track.muted,
|
|
1619
|
-
soloed: track.soloed,
|
|
1620
|
-
stereoPan: track.pan,
|
|
1621
|
-
startTime,
|
|
1622
|
-
endTime
|
|
1623
|
-
};
|
|
1624
|
-
const midiClipInfos = midiClips.map((clip) => ({
|
|
1625
|
-
notes: clip.midiNotes,
|
|
1626
|
-
startTime: (0, import_core.clipStartTime)(clip) - startTime,
|
|
1627
|
-
duration: (0, import_core.clipDurationTime)(clip),
|
|
1628
|
-
offset: (0, import_core.clipOffsetTime)(clip)
|
|
1629
|
-
}));
|
|
1630
|
-
if (options?.soundFontCache?.isLoaded) {
|
|
1631
|
-
const firstClip = midiClips[0];
|
|
1632
|
-
const midiChannel = firstClip.midiChannel;
|
|
1633
|
-
const isPercussion = midiChannel === 9;
|
|
1634
|
-
const programNumber = firstClip.midiProgram ?? 0;
|
|
1635
|
-
playout.addSoundFontTrack({
|
|
1636
|
-
clips: midiClipInfos,
|
|
1637
|
-
track: trackObj,
|
|
1638
|
-
soundFontCache: options.soundFontCache,
|
|
1639
|
-
programNumber,
|
|
1640
|
-
isPercussion,
|
|
1641
|
-
effects: track.effects
|
|
1642
|
-
});
|
|
1643
|
-
} else {
|
|
1644
|
-
if (options?.soundFontCache) {
|
|
1645
|
-
console.warn(
|
|
1646
|
-
`[waveform-playlist] SoundFont not loaded for track "${track.name}" \u2014 falling back to PolySynth.`
|
|
1647
|
-
);
|
|
1648
|
-
}
|
|
1649
|
-
playout.addMidiTrack({
|
|
1650
|
-
clips: midiClipInfos,
|
|
1651
|
-
track: trackObj,
|
|
1652
|
-
effects: track.effects
|
|
1653
|
-
});
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1573
|
+
addTrackToPlayout(playout, track);
|
|
1656
1574
|
}
|
|
1657
1575
|
playout.applyInitialSoloState();
|
|
1658
1576
|
playout.setLoop(_loopEnabled, _loopStart, _loopEnd);
|
|
@@ -1672,6 +1590,15 @@ function createToneAdapter(options) {
|
|
|
1672
1590
|
setTracks(tracks) {
|
|
1673
1591
|
buildPlayout(tracks);
|
|
1674
1592
|
},
|
|
1593
|
+
addTrack(track) {
|
|
1594
|
+
if (!playout) {
|
|
1595
|
+
throw new Error(
|
|
1596
|
+
"[waveform-playlist] adapter.addTrack() called but no playout exists. Call setTracks() first to initialize the playout."
|
|
1597
|
+
);
|
|
1598
|
+
}
|
|
1599
|
+
addTrackToPlayout(playout, track);
|
|
1600
|
+
playout.applyInitialSoloState();
|
|
1601
|
+
},
|
|
1675
1602
|
play(startTime, endTime) {
|
|
1676
1603
|
if (!playout) {
|
|
1677
1604
|
console.warn(
|