diff --git a/pages/index.vue b/pages/studio-1.vue similarity index 100% rename from pages/index.vue rename to pages/studio-1.vue diff --git a/utils/music.ts b/utils/music.ts index 9c329df..ff9e07c 100644 --- a/utils/music.ts +++ b/utils/music.ts @@ -1,5 +1,5 @@ export const MUSIC_DURATION_MIN = 30 -export const MUSIC_DURATION_MAX = 180 +export const MUSIC_DURATION_MAX = 150 export const MUSIC_DURATION_DEFAULT = 60 export const MUSIC_STEPS_MIN = 8 export const MUSIC_STEPS_MAX = 100 @@ -33,27 +33,18 @@ export const DEFAULT_MUSIC_LYRICS = `[Verse 1] [Outro] ` -export type MusicEngine = 'ace-step' | 'ace-step-1.5' | 'yue' | 'yue2' +export type MusicEngine = 'yue2' export function parseMusicEngine(raw: unknown): MusicEngine { const value = String(raw || '').trim().toLowerCase() - if (value === 'ace-step-1.5' || value === 'ace15' || value === 'v1.5') return 'ace-step-1.5' - if (value === 'yue2' || value === 'yue-2') return 'yue2' - if (value === 'yue' || value === 'yue-s1' || value === 'lyrics2song') return 'yue' - return 'ace-step' -} - -export function isAceMusicEngine(engine: MusicEngine | string | undefined) { - const value = parseMusicEngine(engine) - return value !== 'yue' && value !== 'yue2' + if (value === 'yue2' || value === 'yue-2' || !value) return 'yue2' + // Legacy ACE / YuEGP values map to YuE2 — the only supported music engine. + return 'yue2' } export function musicEngineLabel(engine: MusicEngine | string | undefined) { - const value = parseMusicEngine(engine) - if (value === 'ace-step-1.5') return 'ACE-Step 1.5' - if (value === 'yue2') return 'YuE2' - if (value === 'yue') return 'YuE' - return 'ACE-Step' + void engine + return 'YuE2' } export function parseMusicBpm(tags: unknown, fallback = 120) { @@ -97,18 +88,17 @@ export function sanitizeMusicLyrics(raw: unknown, instrumental = false) { return String(raw || '').replace(/\r\n/g, '\n').trim().slice(0, MUSIC_LYRICS_MAX) } -/** YuE splits on [Section] headers. Returns how many sections are present. */ +/** YuE2 splits on [Section] headers. Returns how many section tags are present. */ export function countYueLyricSections(lyrics: unknown) { const text = String(lyrics || '') const matches = text.match(/\[[^\]]+\]/g) return matches ? matches.length : 0 } +/** YuE2 allows multiple lyric sections; only empty lyrics are rejected. */ export function yueLyricsProblem(lyrics: unknown): string | null { const text = String(lyrics || '').trim() - if (!text) return 'YuE needs lyrics with section tags like [Verse 1] and [Chorus].' - const sections = [...text.matchAll(/\[([^\]]+)\]\s*([^\[]*)/gs)].filter(match => match[2].trim()) - if (sections.length !== 1) return 'YuEGP needs exactly one non-empty lyric section. Combine the lyrics under one heading.' + if (!text) return 'YuE2 needs lyrics. Use section tags like [Verse 1] and [Chorus] when you want structure.' return null }