/// <summary> /// Shift all lines in "list to change" by "offset", create a matching, rate the matching and shift lines back. /// </summary> public double GetRatingOfOffset(double offset, SubtitleMatcher.SubtitleMatcherCache subtitleMatcherParams) { /* * Other ideas for rating: * bonus value for censecutive good bi-match ratings */ // move timings of every line subtitleMatcherParams.ShiftTime(offset, false, true); // match lines var biMatchedLinesList = SubtitleMatcher.MatchSubtitles(subtitleMatcherParams); double finalRating = 0; foreach (var biMatchedLines in biMatchedLinesList) { double rating = RateBiMatchedLines(biMatchedLines); // use rating^3 because that way small values will become smaller finalRating += rating * rating * rating; } // shift timings back subtitleMatcherParams.ShiftTime(-offset, false, true); return(finalRating); }
/// <summary> /// This function test "iterations"-times different offsets and saves the best in "returnList". /// The offsets will be around "centerOffset" and "2 * stepSize" is the in every direction. /// The returnList will be filled until "Count==Capacity". At every time, "returnList" is sorted /// by rating ("returnList[0]" has the best rating of all tested offsets). /// </summary> private void FindGoodOffsets(SubtitleMatcher.SubtitleMatcherCache subtitleMatcherParams, double centerOffset, double stepSize, int iterations, List <OffsetRatingTuple> returnList) { int sign = 1; // will alternate every iteration for (int iteration = 0; iteration < iterations; iteration++) { double offset = sign * (stepSize * iteration) + centerOffset; sign *= -1; double averageRating = GetRatingOfOffset(offset, subtitleMatcherParams); if (returnList.Count < returnList.Capacity) { returnList.Add(new OffsetRatingTuple(offset, averageRating)); // if all entries are filled they have to be sorted by how good they are // (at index 0 the rating is best) if (returnList.Count == returnList.Capacity) { returnList.Sort(); } } else { // is value better than worst in return list? if (averageRating > returnList[returnList.Count - 1].rating) { returnList[returnList.Count - 1].offset = offset; returnList[returnList.Count - 1].rating = averageRating; // bubble sort in sorted list for (int i = returnList.Count - 1; i >= 1; i--) { // move value up (rating at lower index is higher) or end loop? if (returnList[i].rating < returnList[i - 1].rating) { break; } var tmp = returnList[i]; returnList[i] = returnList[i - 1]; returnList[i - 1] = tmp; } } } } }