@waveform-playlist/playout 12.1.0 → 12.3.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 CHANGED
@@ -425,6 +425,7 @@ interface TonePlayoutOptions {
425
425
  declare class TonePlayout {
426
426
  private tracks;
427
427
  private masterVolume;
428
+ private _masterTap;
428
429
  private isInitialized;
429
430
  private soloedTracks;
430
431
  private manualMuteState;
@@ -464,6 +465,10 @@ declare class TonePlayout {
464
465
  pause(): void;
465
466
  stop(): void;
466
467
  setMasterGain(gain: number): void;
468
+ /** The master output tap node. In the signal chain: masterVolume → tap → destination.
469
+ * Connect analyzers/effects/recorders here — parallel or serial.
470
+ * The tap's native GainNode is on the same standardized-audio-context as adapter.audioContext. */
471
+ get masterOutputNode(): GainNode;
467
472
  setSolo(trackId: string, soloed: boolean): void;
468
473
  private updateSoloMuting;
469
474
  setMute(trackId: string, muted: boolean): void;
package/dist/index.d.ts CHANGED
@@ -425,6 +425,7 @@ interface TonePlayoutOptions {
425
425
  declare class TonePlayout {
426
426
  private tracks;
427
427
  private masterVolume;
428
+ private _masterTap;
428
429
  private isInitialized;
429
430
  private soloedTracks;
430
431
  private manualMuteState;
@@ -464,6 +465,10 @@ declare class TonePlayout {
464
465
  pause(): void;
465
466
  stop(): void;
466
467
  setMasterGain(gain: number): void;
468
+ /** The master output tap node. In the signal chain: masterVolume → tap → destination.
469
+ * Connect analyzers/effects/recorders here — parallel or serial.
470
+ * The tap's native GainNode is on the same standardized-audio-context as adapter.audioContext. */
471
+ get masterOutputNode(): GainNode;
467
472
  setSolo(trackId: string, soloed: boolean): void;
468
473
  private updateSoloMuting;
469
474
  setMute(trackId: string, muted: boolean): void;
package/dist/index.js CHANGED
@@ -1060,13 +1060,15 @@ var TonePlayout = class {
1060
1060
  this._loopStart = 0;
1061
1061
  this._loopEnd = 0;
1062
1062
  this.masterVolume = new import_tone4.Volume((0, import_core5.gainToDb)(options.masterGain ?? 1));
1063
+ this._masterTap = new import_tone4.Gain(1);
1063
1064
  if (options.effects) {
1064
- const cleanup = options.effects(this.masterVolume, (0, import_tone4.getDestination)(), false);
1065
+ const cleanup = options.effects(this.masterVolume, this._masterTap, false);
1065
1066
  if (cleanup) {
1066
1067
  this.effectsCleanup = cleanup;
1067
1068
  }
1069
+ this._masterTap.connect((0, import_tone4.getDestination)());
1068
1070
  } else {
1069
- this.masterVolume.toDestination();
1071
+ this.masterVolume.chain(this._masterTap, (0, import_tone4.getDestination)());
1070
1072
  }
1071
1073
  if (options.tracks) {
1072
1074
  options.tracks.forEach((track) => {
@@ -1271,6 +1273,12 @@ var TonePlayout = class {
1271
1273
  setMasterGain(gain) {
1272
1274
  this.masterVolume.volume.value = (0, import_core5.gainToDb)(gain);
1273
1275
  }
1276
+ /** The master output tap node. In the signal chain: masterVolume → tap → destination.
1277
+ * Connect analyzers/effects/recorders here — parallel or serial.
1278
+ * The tap's native GainNode is on the same standardized-audio-context as adapter.audioContext. */
1279
+ get masterOutputNode() {
1280
+ return this._masterTap.input;
1281
+ }
1274
1282
  setSolo(trackId, soloed) {
1275
1283
  const track = this.tracks.get(trackId);
1276
1284
  if (track) {
@@ -1370,10 +1378,15 @@ var TonePlayout = class {
1370
1378
  console.warn("[waveform-playlist] Error during master effects cleanup:", err);
1371
1379
  }
1372
1380
  }
1381
+ try {
1382
+ this._masterTap.dispose();
1383
+ } catch (err) {
1384
+ console.warn("[waveform-playlist] Error disposing master tap: " + String(err));
1385
+ }
1373
1386
  try {
1374
1387
  this.masterVolume.dispose();
1375
1388
  } catch (err) {
1376
- console.warn("[waveform-playlist] Error disposing master volume:", err);
1389
+ console.warn("[waveform-playlist] Error disposing master volume: " + String(err));
1377
1390
  }
1378
1391
  }
1379
1392
  get context() {
@@ -1626,9 +1639,15 @@ function hasMediaStreamSource(stream) {
1626
1639
  var import_core6 = require("@waveform-playlist/core");
1627
1640
  var import_tone7 = require("tone");
1628
1641
  function createToneAdapter(options) {
1629
- let playout = null;
1642
+ getGlobalContext();
1643
+ let _playoutGeneration = 1;
1644
+ let playout = new TonePlayout({ effects: options?.effects });
1645
+ playout.setOnPlaybackComplete(() => {
1646
+ if (_playoutGeneration === 1) {
1647
+ _isPlaying = false;
1648
+ }
1649
+ });
1630
1650
  let _isPlaying = false;
1631
- let _playoutGeneration = 0;
1632
1651
  let _loopEnabled = false;
1633
1652
  let _loopStart = 0;
1634
1653
  let _loopEnd = 0;
@@ -1828,9 +1847,10 @@ function createToneAdapter(options) {
1828
1847
  },
1829
1848
  addTrack(track) {
1830
1849
  if (!playout) {
1831
- throw new Error(
1832
- "[waveform-playlist] adapter.addTrack() called but no playout exists. Call setTracks() first to initialize the playout."
1850
+ console.warn(
1851
+ "[waveform-playlist] adapter.addTrack() called but playout is not available (adapter may have been disposed)."
1833
1852
  );
1853
+ return;
1834
1854
  }
1835
1855
  addTrackToPlayout(playout, track);
1836
1856
  playout.applyInitialSoloState();
@@ -1892,6 +1912,9 @@ function createToneAdapter(options) {
1892
1912
  get audioContext() {
1893
1913
  return getGlobalAudioContext();
1894
1914
  },
1915
+ get lookAhead() {
1916
+ return getGlobalContext().lookAhead ?? 0;
1917
+ },
1895
1918
  get ppqn() {
1896
1919
  return _ppqn;
1897
1920
  },
@@ -1928,6 +1951,14 @@ function createToneAdapter(options) {
1928
1951
  createMediaStreamSource(stream) {
1929
1952
  return getGlobalContext().createMediaStreamSource(stream);
1930
1953
  },
1954
+ get masterOutputNode() {
1955
+ if (!playout) {
1956
+ throw new Error(
1957
+ "[waveform-playlist] adapter.masterOutputNode accessed after dispose. Disconnect your analyzer before disposing the adapter."
1958
+ );
1959
+ }
1960
+ return playout.masterOutputNode;
1961
+ },
1931
1962
  dispose() {
1932
1963
  try {
1933
1964
  playout?.dispose();