Skip to content

Commit

Permalink
Fix LRC same-line collapsing sometimes deleting parts of a line
Browse files Browse the repository at this point in the history
Fixes #354
  • Loading branch information
jacquesh committed Aug 5, 2024
1 parent 39ed7b0 commit a5250bd
Show file tree
Hide file tree
Showing 9 changed files with 298 additions and 94 deletions.
23 changes: 11 additions & 12 deletions src/lyric_auto_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ std::optional<LyricData> auto_edit::RunAutoEdit(AutoEditType type, const LyricDa

std::optional<LyricData> auto_edit::ReplaceHtmlEscapedChars(const LyricData& lyrics)
{
LyricDataUnstructured unstructured = parsers::lrc::serialise(lyrics);
std::string text = from_tstring(parsers::lrc::expand_text(lyrics, false));
std::pair<std::string_view, char> replacements[] =
{
{"&amp;", '&'},
Expand All @@ -41,12 +41,12 @@ std::optional<LyricData> auto_edit::ReplaceHtmlEscapedChars(const LyricData& lyr
for(auto [escaped, replacement] : replacements)
{
size_t current_index = 0;
while(current_index < unstructured.text.length())
while(current_index < text.length())
{
size_t next_index = unstructured.text.find(escaped, current_index);
size_t next_index = text.find(escaped, current_index);
if(next_index == std::string::npos) break;

unstructured.text.replace(next_index, escaped.length(), 1, replacement);
text.replace(next_index, escaped.length(), 1, replacement);
current_index = next_index + 1;
replace_count++;
}
Expand All @@ -55,7 +55,7 @@ std::optional<LyricData> auto_edit::ReplaceHtmlEscapedChars(const LyricData& lyr

if(replace_count > 0)
{
return {parsers::lrc::parse(unstructured)};
return {parsers::lrc::parse(lyrics, text)};
}
else
{
Expand Down Expand Up @@ -253,32 +253,31 @@ std::optional<LyricData> auto_edit::FixMalformedTimestamps(const LyricData& lyri
}
};

LyricDataUnstructured new_lyrics = parsers::lrc::serialise(lyrics);

std::string text = from_tstring(parsers::lrc::expand_text(lyrics, false));
int change_count = 0;
size_t current_index = new_lyrics.text.find('[');
size_t current_index = text.find('[');
while(current_index != std::string::npos)
{
bool changed = false;

size_t end_index = new_lyrics.text.find(']', current_index);
size_t end_index = text.find(']', current_index);
if(end_index == std::string::npos)
{
break;
}
std::string_view tag {new_lyrics.text.c_str() + current_index, end_index - current_index + 1};
std::string_view tag {text.c_str() + current_index, end_index - current_index + 1};
changed |= fix_decimal_separator(tag);

if(changed)
{
change_count++;
}
current_index = new_lyrics.text.find('[', current_index+1);
current_index = text.find('[', current_index+1);
}

if(change_count > 0)
{
return {parsers::lrc::parse(new_lyrics)};
return {parsers::lrc::parse(lyrics, text)};
}
else
{
Expand Down
37 changes: 1 addition & 36 deletions src/lyric_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,42 +75,7 @@ bool io::save_lyrics(metadb_handle_ptr track, const metadb_v2_rec_t& track_info,
return false;
}

std::string text;
if(lyrics.IsTimestamped() && preferences::saving::merge_equivalent_lrc_lines())
{
LyricData merged_lyrics = lyrics;
const auto lexicographic_sort = [](const auto& lhs, const auto& rhs){ return lhs.text < rhs.text; };
std::stable_sort(merged_lyrics.lines.begin(), merged_lyrics.lines.end(), lexicographic_sort);
std::vector<LyricDataLine>::iterator equal_begin = merged_lyrics.lines.begin();

while(equal_begin != merged_lyrics.lines.end())
{
std::vector<LyricDataLine>::iterator equal_end = equal_begin + 1;
while((equal_end != merged_lyrics.lines.end()) && (equal_begin->text == equal_end->text) && (equal_end->timestamp != DBL_MAX))
{
equal_end++;
}

// NOTE: We don't need to move equal_begin back one because we don't add
// the first timestamp to the string. That'll happen as part of the
// normal printing below.
for(auto iter=equal_end-1; iter!=equal_begin; iter--)
{
equal_begin->text = to_tstring(parsers::lrc::print_timestamp(iter->timestamp)) + equal_begin->text;
}
equal_begin = merged_lyrics.lines.erase(equal_begin+1, equal_end);
}

const auto timestamp_sort = [](const auto& lhs, const auto& rhs){ return lhs.timestamp < rhs.timestamp; };
std::stable_sort(merged_lyrics.lines.begin(), merged_lyrics.lines.end(), timestamp_sort);

text = from_tstring(parsers::lrc::expand_text(merged_lyrics));
}
else
{
text = from_tstring(parsers::lrc::expand_text(lyrics));
}

const std::string text = from_tstring(parsers::lrc::expand_text(lyrics, preferences::saving::merge_equivalent_lrc_lines()));
try
{
std::string output_path = source->save(track, track_info, lyrics.IsTimestamped(), text, allow_overwrite, abort);
Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void OpenLyricsVersion::get_about_message(pfc::string_base & out)
"- Fix album art backgrounds disappearing when playing the same track twice\n"
"- Fix the 'encoding' tag in LRC files being considered a lyric line\n"
"- Fix rounding errors causing timestamps to randomly change when saving\n"
"- Fix LRC same-line collapsing sometimes deleting parts of a line\n"
"- Many, many minor non-functional internal code improvements\n"
"\n";
out += "Version 1.9 (2024-06-12):\n"
Expand Down
4 changes: 2 additions & 2 deletions src/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ namespace lrc
bool try_parse_timestamp(std::string_view tag, double& out_timestamp);

LyricData parse(const LyricDataUnstructured& input);
LyricDataUnstructured serialise(const LyricData& input);
LyricData parse(const LyricDataCommon& metadata, std::string text_utf8);

std::tstring expand_text(const LyricData& data);
std::tstring expand_text(const LyricData& data, bool merge_equivalent_lrc_lines);
} // namespace lrc

} // namespace parsers
Expand Down
Loading

0 comments on commit a5250bd

Please sign in to comment.