@signalsandsorcery/plugin-sdk 2.24.1 → 2.26.1
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.d.mts +54 -6
- package/dist/index.d.ts +54 -6
- package/dist/index.js +67 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2465,6 +2465,8 @@ function parseCrossfadePairs(sceneData) {
|
|
|
2465
2465
|
sliderPos: g.origin.meta.sliderPos,
|
|
2466
2466
|
originDbId: g.origin.dbId,
|
|
2467
2467
|
targetDbId: g.target.dbId,
|
|
2468
|
+
originSourceDbId: g.origin.meta.sourceTrackDbId,
|
|
2469
|
+
targetSourceDbId: g.target.meta.sourceTrackDbId,
|
|
2468
2470
|
originSourceName: g.origin.meta.sourceName,
|
|
2469
2471
|
originSoundLabel: g.origin.meta.soundLabel,
|
|
2470
2472
|
targetSourceName: g.target.meta.sourceName,
|
|
@@ -2473,6 +2475,25 @@ function parseCrossfadePairs(sceneData) {
|
|
|
2473
2475
|
}
|
|
2474
2476
|
return pairs;
|
|
2475
2477
|
}
|
|
2478
|
+
var FADE_FLOOR_DB = -80;
|
|
2479
|
+
function gainToDb(gain) {
|
|
2480
|
+
return gain <= 1e-4 ? FADE_FLOOR_DB : Math.max(FADE_FLOOR_DB, 20 * Math.log10(gain));
|
|
2481
|
+
}
|
|
2482
|
+
function buildCrossfadeVolumeCurves(bars, bpm, sliderPos, steps = 32) {
|
|
2483
|
+
const durationSeconds = bars * 4 * 60 / Math.max(1, bpm);
|
|
2484
|
+
const s = Math.min(0.98, Math.max(0.02, sliderPos));
|
|
2485
|
+
const round = (n) => Math.round(n * 1e3) / 1e3;
|
|
2486
|
+
const origin = [];
|
|
2487
|
+
const target = [];
|
|
2488
|
+
for (let i = 0; i <= steps; i++) {
|
|
2489
|
+
const x = i / steps;
|
|
2490
|
+
const time = round(x * durationSeconds);
|
|
2491
|
+
const theta = x <= s ? x / s * (Math.PI / 4) : Math.PI / 4 + (x - s) / (1 - s) * (Math.PI / 4);
|
|
2492
|
+
origin.push({ time, db: Math.round(gainToDb(Math.cos(theta)) * 100) / 100 });
|
|
2493
|
+
target.push({ time, db: Math.round(gainToDb(Math.sin(theta)) * 100) / 100 });
|
|
2494
|
+
}
|
|
2495
|
+
return { origin, target };
|
|
2496
|
+
}
|
|
2476
2497
|
|
|
2477
2498
|
// src/crossfade-inpaint.ts
|
|
2478
2499
|
var PITCH_NAMES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
@@ -2721,6 +2742,7 @@ function CrossfadeModal({
|
|
|
2721
2742
|
toSceneId,
|
|
2722
2743
|
fromSceneName,
|
|
2723
2744
|
toSceneName,
|
|
2745
|
+
excludeSourceDbIds,
|
|
2724
2746
|
onClose,
|
|
2725
2747
|
onCreate,
|
|
2726
2748
|
testIdPrefix = "crossfade-modal"
|
|
@@ -2730,6 +2752,8 @@ function CrossfadeModal({
|
|
|
2730
2752
|
const [targetDbId, setTargetDbId] = useState8("");
|
|
2731
2753
|
const [isCreating, setIsCreating] = useState8(false);
|
|
2732
2754
|
const [error, setError] = useState8(null);
|
|
2755
|
+
const [fromName, setFromName] = useState8(null);
|
|
2756
|
+
const [toName, setToName] = useState8(null);
|
|
2733
2757
|
const cancelRef = useRef7(null);
|
|
2734
2758
|
const refresh = useCallback5(async () => {
|
|
2735
2759
|
if (!host.listSceneFamilyTracks) {
|
|
@@ -2738,12 +2762,15 @@ function CrossfadeModal({
|
|
|
2738
2762
|
}
|
|
2739
2763
|
setLoad({ status: "loading" });
|
|
2740
2764
|
try {
|
|
2741
|
-
const [origin, target] = await Promise.all([
|
|
2765
|
+
const [origin, target, fName, tName] = await Promise.all([
|
|
2742
2766
|
host.listSceneFamilyTracks(fromSceneId),
|
|
2743
|
-
host.listSceneFamilyTracks(toSceneId)
|
|
2767
|
+
host.listSceneFamilyTracks(toSceneId),
|
|
2768
|
+
host.getSceneName ? host.getSceneName(fromSceneId) : Promise.resolve(null),
|
|
2769
|
+
host.getSceneName ? host.getSceneName(toSceneId) : Promise.resolve(null)
|
|
2744
2770
|
]);
|
|
2771
|
+
setFromName(fName);
|
|
2772
|
+
setToName(tName);
|
|
2745
2773
|
setLoad({ status: "ready", origin, target });
|
|
2746
|
-
setOriginDbId(origin[0]?.dbId ?? "");
|
|
2747
2774
|
} catch (err) {
|
|
2748
2775
|
setLoad({ status: "error", message: err instanceof Error ? err.message : "Failed to load tracks." });
|
|
2749
2776
|
}
|
|
@@ -2757,21 +2784,26 @@ function CrossfadeModal({
|
|
|
2757
2784
|
void refresh();
|
|
2758
2785
|
}
|
|
2759
2786
|
}, [open, refresh]);
|
|
2760
|
-
const
|
|
2761
|
-
|
|
2762
|
-
|
|
2787
|
+
const excludeSet = useMemo3(() => new Set(excludeSourceDbIds ?? []), [excludeSourceDbIds]);
|
|
2788
|
+
const originCandidates = useMemo3(
|
|
2789
|
+
() => load.status === "ready" ? load.origin.filter((t) => !excludeSet.has(t.dbId)) : [],
|
|
2790
|
+
[load, excludeSet]
|
|
2791
|
+
);
|
|
2792
|
+
const targetCandidates = useMemo3(
|
|
2793
|
+
() => load.status === "ready" ? load.target.filter((t) => !excludeSet.has(t.dbId)) : [],
|
|
2794
|
+
[load, excludeSet]
|
|
2763
2795
|
);
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
}, [load, originRole]);
|
|
2796
|
+
useEffect7(() => {
|
|
2797
|
+
if (!originCandidates.some((t) => t.dbId === originDbId)) {
|
|
2798
|
+
setOriginDbId(originCandidates[0]?.dbId ?? "");
|
|
2799
|
+
}
|
|
2800
|
+
}, [originCandidates, originDbId]);
|
|
2770
2801
|
useEffect7(() => {
|
|
2771
2802
|
if (!targetCandidates.some((t) => t.dbId === targetDbId)) {
|
|
2772
2803
|
setTargetDbId(targetCandidates[0]?.dbId ?? "");
|
|
2773
2804
|
}
|
|
2774
2805
|
}, [targetCandidates, targetDbId]);
|
|
2806
|
+
const originTrack = originCandidates.find((t) => t.dbId === originDbId) ?? null;
|
|
2775
2807
|
const targetTrack = targetCandidates.find((t) => t.dbId === targetDbId) ?? null;
|
|
2776
2808
|
const canCreate = !isCreating && !!originTrack && !!targetTrack;
|
|
2777
2809
|
const handleClose = useCallback5(() => {
|
|
@@ -2792,6 +2824,8 @@ function CrossfadeModal({
|
|
|
2792
2824
|
setIsCreating(false);
|
|
2793
2825
|
}
|
|
2794
2826
|
}, [originTrack, targetTrack, onCreate, onClose]);
|
|
2827
|
+
const fromLabel = fromName ?? fromSceneName ?? null;
|
|
2828
|
+
const toLabel = toName ?? toSceneName ?? null;
|
|
2795
2829
|
if (!open) return null;
|
|
2796
2830
|
return /* @__PURE__ */ jsx14(Modal, { open, onClose: handleClose, testIdPrefix, initialFocusRef: cancelRef, children: /* @__PURE__ */ jsxs10(
|
|
2797
2831
|
"div",
|
|
@@ -2804,24 +2838,31 @@ function CrossfadeModal({
|
|
|
2804
2838
|
/* @__PURE__ */ jsxs10("p", { className: "text-[11px] text-sas-muted leading-relaxed", children: [
|
|
2805
2839
|
"Bridge a track from",
|
|
2806
2840
|
" ",
|
|
2807
|
-
/* @__PURE__ */ jsx14("span", { className: "text-sas-text", children:
|
|
2841
|
+
/* @__PURE__ */ jsx14("span", { className: "text-sas-text", children: fromLabel ?? "the origin scene" }),
|
|
2808
2842
|
" into one from",
|
|
2809
2843
|
" ",
|
|
2810
|
-
/* @__PURE__ */ jsx14("span", { className: "text-sas-text", children:
|
|
2844
|
+
/* @__PURE__ */ jsx14("span", { className: "text-sas-text", children: toLabel ?? "the target scene" }),
|
|
2811
2845
|
". Both layers share one generated part; each keeps its own preset."
|
|
2812
2846
|
] }),
|
|
2813
2847
|
load.status === "loading" && /* @__PURE__ */ jsx14("div", { className: "text-xs text-sas-muted py-4 text-center", children: "Loading tracks\u2026" }),
|
|
2814
2848
|
load.status === "error" && /* @__PURE__ */ jsx14("div", { className: "text-xs text-sas-danger py-4 text-center", children: load.message }),
|
|
2815
|
-
load.status === "ready" && (
|
|
2849
|
+
load.status === "ready" && (originCandidates.length === 0 ? /* @__PURE__ */ jsxs10(
|
|
2816
2850
|
"div",
|
|
2817
2851
|
{
|
|
2818
2852
|
className: "text-xs text-sas-muted py-4 text-center",
|
|
2819
2853
|
"data-testid": `${testIdPrefix}-empty-origin`,
|
|
2820
|
-
children:
|
|
2854
|
+
children: [
|
|
2855
|
+
"No available tracks in ",
|
|
2856
|
+
fromLabel ?? "the origin scene",
|
|
2857
|
+
". Add one (or free one from another crossfade) first."
|
|
2858
|
+
]
|
|
2821
2859
|
}
|
|
2822
2860
|
) : /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
2823
2861
|
/* @__PURE__ */ jsxs10("label", { className: "block", children: [
|
|
2824
|
-
/* @__PURE__ */
|
|
2862
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-[10px] uppercase tracking-wide text-sas-muted", children: [
|
|
2863
|
+
"Origin ",
|
|
2864
|
+
fromLabel ? `(${fromLabel})` : "(top)"
|
|
2865
|
+
] }),
|
|
2825
2866
|
/* @__PURE__ */ jsx14(
|
|
2826
2867
|
"select",
|
|
2827
2868
|
{
|
|
@@ -2830,7 +2871,7 @@ function CrossfadeModal({
|
|
|
2830
2871
|
onChange: (e) => setOriginDbId(e.target.value),
|
|
2831
2872
|
disabled: isCreating,
|
|
2832
2873
|
className: "sas-input w-full mt-0.5 text-xs",
|
|
2833
|
-
children:
|
|
2874
|
+
children: originCandidates.map((t) => /* @__PURE__ */ jsxs10("option", { value: t.dbId, children: [
|
|
2834
2875
|
t.name,
|
|
2835
2876
|
t.role ? ` \xB7 ${t.role}` : ""
|
|
2836
2877
|
] }, t.dbId))
|
|
@@ -2839,13 +2880,13 @@ function CrossfadeModal({
|
|
|
2839
2880
|
] }),
|
|
2840
2881
|
/* @__PURE__ */ jsxs10("label", { className: "block", children: [
|
|
2841
2882
|
/* @__PURE__ */ jsxs10("span", { className: "text-[10px] uppercase tracking-wide text-sas-muted", children: [
|
|
2842
|
-
"Target
|
|
2843
|
-
|
|
2883
|
+
"Target ",
|
|
2884
|
+
toLabel ? `(${toLabel})` : "(bottom)"
|
|
2844
2885
|
] }),
|
|
2845
2886
|
targetCandidates.length === 0 ? /* @__PURE__ */ jsxs10("div", { className: "text-xs text-sas-danger mt-0.5", "data-testid": `${testIdPrefix}-empty-target`, children: [
|
|
2846
|
-
"No ",
|
|
2847
|
-
|
|
2848
|
-
"
|
|
2887
|
+
"No available tracks in ",
|
|
2888
|
+
toLabel ?? "the target scene",
|
|
2889
|
+
" to crossfade into."
|
|
2849
2890
|
] }) : /* @__PURE__ */ jsx14(
|
|
2850
2891
|
"select",
|
|
2851
2892
|
{
|
|
@@ -3764,7 +3805,7 @@ function useTrackReorder({
|
|
|
3764
3805
|
}
|
|
3765
3806
|
|
|
3766
3807
|
// src/constants/sdk-version.ts
|
|
3767
|
-
var PLUGIN_SDK_VERSION = "2.
|
|
3808
|
+
var PLUGIN_SDK_VERSION = "2.26.0";
|
|
3768
3809
|
|
|
3769
3810
|
// src/utils/format-concurrent-tracks.ts
|
|
3770
3811
|
function formatConcurrentTracks(ctx) {
|
|
@@ -3950,6 +3991,7 @@ export {
|
|
|
3950
3991
|
analyzeWavPeak,
|
|
3951
3992
|
asCrossfadeMeta,
|
|
3952
3993
|
buildCrossfadeInpaintPrompt,
|
|
3994
|
+
buildCrossfadeVolumeCurves,
|
|
3953
3995
|
calculateTimeBasedTarget,
|
|
3954
3996
|
cellToPx,
|
|
3955
3997
|
centerScrollTop,
|