@buffered-audio/nodes 0.18.1 → 0.18.2

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/cli.js CHANGED
@@ -39,21 +39,26 @@ function parseParams(entries) {
39
39
  }
40
40
  return Object.fromEntries(parameters);
41
41
  }
42
+ function stamp() {
43
+ const now = /* @__PURE__ */ new Date();
44
+ const pad = (value) => String(value).padStart(2, "0");
45
+ return `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
46
+ }
42
47
  function createEventSink() {
43
48
  const totals = /* @__PURE__ */ new Map();
44
49
  const subscribe = (events) => {
45
50
  events.on("started", (node) => {
46
- process.stdout.write(`[${labelOf(node)}] started
51
+ process.stdout.write(`${stamp()} [${labelOf(node)}] started
47
52
  `);
48
53
  });
49
54
  events.on("progress", (node, payload) => {
50
55
  const label = labelOf(node);
51
56
  if (payload.framesTotal !== void 0) {
52
57
  const percent = Math.round(payload.framesDone / payload.framesTotal * 100);
53
- process.stdout.write(`[${label}] ${payload.phase} ${percent}%
58
+ process.stdout.write(`${stamp()} [${label}] ${payload.phase} ${percent}%
54
59
  `);
55
60
  } else {
56
- process.stdout.write(`[${label}] ${payload.phase} frames=${payload.framesDone}
61
+ process.stdout.write(`${stamp()} [${label}] ${payload.phase} frames=${payload.framesDone}
57
62
  `);
58
63
  }
59
64
  });
@@ -61,12 +66,13 @@ function createEventSink() {
61
66
  const data = payload.data ? Object.entries(payload.data).map(([key, value]) => `${key}=${String(value)}`) : [];
62
67
  const parts = [payload.message, ...data].join(" ");
63
68
  const prefix = payload.level === "warn" ? "warn: " : "";
64
- process.stdout.write(`${prefix}[${labelOf(node)}] ${parts}
69
+ process.stdout.write(`${stamp()} ${prefix}[${labelOf(node)}] ${parts}
65
70
  `);
66
71
  });
67
72
  events.on("finished", (node, payload) => {
68
73
  totals.set(node, { framesDone: payload.framesDone, processingMs: payload.processingMs });
69
- process.stdout.write(`[${labelOf(node)}] finished
74
+ const ms = payload.processingMs !== void 0 ? ` ms=${Math.round(payload.processingMs)}` : "";
75
+ process.stdout.write(`${stamp()} [${labelOf(node)}] finished frames=${payload.framesDone}${ms}
70
76
  `);
71
77
  });
72
78
  };
