feat: add chunk crossfade slider (0ms = hard cut)

Persisted setting (default 50ms) controls how audio chunks are blended
together.  Set to 0 for a clean hard cut with no overlap.
This commit is contained in:
James Pine
2026-03-13 06:48:06 -07:00
parent 837f8525d8
commit 97292ecef7
7 changed files with 43 additions and 2 deletions
@@ -36,6 +36,8 @@ export function ConnectionForm() {
const setMode = useServerStore((state) => state.setMode);
const maxChunkChars = useServerStore((state) => state.maxChunkChars);
const setMaxChunkChars = useServerStore((state) => state.setMaxChunkChars);
const crossfadeMs = useServerStore((state) => state.crossfadeMs);
const setCrossfadeMs = useServerStore((state) => state.setCrossfadeMs);
const { toast } = useToast();
const form = useForm<ConnectionFormValues>({
@@ -177,6 +179,29 @@ export function ConnectionForm() {
can improve quality for long outputs. Default is 800.
</p>
</div>
<div className="space-y-3 mt-4">
<div className="flex items-center justify-between">
<label htmlFor="crossfadeMs" className="text-sm font-medium leading-none">
Chunk crossfade
</label>
<span className="text-sm tabular-nums text-muted-foreground">
{crossfadeMs === 0 ? 'Cut' : `${crossfadeMs}ms`}
</span>
</div>
<Slider
id="crossfadeMs"
value={[crossfadeMs]}
onValueChange={([value]) => setCrossfadeMs(value)}
min={0}
max={200}
step={10}
aria-label="Chunk crossfade duration"
/>
<p className="text-sm text-muted-foreground">
Blends audio between chunks to smooth transitions. Set to 0 for a hard cut.
</p>
</div>
</div>
</CardContent>
</Card>