@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.d.mts
CHANGED
|
@@ -227,6 +227,16 @@ interface PluginHost {
|
|
|
227
227
|
setTrackMute(trackId: string, muted: boolean): Promise<void>;
|
|
228
228
|
/** Set track volume (linear 0.0 - 1.0). Only works on owned tracks. */
|
|
229
229
|
setTrackVolume(trackId: string, volume: number): Promise<void>;
|
|
230
|
+
/**
|
|
231
|
+
* Set/replace a time-based volume automation curve (a fade envelope) on a track,
|
|
232
|
+
* or clear it with an empty array. Points are {time: seconds, db}; linear between
|
|
233
|
+
* points. Used by crossfade tracks to fade origin↔target across the looped
|
|
234
|
+
* transition. Optional — callers MUST null-check. @since SDK 2.25.0
|
|
235
|
+
*/
|
|
236
|
+
setTrackVolumeAutomation?(trackId: string, points: Array<{
|
|
237
|
+
time: number;
|
|
238
|
+
db: number;
|
|
239
|
+
}>): Promise<void>;
|
|
230
240
|
/** Set track pan (-1.0 left to 1.0 right). Only works on owned tracks. */
|
|
231
241
|
setTrackPan(trackId: string, pan: number): Promise<void>;
|
|
232
242
|
/** Set track solo state. Only works on owned tracks. */
|
|
@@ -537,6 +547,11 @@ interface PluginHost {
|
|
|
537
547
|
key: string;
|
|
538
548
|
mode: string;
|
|
539
549
|
} | null>;
|
|
550
|
+
/**
|
|
551
|
+
* Read a scene's human display name by db id (for labelling a crossfade's
|
|
552
|
+
* origin/target scenes). Optional — callers MUST null-check. @since SDK 2.26.0
|
|
553
|
+
*/
|
|
554
|
+
getSceneName?(sceneDbId: string): Promise<string | null>;
|
|
540
555
|
/** Subscribe to transport state changes. Returns unsubscribe function. */
|
|
541
556
|
onTransportEvent(listener: TransportEventListener): UnsubscribeFn;
|
|
542
557
|
/** Subscribe to deck boundary events. Returns unsubscribe function. */
|
|
@@ -2592,6 +2607,10 @@ interface CrossfadePairMeta {
|
|
|
2592
2607
|
sliderPos: number;
|
|
2593
2608
|
originDbId: string;
|
|
2594
2609
|
targetDbId: string;
|
|
2610
|
+
/** DB id of the ORIGIN source track (in the from scene) — drives the "used once" exclusion. */
|
|
2611
|
+
originSourceDbId: string;
|
|
2612
|
+
/** DB id of the TARGET source track (in the to scene). */
|
|
2613
|
+
targetSourceDbId: string;
|
|
2595
2614
|
originSourceName: string;
|
|
2596
2615
|
originSoundLabel: string;
|
|
2597
2616
|
targetSourceName: string;
|
|
@@ -2606,6 +2625,28 @@ declare function asCrossfadeMeta(val: unknown): CrossfadeMeta | null;
|
|
|
2606
2625
|
* row instead of vanishing.
|
|
2607
2626
|
*/
|
|
2608
2627
|
declare function parseCrossfadePairs(sceneData: Record<string, unknown>): CrossfadePairMeta[];
|
|
2628
|
+
/** One volume-automation point: a dB value at a time offset (seconds from clip start). */
|
|
2629
|
+
interface VolumeAutomationPoint {
|
|
2630
|
+
time: number;
|
|
2631
|
+
db: number;
|
|
2632
|
+
}
|
|
2633
|
+
/** Origin + target volume curves for one crossfade pair. */
|
|
2634
|
+
interface CrossfadeVolumeCurves {
|
|
2635
|
+
origin: VolumeAutomationPoint[];
|
|
2636
|
+
target: VolumeAutomationPoint[];
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2639
|
+
* Equal-power crossfade volume curves over a transition of `bars` at `bpm`.
|
|
2640
|
+
* The ORIGIN layer fades OUT and the TARGET fades IN; `sliderPos` (0..1) sets
|
|
2641
|
+
* WHERE in time the equal-power (-3 dB) crossover sits — 0 = hand off near the
|
|
2642
|
+
* start, 1 = hold the origin until near the end. Points span the clip window
|
|
2643
|
+
* [0, durationSeconds] so the engine re-reads them each loop (re-fade per loop).
|
|
2644
|
+
* `steps`+1 points with linear interpolation approximate the cos/sin curve.
|
|
2645
|
+
*
|
|
2646
|
+
* Returns dB point arrays for `host.setTrackVolumeAutomation` — origin on the top
|
|
2647
|
+
* layer, target on the bottom. @since SDK 2.25.0
|
|
2648
|
+
*/
|
|
2649
|
+
declare function buildCrossfadeVolumeCurves(bars: number, bpm: number, sliderPos: number, steps?: number): CrossfadeVolumeCurves;
|
|
2609
2650
|
|
|
2610
2651
|
/**
|
|
2611
2652
|
* CrossfadeTrackRow — a transition "crossfade track": two stacked TrackRows
|
|
@@ -2794,8 +2835,9 @@ declare function ImportTrackModal({ host, open, onClose, onImported, title, test
|
|
|
2794
2835
|
*
|
|
2795
2836
|
* Shown only inside a `scene_type='transition'` scene. The user picks an ORIGIN
|
|
2796
2837
|
* track (from the transition's FROM scene) and a TARGET track (from its TO
|
|
2797
|
-
* scene)
|
|
2798
|
-
*
|
|
2838
|
+
* scene), in ANY order — the only constraint is same plugin/family (the picker is
|
|
2839
|
+
* per-panel). A source track already used in a crossfade is hidden (via
|
|
2840
|
+
* excludeSourceDbIds), so each source is used at most once.
|
|
2799
2841
|
*
|
|
2800
2842
|
* Self-fetching: given the scoped `host`, it calls `host.listSceneFamilyTracks`
|
|
2801
2843
|
* for both scenes (ungated — a transition deliberately bridges different keys).
|
|
@@ -2813,7 +2855,7 @@ interface CrossfadeSelection {
|
|
|
2813
2855
|
dbId: string;
|
|
2814
2856
|
/** Display name (for the row caption). */
|
|
2815
2857
|
name: string;
|
|
2816
|
-
/** Musical role
|
|
2858
|
+
/** Musical role of the source track (the panel uses the TARGET's for generation). */
|
|
2817
2859
|
role?: string;
|
|
2818
2860
|
}
|
|
2819
2861
|
interface CrossfadeModalProps {
|
|
@@ -2829,6 +2871,12 @@ interface CrossfadeModalProps {
|
|
|
2829
2871
|
fromSceneName?: string;
|
|
2830
2872
|
/** Display name for the target scene heading (optional). */
|
|
2831
2873
|
toSceneName?: string;
|
|
2874
|
+
/**
|
|
2875
|
+
* Source-track DB ids already used in a crossfade (origin + target of every
|
|
2876
|
+
* existing pair in this panel). Hidden from BOTH dropdowns so each source is
|
|
2877
|
+
* used at most once. @since SDK 2.26.0
|
|
2878
|
+
*/
|
|
2879
|
+
excludeSourceDbIds?: readonly string[];
|
|
2832
2880
|
/** Close handler (Escape, backdrop, Cancel, or after a successful create). */
|
|
2833
2881
|
onClose: () => void;
|
|
2834
2882
|
/** Build the crossfade pair. Should reject on failure so the modal shows it. */
|
|
@@ -2836,7 +2884,7 @@ interface CrossfadeModalProps {
|
|
|
2836
2884
|
/** data-testid prefix. */
|
|
2837
2885
|
testIdPrefix?: string;
|
|
2838
2886
|
}
|
|
2839
|
-
declare function CrossfadeModal({ host, open, fromSceneId, toSceneId, fromSceneName, toSceneName, onClose, onCreate, testIdPrefix, }: CrossfadeModalProps): React.ReactElement | null;
|
|
2887
|
+
declare function CrossfadeModal({ host, open, fromSceneId, toSceneId, fromSceneName, toSceneName, excludeSourceDbIds, onClose, onCreate, testIdPrefix, }: CrossfadeModalProps): React.ReactElement | null;
|
|
2840
2888
|
|
|
2841
2889
|
/**
|
|
2842
2890
|
* ConfirmDialog — styled in-app confirmation modal (SDK component).
|
|
@@ -3561,7 +3609,7 @@ declare function useSoundHistory(applySound: (trackId: string, descriptor: unkno
|
|
|
3561
3609
|
* Registry checks semver.gte(PLUGIN_SDK_VERSION, manifest.minHostVersion)
|
|
3562
3610
|
* during activation and marks incompatible plugins accordingly.
|
|
3563
3611
|
*/
|
|
3564
|
-
declare const PLUGIN_SDK_VERSION = "2.
|
|
3612
|
+
declare const PLUGIN_SDK_VERSION = "2.26.0";
|
|
3565
3613
|
|
|
3566
3614
|
/**
|
|
3567
3615
|
* FX Preset Definitions
|
|
@@ -3709,4 +3757,4 @@ interface PickTopKOptions {
|
|
|
3709
3757
|
*/
|
|
3710
3758
|
declare function pickTopKWeighted<T>(scored: ReadonlyArray<ScoredCandidate<T>>, options?: PickTopKOptions): T | null;
|
|
3711
3759
|
|
|
3712
|
-
export { type AudioInputDevice, type BulkAddPlaceholderTrack, type ComposeProgressEvent, type ComposeProgressListener, type ComposeSceneOptions, type ComposeSceneResult, ConfirmDialog, type ConfirmDialogProps, type CreateTrackOptions, type CrossfadeInpaintInput, type CrossfadeLayer, type CrossfadeMeta, CrossfadeModal, type CrossfadeModalProps, type CrossfadePairMeta, type CrossfadeSelection, type CrossfadeSlot, CrossfadeTrackRow, type CrossfadeTrackRowProps, DB_MAX, DB_MIN, DEFAULT_FX_CATEGORY_DETAIL, DEFAULT_FX_DRY_WET, DRAG_DEAD_ZONE, type DeckBoundaryEvent, type DeckBoundaryListener, DownloadPackButton, type DownloadPackButtonProps, type DownloadPackButtonVariant, type DrawerTab, type DrumKit, EMPTY_FX_DETAIL_STATE, EMPTY_FX_STATE, EQUAL_POWER_GAIN, type ExportMidiBundleOptions, type ExportMidiBundleResult, type ExportedPluginData, FX_CATEGORIES, FX_CHAIN_ORDER, FX_DISPLAY_LABELS, FX_ENGINE_PLUGIN_NAMES, FX_PRESET_CONFIGS, type FxCategory, type FxCategoryDetailState, type FxPreset, type FxPresetConfig, type FxPresetData, type FxPresetDataEntry, FxToggleBar, type FxToggleBarProps, GUTTER_W, type GeneratorPlugin, type GeneratorType, type ImportCandidateScene, type ImportCandidateTrack, ImportTrackModal, type ImportTrackModalProps, type InstrumentDescriptor, TrackDrawer as InstrumentDrawer, type TrackDrawerProps as InstrumentDrawerProps, type InstrumentSampler, type InstrumentZone, type LLMCandidate, type LLMContent, type LLMFunctionDeclaration, type LLMGenerationConfig, type LLMGenerationRequest, type LLMGenerationResult, type LLMPart, type LLMSystemInstruction, type LLMTool, type LLMToolUseRequest, type LLMToolUseResponse, type LLMUsageMetadata, LevelMeter, type LevelMeterProps, type ListAudioFilesOptions, type ListImportableTracksOptions, type MidiClipData, type MidiWriteResult, type MixInterpolation, Modal, type ModalProps, type MusicalContext, OffsetScrubber, type OffsetScrubberProps, PLUGIN_SDK_VERSION, PX_PER_BEAT, PanSlider, type PeakAnalysis, PianoRollEditor, type PianoRollEditorProps, type PickTopKOptions, type PluginAppTool, type PluginAppToolInputSchema, type PluginAppToolResult, type PluginAudioTextureRequest, type PluginAudioTextureResult, type PluginCapabilities, type PluginChordSegment, type PluginChordTiming, type PluginConcurrentTrackInfo, type PluginCuePoints, type PluginDownloadOptions, PluginError, type PluginErrorCode, type PluginFileDialogOptions, type PluginFxCategoryDetailState, type PluginGenerationContext, type PluginHost, type PluginHttpRequestOptions, type PluginHttpResponse, type PluginManifest, type PluginMidiNote, type PluginPresetData, type PluginPresetInfo, type PluginRegistration, type PluginSampleFilter, type PluginSampleImportResult, type PluginSampleInfo, type PluginSampleTrackInfo, type PluginSceneContext, type PluginSceneInfo, type PluginSettingsSchema, type PluginSettingsStore, type PluginSkill, type PluginSkillInputSchema, type PluginStatus, type PluginStemSplitResult, type PluginStemTrackInfo, type PluginSynthInfo, type PluginTrackFxDetailState, type PluginTrackHandle, type PluginTrackInfo, type PluginTrackLevel, type PluginTrackRuntimeState, type PluginTransportState, type PluginTrimWindow, type PluginUIProps, type PostProcessOptions, RESIZE_HANDLE_PX, ROW_HEIGHT, type ReadMidiClip, type ReadMidiResult, type RecordingChunkFinalizedEvent, type RecordingTargetInfo, type SDKTrackRowProps, SLIDER_UNITY, SamplePackCTACard, type SamplePackCTACardProps, type SamplePackCTACardStatus, type SamplePackCardInfo, type SavePluginPresetOptions, type SceneChangeListener, type SceneFamilyTrack, type ScoredCandidate, ScrollingWaveform, type ScrollingWaveformProps, type SettingDefinition, type ShufflePresetResult, SorceryProgressBar, type SoundHistoryEntry, type StemType, type SynthesizeCuePointsOptions, TrackDrawer, type TrackDrawerProps, type TrackFxDetailState, type TrackFxState, type TrackLevelsHandle, TrackMeterStrip, type TrackMeterStripProps, type TrackMeterView, TrackRow, type TrackRowDragProps, type TrackSoundHistory, type TrackSoundSnapshot, type TrackStateChangeListener, type TransportEvent, type TransportEventListener, type UnsubscribeFn, type UseSoundHistoryOptions, type UseSoundHistoryResult, type UseTrackReorderOptions, type UseTrackReorderResult, VolumeSlider, type WaveformPeaks, WaveformView, type WaveformViewProps, analyzeWavPeak, asCrossfadeMeta, buildCrossfadeInpaintPrompt, calculateTimeBasedTarget, cellToPx, centerScrollTop, computePeaks, dbToSlider, drawWaveform, formatConcurrentTracks, moveItem, parseCrossfadePairs, pickTopKWeighted, pitchToName, pxToCell, resizeNoteDuration, scorePromptMatch, sliderToDb, synthesizeCuePoints, tokenizePrompt, transposeNotes, useAnySolo, useSceneState, useSoundHistory, useTrackLevel, useTrackLevels, useTrackMeter, useTrackReorder, useTransportPlaying };
|
|
3760
|
+
export { type AudioInputDevice, type BulkAddPlaceholderTrack, type ComposeProgressEvent, type ComposeProgressListener, type ComposeSceneOptions, type ComposeSceneResult, ConfirmDialog, type ConfirmDialogProps, type CreateTrackOptions, type CrossfadeInpaintInput, type CrossfadeLayer, type CrossfadeMeta, CrossfadeModal, type CrossfadeModalProps, type CrossfadePairMeta, type CrossfadeSelection, type CrossfadeSlot, CrossfadeTrackRow, type CrossfadeTrackRowProps, type CrossfadeVolumeCurves, DB_MAX, DB_MIN, DEFAULT_FX_CATEGORY_DETAIL, DEFAULT_FX_DRY_WET, DRAG_DEAD_ZONE, type DeckBoundaryEvent, type DeckBoundaryListener, DownloadPackButton, type DownloadPackButtonProps, type DownloadPackButtonVariant, type DrawerTab, type DrumKit, EMPTY_FX_DETAIL_STATE, EMPTY_FX_STATE, EQUAL_POWER_GAIN, type ExportMidiBundleOptions, type ExportMidiBundleResult, type ExportedPluginData, FX_CATEGORIES, FX_CHAIN_ORDER, FX_DISPLAY_LABELS, FX_ENGINE_PLUGIN_NAMES, FX_PRESET_CONFIGS, type FxCategory, type FxCategoryDetailState, type FxPreset, type FxPresetConfig, type FxPresetData, type FxPresetDataEntry, FxToggleBar, type FxToggleBarProps, GUTTER_W, type GeneratorPlugin, type GeneratorType, type ImportCandidateScene, type ImportCandidateTrack, ImportTrackModal, type ImportTrackModalProps, type InstrumentDescriptor, TrackDrawer as InstrumentDrawer, type TrackDrawerProps as InstrumentDrawerProps, type InstrumentSampler, type InstrumentZone, type LLMCandidate, type LLMContent, type LLMFunctionDeclaration, type LLMGenerationConfig, type LLMGenerationRequest, type LLMGenerationResult, type LLMPart, type LLMSystemInstruction, type LLMTool, type LLMToolUseRequest, type LLMToolUseResponse, type LLMUsageMetadata, LevelMeter, type LevelMeterProps, type ListAudioFilesOptions, type ListImportableTracksOptions, type MidiClipData, type MidiWriteResult, type MixInterpolation, Modal, type ModalProps, type MusicalContext, OffsetScrubber, type OffsetScrubberProps, PLUGIN_SDK_VERSION, PX_PER_BEAT, PanSlider, type PeakAnalysis, PianoRollEditor, type PianoRollEditorProps, type PickTopKOptions, type PluginAppTool, type PluginAppToolInputSchema, type PluginAppToolResult, type PluginAudioTextureRequest, type PluginAudioTextureResult, type PluginCapabilities, type PluginChordSegment, type PluginChordTiming, type PluginConcurrentTrackInfo, type PluginCuePoints, type PluginDownloadOptions, PluginError, type PluginErrorCode, type PluginFileDialogOptions, type PluginFxCategoryDetailState, type PluginGenerationContext, type PluginHost, type PluginHttpRequestOptions, type PluginHttpResponse, type PluginManifest, type PluginMidiNote, type PluginPresetData, type PluginPresetInfo, type PluginRegistration, type PluginSampleFilter, type PluginSampleImportResult, type PluginSampleInfo, type PluginSampleTrackInfo, type PluginSceneContext, type PluginSceneInfo, type PluginSettingsSchema, type PluginSettingsStore, type PluginSkill, type PluginSkillInputSchema, type PluginStatus, type PluginStemSplitResult, type PluginStemTrackInfo, type PluginSynthInfo, type PluginTrackFxDetailState, type PluginTrackHandle, type PluginTrackInfo, type PluginTrackLevel, type PluginTrackRuntimeState, type PluginTransportState, type PluginTrimWindow, type PluginUIProps, type PostProcessOptions, RESIZE_HANDLE_PX, ROW_HEIGHT, type ReadMidiClip, type ReadMidiResult, type RecordingChunkFinalizedEvent, type RecordingTargetInfo, type SDKTrackRowProps, SLIDER_UNITY, SamplePackCTACard, type SamplePackCTACardProps, type SamplePackCTACardStatus, type SamplePackCardInfo, type SavePluginPresetOptions, type SceneChangeListener, type SceneFamilyTrack, type ScoredCandidate, ScrollingWaveform, type ScrollingWaveformProps, type SettingDefinition, type ShufflePresetResult, SorceryProgressBar, type SoundHistoryEntry, type StemType, type SynthesizeCuePointsOptions, TrackDrawer, type TrackDrawerProps, type TrackFxDetailState, type TrackFxState, type TrackLevelsHandle, TrackMeterStrip, type TrackMeterStripProps, type TrackMeterView, TrackRow, type TrackRowDragProps, type TrackSoundHistory, type TrackSoundSnapshot, type TrackStateChangeListener, type TransportEvent, type TransportEventListener, type UnsubscribeFn, type UseSoundHistoryOptions, type UseSoundHistoryResult, type UseTrackReorderOptions, type UseTrackReorderResult, type VolumeAutomationPoint, VolumeSlider, type WaveformPeaks, WaveformView, type WaveformViewProps, analyzeWavPeak, asCrossfadeMeta, buildCrossfadeInpaintPrompt, buildCrossfadeVolumeCurves, calculateTimeBasedTarget, cellToPx, centerScrollTop, computePeaks, dbToSlider, drawWaveform, formatConcurrentTracks, moveItem, parseCrossfadePairs, pickTopKWeighted, pitchToName, pxToCell, resizeNoteDuration, scorePromptMatch, sliderToDb, synthesizeCuePoints, tokenizePrompt, transposeNotes, useAnySolo, useSceneState, useSoundHistory, useTrackLevel, useTrackLevels, useTrackMeter, useTrackReorder, useTransportPlaying };
|
package/dist/index.d.ts
CHANGED
|
@@ -227,6 +227,16 @@ interface PluginHost {
|
|
|
227
227
|
setTrackMute(trackId: string, muted: boolean): Promise<void>;
|
|
228
228
|
/** Set track volume (linear 0.0 - 1.0). Only works on owned tracks. */
|
|
229
229
|
setTrackVolume(trackId: string, volume: number): Promise<void>;
|
|
230
|
+
/**
|
|
231
|
+
* Set/replace a time-based volume automation curve (a fade envelope) on a track,
|
|
232
|
+
* or clear it with an empty array. Points are {time: seconds, db}; linear between
|
|
233
|
+
* points. Used by crossfade tracks to fade origin↔target across the looped
|
|
234
|
+
* transition. Optional — callers MUST null-check. @since SDK 2.25.0
|
|
235
|
+
*/
|
|
236
|
+
setTrackVolumeAutomation?(trackId: string, points: Array<{
|
|
237
|
+
time: number;
|
|
238
|
+
db: number;
|
|
239
|
+
}>): Promise<void>;
|
|
230
240
|
/** Set track pan (-1.0 left to 1.0 right). Only works on owned tracks. */
|
|
231
241
|
setTrackPan(trackId: string, pan: number): Promise<void>;
|
|
232
242
|
/** Set track solo state. Only works on owned tracks. */
|
|
@@ -537,6 +547,11 @@ interface PluginHost {
|
|
|
537
547
|
key: string;
|
|
538
548
|
mode: string;
|
|
539
549
|
} | null>;
|
|
550
|
+
/**
|
|
551
|
+
* Read a scene's human display name by db id (for labelling a crossfade's
|
|
552
|
+
* origin/target scenes). Optional — callers MUST null-check. @since SDK 2.26.0
|
|
553
|
+
*/
|
|
554
|
+
getSceneName?(sceneDbId: string): Promise<string | null>;
|
|
540
555
|
/** Subscribe to transport state changes. Returns unsubscribe function. */
|
|
541
556
|
onTransportEvent(listener: TransportEventListener): UnsubscribeFn;
|
|
542
557
|
/** Subscribe to deck boundary events. Returns unsubscribe function. */
|
|
@@ -2592,6 +2607,10 @@ interface CrossfadePairMeta {
|
|
|
2592
2607
|
sliderPos: number;
|
|
2593
2608
|
originDbId: string;
|
|
2594
2609
|
targetDbId: string;
|
|
2610
|
+
/** DB id of the ORIGIN source track (in the from scene) — drives the "used once" exclusion. */
|
|
2611
|
+
originSourceDbId: string;
|
|
2612
|
+
/** DB id of the TARGET source track (in the to scene). */
|
|
2613
|
+
targetSourceDbId: string;
|
|
2595
2614
|
originSourceName: string;
|
|
2596
2615
|
originSoundLabel: string;
|
|
2597
2616
|
targetSourceName: string;
|
|
@@ -2606,6 +2625,28 @@ declare function asCrossfadeMeta(val: unknown): CrossfadeMeta | null;
|
|
|
2606
2625
|
* row instead of vanishing.
|
|
2607
2626
|
*/
|
|
2608
2627
|
declare function parseCrossfadePairs(sceneData: Record<string, unknown>): CrossfadePairMeta[];
|
|
2628
|
+
/** One volume-automation point: a dB value at a time offset (seconds from clip start). */
|
|
2629
|
+
interface VolumeAutomationPoint {
|
|
2630
|
+
time: number;
|
|
2631
|
+
db: number;
|
|
2632
|
+
}
|
|
2633
|
+
/** Origin + target volume curves for one crossfade pair. */
|
|
2634
|
+
interface CrossfadeVolumeCurves {
|
|
2635
|
+
origin: VolumeAutomationPoint[];
|
|
2636
|
+
target: VolumeAutomationPoint[];
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2639
|
+
* Equal-power crossfade volume curves over a transition of `bars` at `bpm`.
|
|
2640
|
+
* The ORIGIN layer fades OUT and the TARGET fades IN; `sliderPos` (0..1) sets
|
|
2641
|
+
* WHERE in time the equal-power (-3 dB) crossover sits — 0 = hand off near the
|
|
2642
|
+
* start, 1 = hold the origin until near the end. Points span the clip window
|
|
2643
|
+
* [0, durationSeconds] so the engine re-reads them each loop (re-fade per loop).
|
|
2644
|
+
* `steps`+1 points with linear interpolation approximate the cos/sin curve.
|
|
2645
|
+
*
|
|
2646
|
+
* Returns dB point arrays for `host.setTrackVolumeAutomation` — origin on the top
|
|
2647
|
+
* layer, target on the bottom. @since SDK 2.25.0
|
|
2648
|
+
*/
|
|
2649
|
+
declare function buildCrossfadeVolumeCurves(bars: number, bpm: number, sliderPos: number, steps?: number): CrossfadeVolumeCurves;
|
|
2609
2650
|
|
|
2610
2651
|
/**
|
|
2611
2652
|
* CrossfadeTrackRow — a transition "crossfade track": two stacked TrackRows
|
|
@@ -2794,8 +2835,9 @@ declare function ImportTrackModal({ host, open, onClose, onImported, title, test
|
|
|
2794
2835
|
*
|
|
2795
2836
|
* Shown only inside a `scene_type='transition'` scene. The user picks an ORIGIN
|
|
2796
2837
|
* track (from the transition's FROM scene) and a TARGET track (from its TO
|
|
2797
|
-
* scene)
|
|
2798
|
-
*
|
|
2838
|
+
* scene), in ANY order — the only constraint is same plugin/family (the picker is
|
|
2839
|
+
* per-panel). A source track already used in a crossfade is hidden (via
|
|
2840
|
+
* excludeSourceDbIds), so each source is used at most once.
|
|
2799
2841
|
*
|
|
2800
2842
|
* Self-fetching: given the scoped `host`, it calls `host.listSceneFamilyTracks`
|
|
2801
2843
|
* for both scenes (ungated — a transition deliberately bridges different keys).
|
|
@@ -2813,7 +2855,7 @@ interface CrossfadeSelection {
|
|
|
2813
2855
|
dbId: string;
|
|
2814
2856
|
/** Display name (for the row caption). */
|
|
2815
2857
|
name: string;
|
|
2816
|
-
/** Musical role
|
|
2858
|
+
/** Musical role of the source track (the panel uses the TARGET's for generation). */
|
|
2817
2859
|
role?: string;
|
|
2818
2860
|
}
|
|
2819
2861
|
interface CrossfadeModalProps {
|
|
@@ -2829,6 +2871,12 @@ interface CrossfadeModalProps {
|
|
|
2829
2871
|
fromSceneName?: string;
|
|
2830
2872
|
/** Display name for the target scene heading (optional). */
|
|
2831
2873
|
toSceneName?: string;
|
|
2874
|
+
/**
|
|
2875
|
+
* Source-track DB ids already used in a crossfade (origin + target of every
|
|
2876
|
+
* existing pair in this panel). Hidden from BOTH dropdowns so each source is
|
|
2877
|
+
* used at most once. @since SDK 2.26.0
|
|
2878
|
+
*/
|
|
2879
|
+
excludeSourceDbIds?: readonly string[];
|
|
2832
2880
|
/** Close handler (Escape, backdrop, Cancel, or after a successful create). */
|
|
2833
2881
|
onClose: () => void;
|
|
2834
2882
|
/** Build the crossfade pair. Should reject on failure so the modal shows it. */
|
|
@@ -2836,7 +2884,7 @@ interface CrossfadeModalProps {
|
|
|
2836
2884
|
/** data-testid prefix. */
|
|
2837
2885
|
testIdPrefix?: string;
|
|
2838
2886
|
}
|
|
2839
|
-
declare function CrossfadeModal({ host, open, fromSceneId, toSceneId, fromSceneName, toSceneName, onClose, onCreate, testIdPrefix, }: CrossfadeModalProps): React.ReactElement | null;
|
|
2887
|
+
declare function CrossfadeModal({ host, open, fromSceneId, toSceneId, fromSceneName, toSceneName, excludeSourceDbIds, onClose, onCreate, testIdPrefix, }: CrossfadeModalProps): React.ReactElement | null;
|
|
2840
2888
|
|
|
2841
2889
|
/**
|
|
2842
2890
|
* ConfirmDialog — styled in-app confirmation modal (SDK component).
|
|
@@ -3561,7 +3609,7 @@ declare function useSoundHistory(applySound: (trackId: string, descriptor: unkno
|
|
|
3561
3609
|
* Registry checks semver.gte(PLUGIN_SDK_VERSION, manifest.minHostVersion)
|
|
3562
3610
|
* during activation and marks incompatible plugins accordingly.
|
|
3563
3611
|
*/
|
|
3564
|
-
declare const PLUGIN_SDK_VERSION = "2.
|
|
3612
|
+
declare const PLUGIN_SDK_VERSION = "2.26.0";
|
|
3565
3613
|
|
|
3566
3614
|
/**
|
|
3567
3615
|
* FX Preset Definitions
|
|
@@ -3709,4 +3757,4 @@ interface PickTopKOptions {
|
|
|
3709
3757
|
*/
|
|
3710
3758
|
declare function pickTopKWeighted<T>(scored: ReadonlyArray<ScoredCandidate<T>>, options?: PickTopKOptions): T | null;
|
|
3711
3759
|
|
|
3712
|
-
export { type AudioInputDevice, type BulkAddPlaceholderTrack, type ComposeProgressEvent, type ComposeProgressListener, type ComposeSceneOptions, type ComposeSceneResult, ConfirmDialog, type ConfirmDialogProps, type CreateTrackOptions, type CrossfadeInpaintInput, type CrossfadeLayer, type CrossfadeMeta, CrossfadeModal, type CrossfadeModalProps, type CrossfadePairMeta, type CrossfadeSelection, type CrossfadeSlot, CrossfadeTrackRow, type CrossfadeTrackRowProps, DB_MAX, DB_MIN, DEFAULT_FX_CATEGORY_DETAIL, DEFAULT_FX_DRY_WET, DRAG_DEAD_ZONE, type DeckBoundaryEvent, type DeckBoundaryListener, DownloadPackButton, type DownloadPackButtonProps, type DownloadPackButtonVariant, type DrawerTab, type DrumKit, EMPTY_FX_DETAIL_STATE, EMPTY_FX_STATE, EQUAL_POWER_GAIN, type ExportMidiBundleOptions, type ExportMidiBundleResult, type ExportedPluginData, FX_CATEGORIES, FX_CHAIN_ORDER, FX_DISPLAY_LABELS, FX_ENGINE_PLUGIN_NAMES, FX_PRESET_CONFIGS, type FxCategory, type FxCategoryDetailState, type FxPreset, type FxPresetConfig, type FxPresetData, type FxPresetDataEntry, FxToggleBar, type FxToggleBarProps, GUTTER_W, type GeneratorPlugin, type GeneratorType, type ImportCandidateScene, type ImportCandidateTrack, ImportTrackModal, type ImportTrackModalProps, type InstrumentDescriptor, TrackDrawer as InstrumentDrawer, type TrackDrawerProps as InstrumentDrawerProps, type InstrumentSampler, type InstrumentZone, type LLMCandidate, type LLMContent, type LLMFunctionDeclaration, type LLMGenerationConfig, type LLMGenerationRequest, type LLMGenerationResult, type LLMPart, type LLMSystemInstruction, type LLMTool, type LLMToolUseRequest, type LLMToolUseResponse, type LLMUsageMetadata, LevelMeter, type LevelMeterProps, type ListAudioFilesOptions, type ListImportableTracksOptions, type MidiClipData, type MidiWriteResult, type MixInterpolation, Modal, type ModalProps, type MusicalContext, OffsetScrubber, type OffsetScrubberProps, PLUGIN_SDK_VERSION, PX_PER_BEAT, PanSlider, type PeakAnalysis, PianoRollEditor, type PianoRollEditorProps, type PickTopKOptions, type PluginAppTool, type PluginAppToolInputSchema, type PluginAppToolResult, type PluginAudioTextureRequest, type PluginAudioTextureResult, type PluginCapabilities, type PluginChordSegment, type PluginChordTiming, type PluginConcurrentTrackInfo, type PluginCuePoints, type PluginDownloadOptions, PluginError, type PluginErrorCode, type PluginFileDialogOptions, type PluginFxCategoryDetailState, type PluginGenerationContext, type PluginHost, type PluginHttpRequestOptions, type PluginHttpResponse, type PluginManifest, type PluginMidiNote, type PluginPresetData, type PluginPresetInfo, type PluginRegistration, type PluginSampleFilter, type PluginSampleImportResult, type PluginSampleInfo, type PluginSampleTrackInfo, type PluginSceneContext, type PluginSceneInfo, type PluginSettingsSchema, type PluginSettingsStore, type PluginSkill, type PluginSkillInputSchema, type PluginStatus, type PluginStemSplitResult, type PluginStemTrackInfo, type PluginSynthInfo, type PluginTrackFxDetailState, type PluginTrackHandle, type PluginTrackInfo, type PluginTrackLevel, type PluginTrackRuntimeState, type PluginTransportState, type PluginTrimWindow, type PluginUIProps, type PostProcessOptions, RESIZE_HANDLE_PX, ROW_HEIGHT, type ReadMidiClip, type ReadMidiResult, type RecordingChunkFinalizedEvent, type RecordingTargetInfo, type SDKTrackRowProps, SLIDER_UNITY, SamplePackCTACard, type SamplePackCTACardProps, type SamplePackCTACardStatus, type SamplePackCardInfo, type SavePluginPresetOptions, type SceneChangeListener, type SceneFamilyTrack, type ScoredCandidate, ScrollingWaveform, type ScrollingWaveformProps, type SettingDefinition, type ShufflePresetResult, SorceryProgressBar, type SoundHistoryEntry, type StemType, type SynthesizeCuePointsOptions, TrackDrawer, type TrackDrawerProps, type TrackFxDetailState, type TrackFxState, type TrackLevelsHandle, TrackMeterStrip, type TrackMeterStripProps, type TrackMeterView, TrackRow, type TrackRowDragProps, type TrackSoundHistory, type TrackSoundSnapshot, type TrackStateChangeListener, type TransportEvent, type TransportEventListener, type UnsubscribeFn, type UseSoundHistoryOptions, type UseSoundHistoryResult, type UseTrackReorderOptions, type UseTrackReorderResult, VolumeSlider, type WaveformPeaks, WaveformView, type WaveformViewProps, analyzeWavPeak, asCrossfadeMeta, buildCrossfadeInpaintPrompt, calculateTimeBasedTarget, cellToPx, centerScrollTop, computePeaks, dbToSlider, drawWaveform, formatConcurrentTracks, moveItem, parseCrossfadePairs, pickTopKWeighted, pitchToName, pxToCell, resizeNoteDuration, scorePromptMatch, sliderToDb, synthesizeCuePoints, tokenizePrompt, transposeNotes, useAnySolo, useSceneState, useSoundHistory, useTrackLevel, useTrackLevels, useTrackMeter, useTrackReorder, useTransportPlaying };
|
|
3760
|
+
export { type AudioInputDevice, type BulkAddPlaceholderTrack, type ComposeProgressEvent, type ComposeProgressListener, type ComposeSceneOptions, type ComposeSceneResult, ConfirmDialog, type ConfirmDialogProps, type CreateTrackOptions, type CrossfadeInpaintInput, type CrossfadeLayer, type CrossfadeMeta, CrossfadeModal, type CrossfadeModalProps, type CrossfadePairMeta, type CrossfadeSelection, type CrossfadeSlot, CrossfadeTrackRow, type CrossfadeTrackRowProps, type CrossfadeVolumeCurves, DB_MAX, DB_MIN, DEFAULT_FX_CATEGORY_DETAIL, DEFAULT_FX_DRY_WET, DRAG_DEAD_ZONE, type DeckBoundaryEvent, type DeckBoundaryListener, DownloadPackButton, type DownloadPackButtonProps, type DownloadPackButtonVariant, type DrawerTab, type DrumKit, EMPTY_FX_DETAIL_STATE, EMPTY_FX_STATE, EQUAL_POWER_GAIN, type ExportMidiBundleOptions, type ExportMidiBundleResult, type ExportedPluginData, FX_CATEGORIES, FX_CHAIN_ORDER, FX_DISPLAY_LABELS, FX_ENGINE_PLUGIN_NAMES, FX_PRESET_CONFIGS, type FxCategory, type FxCategoryDetailState, type FxPreset, type FxPresetConfig, type FxPresetData, type FxPresetDataEntry, FxToggleBar, type FxToggleBarProps, GUTTER_W, type GeneratorPlugin, type GeneratorType, type ImportCandidateScene, type ImportCandidateTrack, ImportTrackModal, type ImportTrackModalProps, type InstrumentDescriptor, TrackDrawer as InstrumentDrawer, type TrackDrawerProps as InstrumentDrawerProps, type InstrumentSampler, type InstrumentZone, type LLMCandidate, type LLMContent, type LLMFunctionDeclaration, type LLMGenerationConfig, type LLMGenerationRequest, type LLMGenerationResult, type LLMPart, type LLMSystemInstruction, type LLMTool, type LLMToolUseRequest, type LLMToolUseResponse, type LLMUsageMetadata, LevelMeter, type LevelMeterProps, type ListAudioFilesOptions, type ListImportableTracksOptions, type MidiClipData, type MidiWriteResult, type MixInterpolation, Modal, type ModalProps, type MusicalContext, OffsetScrubber, type OffsetScrubberProps, PLUGIN_SDK_VERSION, PX_PER_BEAT, PanSlider, type PeakAnalysis, PianoRollEditor, type PianoRollEditorProps, type PickTopKOptions, type PluginAppTool, type PluginAppToolInputSchema, type PluginAppToolResult, type PluginAudioTextureRequest, type PluginAudioTextureResult, type PluginCapabilities, type PluginChordSegment, type PluginChordTiming, type PluginConcurrentTrackInfo, type PluginCuePoints, type PluginDownloadOptions, PluginError, type PluginErrorCode, type PluginFileDialogOptions, type PluginFxCategoryDetailState, type PluginGenerationContext, type PluginHost, type PluginHttpRequestOptions, type PluginHttpResponse, type PluginManifest, type PluginMidiNote, type PluginPresetData, type PluginPresetInfo, type PluginRegistration, type PluginSampleFilter, type PluginSampleImportResult, type PluginSampleInfo, type PluginSampleTrackInfo, type PluginSceneContext, type PluginSceneInfo, type PluginSettingsSchema, type PluginSettingsStore, type PluginSkill, type PluginSkillInputSchema, type PluginStatus, type PluginStemSplitResult, type PluginStemTrackInfo, type PluginSynthInfo, type PluginTrackFxDetailState, type PluginTrackHandle, type PluginTrackInfo, type PluginTrackLevel, type PluginTrackRuntimeState, type PluginTransportState, type PluginTrimWindow, type PluginUIProps, type PostProcessOptions, RESIZE_HANDLE_PX, ROW_HEIGHT, type ReadMidiClip, type ReadMidiResult, type RecordingChunkFinalizedEvent, type RecordingTargetInfo, type SDKTrackRowProps, SLIDER_UNITY, SamplePackCTACard, type SamplePackCTACardProps, type SamplePackCTACardStatus, type SamplePackCardInfo, type SavePluginPresetOptions, type SceneChangeListener, type SceneFamilyTrack, type ScoredCandidate, ScrollingWaveform, type ScrollingWaveformProps, type SettingDefinition, type ShufflePresetResult, SorceryProgressBar, type SoundHistoryEntry, type StemType, type SynthesizeCuePointsOptions, TrackDrawer, type TrackDrawerProps, type TrackFxDetailState, type TrackFxState, type TrackLevelsHandle, TrackMeterStrip, type TrackMeterStripProps, type TrackMeterView, TrackRow, type TrackRowDragProps, type TrackSoundHistory, type TrackSoundSnapshot, type TrackStateChangeListener, type TransportEvent, type TransportEventListener, type UnsubscribeFn, type UseSoundHistoryOptions, type UseSoundHistoryResult, type UseTrackReorderOptions, type UseTrackReorderResult, type VolumeAutomationPoint, VolumeSlider, type WaveformPeaks, WaveformView, type WaveformViewProps, analyzeWavPeak, asCrossfadeMeta, buildCrossfadeInpaintPrompt, buildCrossfadeVolumeCurves, calculateTimeBasedTarget, cellToPx, centerScrollTop, computePeaks, dbToSlider, drawWaveform, formatConcurrentTracks, moveItem, parseCrossfadePairs, pickTopKWeighted, pitchToName, pxToCell, resizeNoteDuration, scorePromptMatch, sliderToDb, synthesizeCuePoints, tokenizePrompt, transposeNotes, useAnySolo, useSceneState, useSoundHistory, useTrackLevel, useTrackLevels, useTrackMeter, useTrackReorder, useTransportPlaying };
|
package/dist/index.js
CHANGED
|
@@ -73,6 +73,7 @@ __export(index_exports, {
|
|
|
73
73
|
analyzeWavPeak: () => analyzeWavPeak,
|
|
74
74
|
asCrossfadeMeta: () => asCrossfadeMeta,
|
|
75
75
|
buildCrossfadeInpaintPrompt: () => buildCrossfadeInpaintPrompt,
|
|
76
|
+
buildCrossfadeVolumeCurves: () => buildCrossfadeVolumeCurves,
|
|
76
77
|
calculateTimeBasedTarget: () => calculateTimeBasedTarget,
|
|
77
78
|
cellToPx: () => cellToPx,
|
|
78
79
|
centerScrollTop: () => centerScrollTop,
|
|
@@ -2569,6 +2570,8 @@ function parseCrossfadePairs(sceneData) {
|
|
|
2569
2570
|
sliderPos: g.origin.meta.sliderPos,
|
|
2570
2571
|
originDbId: g.origin.dbId,
|
|
2571
2572
|
targetDbId: g.target.dbId,
|
|
2573
|
+
originSourceDbId: g.origin.meta.sourceTrackDbId,
|
|
2574
|
+
targetSourceDbId: g.target.meta.sourceTrackDbId,
|
|
2572
2575
|
originSourceName: g.origin.meta.sourceName,
|
|
2573
2576
|
originSoundLabel: g.origin.meta.soundLabel,
|
|
2574
2577
|
targetSourceName: g.target.meta.sourceName,
|
|
@@ -2577,6 +2580,25 @@ function parseCrossfadePairs(sceneData) {
|
|
|
2577
2580
|
}
|
|
2578
2581
|
return pairs;
|
|
2579
2582
|
}
|
|
2583
|
+
var FADE_FLOOR_DB = -80;
|
|
2584
|
+
function gainToDb(gain) {
|
|
2585
|
+
return gain <= 1e-4 ? FADE_FLOOR_DB : Math.max(FADE_FLOOR_DB, 20 * Math.log10(gain));
|
|
2586
|
+
}
|
|
2587
|
+
function buildCrossfadeVolumeCurves(bars, bpm, sliderPos, steps = 32) {
|
|
2588
|
+
const durationSeconds = bars * 4 * 60 / Math.max(1, bpm);
|
|
2589
|
+
const s = Math.min(0.98, Math.max(0.02, sliderPos));
|
|
2590
|
+
const round = (n) => Math.round(n * 1e3) / 1e3;
|
|
2591
|
+
const origin = [];
|
|
2592
|
+
const target = [];
|
|
2593
|
+
for (let i = 0; i <= steps; i++) {
|
|
2594
|
+
const x = i / steps;
|
|
2595
|
+
const time = round(x * durationSeconds);
|
|
2596
|
+
const theta = x <= s ? x / s * (Math.PI / 4) : Math.PI / 4 + (x - s) / (1 - s) * (Math.PI / 4);
|
|
2597
|
+
origin.push({ time, db: Math.round(gainToDb(Math.cos(theta)) * 100) / 100 });
|
|
2598
|
+
target.push({ time, db: Math.round(gainToDb(Math.sin(theta)) * 100) / 100 });
|
|
2599
|
+
}
|
|
2600
|
+
return { origin, target };
|
|
2601
|
+
}
|
|
2580
2602
|
|
|
2581
2603
|
// src/crossfade-inpaint.ts
|
|
2582
2604
|
var PITCH_NAMES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
@@ -2825,6 +2847,7 @@ function CrossfadeModal({
|
|
|
2825
2847
|
toSceneId,
|
|
2826
2848
|
fromSceneName,
|
|
2827
2849
|
toSceneName,
|
|
2850
|
+
excludeSourceDbIds,
|
|
2828
2851
|
onClose,
|
|
2829
2852
|
onCreate,
|
|
2830
2853
|
testIdPrefix = "crossfade-modal"
|
|
@@ -2834,6 +2857,8 @@ function CrossfadeModal({
|
|
|
2834
2857
|
const [targetDbId, setTargetDbId] = (0, import_react12.useState)("");
|
|
2835
2858
|
const [isCreating, setIsCreating] = (0, import_react12.useState)(false);
|
|
2836
2859
|
const [error, setError] = (0, import_react12.useState)(null);
|
|
2860
|
+
const [fromName, setFromName] = (0, import_react12.useState)(null);
|
|
2861
|
+
const [toName, setToName] = (0, import_react12.useState)(null);
|
|
2837
2862
|
const cancelRef = (0, import_react12.useRef)(null);
|
|
2838
2863
|
const refresh = (0, import_react12.useCallback)(async () => {
|
|
2839
2864
|
if (!host.listSceneFamilyTracks) {
|
|
@@ -2842,12 +2867,15 @@ function CrossfadeModal({
|
|
|
2842
2867
|
}
|
|
2843
2868
|
setLoad({ status: "loading" });
|
|
2844
2869
|
try {
|
|
2845
|
-
const [origin, target] = await Promise.all([
|
|
2870
|
+
const [origin, target, fName, tName] = await Promise.all([
|
|
2846
2871
|
host.listSceneFamilyTracks(fromSceneId),
|
|
2847
|
-
host.listSceneFamilyTracks(toSceneId)
|
|
2872
|
+
host.listSceneFamilyTracks(toSceneId),
|
|
2873
|
+
host.getSceneName ? host.getSceneName(fromSceneId) : Promise.resolve(null),
|
|
2874
|
+
host.getSceneName ? host.getSceneName(toSceneId) : Promise.resolve(null)
|
|
2848
2875
|
]);
|
|
2876
|
+
setFromName(fName);
|
|
2877
|
+
setToName(tName);
|
|
2849
2878
|
setLoad({ status: "ready", origin, target });
|
|
2850
|
-
setOriginDbId(origin[0]?.dbId ?? "");
|
|
2851
2879
|
} catch (err) {
|
|
2852
2880
|
setLoad({ status: "error", message: err instanceof Error ? err.message : "Failed to load tracks." });
|
|
2853
2881
|
}
|
|
@@ -2861,21 +2889,26 @@ function CrossfadeModal({
|
|
|
2861
2889
|
void refresh();
|
|
2862
2890
|
}
|
|
2863
2891
|
}, [open, refresh]);
|
|
2864
|
-
const
|
|
2865
|
-
|
|
2866
|
-
|
|
2892
|
+
const excludeSet = (0, import_react12.useMemo)(() => new Set(excludeSourceDbIds ?? []), [excludeSourceDbIds]);
|
|
2893
|
+
const originCandidates = (0, import_react12.useMemo)(
|
|
2894
|
+
() => load.status === "ready" ? load.origin.filter((t) => !excludeSet.has(t.dbId)) : [],
|
|
2895
|
+
[load, excludeSet]
|
|
2867
2896
|
);
|
|
2868
|
-
const
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2897
|
+
const targetCandidates = (0, import_react12.useMemo)(
|
|
2898
|
+
() => load.status === "ready" ? load.target.filter((t) => !excludeSet.has(t.dbId)) : [],
|
|
2899
|
+
[load, excludeSet]
|
|
2900
|
+
);
|
|
2901
|
+
(0, import_react12.useEffect)(() => {
|
|
2902
|
+
if (!originCandidates.some((t) => t.dbId === originDbId)) {
|
|
2903
|
+
setOriginDbId(originCandidates[0]?.dbId ?? "");
|
|
2904
|
+
}
|
|
2905
|
+
}, [originCandidates, originDbId]);
|
|
2874
2906
|
(0, import_react12.useEffect)(() => {
|
|
2875
2907
|
if (!targetCandidates.some((t) => t.dbId === targetDbId)) {
|
|
2876
2908
|
setTargetDbId(targetCandidates[0]?.dbId ?? "");
|
|
2877
2909
|
}
|
|
2878
2910
|
}, [targetCandidates, targetDbId]);
|
|
2911
|
+
const originTrack = originCandidates.find((t) => t.dbId === originDbId) ?? null;
|
|
2879
2912
|
const targetTrack = targetCandidates.find((t) => t.dbId === targetDbId) ?? null;
|
|
2880
2913
|
const canCreate = !isCreating && !!originTrack && !!targetTrack;
|
|
2881
2914
|
const handleClose = (0, import_react12.useCallback)(() => {
|
|
@@ -2896,6 +2929,8 @@ function CrossfadeModal({
|
|
|
2896
2929
|
setIsCreating(false);
|
|
2897
2930
|
}
|
|
2898
2931
|
}, [originTrack, targetTrack, onCreate, onClose]);
|
|
2932
|
+
const fromLabel = fromName ?? fromSceneName ?? null;
|
|
2933
|
+
const toLabel = toName ?? toSceneName ?? null;
|
|
2899
2934
|
if (!open) return null;
|
|
2900
2935
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Modal, { open, onClose: handleClose, testIdPrefix, initialFocusRef: cancelRef, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2901
2936
|
"div",
|
|
@@ -2908,24 +2943,31 @@ function CrossfadeModal({
|
|
|
2908
2943
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "text-[11px] text-sas-muted leading-relaxed", children: [
|
|
2909
2944
|
"Bridge a track from",
|
|
2910
2945
|
" ",
|
|
2911
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sas-text", children:
|
|
2946
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sas-text", children: fromLabel ?? "the origin scene" }),
|
|
2912
2947
|
" into one from",
|
|
2913
2948
|
" ",
|
|
2914
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sas-text", children:
|
|
2949
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sas-text", children: toLabel ?? "the target scene" }),
|
|
2915
2950
|
". Both layers share one generated part; each keeps its own preset."
|
|
2916
2951
|
] }),
|
|
2917
2952
|
load.status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "text-xs text-sas-muted py-4 text-center", children: "Loading tracks\u2026" }),
|
|
2918
2953
|
load.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "text-xs text-sas-danger py-4 text-center", children: load.message }),
|
|
2919
|
-
load.status === "ready" && (
|
|
2954
|
+
load.status === "ready" && (originCandidates.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2920
2955
|
"div",
|
|
2921
2956
|
{
|
|
2922
2957
|
className: "text-xs text-sas-muted py-4 text-center",
|
|
2923
2958
|
"data-testid": `${testIdPrefix}-empty-origin`,
|
|
2924
|
-
children:
|
|
2959
|
+
children: [
|
|
2960
|
+
"No available tracks in ",
|
|
2961
|
+
fromLabel ?? "the origin scene",
|
|
2962
|
+
". Add one (or free one from another crossfade) first."
|
|
2963
|
+
]
|
|
2925
2964
|
}
|
|
2926
2965
|
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2927
2966
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "block", children: [
|
|
2928
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.
|
|
2967
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-[10px] uppercase tracking-wide text-sas-muted", children: [
|
|
2968
|
+
"Origin ",
|
|
2969
|
+
fromLabel ? `(${fromLabel})` : "(top)"
|
|
2970
|
+
] }),
|
|
2929
2971
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2930
2972
|
"select",
|
|
2931
2973
|
{
|
|
@@ -2934,7 +2976,7 @@ function CrossfadeModal({
|
|
|
2934
2976
|
onChange: (e) => setOriginDbId(e.target.value),
|
|
2935
2977
|
disabled: isCreating,
|
|
2936
2978
|
className: "sas-input w-full mt-0.5 text-xs",
|
|
2937
|
-
children:
|
|
2979
|
+
children: originCandidates.map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("option", { value: t.dbId, children: [
|
|
2938
2980
|
t.name,
|
|
2939
2981
|
t.role ? ` \xB7 ${t.role}` : ""
|
|
2940
2982
|
] }, t.dbId))
|
|
@@ -2943,13 +2985,13 @@ function CrossfadeModal({
|
|
|
2943
2985
|
] }),
|
|
2944
2986
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "block", children: [
|
|
2945
2987
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-[10px] uppercase tracking-wide text-sas-muted", children: [
|
|
2946
|
-
"Target
|
|
2947
|
-
|
|
2988
|
+
"Target ",
|
|
2989
|
+
toLabel ? `(${toLabel})` : "(bottom)"
|
|
2948
2990
|
] }),
|
|
2949
2991
|
targetCandidates.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "text-xs text-sas-danger mt-0.5", "data-testid": `${testIdPrefix}-empty-target`, children: [
|
|
2950
|
-
"No ",
|
|
2951
|
-
|
|
2952
|
-
"
|
|
2992
|
+
"No available tracks in ",
|
|
2993
|
+
toLabel ?? "the target scene",
|
|
2994
|
+
" to crossfade into."
|
|
2953
2995
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2954
2996
|
"select",
|
|
2955
2997
|
{
|
|
@@ -3868,7 +3910,7 @@ function useTrackReorder({
|
|
|
3868
3910
|
}
|
|
3869
3911
|
|
|
3870
3912
|
// src/constants/sdk-version.ts
|
|
3871
|
-
var PLUGIN_SDK_VERSION = "2.
|
|
3913
|
+
var PLUGIN_SDK_VERSION = "2.26.0";
|
|
3872
3914
|
|
|
3873
3915
|
// src/utils/format-concurrent-tracks.ts
|
|
3874
3916
|
function formatConcurrentTracks(ctx) {
|
|
@@ -4055,6 +4097,7 @@ function pickTopKWeighted(scored, options = {}) {
|
|
|
4055
4097
|
analyzeWavPeak,
|
|
4056
4098
|
asCrossfadeMeta,
|
|
4057
4099
|
buildCrossfadeInpaintPrompt,
|
|
4100
|
+
buildCrossfadeVolumeCurves,
|
|
4058
4101
|
calculateTimeBasedTarget,
|
|
4059
4102
|
cellToPx,
|
|
4060
4103
|
centerScrollTop,
|