@waveform-playlist/spectrogram 7.1.1 → 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.js +207 -129
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +212 -130
- package/dist/index.mjs.map +1 -1
- package/dist/worker/spectrogram.worker.mjs +68 -8
- package/dist/worker/spectrogram.worker.mjs.map +1 -1
- package/package.json +4 -4
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 = [
|
|
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(
|
|
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(
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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,24 +3941,32 @@ 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 {
|
|
3944
|
+
import {
|
|
3945
|
+
MAX_CANVAS_WIDTH
|
|
3946
|
+
} from "@waveform-playlist/core";
|
|
3947
|
+
import {
|
|
3948
|
+
SpectrogramIntegrationProvider
|
|
3949
|
+
} from "@waveform-playlist/browser";
|
|
3911
3950
|
import { usePlaylistData, usePlaylistControls } from "@waveform-playlist/browser";
|
|
3912
3951
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
3952
|
+
function extractChunkNumber(canvasId) {
|
|
3953
|
+
const match = canvasId.match(/chunk(\d+)$/);
|
|
3954
|
+
if (!match) {
|
|
3955
|
+
console.warn(`[spectrogram] Unexpected canvas ID format: ${canvasId}`);
|
|
3956
|
+
return 0;
|
|
3957
|
+
}
|
|
3958
|
+
return parseInt(match[1], 10);
|
|
3959
|
+
}
|
|
3913
3960
|
var SpectrogramProvider = ({
|
|
3914
3961
|
config: spectrogramConfig,
|
|
3915
3962
|
colorMap: spectrogramColorMap,
|
|
3916
3963
|
children
|
|
3917
3964
|
}) => {
|
|
3918
|
-
const {
|
|
3919
|
-
tracks,
|
|
3920
|
-
waveHeight,
|
|
3921
|
-
samplesPerPixel,
|
|
3922
|
-
isReady,
|
|
3923
|
-
mono,
|
|
3924
|
-
controls
|
|
3925
|
-
} = usePlaylistData();
|
|
3965
|
+
const { tracks, waveHeight, samplesPerPixel, isReady, mono, controls } = usePlaylistData();
|
|
3926
3966
|
const { scrollContainerRef } = usePlaylistControls();
|
|
3927
|
-
const [spectrogramDataMap, setSpectrogramDataMap] = useState2(
|
|
3967
|
+
const [spectrogramDataMap, setSpectrogramDataMap] = useState2(
|
|
3968
|
+
/* @__PURE__ */ new Map()
|
|
3969
|
+
);
|
|
3928
3970
|
const [trackSpectrogramOverrides, setTrackSpectrogramOverrides] = useState2(/* @__PURE__ */ new Map());
|
|
3929
3971
|
const spectrogramCanvasRegistryRef = useRef2(/* @__PURE__ */ new Map());
|
|
3930
3972
|
const [spectrogramCanvasVersion, setSpectrogramCanvasVersion] = useState2(0);
|
|
@@ -4073,9 +4115,7 @@ var SpectrogramProvider = ({
|
|
|
4073
4115
|
if (mode === "waveform") return;
|
|
4074
4116
|
const trackConfigChanged = configChanged && currentKeys.get(track.id) !== prevKeys.get(track.id);
|
|
4075
4117
|
const trackFFTChanged = fftKeyChanged && currentFFTKeys.get(track.id) !== prevFFTKeys.get(track.id);
|
|
4076
|
-
const hasRegisteredCanvases = canvasVersionChanged && track.clips.some(
|
|
4077
|
-
(clip) => spectrogramCanvasRegistryRef.current.has(clip.id)
|
|
4078
|
-
);
|
|
4118
|
+
const hasRegisteredCanvases = canvasVersionChanged && track.clips.some((clip) => spectrogramCanvasRegistryRef.current.has(clip.id));
|
|
4079
4119
|
if (!trackConfigChanged && !hasRegisteredCanvases) return;
|
|
4080
4120
|
const cfg = trackSpectrogramOverrides.get(track.id)?.config ?? track.spectrogramConfig ?? spectrogramConfig ?? {};
|
|
4081
4121
|
const cm = trackSpectrogramOverrides.get(track.id)?.colorMap ?? track.spectrogramColorMap ?? spectrogramColorMap ?? "viridis";
|
|
@@ -4133,7 +4173,13 @@ var SpectrogramProvider = ({
|
|
|
4133
4173
|
} else {
|
|
4134
4174
|
for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {
|
|
4135
4175
|
channelSpectrograms.push(
|
|
4136
|
-
computeSpectrogram(
|
|
4176
|
+
computeSpectrogram(
|
|
4177
|
+
clip.audioBuffer,
|
|
4178
|
+
item.config,
|
|
4179
|
+
item.offsetSamples,
|
|
4180
|
+
item.durationSamples,
|
|
4181
|
+
ch
|
|
4182
|
+
)
|
|
4137
4183
|
);
|
|
4138
4184
|
}
|
|
4139
4185
|
}
|
|
@@ -4146,26 +4192,25 @@ var SpectrogramProvider = ({
|
|
|
4146
4192
|
}
|
|
4147
4193
|
return;
|
|
4148
4194
|
}
|
|
4149
|
-
const getVisibleChunkRange = (
|
|
4195
|
+
const getVisibleChunkRange = (channelInfo, clipPixelOffset = 0) => {
|
|
4150
4196
|
const container = scrollContainerRef.current;
|
|
4151
4197
|
if (!container) {
|
|
4152
|
-
return { visibleIndices: canvasWidths.map((_, i) => i), remainingIndices: [] };
|
|
4198
|
+
return { visibleIndices: channelInfo.canvasWidths.map((_, i) => i), remainingIndices: [] };
|
|
4153
4199
|
}
|
|
4154
4200
|
const scrollLeft = container.scrollLeft;
|
|
4155
4201
|
const viewportWidth = container.clientWidth;
|
|
4156
4202
|
const controlWidth = controls.show ? controls.width : 0;
|
|
4157
4203
|
const visibleIndices = [];
|
|
4158
4204
|
const remainingIndices = [];
|
|
4159
|
-
let
|
|
4160
|
-
|
|
4161
|
-
const chunkLeft =
|
|
4162
|
-
const chunkRight = chunkLeft + canvasWidths[i];
|
|
4205
|
+
for (let i = 0; i < channelInfo.canvasWidths.length; i++) {
|
|
4206
|
+
const chunkNumber = extractChunkNumber(channelInfo.canvasIds[i]);
|
|
4207
|
+
const chunkLeft = chunkNumber * MAX_CANVAS_WIDTH + controlWidth + clipPixelOffset;
|
|
4208
|
+
const chunkRight = chunkLeft + channelInfo.canvasWidths[i];
|
|
4163
4209
|
if (chunkRight > scrollLeft && chunkLeft < scrollLeft + viewportWidth) {
|
|
4164
4210
|
visibleIndices.push(i);
|
|
4165
4211
|
} else {
|
|
4166
4212
|
remainingIndices.push(i);
|
|
4167
4213
|
}
|
|
4168
|
-
offset += canvasWidths[i];
|
|
4169
4214
|
}
|
|
4170
4215
|
return { visibleIndices, remainingIndices };
|
|
4171
4216
|
};
|
|
@@ -4175,11 +4220,8 @@ var SpectrogramProvider = ({
|
|
|
4175
4220
|
const canvasWidths = indices.map((i) => channelInfo.canvasWidths[i]);
|
|
4176
4221
|
const globalPixelOffsets = [];
|
|
4177
4222
|
for (const idx of indices) {
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
offset += channelInfo.canvasWidths[j];
|
|
4181
|
-
}
|
|
4182
|
-
globalPixelOffsets.push(offset);
|
|
4223
|
+
const chunkNumber = extractChunkNumber(channelInfo.canvasIds[idx]);
|
|
4224
|
+
globalPixelOffsets.push(chunkNumber * MAX_CANVAS_WIDTH);
|
|
4183
4225
|
}
|
|
4184
4226
|
const colorLUT = getColorMap(item.colorMap);
|
|
4185
4227
|
await api.renderChunks({
|
|
@@ -4202,6 +4244,25 @@ var SpectrogramProvider = ({
|
|
|
4202
4244
|
const computeAsync = async () => {
|
|
4203
4245
|
const abortToken = { aborted: false };
|
|
4204
4246
|
backgroundRenderAbortRef.current = abortToken;
|
|
4247
|
+
const renderBackgroundBatches = async (channelRanges, cacheKey, item) => {
|
|
4248
|
+
const BATCH_SIZE = 4;
|
|
4249
|
+
for (const { ch, channelInfo, remainingIndices } of channelRanges) {
|
|
4250
|
+
for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {
|
|
4251
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return true;
|
|
4252
|
+
const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);
|
|
4253
|
+
await new Promise((resolve) => {
|
|
4254
|
+
if (typeof requestIdleCallback === "function") {
|
|
4255
|
+
requestIdleCallback(() => resolve());
|
|
4256
|
+
} else {
|
|
4257
|
+
setTimeout(resolve, 0);
|
|
4258
|
+
}
|
|
4259
|
+
});
|
|
4260
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return true;
|
|
4261
|
+
await renderChunkSubset(workerApi, cacheKey, channelInfo, batch, item, ch);
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
return false;
|
|
4265
|
+
};
|
|
4205
4266
|
for (const item of clipsNeedingFFT) {
|
|
4206
4267
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4207
4268
|
try {
|
|
@@ -4231,7 +4292,10 @@ var SpectrogramProvider = ({
|
|
|
4231
4292
|
item.offsetSamples + Math.ceil(localEndPx * samplesPerPixel)
|
|
4232
4293
|
);
|
|
4233
4294
|
const paddedStart = Math.max(item.offsetSamples, visStartSample - windowSize);
|
|
4234
|
-
const paddedEnd = Math.min(
|
|
4295
|
+
const paddedEnd = Math.min(
|
|
4296
|
+
item.offsetSamples + item.durationSamples,
|
|
4297
|
+
visEndSample + windowSize
|
|
4298
|
+
);
|
|
4235
4299
|
if (paddedEnd - paddedStart < item.durationSamples * 0.8) {
|
|
4236
4300
|
visibleRange = { start: paddedStart, end: paddedEnd };
|
|
4237
4301
|
}
|
|
@@ -4253,8 +4317,15 @@ var SpectrogramProvider = ({
|
|
|
4253
4317
|
for (let ch = 0; ch < numChannels; ch++) {
|
|
4254
4318
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4255
4319
|
if (!channelInfo) continue;
|
|
4256
|
-
const { visibleIndices } = getVisibleChunkRange(channelInfo
|
|
4257
|
-
await renderChunkSubset(
|
|
4320
|
+
const { visibleIndices } = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4321
|
+
await renderChunkSubset(
|
|
4322
|
+
workerApi,
|
|
4323
|
+
visibleCacheKey,
|
|
4324
|
+
channelInfo,
|
|
4325
|
+
visibleIndices,
|
|
4326
|
+
item,
|
|
4327
|
+
ch
|
|
4328
|
+
);
|
|
4258
4329
|
}
|
|
4259
4330
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4260
4331
|
}
|
|
@@ -4269,27 +4340,23 @@ var SpectrogramProvider = ({
|
|
|
4269
4340
|
});
|
|
4270
4341
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4271
4342
|
clipCacheKeysRef.current.set(item.clipId, cacheKey);
|
|
4343
|
+
const channelRanges = [];
|
|
4272
4344
|
for (let ch = 0; ch < numChannels; ch++) {
|
|
4273
4345
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4274
4346
|
if (!channelInfo) continue;
|
|
4275
|
-
const
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
} else {
|
|
4286
|
-
setTimeout(resolve, 0);
|
|
4287
|
-
}
|
|
4288
|
-
});
|
|
4289
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4290
|
-
await renderChunkSubset(workerApi, cacheKey, channelInfo, batch, item, ch);
|
|
4291
|
-
}
|
|
4347
|
+
const range = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4348
|
+
channelRanges.push({ ch, channelInfo, ...range });
|
|
4349
|
+
await renderChunkSubset(
|
|
4350
|
+
workerApi,
|
|
4351
|
+
cacheKey,
|
|
4352
|
+
channelInfo,
|
|
4353
|
+
range.visibleIndices,
|
|
4354
|
+
item,
|
|
4355
|
+
ch
|
|
4356
|
+
);
|
|
4292
4357
|
}
|
|
4358
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4359
|
+
if (await renderBackgroundBatches(channelRanges, cacheKey, item)) return;
|
|
4293
4360
|
} else {
|
|
4294
4361
|
const spectrograms = await workerApi.compute({
|
|
4295
4362
|
channelDataArrays: item.channelDataArrays,
|
|
@@ -4318,27 +4385,19 @@ var SpectrogramProvider = ({
|
|
|
4318
4385
|
if (!clipCanvasInfo || clipCanvasInfo.size === 0) continue;
|
|
4319
4386
|
try {
|
|
4320
4387
|
const clipPixelOffset = Math.floor(item.clipStartSample / samplesPerPixel);
|
|
4388
|
+
const channelRanges = [];
|
|
4321
4389
|
for (let ch = 0; ch < item.numChannels; ch++) {
|
|
4322
4390
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4323
4391
|
if (!channelInfo) continue;
|
|
4324
|
-
const { visibleIndices, remainingIndices } = getVisibleChunkRange(
|
|
4392
|
+
const { visibleIndices, remainingIndices } = getVisibleChunkRange(
|
|
4393
|
+
channelInfo,
|
|
4394
|
+
clipPixelOffset
|
|
4395
|
+
);
|
|
4396
|
+
channelRanges.push({ ch, channelInfo, remainingIndices });
|
|
4325
4397
|
await renderChunkSubset(workerApi, cacheKey, channelInfo, visibleIndices, item, ch);
|
|
4326
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4327
|
-
const BATCH_SIZE = 4;
|
|
4328
|
-
for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {
|
|
4329
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4330
|
-
const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);
|
|
4331
|
-
await new Promise((resolve) => {
|
|
4332
|
-
if (typeof requestIdleCallback === "function") {
|
|
4333
|
-
requestIdleCallback(() => resolve());
|
|
4334
|
-
} else {
|
|
4335
|
-
setTimeout(resolve, 0);
|
|
4336
|
-
}
|
|
4337
|
-
});
|
|
4338
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4339
|
-
await renderChunkSubset(workerApi, cacheKey, channelInfo, batch, item, ch);
|
|
4340
|
-
}
|
|
4341
4398
|
}
|
|
4399
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4400
|
+
if (await renderBackgroundBatches(channelRanges, cacheKey, item)) return;
|
|
4342
4401
|
} catch (err) {
|
|
4343
4402
|
console.warn("Spectrogram display re-render error for clip", item.clipId, err);
|
|
4344
4403
|
}
|
|
@@ -4347,7 +4406,18 @@ var SpectrogramProvider = ({
|
|
|
4347
4406
|
computeAsync().catch((err) => {
|
|
4348
4407
|
console.error("[waveform-playlist] Spectrogram computation failed:", err);
|
|
4349
4408
|
});
|
|
4350
|
-
}, [
|
|
4409
|
+
}, [
|
|
4410
|
+
tracks,
|
|
4411
|
+
mono,
|
|
4412
|
+
spectrogramConfig,
|
|
4413
|
+
spectrogramColorMap,
|
|
4414
|
+
trackSpectrogramOverrides,
|
|
4415
|
+
waveHeight,
|
|
4416
|
+
samplesPerPixel,
|
|
4417
|
+
spectrogramCanvasVersion,
|
|
4418
|
+
controls,
|
|
4419
|
+
scrollContainerRef
|
|
4420
|
+
]);
|
|
4351
4421
|
const setTrackRenderMode = useCallback((trackId, mode) => {
|
|
4352
4422
|
setTrackSpectrogramOverrides((prev) => {
|
|
4353
4423
|
const next = new Map(prev);
|
|
@@ -4356,26 +4426,32 @@ var SpectrogramProvider = ({
|
|
|
4356
4426
|
return next;
|
|
4357
4427
|
});
|
|
4358
4428
|
}, []);
|
|
4359
|
-
const setTrackSpectrogramConfig = useCallback(
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
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;
|
|
4367
4440
|
});
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
const registerSpectrogramCanvases = useCallback(
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
registry.
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
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
|
+
);
|
|
4379
4455
|
const unregisterSpectrogramCanvases = useCallback((clipId, channelIndex) => {
|
|
4380
4456
|
const registry = spectrogramCanvasRegistryRef.current;
|
|
4381
4457
|
const clipChannels = registry.get(clipId);
|
|
@@ -4386,40 +4462,46 @@ var SpectrogramProvider = ({
|
|
|
4386
4462
|
}
|
|
4387
4463
|
}
|
|
4388
4464
|
}, []);
|
|
4389
|
-
const renderMenuItems = useCallback(
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
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
|
+
);
|
|
4423
4505
|
return /* @__PURE__ */ jsx3(SpectrogramIntegrationProvider, { value, children });
|
|
4424
4506
|
};
|
|
4425
4507
|
export {
|