@waveform-playlist/spectrogram 7.1.2 → 7.1.3

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.mjs CHANGED
@@ -3563,7 +3563,14 @@ var ModalButton = styled2.button`
3563
3563
  }
3564
3564
  `;
3565
3565
  var FFT_SIZES = [256, 512, 1024, 2048, 4096, 8192];
3566
- var WINDOW_FUNCTIONS = ["hann", "hamming", "blackman", "blackman-harris", "bartlett", "rectangular"];
3566
+ var WINDOW_FUNCTIONS = [
3567
+ "hann",
3568
+ "hamming",
3569
+ "blackman",
3570
+ "blackman-harris",
3571
+ "bartlett",
3572
+ "rectangular"
3573
+ ];
3567
3574
  var FREQ_SCALES = ["linear", "logarithmic", "mel", "bark", "erb"];
3568
3575
  var COLOR_MAPS = ["viridis", "magma", "inferno", "grayscale", "igray", "roseus"];
3569
3576
  var SpectrogramSettingsModal = ({
@@ -3585,7 +3592,9 @@ var SpectrogramSettingsModal = ({
3585
3592
  const [gainDb, setGainDb] = useState(config.gainDb ?? 20);
3586
3593
  const [rangeDb, setRangeDb] = useState(config.rangeDb ?? 80);
3587
3594
  const [zeroPadding, setZeroPadding] = useState(config.zeroPaddingFactor ?? 2);
3588
- const [hopSize, setHopSize] = useState(config.hopSize ?? Math.floor((config.fftSize ?? 2048) / 4));
3595
+ const [hopSize, setHopSize] = useState(
3596
+ config.hopSize ?? Math.floor((config.fftSize ?? 2048) / 4)
3597
+ );
3589
3598
  const [showLabels, setShowLabels] = useState(config.labels ?? false);
3590
3599
  useEffect(() => {
3591
3600
  setFftSize(config.fftSize ?? 2048);
@@ -3639,11 +3648,18 @@ var SpectrogramSettingsModal = ({
3639
3648
  /* @__PURE__ */ jsxs2(FormGrid, { children: [
3640
3649
  /* @__PURE__ */ jsxs2(Field, { children: [
3641
3650
  /* @__PURE__ */ jsx2(Label, { children: "FFT Size" }),
3642
- /* @__PURE__ */ jsx2(Select, { value: fftSize, onChange: (e) => {
3643
- const v = Number(e.target.value);
3644
- setFftSize(v);
3645
- setHopSize(Math.floor(v / 4));
3646
- }, children: FFT_SIZES.map((s) => /* @__PURE__ */ jsx2("option", { value: s, children: s }, s)) })
3651
+ /* @__PURE__ */ jsx2(
3652
+ Select,
3653
+ {
3654
+ value: fftSize,
3655
+ onChange: (e) => {
3656
+ const v = Number(e.target.value);
3657
+ setFftSize(v);
3658
+ setHopSize(Math.floor(v / 4));
3659
+ },
3660
+ children: FFT_SIZES.map((s) => /* @__PURE__ */ jsx2("option", { value: s, children: s }, s))
3661
+ }
3662
+ )
3647
3663
  ] }),
3648
3664
  /* @__PURE__ */ jsxs2(Field, { children: [
3649
3665
  /* @__PURE__ */ jsx2(Label, { children: "Hop Size" }),
@@ -3664,11 +3680,25 @@ var SpectrogramSettingsModal = ({
3664
3680
  ] }),
3665
3681
  /* @__PURE__ */ jsxs2(Field, { children: [
3666
3682
  /* @__PURE__ */ jsx2(Label, { children: "Frequency Scale" }),
3667
- /* @__PURE__ */ jsx2(Select, { value: freqScale, onChange: (e) => setFreqScale(e.target.value), children: FREQ_SCALES.map((s) => /* @__PURE__ */ jsx2("option", { value: s, children: s }, s)) })
3683
+ /* @__PURE__ */ jsx2(
3684
+ Select,
3685
+ {
3686
+ value: freqScale,
3687
+ onChange: (e) => setFreqScale(e.target.value),
3688
+ children: FREQ_SCALES.map((s) => /* @__PURE__ */ jsx2("option", { value: s, children: s }, s))
3689
+ }
3690
+ )
3668
3691
  ] }),
3669
3692
  /* @__PURE__ */ jsxs2(Field, { children: [
3670
3693
  /* @__PURE__ */ jsx2(Label, { children: "Color Map" }),
3671
- /* @__PURE__ */ jsx2(Select, { value: localColorMap, onChange: (e) => setLocalColorMap(e.target.value), children: COLOR_MAPS.map((c) => /* @__PURE__ */ jsx2("option", { value: c, children: c }, c)) })
3694
+ /* @__PURE__ */ jsx2(
3695
+ Select,
3696
+ {
3697
+ value: localColorMap,
3698
+ onChange: (e) => setLocalColorMap(e.target.value),
3699
+ children: COLOR_MAPS.map((c) => /* @__PURE__ */ jsx2("option", { value: c, children: c }, c))
3700
+ }
3701
+ )
3672
3702
  ] }),
3673
3703
  /* @__PURE__ */ jsxs2(Field, { children: [
3674
3704
  /* @__PURE__ */ jsx2(Label, { children: "Min Frequency (Hz)" }),
@@ -3727,7 +3757,14 @@ var SpectrogramSettingsModal = ({
3727
3757
  )
3728
3758
  ] }),
3729
3759
  /* @__PURE__ */ jsx2(Field, { $span: true, children: /* @__PURE__ */ jsxs2(CheckboxLabel, { children: [
3730
- /* @__PURE__ */ jsx2("input", { type: "checkbox", checked: showLabels, onChange: (e) => setShowLabels(e.target.checked) }),
3760
+ /* @__PURE__ */ jsx2(
3761
+ "input",
3762
+ {
3763
+ type: "checkbox",
3764
+ checked: showLabels,
3765
+ onChange: (e) => setShowLabels(e.target.checked)
3766
+ }
3767
+ ),
3731
3768
  "Show Frequency Labels"
3732
3769
  ] }) })
3733
3770
  ] }),
@@ -3850,10 +3887,7 @@ function createSpectrogramWorker(worker) {
3850
3887
  });
3851
3888
  },
3852
3889
  registerCanvas(canvasId, canvas) {
3853
- worker.postMessage(
3854
- { type: "register-canvas", canvasId, canvas },
3855
- [canvas]
3856
- );
3890
+ worker.postMessage({ type: "register-canvas", canvasId, canvas }, [canvas]);
3857
3891
  },
3858
3892
  unregisterCanvas(canvasId) {
3859
3893
  worker.postMessage({ type: "unregister-canvas", canvasId });
@@ -3907,8 +3941,12 @@ function createSpectrogramWorker(worker) {
3907
3941
 
3908
3942
  // src/SpectrogramProvider.tsx
3909
3943
  import { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback, useMemo } from "react";
3910
- import { MAX_CANVAS_WIDTH } from "@waveform-playlist/core";
3911
- import { SpectrogramIntegrationProvider } from "@waveform-playlist/browser";
3944
+ import {
3945
+ MAX_CANVAS_WIDTH
3946
+ } from "@waveform-playlist/core";
3947
+ import {
3948
+ SpectrogramIntegrationProvider
3949
+ } from "@waveform-playlist/browser";
3912
3950
  import { usePlaylistData, usePlaylistControls } from "@waveform-playlist/browser";
3913
3951
  import { jsx as jsx3 } from "react/jsx-runtime";
3914
3952
  function extractChunkNumber(canvasId) {
@@ -3924,16 +3962,11 @@ var SpectrogramProvider = ({
3924
3962
  colorMap: spectrogramColorMap,
3925
3963
  children
3926
3964
  }) => {
3927
- const {
3928
- tracks,
3929
- waveHeight,
3930
- samplesPerPixel,
3931
- isReady,
3932
- mono,
3933
- controls
3934
- } = usePlaylistData();
3965
+ const { tracks, waveHeight, samplesPerPixel, isReady, mono, controls } = usePlaylistData();
3935
3966
  const { scrollContainerRef } = usePlaylistControls();
3936
- const [spectrogramDataMap, setSpectrogramDataMap] = useState2(/* @__PURE__ */ new Map());
3967
+ const [spectrogramDataMap, setSpectrogramDataMap] = useState2(
3968
+ /* @__PURE__ */ new Map()
3969
+ );
3937
3970
  const [trackSpectrogramOverrides, setTrackSpectrogramOverrides] = useState2(/* @__PURE__ */ new Map());
3938
3971
  const spectrogramCanvasRegistryRef = useRef2(/* @__PURE__ */ new Map());
3939
3972
  const [spectrogramCanvasVersion, setSpectrogramCanvasVersion] = useState2(0);
@@ -4082,9 +4115,7 @@ var SpectrogramProvider = ({
4082
4115
  if (mode === "waveform") return;
4083
4116
  const trackConfigChanged = configChanged && currentKeys.get(track.id) !== prevKeys.get(track.id);
4084
4117
  const trackFFTChanged = fftKeyChanged && currentFFTKeys.get(track.id) !== prevFFTKeys.get(track.id);
4085
- const hasRegisteredCanvases = canvasVersionChanged && track.clips.some(
4086
- (clip) => spectrogramCanvasRegistryRef.current.has(clip.id)
4087
- );
4118
+ const hasRegisteredCanvases = canvasVersionChanged && track.clips.some((clip) => spectrogramCanvasRegistryRef.current.has(clip.id));
4088
4119
  if (!trackConfigChanged && !hasRegisteredCanvases) return;
4089
4120
  const cfg = trackSpectrogramOverrides.get(track.id)?.config ?? track.spectrogramConfig ?? spectrogramConfig ?? {};
4090
4121
  const cm = trackSpectrogramOverrides.get(track.id)?.colorMap ?? track.spectrogramColorMap ?? spectrogramColorMap ?? "viridis";
@@ -4142,7 +4173,13 @@ var SpectrogramProvider = ({
4142
4173
  } else {
4143
4174
  for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {
4144
4175
  channelSpectrograms.push(
4145
- computeSpectrogram(clip.audioBuffer, item.config, item.offsetSamples, item.durationSamples, ch)
4176
+ computeSpectrogram(
4177
+ clip.audioBuffer,
4178
+ item.config,
4179
+ item.offsetSamples,
4180
+ item.durationSamples,
4181
+ ch
4182
+ )
4146
4183
  );
4147
4184
  }
4148
4185
  }
@@ -4255,7 +4292,10 @@ var SpectrogramProvider = ({
4255
4292
  item.offsetSamples + Math.ceil(localEndPx * samplesPerPixel)
4256
4293
  );
4257
4294
  const paddedStart = Math.max(item.offsetSamples, visStartSample - windowSize);
4258
- const paddedEnd = Math.min(item.offsetSamples + item.durationSamples, visEndSample + windowSize);
4295
+ const paddedEnd = Math.min(
4296
+ item.offsetSamples + item.durationSamples,
4297
+ visEndSample + windowSize
4298
+ );
4259
4299
  if (paddedEnd - paddedStart < item.durationSamples * 0.8) {
4260
4300
  visibleRange = { start: paddedStart, end: paddedEnd };
4261
4301
  }
@@ -4278,7 +4318,14 @@ var SpectrogramProvider = ({
4278
4318
  const channelInfo = clipCanvasInfo.get(ch);
4279
4319
  if (!channelInfo) continue;
4280
4320
  const { visibleIndices } = getVisibleChunkRange(channelInfo, clipPixelOffset);
4281
- await renderChunkSubset(workerApi, visibleCacheKey, channelInfo, visibleIndices, item, ch);
4321
+ await renderChunkSubset(
4322
+ workerApi,
4323
+ visibleCacheKey,
4324
+ channelInfo,
4325
+ visibleIndices,
4326
+ item,
4327
+ ch
4328
+ );
4282
4329
  }
4283
4330
  if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
4284
4331
  }
@@ -4299,7 +4346,14 @@ var SpectrogramProvider = ({
4299
4346
  if (!channelInfo) continue;
4300
4347
  const range = getVisibleChunkRange(channelInfo, clipPixelOffset);
4301
4348
  channelRanges.push({ ch, channelInfo, ...range });
4302
- await renderChunkSubset(workerApi, cacheKey, channelInfo, range.visibleIndices, item, ch);
4349
+ await renderChunkSubset(
4350
+ workerApi,
4351
+ cacheKey,
4352
+ channelInfo,
4353
+ range.visibleIndices,
4354
+ item,
4355
+ ch
4356
+ );
4303
4357
  }
4304
4358
  if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
4305
4359
  if (await renderBackgroundBatches(channelRanges, cacheKey, item)) return;
@@ -4335,7 +4389,10 @@ var SpectrogramProvider = ({
4335
4389
  for (let ch = 0; ch < item.numChannels; ch++) {
4336
4390
  const channelInfo = clipCanvasInfo.get(ch);
4337
4391
  if (!channelInfo) continue;
4338
- const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo, clipPixelOffset);
4392
+ const { visibleIndices, remainingIndices } = getVisibleChunkRange(
4393
+ channelInfo,
4394
+ clipPixelOffset
4395
+ );
4339
4396
  channelRanges.push({ ch, channelInfo, remainingIndices });
4340
4397
  await renderChunkSubset(workerApi, cacheKey, channelInfo, visibleIndices, item, ch);
4341
4398
  }
@@ -4349,7 +4406,18 @@ var SpectrogramProvider = ({
4349
4406
  computeAsync().catch((err) => {
4350
4407
  console.error("[waveform-playlist] Spectrogram computation failed:", err);
4351
4408
  });
4352
- }, [tracks, mono, spectrogramConfig, spectrogramColorMap, trackSpectrogramOverrides, waveHeight, samplesPerPixel, spectrogramCanvasVersion, controls, scrollContainerRef]);
4409
+ }, [
4410
+ tracks,
4411
+ mono,
4412
+ spectrogramConfig,
4413
+ spectrogramColorMap,
4414
+ trackSpectrogramOverrides,
4415
+ waveHeight,
4416
+ samplesPerPixel,
4417
+ spectrogramCanvasVersion,
4418
+ controls,
4419
+ scrollContainerRef
4420
+ ]);
4353
4421
  const setTrackRenderMode = useCallback((trackId, mode) => {
4354
4422
  setTrackSpectrogramOverrides((prev) => {
4355
4423
  const next = new Map(prev);
@@ -4358,26 +4426,32 @@ var SpectrogramProvider = ({
4358
4426
  return next;
4359
4427
  });
4360
4428
  }, []);
4361
- const setTrackSpectrogramConfig = useCallback((trackId, config, colorMap) => {
4362
- setTrackSpectrogramOverrides((prev) => {
4363
- const next = new Map(prev);
4364
- const existing = next.get(trackId);
4365
- next.set(trackId, {
4366
- renderMode: existing?.renderMode ?? "waveform",
4367
- config,
4368
- ...colorMap !== void 0 ? { colorMap } : { colorMap: existing?.colorMap }
4429
+ const setTrackSpectrogramConfig = useCallback(
4430
+ (trackId, config, colorMap) => {
4431
+ setTrackSpectrogramOverrides((prev) => {
4432
+ const next = new Map(prev);
4433
+ const existing = next.get(trackId);
4434
+ next.set(trackId, {
4435
+ renderMode: existing?.renderMode ?? "waveform",
4436
+ config,
4437
+ ...colorMap !== void 0 ? { colorMap } : { colorMap: existing?.colorMap }
4438
+ });
4439
+ return next;
4369
4440
  });
4370
- return next;
4371
- });
4372
- }, []);
4373
- const registerSpectrogramCanvases = useCallback((clipId, channelIndex, canvasIds, canvasWidths) => {
4374
- const registry = spectrogramCanvasRegistryRef.current;
4375
- if (!registry.has(clipId)) {
4376
- registry.set(clipId, /* @__PURE__ */ new Map());
4377
- }
4378
- registry.get(clipId).set(channelIndex, { canvasIds, canvasWidths });
4379
- setSpectrogramCanvasVersion((v) => v + 1);
4380
- }, []);
4441
+ },
4442
+ []
4443
+ );
4444
+ const registerSpectrogramCanvases = useCallback(
4445
+ (clipId, channelIndex, canvasIds, canvasWidths) => {
4446
+ const registry = spectrogramCanvasRegistryRef.current;
4447
+ if (!registry.has(clipId)) {
4448
+ registry.set(clipId, /* @__PURE__ */ new Map());
4449
+ }
4450
+ registry.get(clipId).set(channelIndex, { canvasIds, canvasWidths });
4451
+ setSpectrogramCanvasVersion((v) => v + 1);
4452
+ },
4453
+ []
4454
+ );
4381
4455
  const unregisterSpectrogramCanvases = useCallback((clipId, channelIndex) => {
4382
4456
  const registry = spectrogramCanvasRegistryRef.current;
4383
4457
  const clipChannels = registry.get(clipId);
@@ -4388,40 +4462,46 @@ var SpectrogramProvider = ({
4388
4462
  }
4389
4463
  }
4390
4464
  }, []);
4391
- const renderMenuItems = useCallback((props) => {
4392
- return SpectrogramMenuItems({
4393
- renderMode: props.renderMode,
4394
- onRenderModeChange: props.onRenderModeChange,
4395
- onOpenSettings: props.onOpenSettings,
4396
- onClose: props.onClose
4397
- });
4398
- }, []);
4399
- const value = useMemo(() => ({
4400
- spectrogramDataMap,
4401
- trackSpectrogramOverrides,
4402
- spectrogramWorkerApi: spectrogramWorkerReady ? spectrogramWorkerRef.current : null,
4403
- spectrogramConfig,
4404
- spectrogramColorMap,
4405
- setTrackRenderMode,
4406
- setTrackSpectrogramConfig,
4407
- registerSpectrogramCanvases,
4408
- unregisterSpectrogramCanvases,
4409
- renderMenuItems,
4410
- SettingsModal: SpectrogramSettingsModal,
4411
- getColorMap,
4412
- getFrequencyScale
4413
- }), [
4414
- spectrogramDataMap,
4415
- trackSpectrogramOverrides,
4416
- spectrogramWorkerReady,
4417
- spectrogramConfig,
4418
- spectrogramColorMap,
4419
- setTrackRenderMode,
4420
- setTrackSpectrogramConfig,
4421
- registerSpectrogramCanvases,
4422
- unregisterSpectrogramCanvases,
4423
- renderMenuItems
4424
- ]);
4465
+ const renderMenuItems = useCallback(
4466
+ (props) => {
4467
+ return SpectrogramMenuItems({
4468
+ renderMode: props.renderMode,
4469
+ onRenderModeChange: props.onRenderModeChange,
4470
+ onOpenSettings: props.onOpenSettings,
4471
+ onClose: props.onClose
4472
+ });
4473
+ },
4474
+ []
4475
+ );
4476
+ const value = useMemo(
4477
+ () => ({
4478
+ spectrogramDataMap,
4479
+ trackSpectrogramOverrides,
4480
+ spectrogramWorkerApi: spectrogramWorkerReady ? spectrogramWorkerRef.current : null,
4481
+ spectrogramConfig,
4482
+ spectrogramColorMap,
4483
+ setTrackRenderMode,
4484
+ setTrackSpectrogramConfig,
4485
+ registerSpectrogramCanvases,
4486
+ unregisterSpectrogramCanvases,
4487
+ renderMenuItems,
4488
+ SettingsModal: SpectrogramSettingsModal,
4489
+ getColorMap,
4490
+ getFrequencyScale
4491
+ }),
4492
+ [
4493
+ spectrogramDataMap,
4494
+ trackSpectrogramOverrides,
4495
+ spectrogramWorkerReady,
4496
+ spectrogramConfig,
4497
+ spectrogramColorMap,
4498
+ setTrackRenderMode,
4499
+ setTrackSpectrogramConfig,
4500
+ registerSpectrogramCanvases,
4501
+ unregisterSpectrogramCanvases,
4502
+ renderMenuItems
4503
+ ]
4504
+ );
4425
4505
  return /* @__PURE__ */ jsx3(SpectrogramIntegrationProvider, { value, children });
4426
4506
  };
4427
4507
  export {