fix(lyrics): preserve Telugu shaping in karaoke - #1174
Open
Alvaro-Manzo wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves Enhanced Lyrics TTML karaoke rendering for Telugu by grouping TTML fragments into larger layout nodes so Telugu grapheme shaping is preserved and glyph overlap is avoided.
Changes:
- Group
WordTimestampfragments for Telugu into “syllable groups” before buildingKaraokeSyllables. - Merge grouped fragment text into a single
KaraokeSyllable.contentwhile keeping timing derived from the group boundaries. - Aggregate per-fragment romanization (“phonetics”) into a single phonetic string per grouped syllable.
1. PR Summary
The grouping approach is directionally correct for fixing Telugu shaping issues caused by TTML fragmenting. However, the current phonetic aggregation inserts spaces between fragments, which can break word-level romanization, and the phonetic index computation is O(n²) in the common (non-Telugu) case.
2. Blocking Issues (Changes Requested)
- Grouped fragment phonetics are joined with spaces, which can introduce incorrect word breaks in romanization and conflicts with the PR’s intent to preserve word-level phonetics.
3. Non-Blocking Feedback (Nitpicks & Polish)
phoneticStartIndexis recomputed via prefix summing insidemapIndexed, makingtoKaraokeSyllables()O(n²) when no grouping occurs (typical for non-Telugu). This is avoidable with a small refactor.
4. Suggested Code Fixes
app/src/main/kotlin/moe/rukamori/archivetune/ui/component/LyricsEnhanced.kt
- Concatenate grouped fragment phonetics without separators:
.filterNotNull()
.joinToString(separator = "")
.takeIf(String::isNotEmpty)- Precompute phonetic offsets once instead of summing inside
mapIndexed:
val phoneticOffsets =
IntArray(syllableGroups.size).also { offsets ->
var offset = 0
syllableGroups.forEachIndexed { i, group ->
offsets[i] = offset
offset += group.size
}
}
// ...
val phoneticStartIndex = phoneticOffsets[index]5. Final Verdict
REQUEST CHANGES
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+1230
to
+1234
| .drop(phoneticStartIndex) | ||
| .take(group.size) | ||
| .filterNotNull() | ||
| .joinToString(" ") | ||
| .takeIf(String::isNotEmpty), |
Comment on lines
+1212
to
+1218
| val syllableGroups = groupTeluguSyllables() | ||
|
|
||
| return syllableGroups.mapIndexed { index, group -> | ||
| val start = group.first().startTime.toMilliseconds() | ||
| val nextStart = syllableGroups.getOrNull(index + 1)?.first()?.startTime?.toMilliseconds() | ||
| val rawEnd = group.last().endTime.toMilliseconds() | ||
| val phoneticStartIndex = syllableGroups.take(index).sumOf { it.size } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1084.
Timed TTML can split Telugu words into multiple karaoke fragments. Rendering those fragments separately breaks Telugu text shaping and can cause overlapping glyphs.
This change groups fragments belonging to the same Telugu word before creating karaoke syllables, while preserving word-level timing and phonetics.