jam-tracks / frontend /src /components /generation /ACEStepParams.jsx
Mina Emadi
added the music generation functionality
59dcfdf
Raw
History Blame Contribute Delete
4.79 kB
import React, { useState } from 'react'
import ParamSlider from './ParamSlider'
export default function ACEStepParams({ params, onParamChange, detection }) {
const [showAdvanced, setShowAdvanced] = useState(false)
return (
<div className="space-y-3">
<div className="text-[10px] text-gray-500 bg-white/[0.02] rounded-lg px-3 py-2">
Caption is auto-generated from your seed's analysis (BPM, key, brightness, instruments) for musical coherence. Override below if needed.
</div>
{/* Optional caption override (collapsed by default) */}
<button
onClick={() => setShowAdvanced(!showAdvanced)}
className="text-xs text-gray-500 hover:text-gray-300 transition-colors flex items-center gap-1"
>
<span className={`transition-transform ${showAdvanced ? 'rotate-90' : ''}`}>&#9654;</span>
Custom Caption & Advanced
</button>
{showAdvanced && (
<div className="space-y-3 pl-3 border-l border-white/[0.06]">
<div>
<label className="text-xs text-gray-400 font-medium mb-1 block">Caption Override</label>
<textarea
value={params.caption}
onChange={e => onParamChange('caption', e.target.value)}
placeholder="Leave empty for auto-generated caption"
className="w-full bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-2 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-accent-500/40 resize-none font-mono"
rows={2}
/>
</div>
<ParamSlider
label="CFG Scale"
value={params.cfg_scale || 7}
min={1}
max={15}
step={0.5}
onChange={v => onParamChange('cfg_scale', v)}
/>
<div>
<label className="text-xs text-gray-400 font-medium mb-1 block">Scheduler</label>
<select
value={params.scheduler}
onChange={e => onParamChange('scheduler', e.target.value)}
className="bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-1.5 text-sm text-white focus:outline-none focus:border-accent-500/40"
>
<option value="ode">ODE (recommended)</option>
<option value="sde">SDE</option>
</select>
</div>
</div>
)}
<ParamSlider
label="Duration"
value={params.duration}
min={10}
max={120}
step={5}
onChange={v => onParamChange('duration', v)}
leftLabel="10s"
rightLabel="120s"
/>
<ParamSlider
label="Source Fidelity"
value={params.audio_cover_strength}
min={0}
max={1}
step={0.05}
onChange={v => onParamChange('audio_cover_strength', v)}
leftLabel="Creative"
rightLabel="Faithful"
/>
{/* Model Variant */}
<div>
<label className="text-xs text-gray-400 font-medium mb-1 block">Model Variant</label>
<select
value={params.model_variant}
onChange={e => onParamChange('model_variant', e.target.value)}
className="bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-1.5 text-sm text-white focus:outline-none focus:border-accent-500/40"
>
<option value="xl-turbo">XL Turbo (best for 32GB)</option>
<option value="standard-turbo">Standard Turbo (faster)</option>
<option value="standard-sft">Standard SFT (balanced)</option>
</select>
</div>
<ParamSlider
label="Inference Steps"
value={params.inference_steps}
min={1}
max={50}
step={1}
onChange={v => onParamChange('inference_steps', v)}
leftLabel="Fast (1)"
rightLabel="Quality (50)"
/>
{/* Seed */}
<div>
<label className="text-xs text-gray-400 font-medium mb-1 block">Seed</label>
<div className="flex gap-2">
<input
type="number"
value={params.seed}
onChange={e => onParamChange('seed', parseInt(e.target.value) || -1)}
className="flex-1 bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-1.5 text-sm text-white font-mono focus:outline-none focus:border-accent-500/40"
/>
<button
onClick={() => onParamChange('seed', Math.floor(Math.random() * 999999))}
className="px-2 py-1.5 rounded-lg bg-white/[0.06] hover:bg-white/[0.1] text-sm transition-colors"
title="Random seed"
>
🎲
</button>
</div>
<span className="text-[10px] text-gray-600 mt-0.5 block">-1 = random</span>
</div>
</div>
)
}