@waveform-playlist/playout 11.3.0 → 12.0.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 +2 -5
- package/dist/index.d.ts +2 -5
- package/dist/index.js +33 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
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';
|
|
4
3
|
import { ZoneMap, Generator, GeneratorType } from 'soundfont2';
|
|
5
4
|
import { PlayoutAdapter } from '@waveform-playlist/engine';
|
|
6
5
|
|
|
@@ -20,6 +19,8 @@ interface ToneTrackOptions {
|
|
|
20
19
|
track: Track;
|
|
21
20
|
effects?: TrackEffectsFunction;
|
|
22
21
|
destination?: ToneAudioNode;
|
|
22
|
+
/** Max channel count across clips — sets Panner channelCount. Default: 1 */
|
|
23
|
+
channelCount?: number;
|
|
23
24
|
}
|
|
24
25
|
/** Per-clip scheduling info and audio nodes */
|
|
25
26
|
interface ScheduledClip {
|
|
@@ -98,7 +99,6 @@ declare class ToneTrack {
|
|
|
98
99
|
* Called on pause/stop to prevent stale fade envelopes.
|
|
99
100
|
*/
|
|
100
101
|
cancelFades(): void;
|
|
101
|
-
private gainToDb;
|
|
102
102
|
setVolume(gain: number): void;
|
|
103
103
|
setPan(pan: number): void;
|
|
104
104
|
setMute(muted: boolean): void;
|
|
@@ -169,7 +169,6 @@ declare class MidiToneTrack implements PlayableTrack {
|
|
|
169
169
|
* Routes per-note: channel 9 → percussion synths, others → melodic PolySynth.
|
|
170
170
|
*/
|
|
171
171
|
private triggerNote;
|
|
172
|
-
private gainToDb;
|
|
173
172
|
/**
|
|
174
173
|
* No-op for MIDI — schedule guard is for AudioBufferSourceNode ghost tick prevention.
|
|
175
174
|
* Tone.Part handles its own scheduling relative to Transport.
|
|
@@ -390,7 +389,6 @@ declare class SoundFontToneTrack implements PlayableTrack {
|
|
|
390
389
|
* Per-note routing: channel 9 → bank 128 (drums), others → bank 0 with programNumber.
|
|
391
390
|
*/
|
|
392
391
|
private triggerNote;
|
|
393
|
-
private gainToDb;
|
|
394
392
|
/**
|
|
395
393
|
* No-op — Tone.Part handles scheduling internally, no ghost tick guard needed.
|
|
396
394
|
*/
|
|
@@ -438,7 +436,6 @@ declare class TonePlayout {
|
|
|
438
436
|
private _loopStart;
|
|
439
437
|
private _loopEnd;
|
|
440
438
|
constructor(options?: TonePlayoutOptions);
|
|
441
|
-
private gainToDb;
|
|
442
439
|
private clearCompletionEvent;
|
|
443
440
|
init(): Promise<void>;
|
|
444
441
|
addTrack(trackOptions: ToneTrackOptions): ToneTrack;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
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';
|
|
4
3
|
import { ZoneMap, Generator, GeneratorType } from 'soundfont2';
|
|
5
4
|
import { PlayoutAdapter } from '@waveform-playlist/engine';
|
|
6
5
|
|
|
@@ -20,6 +19,8 @@ interface ToneTrackOptions {
|
|
|
20
19
|
track: Track;
|
|
21
20
|
effects?: TrackEffectsFunction;
|
|
22
21
|
destination?: ToneAudioNode;
|
|
22
|
+
/** Max channel count across clips — sets Panner channelCount. Default: 1 */
|
|
23
|
+
channelCount?: number;
|
|
23
24
|
}
|
|
24
25
|
/** Per-clip scheduling info and audio nodes */
|
|
25
26
|
interface ScheduledClip {
|
|
@@ -98,7 +99,6 @@ declare class ToneTrack {
|
|
|
98
99
|
* Called on pause/stop to prevent stale fade envelopes.
|
|
99
100
|
*/
|
|
100
101
|
cancelFades(): void;
|
|
101
|
-
private gainToDb;
|
|
102
102
|
setVolume(gain: number): void;
|
|
103
103
|
setPan(pan: number): void;
|
|
104
104
|
setMute(muted: boolean): void;
|
|
@@ -169,7 +169,6 @@ declare class MidiToneTrack implements PlayableTrack {
|
|
|
169
169
|
* Routes per-note: channel 9 → percussion synths, others → melodic PolySynth.
|
|
170
170
|
*/
|
|
171
171
|
private triggerNote;
|
|
172
|
-
private gainToDb;
|
|
173
172
|
/**
|
|
174
173
|
* No-op for MIDI — schedule guard is for AudioBufferSourceNode ghost tick prevention.
|
|
175
174
|
* Tone.Part handles its own scheduling relative to Transport.
|
|
@@ -390,7 +389,6 @@ declare class SoundFontToneTrack implements PlayableTrack {
|
|
|
390
389
|
* Per-note routing: channel 9 → bank 128 (drums), others → bank 0 with programNumber.
|
|
391
390
|
*/
|
|
392
391
|
private triggerNote;
|
|
393
|
-
private gainToDb;
|
|
394
392
|
/**
|
|
395
393
|
* No-op — Tone.Part handles scheduling internally, no ghost tick guard needed.
|
|
396
394
|
*/
|
|
@@ -438,7 +436,6 @@ declare class TonePlayout {
|
|
|
438
436
|
private _loopStart;
|
|
439
437
|
private _loopEnd;
|
|
440
438
|
constructor(options?: TonePlayoutOptions);
|
|
441
|
-
private gainToDb;
|
|
442
439
|
private clearCompletionEvent;
|
|
443
440
|
init(): Promise<void>;
|
|
444
441
|
addTrack(trackOptions: ToneTrackOptions): ToneTrack;
|
package/dist/index.js
CHANGED
|
@@ -25,8 +25,6 @@ __export(index_exports, {
|
|
|
25
25
|
SoundFontToneTrack: () => SoundFontToneTrack,
|
|
26
26
|
TonePlayout: () => TonePlayout,
|
|
27
27
|
ToneTrack: () => ToneTrack,
|
|
28
|
-
applyFadeIn: () => import_core.applyFadeIn,
|
|
29
|
-
applyFadeOut: () => import_core.applyFadeOut,
|
|
30
28
|
calculatePlaybackRate: () => calculatePlaybackRate,
|
|
31
29
|
closeGlobalAudioContext: () => closeGlobalAudioContext,
|
|
32
30
|
configureGlobalContext: () => configureGlobalContext,
|
|
@@ -49,9 +47,11 @@ module.exports = __toCommonJS(index_exports);
|
|
|
49
47
|
|
|
50
48
|
// src/TonePlayout.ts
|
|
51
49
|
var import_tone4 = require("tone");
|
|
50
|
+
var import_core5 = require("@waveform-playlist/core");
|
|
52
51
|
|
|
53
52
|
// src/ToneTrack.ts
|
|
54
53
|
var import_tone = require("tone");
|
|
54
|
+
var import_core2 = require("@waveform-playlist/core");
|
|
55
55
|
|
|
56
56
|
// src/fades.ts
|
|
57
57
|
var import_core = require("@waveform-playlist/core");
|
|
@@ -79,8 +79,11 @@ var ToneTrack = class {
|
|
|
79
79
|
// clips at/after this offset.
|
|
80
80
|
this._scheduleGuardOffset = 0;
|
|
81
81
|
this.track = options.track;
|
|
82
|
-
this.volumeNode = new import_tone.Volume(
|
|
83
|
-
this.panNode = new import_tone.Panner({
|
|
82
|
+
this.volumeNode = new import_tone.Volume((0, import_core2.gainToDb)(options.track.gain));
|
|
83
|
+
this.panNode = new import_tone.Panner({
|
|
84
|
+
pan: options.track.stereoPan,
|
|
85
|
+
channelCount: options.channelCount ?? 1
|
|
86
|
+
});
|
|
84
87
|
this.muteGain = new import_tone.Gain(options.track.muted ? 0 : 1);
|
|
85
88
|
this.volumeNode.chain(this.panNode, this.muteGain);
|
|
86
89
|
const destination = options.destination || (0, import_tone.getDestination)();
|
|
@@ -412,12 +415,9 @@ var ToneTrack = class {
|
|
|
412
415
|
audioParam.setValueAtTime(clipInfo.gain, 0);
|
|
413
416
|
});
|
|
414
417
|
}
|
|
415
|
-
gainToDb(gain) {
|
|
416
|
-
return 20 * Math.log10(gain);
|
|
417
|
-
}
|
|
418
418
|
setVolume(gain) {
|
|
419
419
|
this.track.gain = gain;
|
|
420
|
-
this.volumeNode.volume.value =
|
|
420
|
+
this.volumeNode.volume.value = (0, import_core2.gainToDb)(gain);
|
|
421
421
|
}
|
|
422
422
|
setPan(pan) {
|
|
423
423
|
this.track.stereoPan = pan;
|
|
@@ -498,6 +498,7 @@ var ToneTrack = class {
|
|
|
498
498
|
|
|
499
499
|
// src/MidiToneTrack.ts
|
|
500
500
|
var import_tone2 = require("tone");
|
|
501
|
+
var import_core3 = require("@waveform-playlist/core");
|
|
501
502
|
function getDrumCategory(midiNote) {
|
|
502
503
|
if (midiNote === 35 || midiNote === 36) return "kick";
|
|
503
504
|
if (midiNote >= 37 && midiNote <= 40) return "snare";
|
|
@@ -508,7 +509,7 @@ function getDrumCategory(midiNote) {
|
|
|
508
509
|
var MidiToneTrack = class {
|
|
509
510
|
constructor(options) {
|
|
510
511
|
this.track = options.track;
|
|
511
|
-
this.volumeNode = new import_tone2.Volume(
|
|
512
|
+
this.volumeNode = new import_tone2.Volume((0, import_core3.gainToDb)(options.track.gain));
|
|
512
513
|
this.panNode = new import_tone2.Panner(options.track.stereoPan);
|
|
513
514
|
this.muteGain = new import_tone2.Gain(options.track.muted ? 0 : 1);
|
|
514
515
|
this.volumeNode.chain(this.panNode, this.muteGain);
|
|
@@ -641,9 +642,6 @@ var MidiToneTrack = class {
|
|
|
641
642
|
this.synth.triggerAttackRelease(noteName, duration, time, velocity);
|
|
642
643
|
}
|
|
643
644
|
}
|
|
644
|
-
gainToDb(gain) {
|
|
645
|
-
return 20 * Math.log10(gain);
|
|
646
|
-
}
|
|
647
645
|
/**
|
|
648
646
|
* No-op for MIDI — schedule guard is for AudioBufferSourceNode ghost tick prevention.
|
|
649
647
|
* Tone.Part handles its own scheduling relative to Transport.
|
|
@@ -711,7 +709,7 @@ var MidiToneTrack = class {
|
|
|
711
709
|
}
|
|
712
710
|
setVolume(gain) {
|
|
713
711
|
this.track.gain = gain;
|
|
714
|
-
this.volumeNode.volume.value =
|
|
712
|
+
this.volumeNode.volume.value = (0, import_core3.gainToDb)(gain);
|
|
715
713
|
}
|
|
716
714
|
setPan(pan) {
|
|
717
715
|
this.track.stereoPan = pan;
|
|
@@ -800,6 +798,7 @@ var MidiToneTrack = class {
|
|
|
800
798
|
|
|
801
799
|
// src/SoundFontToneTrack.ts
|
|
802
800
|
var import_tone3 = require("tone");
|
|
801
|
+
var import_core4 = require("@waveform-playlist/core");
|
|
803
802
|
var _SoundFontToneTrack = class _SoundFontToneTrack {
|
|
804
803
|
constructor(options) {
|
|
805
804
|
this.activeSources = /* @__PURE__ */ new Set();
|
|
@@ -807,7 +806,7 @@ var _SoundFontToneTrack = class _SoundFontToneTrack {
|
|
|
807
806
|
this.soundFontCache = options.soundFontCache;
|
|
808
807
|
this.programNumber = options.programNumber ?? 0;
|
|
809
808
|
this.bankNumber = options.isPercussion ? 128 : 0;
|
|
810
|
-
this.volumeNode = new import_tone3.Volume(
|
|
809
|
+
this.volumeNode = new import_tone3.Volume((0, import_core4.gainToDb)(options.track.gain));
|
|
811
810
|
this.panNode = new import_tone3.Panner(options.track.stereoPan);
|
|
812
811
|
this.muteGain = new import_tone3.Gain(options.track.muted ? 0 : 1);
|
|
813
812
|
this.volumeNode.chain(this.panNode, this.muteGain);
|
|
@@ -907,9 +906,6 @@ var _SoundFontToneTrack = class _SoundFontToneTrack {
|
|
|
907
906
|
source.start(time);
|
|
908
907
|
source.stop(time + effectiveDuration + releaseVolEnv);
|
|
909
908
|
}
|
|
910
|
-
gainToDb(gain) {
|
|
911
|
-
return 20 * Math.log10(gain);
|
|
912
|
-
}
|
|
913
909
|
/**
|
|
914
910
|
* No-op — Tone.Part handles scheduling internally, no ghost tick guard needed.
|
|
915
911
|
*/
|
|
@@ -969,7 +965,7 @@ var _SoundFontToneTrack = class _SoundFontToneTrack {
|
|
|
969
965
|
}
|
|
970
966
|
setVolume(gain) {
|
|
971
967
|
this.track.gain = gain;
|
|
972
|
-
this.volumeNode.volume.value =
|
|
968
|
+
this.volumeNode.volume.value = (0, import_core4.gainToDb)(gain);
|
|
973
969
|
}
|
|
974
970
|
setPan(pan) {
|
|
975
971
|
this.track.stereoPan = pan;
|
|
@@ -1063,7 +1059,7 @@ var TonePlayout = class {
|
|
|
1063
1059
|
this._loopEnabled = false;
|
|
1064
1060
|
this._loopStart = 0;
|
|
1065
1061
|
this._loopEnd = 0;
|
|
1066
|
-
this.masterVolume = new import_tone4.Volume(
|
|
1062
|
+
this.masterVolume = new import_tone4.Volume((0, import_core5.gainToDb)(options.masterGain ?? 1));
|
|
1067
1063
|
if (options.effects) {
|
|
1068
1064
|
const cleanup = options.effects(this.masterVolume, (0, import_tone4.getDestination)(), false);
|
|
1069
1065
|
if (cleanup) {
|
|
@@ -1079,9 +1075,6 @@ var TonePlayout = class {
|
|
|
1079
1075
|
});
|
|
1080
1076
|
}
|
|
1081
1077
|
}
|
|
1082
|
-
gainToDb(gain) {
|
|
1083
|
-
return 20 * Math.log10(gain);
|
|
1084
|
-
}
|
|
1085
1078
|
clearCompletionEvent() {
|
|
1086
1079
|
if (this._completionEventId !== null) {
|
|
1087
1080
|
try {
|
|
@@ -1276,7 +1269,7 @@ var TonePlayout = class {
|
|
|
1276
1269
|
this.clearCompletionEvent();
|
|
1277
1270
|
}
|
|
1278
1271
|
setMasterGain(gain) {
|
|
1279
|
-
this.masterVolume.volume.value =
|
|
1272
|
+
this.masterVolume.volume.value = (0, import_core5.gainToDb)(gain);
|
|
1280
1273
|
}
|
|
1281
1274
|
setSolo(trackId, soloed) {
|
|
1282
1275
|
const track = this.tracks.get(trackId);
|
|
@@ -1630,7 +1623,7 @@ function hasMediaStreamSource(stream) {
|
|
|
1630
1623
|
}
|
|
1631
1624
|
|
|
1632
1625
|
// src/TonePlayoutAdapter.ts
|
|
1633
|
-
var
|
|
1626
|
+
var import_core6 = require("@waveform-playlist/core");
|
|
1634
1627
|
var import_tone7 = require("tone");
|
|
1635
1628
|
function createToneAdapter(options) {
|
|
1636
1629
|
let playout = null;
|
|
@@ -1645,8 +1638,8 @@ function createToneAdapter(options) {
|
|
|
1645
1638
|
const audioClips = track.clips.filter((c) => c.audioBuffer && !c.midiNotes);
|
|
1646
1639
|
const midiClips = track.clips.filter((c) => c.midiNotes && c.midiNotes.length > 0);
|
|
1647
1640
|
if (audioClips.length > 0) {
|
|
1648
|
-
const startTime = Math.min(...audioClips.map(
|
|
1649
|
-
const endTime = Math.max(...audioClips.map(
|
|
1641
|
+
const startTime = Math.min(...audioClips.map(import_core6.clipStartTime));
|
|
1642
|
+
const endTime = Math.max(...audioClips.map(import_core6.clipEndTime));
|
|
1650
1643
|
const trackObj = {
|
|
1651
1644
|
id: track.id,
|
|
1652
1645
|
name: track.name,
|
|
@@ -1659,9 +1652,9 @@ function createToneAdapter(options) {
|
|
|
1659
1652
|
};
|
|
1660
1653
|
const clipInfos = audioClips.map((clip) => ({
|
|
1661
1654
|
buffer: clip.audioBuffer,
|
|
1662
|
-
startTime: (0,
|
|
1663
|
-
duration: (0,
|
|
1664
|
-
offset: (0,
|
|
1655
|
+
startTime: (0, import_core6.clipStartTime)(clip) - startTime,
|
|
1656
|
+
duration: (0, import_core6.clipDurationTime)(clip),
|
|
1657
|
+
offset: (0, import_core6.clipOffsetTime)(clip),
|
|
1665
1658
|
fadeIn: clip.fadeIn,
|
|
1666
1659
|
fadeOut: clip.fadeOut,
|
|
1667
1660
|
gain: clip.gain
|
|
@@ -1669,12 +1662,13 @@ function createToneAdapter(options) {
|
|
|
1669
1662
|
p.addTrack({
|
|
1670
1663
|
clips: clipInfos,
|
|
1671
1664
|
track: trackObj,
|
|
1672
|
-
effects: track.effects
|
|
1665
|
+
effects: track.effects,
|
|
1666
|
+
channelCount: (0, import_core6.trackChannelCount)(track)
|
|
1673
1667
|
});
|
|
1674
1668
|
}
|
|
1675
1669
|
if (midiClips.length > 0) {
|
|
1676
|
-
const startTime = Math.min(...midiClips.map(
|
|
1677
|
-
const endTime = Math.max(...midiClips.map(
|
|
1670
|
+
const startTime = Math.min(...midiClips.map(import_core6.clipStartTime));
|
|
1671
|
+
const endTime = Math.max(...midiClips.map(import_core6.clipEndTime));
|
|
1678
1672
|
const trackId = audioClips.length > 0 ? `${track.id}:midi` : track.id;
|
|
1679
1673
|
const trackObj = {
|
|
1680
1674
|
id: trackId,
|
|
@@ -1688,9 +1682,9 @@ function createToneAdapter(options) {
|
|
|
1688
1682
|
};
|
|
1689
1683
|
const midiClipInfos = midiClips.map((clip) => ({
|
|
1690
1684
|
notes: clip.midiNotes,
|
|
1691
|
-
startTime: (0,
|
|
1692
|
-
duration: (0,
|
|
1693
|
-
offset: (0,
|
|
1685
|
+
startTime: (0, import_core6.clipStartTime)(clip) - startTime,
|
|
1686
|
+
duration: (0, import_core6.clipDurationTime)(clip),
|
|
1687
|
+
offset: (0, import_core6.clipOffsetTime)(clip)
|
|
1694
1688
|
}));
|
|
1695
1689
|
if (options?.soundFontCache?.isLoaded) {
|
|
1696
1690
|
const firstClip = midiClips[0];
|
|
@@ -1796,12 +1790,12 @@ function createToneAdapter(options) {
|
|
|
1796
1790
|
if (!playout) return;
|
|
1797
1791
|
const audioClips = track.clips.filter((c) => c.audioBuffer && !c.midiNotes);
|
|
1798
1792
|
if (audioClips.length > 0) {
|
|
1799
|
-
const startTime = Math.min(...audioClips.map(
|
|
1793
|
+
const startTime = Math.min(...audioClips.map(import_core6.clipStartTime));
|
|
1800
1794
|
const clipInfos = audioClips.map((clip) => ({
|
|
1801
1795
|
buffer: clip.audioBuffer,
|
|
1802
|
-
startTime: (0,
|
|
1803
|
-
duration: (0,
|
|
1804
|
-
offset: (0,
|
|
1796
|
+
startTime: (0, import_core6.clipStartTime)(clip) - startTime,
|
|
1797
|
+
duration: (0, import_core6.clipDurationTime)(clip),
|
|
1798
|
+
offset: (0, import_core6.clipOffsetTime)(clip),
|
|
1805
1799
|
fadeIn: clip.fadeIn,
|
|
1806
1800
|
fadeOut: clip.fadeOut,
|
|
1807
1801
|
gain: clip.gain
|
|
@@ -1911,8 +1905,6 @@ function createToneAdapter(options) {
|
|
|
1911
1905
|
SoundFontToneTrack,
|
|
1912
1906
|
TonePlayout,
|
|
1913
1907
|
ToneTrack,
|
|
1914
|
-
applyFadeIn,
|
|
1915
|
-
applyFadeOut,
|
|
1916
1908
|
calculatePlaybackRate,
|
|
1917
1909
|
closeGlobalAudioContext,
|
|
1918
1910
|
configureGlobalContext,
|