@waveform-playlist/spectrogram 7.1.1 → 7.1.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/index.js +48 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +48 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -3907,9 +3907,18 @@ function createSpectrogramWorker(worker) {
|
|
|
3907
3907
|
|
|
3908
3908
|
// src/SpectrogramProvider.tsx
|
|
3909
3909
|
import { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback, useMemo } from "react";
|
|
3910
|
+
import { MAX_CANVAS_WIDTH } from "@waveform-playlist/core";
|
|
3910
3911
|
import { SpectrogramIntegrationProvider } from "@waveform-playlist/browser";
|
|
3911
3912
|
import { usePlaylistData, usePlaylistControls } from "@waveform-playlist/browser";
|
|
3912
3913
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
3914
|
+
function extractChunkNumber(canvasId) {
|
|
3915
|
+
const match = canvasId.match(/chunk(\d+)$/);
|
|
3916
|
+
if (!match) {
|
|
3917
|
+
console.warn(`[spectrogram] Unexpected canvas ID format: ${canvasId}`);
|
|
3918
|
+
return 0;
|
|
3919
|
+
}
|
|
3920
|
+
return parseInt(match[1], 10);
|
|
3921
|
+
}
|
|
3913
3922
|
var SpectrogramProvider = ({
|
|
3914
3923
|
config: spectrogramConfig,
|
|
3915
3924
|
colorMap: spectrogramColorMap,
|
|
@@ -4146,26 +4155,25 @@ var SpectrogramProvider = ({
|
|
|
4146
4155
|
}
|
|
4147
4156
|
return;
|
|
4148
4157
|
}
|
|
4149
|
-
const getVisibleChunkRange = (
|
|
4158
|
+
const getVisibleChunkRange = (channelInfo, clipPixelOffset = 0) => {
|
|
4150
4159
|
const container = scrollContainerRef.current;
|
|
4151
4160
|
if (!container) {
|
|
4152
|
-
return { visibleIndices: canvasWidths.map((_, i) => i), remainingIndices: [] };
|
|
4161
|
+
return { visibleIndices: channelInfo.canvasWidths.map((_, i) => i), remainingIndices: [] };
|
|
4153
4162
|
}
|
|
4154
4163
|
const scrollLeft = container.scrollLeft;
|
|
4155
4164
|
const viewportWidth = container.clientWidth;
|
|
4156
4165
|
const controlWidth = controls.show ? controls.width : 0;
|
|
4157
4166
|
const visibleIndices = [];
|
|
4158
4167
|
const remainingIndices = [];
|
|
4159
|
-
let
|
|
4160
|
-
|
|
4161
|
-
const chunkLeft =
|
|
4162
|
-
const chunkRight = chunkLeft + canvasWidths[i];
|
|
4168
|
+
for (let i = 0; i < channelInfo.canvasWidths.length; i++) {
|
|
4169
|
+
const chunkNumber = extractChunkNumber(channelInfo.canvasIds[i]);
|
|
4170
|
+
const chunkLeft = chunkNumber * MAX_CANVAS_WIDTH + controlWidth + clipPixelOffset;
|
|
4171
|
+
const chunkRight = chunkLeft + channelInfo.canvasWidths[i];
|
|
4163
4172
|
if (chunkRight > scrollLeft && chunkLeft < scrollLeft + viewportWidth) {
|
|
4164
4173
|
visibleIndices.push(i);
|
|
4165
4174
|
} else {
|
|
4166
4175
|
remainingIndices.push(i);
|
|
4167
4176
|
}
|
|
4168
|
-
offset += canvasWidths[i];
|
|
4169
4177
|
}
|
|
4170
4178
|
return { visibleIndices, remainingIndices };
|
|
4171
4179
|
};
|
|
@@ -4175,11 +4183,8 @@ var SpectrogramProvider = ({
|
|
|
4175
4183
|
const canvasWidths = indices.map((i) => channelInfo.canvasWidths[i]);
|
|
4176
4184
|
const globalPixelOffsets = [];
|
|
4177
4185
|
for (const idx of indices) {
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
offset += channelInfo.canvasWidths[j];
|
|
4181
|
-
}
|
|
4182
|
-
globalPixelOffsets.push(offset);
|
|
4186
|
+
const chunkNumber = extractChunkNumber(channelInfo.canvasIds[idx]);
|
|
4187
|
+
globalPixelOffsets.push(chunkNumber * MAX_CANVAS_WIDTH);
|
|
4183
4188
|
}
|
|
4184
4189
|
const colorLUT = getColorMap(item.colorMap);
|
|
4185
4190
|
await api.renderChunks({
|
|
@@ -4202,6 +4207,25 @@ var SpectrogramProvider = ({
|
|
|
4202
4207
|
const computeAsync = async () => {
|
|
4203
4208
|
const abortToken = { aborted: false };
|
|
4204
4209
|
backgroundRenderAbortRef.current = abortToken;
|
|
4210
|
+
const renderBackgroundBatches = async (channelRanges, cacheKey, item) => {
|
|
4211
|
+
const BATCH_SIZE = 4;
|
|
4212
|
+
for (const { ch, channelInfo, remainingIndices } of channelRanges) {
|
|
4213
|
+
for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {
|
|
4214
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return true;
|
|
4215
|
+
const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);
|
|
4216
|
+
await new Promise((resolve) => {
|
|
4217
|
+
if (typeof requestIdleCallback === "function") {
|
|
4218
|
+
requestIdleCallback(() => resolve());
|
|
4219
|
+
} else {
|
|
4220
|
+
setTimeout(resolve, 0);
|
|
4221
|
+
}
|
|
4222
|
+
});
|
|
4223
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return true;
|
|
4224
|
+
await renderChunkSubset(workerApi, cacheKey, channelInfo, batch, item, ch);
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4227
|
+
return false;
|
|
4228
|
+
};
|
|
4205
4229
|
for (const item of clipsNeedingFFT) {
|
|
4206
4230
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4207
4231
|
try {
|
|
@@ -4253,7 +4277,7 @@ var SpectrogramProvider = ({
|
|
|
4253
4277
|
for (let ch = 0; ch < numChannels; ch++) {
|
|
4254
4278
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4255
4279
|
if (!channelInfo) continue;
|
|
4256
|
-
const { visibleIndices } = getVisibleChunkRange(channelInfo
|
|
4280
|
+
const { visibleIndices } = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4257
4281
|
await renderChunkSubset(workerApi, visibleCacheKey, channelInfo, visibleIndices, item, ch);
|
|
4258
4282
|
}
|
|
4259
4283
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
@@ -4269,27 +4293,16 @@ var SpectrogramProvider = ({
|
|
|
4269
4293
|
});
|
|
4270
4294
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4271
4295
|
clipCacheKeysRef.current.set(item.clipId, cacheKey);
|
|
4296
|
+
const channelRanges = [];
|
|
4272
4297
|
for (let ch = 0; ch < numChannels; ch++) {
|
|
4273
4298
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4274
4299
|
if (!channelInfo) continue;
|
|
4275
|
-
const
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
const BATCH_SIZE = 4;
|
|
4279
|
-
for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {
|
|
4280
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4281
|
-
const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);
|
|
4282
|
-
await new Promise((resolve) => {
|
|
4283
|
-
if (typeof requestIdleCallback === "function") {
|
|
4284
|
-
requestIdleCallback(() => resolve());
|
|
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
|
-
}
|
|
4300
|
+
const range = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4301
|
+
channelRanges.push({ ch, channelInfo, ...range });
|
|
4302
|
+
await renderChunkSubset(workerApi, cacheKey, channelInfo, range.visibleIndices, item, ch);
|
|
4292
4303
|
}
|
|
4304
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4305
|
+
if (await renderBackgroundBatches(channelRanges, cacheKey, item)) return;
|
|
4293
4306
|
} else {
|
|
4294
4307
|
const spectrograms = await workerApi.compute({
|
|
4295
4308
|
channelDataArrays: item.channelDataArrays,
|
|
@@ -4318,27 +4331,16 @@ var SpectrogramProvider = ({
|
|
|
4318
4331
|
if (!clipCanvasInfo || clipCanvasInfo.size === 0) continue;
|
|
4319
4332
|
try {
|
|
4320
4333
|
const clipPixelOffset = Math.floor(item.clipStartSample / samplesPerPixel);
|
|
4334
|
+
const channelRanges = [];
|
|
4321
4335
|
for (let ch = 0; ch < item.numChannels; ch++) {
|
|
4322
4336
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4323
4337
|
if (!channelInfo) continue;
|
|
4324
|
-
const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo
|
|
4338
|
+
const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4339
|
+
channelRanges.push({ ch, channelInfo, remainingIndices });
|
|
4325
4340
|
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
4341
|
}
|
|
4342
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4343
|
+
if (await renderBackgroundBatches(channelRanges, cacheKey, item)) return;
|
|
4342
4344
|
} catch (err) {
|
|
4343
4345
|
console.warn("Spectrogram display re-render error for clip", item.clipId, err);
|
|
4344
4346
|
}
|