@@ -74,10 +80,10 @@ function createEventSink() {
74
80
  for (const [node, { framesDone, processingMs }] of totals) {
75
81
  const label = labelOf(node);
76
82
  if (processingMs !== void 0) {
77
- process.stdout.write(`[${label}] processed ${framesDone} frames in ${Math.round(processingMs)}ms
83
+ process.stdout.write(`${stamp()} [${label}] processed ${framesDone} frames in ${Math.round(processingMs)}ms
78
84
  `);
79
85
  } else {
80
- process.stdout.write(`[${label}] processed ${framesDone} frames
86
+ process.stdout.write(`${stamp()} [${label}] processed ${framesDone} frames
81
87
  `);
82
88
  }
83
89
  }
@@ -85,7 +91,7 @@ function createEventSink() {
85
91
  const timing = job.timing;
86
92
  if (!timing) continue;
87
93
  const label = sourceLabel(job) ?? "source";
88
- process.stdout.write(`[${label}] total ${(timing.totalMs / 1e3).toFixed(1)}s, ${timing.realTimeMultiplier.toFixed(1)}x RT
94
+ process.stdout.write(`${stamp()} [${label}] total ${(timing.totalMs / 1e3).toFixed(1)}s, ${timing.realTimeMultiplier.toFixed(1)}x RT
89
95
  `);
90
96
  }
91
97
  };
package/dist/index.js CHANGED
@@ -29629,6 +29629,7 @@ BufferedAudioNode.nodeDescription = "";
29629
29629
  BufferedAudioNode.schema = external_exports2.object({});
29630
29630
  var UNKNOWN_TOTAL_QUANTUM_FRAMES = 48e4;
29631
29631
  var DEFAULT_PROGRESS_QUANTUM = 0.1;
29632
+ var PROCESS_QUANTUM_FRACTION = 0.02;
29632
29633
  var BufferedStream = class {
29633
29634
  constructor(node) {
29634
29635
  this.quantumFraction = DEFAULT_PROGRESS_QUANTUM;
@@ -29656,7 +29657,8 @@ var BufferedStream = class {
29656
29657
  this.renderEvents.emit("progress", this.identity, { phase: phase2, framesDone, framesTotal: total });
29657
29658
  return;
29658
29659
  }
29659
- const quantum = total ? Math.max(1, Math.floor(total * this.quantumFraction)) : UNKNOWN_TOTAL_QUANTUM_FRAMES;
29660
+ const fraction = phase2 === "process" ? Math.min(this.quantumFraction, PROCESS_QUANTUM_FRACTION) : this.quantumFraction;
29661
+ const quantum = total ? Math.max(1, Math.floor(total * fraction)) : UNKNOWN_TOTAL_QUANTUM_FRAMES;
29660
29662
  const boundary = Math.floor(framesDone / quantum) * quantum;
29661
29663
  const last = this.lastBoundaryByPhase.get(phase2);
29662
29664
  if (last !== void 0 && boundary <= last) return;
@@ -29733,7 +29735,7 @@ var BufferedTransformStream = class extends BufferedStream {
29733
29735
  controller.enqueue(block);
29734
29736
  }
29735
29737
  this.framesEmitted += frames;
29736
- this.emitProgress("emit", this.framesEmitted);
29738
+ this.emitProgress("emit", this.framesEmitted, this.sourceTotalFrames);
29737
29739
  };
29738
29740
  }
29739
29741
  async handleTransform(block, controller) {
@@ -29777,7 +29779,7 @@ var BufferedTransformStream = class extends BufferedStream {
29777
29779
  const start = performance.now();
29778
29780
  const wholeFile = this.blockSize === WHOLE_FILE;
29779
29781
  await this.buffer.flushWrites();
29780
- if (wholeFile) this.emitProgress("process", 0, void 0, { force: true });
29782
+ if (wholeFile) this.emitProgress("process", 0, framesBefore, { force: true });
29781
29783
  await this.transform(this.buffer, this.makeEnqueue(controller));
29782
29784
  if (wholeFile) this.emitProgress("process", framesBefore, framesBefore, { force: true });
29783
29785
  await this.buffer.clear();
@@ -29793,7 +29795,7 @@ var BufferedTransformStream = class extends BufferedStream {
29793
29795
  await this.fireTransform(controller);
29794
29796
  }
29795
29797
  await this.flush(this.makeEnqueue(controller));
29796
- this.emitProgress("emit", this.framesEmitted, void 0, { force: true });
29798
+ this.emitProgress("emit", this.framesEmitted, this.sourceTotalFrames, { force: true });
29797
29799
  this.emitFinished({ framesDone: this.framesBuffered, processingMs: this.processingMs });
29798
29800
  }
29799
29801
  async destroy() {
@@ -29967,7 +29969,7 @@ var UnbufferedTransformStream = class extends BufferedStream {
29967
29969
  return (block) => {
29968
29970
  controller.enqueue(block);
29969
29971
  this.framesEmitted += block.samples[0]?.length ?? 0;
29970
- this.emitProgress("emit", this.framesEmitted);
29972
+ this.emitProgress("emit", this.framesEmitted, this.sourceTotalFrames);
29971
29973
  };
29972
29974
  }
29973
29975
  async handleTransform(block, controller) {
@@ -29986,7 +29988,7 @@ var UnbufferedTransformStream = class extends BufferedStream {
29986
29988
  await this.flush(this.makeEnqueue(controller));
29987
29989
  this.processingMs += performance.now() - start;
29988
29990
  this.emitProgress("buffer", this.framesBuffered, this.sourceTotalFrames, { force: true });
29989
- this.emitProgress("emit", this.framesEmitted, void 0, { force: true });
29991
+ this.emitProgress("emit", this.framesEmitted, this.sourceTotalFrames, { force: true });
29990
29992
  this.emitFinished({ framesDone: this.framesBuffered, processingMs: this.processingMs });
29991
29993
  await this.destroy();
29992
29994
  }
@@ -32182,7 +32184,7 @@ function applyNlmSmoothing(mask, numFrames, numBins, nlmOptions, output) {
32182
32184
  // package.json
32183
32185
  var package_default = {
32184
32186
  name: "@buffered-audio/nodes",
32185
- version: "0.18.1"};
32187
+ version: "0.18.2"};
32186
32188
 
32187
32189
  // src/package-metadata.ts
32188
32190
  var PACKAGE_NAME = package_default.name;
@@ -33655,6 +33657,7 @@ var NormalizeStream = class extends BufferedTransformStream {
33655
33657
  async transform(buffered, enqueue) {
33656
33658
  const raw = this.peak === 0 ? 1 : this.properties.ceiling / this.peak;
33657
33659
  const scale = Number.isFinite(raw) ? raw : 1;
33660
+ this.log("peak measured", { peak: this.peak, scale, ceiling: this.properties.ceiling });
33658
33661
  for await (const block of buffered.iterate(44100)) {
33659
33662
  if (scale === 1) {
33660
33663
  enqueue(block);
@@ -34814,7 +34817,8 @@ async function iterateForTargets(args) {
34814
34817
  maxAttempts = DEFAULT_MAX_ATTEMPTS,
34815
34818
  tolerance = DEFAULT_TOLERANCE,
34816
34819
  peakTolerance,
34817
- seedB
34820
+ seedB,
34821
+ onAttempt
34818
34822
  } = args;
34819
34823
  const channelCount = buffer.channels;
34820
34824
  const frames = buffer.frames;
@@ -34903,7 +34907,7 @@ async function iterateForTargets(args) {
34903
34907
  const measured = await measureAttemptOutput({ source: buffer, sampleRate, channelCount, gSmoothed: activeRef });
34904
34908
  const lufsErr = measured.outputLufs - targetLufs;
34905
34909
  const peakErr = measured.outputTruePeakDb - effectiveTargetTp;
34906
- attempts.push({
34910
+ const attempt = {
34907
34911
  boost: currentBoost,
34908
34912
  limitDb: currentLimit,
34909
34913
  lufsErr,
@@ -34913,7 +34917,9 @@ async function iterateForTargets(args) {
34913
34917
  peakGainDb: currentPeakGainDb,
34914
34918
  peakErr,
34915
34919
  elapsedMs: Date.now() - tAttempt0
34916
- });
34920
+ };
34921
+ attempts.push(attempt);
34922
+ onAttempt?.(attempt, attemptIdx);
34917
34923
  const lufsScoreTerm = Math.abs(lufsErr) / tolerance;
34918
34924
  const peakScoreTerm = skipPeak ? 0 : Math.abs(peakErr) / peakTolerance;
34919
34925
  const score = Math.max(lufsScoreTerm, peakScoreTerm);
@@ -35520,7 +35526,19 @@ var LoudnessTargetStream = class extends BufferedTransformStream {
35520
35526
  tolerance,
35521
35527
  peakTolerance,
35522
35528
  seedB,
35523
- detectionEnvelope
35529
+ detectionEnvelope,
35530
+ onAttempt: (attempt, attemptIndex) => {
35531
+ this.log("attempt", {
35532
+ attempt: attemptIndex + 1,
35533
+ B: attempt.boost,
35534
+ peakGainDb: attempt.peakGainDb,
35535
+ lufsErr: attempt.lufsErr,
35536
+ peakErr: attempt.peakErr,
35537
+ outputLra: attempt.outputLra,
35538
+ elapsedMs: attempt.elapsedMs
35539
+ });
35540
+ this.progress(attemptIndex + 1, maxAttempts);
35541
+ }
35524
35542
  });
35525
35543
  this.learnTimingMs.iteration = Date.now() - tIterate0;
35526
35544
  this.learnTimingMs.detection = result.detectionCacheBuildMs;
@@ -35547,20 +35565,6 @@ var LoudnessTargetStream = class extends BufferedTransformStream {
35547
35565
  }
35548
35566
  const limitDbRepr = `${bestLimitDbRepr} (${limitDbSource})`;
35549
35567
  const expansiveGeometry = result.bestPeakGainDb > result.bestB;
35550
- for (let attemptIdx = 0; attemptIdx < result.attempts.length; attemptIdx++) {
35551
- const attempt = result.attempts[attemptIdx];
35552
- if (attempt === void 0) continue;
35553
- this.log("attempt", {
35554
- attempt: attemptIdx + 1,
35555
- B: attempt.boost,
35556
- peakGainDb: attempt.peakGainDb,
35557
- lufsErr: attempt.lufsErr,
35558
- peakErr: attempt.peakErr,
35559
- outputLra: attempt.outputLra,
35560
- elapsedMs: attempt.elapsedMs
35561
- });
35562
- this.progress(attemptIdx + 1, maxAttempts);
35563
- }
35564
35568
  const fmt = (x) => x === void 0 ? "off" : String(x);
35565
35569
  this.log("iteration", {
35566
35570
  attempts: result.attempts.length,
@@ -35700,6 +35704,7 @@ var LoudnessNormalizeStream = class extends BufferedTransformStream {
35700
35704
  async transform(buffered, enqueue) {
35701
35705
  const integrated = this.accumulator === void 0 ? -Infinity : this.accumulator.finalize();
35702
35706
  const gain2 = Number.isFinite(integrated) ? Math.pow(10, (this.properties.target - integrated) / 20) : 1;
35707
+ this.log("loudness measured", { integrated, gain: gain2, target: this.properties.target });
35703
35708
  for await (const block of buffered.iterate(44100)) {
35704
35709
  if (gain2 === 1) {
35705
35710
  enqueue(block);
@@ -36268,7 +36273,7 @@ var TruePeakArgmaxAccumulator = class {
36268
36273
  return { db: linearToDb(this.runningMax), peakInputSample: this.peakInputSample };
36269
36274
  }
36270
36275
  };
36271
- async function streamLatticeTrajectory(buffer, frameSize, hopSize, backend, addonOptions, search) {
36276
+ async function streamLatticeTrajectory(buffer, frameSize, hopSize, backend, addonOptions, search, progress) {
36272
36277
  const channelCount = buffer.channels;
36273
36278
  const signalLength = buffer.frames;
36274
36279
  const order = LATTICE_ORDER;
@@ -36374,6 +36379,7 @@ async function streamLatticeTrajectory(buffer, frameSize, hopSize, backend, addo
36374
36379
  }
36375
36380
  }
36376
36381
  toRead -= got;
36382
+ progress?.(nextFrame, frameCount);
36377
36383
  }
36378
36384
  for (let frame = 0; frame < frameCount; frame++) {
36379
36385
  const wasReached = baseRows[frame] !== void 0;
@@ -36482,16 +36488,18 @@ var CrestReduceStream = class extends BufferedTransformStream {
36482
36488
  peakInputSample,
36483
36489
  sampleRate,
36484
36490
  lambda
36485
- });
36491
+ }, (done, total) => this.progress(done, total));
36486
36492
  if (frameCount === 0) {
36487
36493
  for await (const block of buffered.iterate(44100)) {
36488
36494
  enqueue(block);
36489
36495
  }
36490
36496
  return;
36491
36497
  }
36498
+ this.log("trajectory analysed", { frameCount });
36492
36499
  const smoothedTrajectory = smoothControlTrajectory(trajectory, smoothing, trajectoryFrameRate(sampleRate, hopSize), exactHoldHalfWidthFrames(sampleRate, hopSize), hopSize);
36493
36500
  await buffered.reset();
36494
36501
  let applyState;
36502
+ let appliedFrames = 0;
36495
36503
  for await (const block of buffered.iterate(44100)) {
36496
36504
  const frames = block.samples[0]?.length ?? 0;
36497
36505
  const blockChannelCount = block.samples.length;
@@ -36503,6 +36511,8 @@ var CrestReduceStream = class extends BufferedTransformStream {
36503
36511
  const transformed = applyState.apply(block.samples, frames);
36504
36512
  const samples = block.samples.map((inputChannel, ch) => transformed[ch] ?? inputChannel);
36505
36513
  enqueue({ samples, offset: block.offset, sampleRate: block.sampleRate, bitDepth: block.bitDepth });
36514
+ appliedFrames += frames;
36515
+ this.progress(Math.min(appliedFrames, totalFrames), totalFrames);
36506
36516
  }
36507
36517
  }
36508
36518
  };
@@ -37228,6 +37238,7 @@ var DeBleedStream = class extends BufferedTransformStream {
37228
37238
  const _twarm = _profStart();
37229
37239
  const seedsByChannel = await this.warmupSeedsAllChannels(buffered, channels, warmupFrames, fftSize, hopSize);
37230
37240
  _profAdd("warmup", _twarm);
37241
+ this.log("warm-up seed complete", { warmupSeconds: WARMUP_SECONDS });
37231
37242
  await buffered.reset();
37232
37243
  for (const refBuffer of referenceBuffers) await refBuffer.reset();
37233
37244
  const kalmanStatesByCh = seedsByChannel.map((seeds) => seeds.map((seed) => createKalmanState(numBins, seed)));
@@ -37424,6 +37435,7 @@ var DeBleedStream = class extends BufferedTransformStream {
37424
37435
  const _twrite = _profStart();
37425
37436
  await outputBuffer.write(writeSamplesByChannel, sampleRate, bitDepth);
37426
37437
  _profAdd("write", _twrite);
37438
+ this.progress(Math.min(outStart + chunkFrames, processStftFrames), processStftFrames);
37427
37439
  }
37428
37440
  if (outputBuffer.frames < totalFrames) {
37429
37441
  const padFrames = totalFrames - outputBuffer.frames;
@@ -37991,6 +38003,7 @@ var DtlnStream = class extends BufferedTransformStream {
37991
38003
  const writerState = { written: 0 };
37992
38004
  const pumpDone = pair !== void 0 ? pumpSourceToResampleIn({ buffer, resampleIn: pair.resampleIn, channels, chunkFrames: CHUNK_FRAMES5 }) : Promise.resolve();
37993
38005
  const drainerDone = pair !== void 0 ? drainResampleOutToBuffer({ resampleOut: pair.resampleOut, output, channels, sourceRate, bitDepth, originalFrames, writerState }) : Promise.resolve();
38006
+ const total16k = Math.round(originalFrames * DTLN_SAMPLE_RATE / sourceRate);
37994
38007
  for (; ; ) {
37995
38008
  const got16k = await pullNextChunkAt16k({ buffer, pair, channels, frames: CHUNK_FRAMES5 });
37996
38009
  if (got16k === void 0) break;
@@ -38021,6 +38034,7 @@ var DtlnStream = class extends BufferedTransformStream {
38021
38034
  }
38022
38035
  }
38023
38036
  }
38037
+ this.progress(Math.min(samplesFed, total16k), total16k);
38024
38038
  }
38025
38039
  await pumpDone;
38026
38040
  if (samplesFed > 0 && samplesFed < BLOCK_LEN) {
@@ -38232,6 +38246,7 @@ var HtdemucsStream = class extends BufferedTransformStream {
38232
38246
  const bitDepth = this.bitDepth;
38233
38247
  const needsResample = sourceRate !== HTDEMUCS_SAMPLE_RATE;
38234
38248
  const stats = await computeStreamingStats(buffered, channels);
38249
+ this.log("streaming stats computed", { mean: stats.mean, std: stats.std });
38235
38250
  await buffered.reset();
38236
38251
  let pair;
38237
38252
  if (needsResample) {
@@ -38317,6 +38332,8 @@ var HtdemucsStream = class extends BufferedTransformStream {
38317
38332
  const { stems } = this.properties;
38318
38333
  const stemGains = [stems.drums, stems.bass, stems.other, stems.vocals];
38319
38334
  const inv = 1 / (stats.std || 1);
38335
+ const modelRateFrames = Math.round(originalFrames * HTDEMUCS_SAMPLE_RATE / sourceRate);
38336
+ let stableEmitted = 0;
38320
38337
  for (; ; ) {
38321
38338
  if (!inputExhausted) {
38322
38339
  while (segFilled < SEGMENT_SAMPLES) {
@@ -38371,6 +38388,8 @@ var HtdemucsStream = class extends BufferedTransformStream {
38371
38388
  originalFrames,
38372
38389
  writerState
38373
38390
  });
38391
+ stableEmitted += nStable;
38392
+ this.progress(Math.min(stableEmitted, modelRateFrames), modelRateFrames);
38374
38393
  if (!isFinalIter) {
38375
38394
  segLeft.copyWithin(0, nStable, SEGMENT_SAMPLES);
38376
38395
  segRight.copyWithin(0, nStable, SEGMENT_SAMPLES);
@@ -38794,6 +38813,8 @@ var KimVocal2Stream = class extends BufferedTransformStream {
38794
38813
  const outAccumLeft = new Float32Array(SEGMENT_SAMPLES2);
38795
38814
  const outAccumRight = new Float32Array(SEGMENT_SAMPLES2);
38796
38815
  const sumWeight = new Float32Array(SEGMENT_SAMPLES2);
38816
+ const modelRateFrames = Math.round(originalFrames * SAMPLE_RATE / sourceRate);
38817
+ let stableEmitted = 0;
38797
38818
  for (; ; ) {
38798
38819
  if (!inputExhausted) {
38799
38820
  while (segFilled < SEGMENT_SAMPLES2) {
@@ -38839,6 +38860,8 @@ var KimVocal2Stream = class extends BufferedTransformStream {
38839
38860
  originalFrames,
38840
38861
  writerState
38841
38862
  });
38863
+ stableEmitted += nStable;
38864
+ this.progress(Math.min(stableEmitted, modelRateFrames), modelRateFrames);
38842
38865
  if (!isFinalIter) {
38843
38866
  segLeft.copyWithin(0, nStable, SEGMENT_SAMPLES2);
38844
38867
  segRight.copyWithin(0, nStable, SEGMENT_SAMPLES2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buffered-audio/nodes",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -45,8 +45,8 @@
45
45
  "vitest": "^3.0.0"
46
46
  },
47
47
  "dependencies": {
48
- "@buffered-audio/core": "0.7.1",
49
- "@buffered-audio/utils": "0.6.1",
48
+ "@buffered-audio/core": "0.7.2",
49
+ "@buffered-audio/utils": "0.6.2",
50
50
  "bufferfy": "^4.0.3",
51
51
  "commander": "^14.0.3",
52
52
  "tsx": "^4.21.0",