feat: add Qwen CustomVoice preset engine

This commit is contained in:
James Pine
2026-03-19 19:48:50 -07:00
parent d70b878b71
commit 4e0c731db8
14 changed files with 399 additions and 21 deletions
@@ -17,6 +17,12 @@ import { useDeleteProfile, useExportProfile } from '@/lib/hooks/useProfiles';
import { cn } from '@/lib/utils/cn';
import { useUIStore } from '@/stores/uiStore';
/** Human-readable display names for preset engine badges. */
const ENGINE_DISPLAY_NAMES: Record<string, string> = {
kokoro: 'Kokoro',
qwen_custom_voice: 'CustomVoice',
};
interface ProfileCardProps {
profile: VoiceProfileResponse;
}
@@ -99,7 +105,7 @@ export function ProfileCard({ profile }: ProfileCardProps) {
</Badge>
{profile.voice_type === 'preset' && (
<Badge variant="secondary" className="text-xs h-5 px-1.5">
{profile.preset_engine}
{ENGINE_DISPLAY_NAMES[profile.preset_engine ?? ''] ?? profile.preset_engine}
</Badge>
)}
{profile.voice_type === 'designed' && (
@@ -60,9 +60,10 @@ import { AudioSampleUpload } from './AudioSampleUpload';
import { SampleList } from './SampleList';
const MAX_AUDIO_DURATION_SECONDS = 30;
const PRESET_ONLY_ENGINES = new Set(['kokoro']);
const PRESET_ONLY_ENGINES = new Set(['kokoro', 'qwen_custom_voice']);
const DEFAULT_ENGINE_OPTIONS = [
{ value: 'qwen', label: 'Qwen3-TTS' },
{ value: 'qwen_custom_voice', label: 'Qwen CustomVoice' },
{ value: 'luxtts', label: 'LuxTTS' },
{ value: 'chatterbox', label: 'Chatterbox' },
{ value: 'chatterbox_turbo', label: 'Chatterbox Turbo' },
@@ -849,6 +850,7 @@ export function ProfileForm() {
</FormControl>
<SelectContent>
<SelectItem value="kokoro">Kokoro 82M</SelectItem>
<SelectItem value="qwen_custom_voice">Qwen CustomVoice</SelectItem>
</SelectContent>
</Select>
</FormItem>
@@ -7,11 +7,12 @@ import { ProfileCard } from './ProfileCard';
import { ProfileForm } from './ProfileForm';
/** Engines that use preset (built-in) voices instead of cloned profiles. */
const PRESET_ENGINES = new Set(['kokoro']);
const PRESET_ENGINES = new Set(['kokoro', 'qwen_custom_voice']);
/** Human-readable engine names for empty state messages. */
const ENGINE_NAMES: Record<string, string> = {
kokoro: 'Kokoro',
qwen_custom_voice: 'Qwen CustomVoice',
};
export function ProfileList() {