@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.js
CHANGED
|
@@ -3950,10 +3950,19 @@ function createSpectrogramWorker(worker) {
|
|
|
3950
3950
|
|
|
3951
3951
|
// src/SpectrogramProvider.tsx
|
|
3952
3952
|
var import_react2 = require("react");
|
|
3953
|
+
var import_core = require("@waveform-playlist/core");
|
|
3953
3954
|
var import_browser = require("@waveform-playlist/browser");
|
|
3954
3955
|
var import_browser2 = require("@waveform-playlist/browser");
|
|
3955
3956
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
3956
3957
|
var import_meta = {};
|
|
3958
|
+
function extractChunkNumber(canvasId) {
|
|
3959
|
+
const match = canvasId.match(/chunk(\d+)$/);
|
|
3960
|
+
if (!match) {
|
|
3961
|
+
console.warn(`[spectrogram] Unexpected canvas ID format: ${canvasId}`);
|
|
3962
|
+
return 0;
|
|
3963
|
+
}
|
|
3964
|
+
return parseInt(match[1], 10);
|
|
3965
|
+
}
|
|
3957
3966
|
var SpectrogramProvider = ({
|
|
3958
3967
|
config: spectrogramConfig,
|
|
3959
3968
|
colorMap: spectrogramColorMap,
|
|
@@ -4190,26 +4199,25 @@ var SpectrogramProvider = ({
|
|
|
4190
4199
|
}
|
|
4191
4200
|
return;
|
|
4192
4201
|
}
|
|
4193
|
-
const getVisibleChunkRange = (
|
|
4202
|
+
const getVisibleChunkRange = (channelInfo, clipPixelOffset = 0) => {
|
|
4194
4203
|
const container = scrollContainerRef.current;
|
|
4195
4204
|
if (!container) {
|
|
4196
|
-
return { visibleIndices: canvasWidths.map((_, i) => i), remainingIndices: [] };
|
|
4205
|
+
return { visibleIndices: channelInfo.canvasWidths.map((_, i) => i), remainingIndices: [] };
|
|
4197
4206
|
}
|
|
4198
4207
|
const scrollLeft = container.scrollLeft;
|
|
4199
4208
|
const viewportWidth = container.clientWidth;
|
|
4200
4209
|
const controlWidth = controls.show ? controls.width : 0;
|
|
4201
4210
|
const visibleIndices = [];
|
|
4202
4211
|
const remainingIndices = [];
|
|
4203
|
-
let
|
|
4204
|
-
|
|
4205
|
-
const chunkLeft =
|
|
4206
|
-
const chunkRight = chunkLeft + canvasWidths[i];
|
|
4212
|
+
for (let i = 0; i < channelInfo.canvasWidths.length; i++) {
|
|
4213
|
+
const chunkNumber = extractChunkNumber(channelInfo.canvasIds[i]);
|
|
4214
|
+
const chunkLeft = chunkNumber * import_core.MAX_CANVAS_WIDTH + controlWidth + clipPixelOffset;
|
|
4215
|
+
const chunkRight = chunkLeft + channelInfo.canvasWidths[i];
|
|
4207
4216
|
if (chunkRight > scrollLeft && chunkLeft < scrollLeft + viewportWidth) {
|
|
4208
4217
|
visibleIndices.push(i);
|
|
4209
4218
|
} else {
|
|
4210
4219
|
remainingIndices.push(i);
|
|
4211
4220
|
}
|
|
4212
|
-
offset += canvasWidths[i];
|
|
4213
4221
|
}
|
|
4214
4222
|
return { visibleIndices, remainingIndices };
|
|
4215
4223
|
};
|
|
@@ -4219,11 +4227,8 @@ var SpectrogramProvider = ({
|
|
|
4219
4227
|
const canvasWidths = indices.map((i) => channelInfo.canvasWidths[i]);
|
|
4220
4228
|
const globalPixelOffsets = [];
|
|
4221
4229
|
for (const idx of indices) {
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
offset += channelInfo.canvasWidths[j];
|
|
4225
|
-
}
|
|
4226
|
-
globalPixelOffsets.push(offset);
|
|
4230
|
+
const chunkNumber = extractChunkNumber(channelInfo.canvasIds[idx]);
|
|
4231
|
+
globalPixelOffsets.push(chunkNumber * import_core.MAX_CANVAS_WIDTH);
|
|
4227
4232
|
}
|
|
4228
4233
|
const colorLUT = getColorMap(item.colorMap);
|
|
4229
4234
|
await api.renderChunks({
|
|
@@ -4246,6 +4251,25 @@ var SpectrogramProvider = ({
|
|
|
4246
4251
|
const computeAsync = async () => {
|
|
4247
4252
|
const abortToken = { aborted: false };
|
|
4248
4253
|
backgroundRenderAbortRef.current = abortToken;
|
|
4254
|
+
const renderBackgroundBatches = async (channelRanges, cacheKey, item) => {
|
|
4255
|
+
const BATCH_SIZE = 4;
|
|
4256
|
+
for (const { ch, channelInfo, remainingIndices } of channelRanges) {
|
|
4257
|
+
for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {
|
|
4258
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return true;
|
|
4259
|
+
const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);
|
|
4260
|
+
await new Promise((resolve) => {
|
|
4261
|
+
if (typeof requestIdleCallback === "function") {
|
|
4262
|
+
requestIdleCallback(() => resolve());
|
|
4263
|
+
} else {
|
|
4264
|
+
setTimeout(resolve, 0);
|
|
4265
|
+
}
|
|
4266
|
+
});
|
|
4267
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return true;
|
|
4268
|
+
await renderChunkSubset(workerApi, cacheKey, channelInfo, batch, item, ch);
|
|
4269
|
+
}
|
|
4270
|
+
}
|
|
4271
|
+
return false;
|
|
4272
|
+
};
|
|
4249
4273
|
for (const item of clipsNeedingFFT) {
|
|
4250
4274
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4251
4275
|
try {
|
|
@@ -4297,7 +4321,7 @@ var SpectrogramProvider = ({
|
|
|
4297
4321
|
for (let ch = 0; ch < numChannels; ch++) {
|
|
4298
4322
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4299
4323
|
if (!channelInfo) continue;
|
|
4300
|
-
const { visibleIndices } = getVisibleChunkRange(channelInfo
|
|
4324
|
+
const { visibleIndices } = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4301
4325
|
await renderChunkSubset(workerApi, visibleCacheKey, channelInfo, visibleIndices, item, ch);
|
|
4302
4326
|
}
|
|
4303
4327
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
@@ -4313,27 +4337,16 @@ var SpectrogramProvider = ({
|
|
|
4313
4337
|
});
|
|
4314
4338
|
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4315
4339
|
clipCacheKeysRef.current.set(item.clipId, cacheKey);
|
|
4340
|
+
const channelRanges = [];
|
|
4316
4341
|
for (let ch = 0; ch < numChannels; ch++) {
|
|
4317
4342
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4318
4343
|
if (!channelInfo) continue;
|
|
4319
|
-
const
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
const BATCH_SIZE = 4;
|
|
4323
|
-
for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {
|
|
4324
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4325
|
-
const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);
|
|
4326
|
-
await new Promise((resolve) => {
|
|
4327
|
-
if (typeof requestIdleCallback === "function") {
|
|
4328
|
-
requestIdleCallback(() => resolve());
|
|
4329
|
-
} else {
|
|
4330
|
-
setTimeout(resolve, 0);
|
|
4331
|
-
}
|
|
4332
|
-
});
|
|
4333
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4334
|
-
await renderChunkSubset(workerApi, cacheKey, channelInfo, batch, item, ch);
|
|
4335
|
-
}
|
|
4344
|
+
const range = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4345
|
+
channelRanges.push({ ch, channelInfo, ...range });
|
|
4346
|
+
await renderChunkSubset(workerApi, cacheKey, channelInfo, range.visibleIndices, item, ch);
|
|
4336
4347
|
}
|
|
4348
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4349
|
+
if (await renderBackgroundBatches(channelRanges, cacheKey, item)) return;
|
|
4337
4350
|
} else {
|
|
4338
4351
|
const spectrograms = await workerApi.compute({
|
|
4339
4352
|
channelDataArrays: item.channelDataArrays,
|
|
@@ -4362,27 +4375,16 @@ var SpectrogramProvider = ({
|
|
|
4362
4375
|
if (!clipCanvasInfo || clipCanvasInfo.size === 0) continue;
|
|
4363
4376
|
try {
|
|
4364
4377
|
const clipPixelOffset = Math.floor(item.clipStartSample / samplesPerPixel);
|
|
4378
|
+
const channelRanges = [];
|
|
4365
4379
|
for (let ch = 0; ch < item.numChannels; ch++) {
|
|
4366
4380
|
const channelInfo = clipCanvasInfo.get(ch);
|
|
4367
4381
|
if (!channelInfo) continue;
|
|
4368
|
-
const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo
|
|
4382
|
+
const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo, clipPixelOffset);
|
|
4383
|
+
channelRanges.push({ ch, channelInfo, remainingIndices });
|
|
4369
4384
|
await renderChunkSubset(workerApi, cacheKey, channelInfo, visibleIndices, item, ch);
|
|
4370
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4371
|
-
const BATCH_SIZE = 4;
|
|
4372
|
-
for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {
|
|
4373
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4374
|
-
const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);
|
|
4375
|
-
await new Promise((resolve) => {
|
|
4376
|
-
if (typeof requestIdleCallback === "function") {
|
|
4377
|
-
requestIdleCallback(() => resolve());
|
|
4378
|
-
} else {
|
|
4379
|
-
setTimeout(resolve, 0);
|
|
4380
|
-
}
|
|
4381
|
-
});
|
|
4382
|
-
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4383
|
-
await renderChunkSubset(workerApi, cacheKey, channelInfo, batch, item, ch);
|
|
4384
|
-
}
|
|
4385
4385
|
}
|
|
4386
|
+
if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;
|
|
4387
|
+
if (await renderBackgroundBatches(channelRanges, cacheKey, item)) return;
|
|
4386
4388
|
} catch (err) {
|
|
4387
4389
|
console.warn("Spectrogram display re-render error for clip", item.clipId, err);
|
|
4388
4390
|
}
|