Add section performance directives
This commit is contained in:
@@ -30,15 +30,20 @@ public struct SongProjectPromptCompiler: PromptCompiling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return project.orderedSections
|
return project.orderedSections
|
||||||
.compactMap { section in
|
.compactMap { sectionLyricsBlock(for: $0, project: project) }
|
||||||
let lyrics = project.lyrics.sectionTexts[section.id] ?? section.lyrics
|
|
||||||
let trimmedLyrics = lyrics.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
||||||
guard !trimmedLyrics.isEmpty else { return nil }
|
|
||||||
return "[\(section.title)]\n\(trimmedLyrics)"
|
|
||||||
}
|
|
||||||
.joined(separator: "\n\n")
|
.joined(separator: "\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func sectionLyricsBlock(for section: SongSection, project: SongProject) -> String? {
|
||||||
|
let lyrics = project.lyrics.sectionTexts[section.id] ?? section.lyrics
|
||||||
|
let trimmedLyrics = lyrics.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !trimmedLyrics.isEmpty else { return nil }
|
||||||
|
|
||||||
|
let performanceDirective = normalized(section.vocalDirection)
|
||||||
|
let header = performanceDirective.map { "[\(section.title) - \($0)]" } ?? "[\(section.title)]"
|
||||||
|
return "\(header)\n\(trimmedLyrics)"
|
||||||
|
}
|
||||||
|
|
||||||
private func stylePrompt(for project: SongProject) -> String {
|
private func stylePrompt(for project: SongProject) -> String {
|
||||||
let context = SongGenerationContext(project: project)
|
let context = SongGenerationContext(project: project)
|
||||||
var components: [String] = []
|
var components: [String] = []
|
||||||
|
|||||||
@@ -62,4 +62,35 @@ final class SongProjectPromptCompilerTests: XCTestCase {
|
|||||||
|
|
||||||
XCTAssertEqual(output.lyricsText, "[Verse]\nVerse line\n\n[Chorus]\nHook line")
|
XCTAssertEqual(output.lyricsText, "[Verse]\nVerse line\n\n[Chorus]\nHook line")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testCompilerIncludesSectionPerformanceDirectivesInFallbackLyrics() throws {
|
||||||
|
let project = SongProject(
|
||||||
|
title: "Directed Sections",
|
||||||
|
idea: "Compile performance directions",
|
||||||
|
sections: [
|
||||||
|
SongSection(
|
||||||
|
id: "intro",
|
||||||
|
type: .intro,
|
||||||
|
title: "Intro",
|
||||||
|
lyrics: "First line",
|
||||||
|
vocalDirection: "whispered lead"
|
||||||
|
),
|
||||||
|
SongSection(
|
||||||
|
id: "chorus",
|
||||||
|
type: .chorus,
|
||||||
|
title: "Chorus",
|
||||||
|
order: 1,
|
||||||
|
lyrics: "Original hook"
|
||||||
|
)
|
||||||
|
],
|
||||||
|
lyrics: Lyrics(sectionTexts: ["chorus": "Approved hook"])
|
||||||
|
)
|
||||||
|
|
||||||
|
let output = try SongProjectPromptCompiler().compile(project: project)
|
||||||
|
|
||||||
|
XCTAssertEqual(
|
||||||
|
output.lyricsText,
|
||||||
|
"[Intro - whispered lead]\nFirst line\n\n[Chorus]\nApproved hook"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -98,7 +98,7 @@ requirement is missing and blocks implementation, record it in
|
|||||||
|
|
||||||
- [x] Create deterministic compiler from approved SongProject → Suno
|
- [x] Create deterministic compiler from approved SongProject → Suno
|
||||||
output.
|
output.
|
||||||
- [ ] Generate lyrics text with section/performance directives where
|
- [x] Generate lyrics text with section/performance directives where
|
||||||
appropriate.
|
appropriate.
|
||||||
- [ ] Generate style prompt from genre blend, instrumentation, vocals,
|
- [ ] Generate style prompt from genre blend, instrumentation, vocals,
|
||||||
tempo, harmony, emotion and production instructions.
|
tempo, harmony, emotion and production instructions.
|
||||||
|
|||||||
Reference in New Issue
Block a user