[gnome-subtitles] Fixed timings synchronization issue when "Sync All Subtitles" was used



commit 2522710b0bfeb6e671f25d96585da5a5a166af62
Author: Pedro Castro <mail>
Date:   Sun Jan 3 18:41:09 2010 +0000

    Fixed timings synchronization issue when "Sync All Subtitles" was used
    
    When using "Sync All Subtitles", the times for subtitles outside the selected
    syncpoint ranges were being incorrectly calculated.

 .../Core/Command/SynchronizeTimingsCommand.cs      |    2 +-
 src/SubLib/Core/Domain/Frames.cs                   |   10 ++--
 src/SubLib/Core/Domain/Times.cs                    |   12 +---
 src/SubLib/Core/Timing/AdjustOperator.cs           |    6 +-
 src/SubLib/Core/Timing/SyncUtil.cs                 |   52 ++++++++++++++------
 src/SubLib/Core/Timing/SynchronizeOperator.cs      |   49 +++++++++++++-----
 6 files changed, 84 insertions(+), 47 deletions(-)
---
diff --git a/src/GnomeSubtitles/Core/Command/SynchronizeTimingsCommand.cs b/src/GnomeSubtitles/Core/Command/SynchronizeTimingsCommand.cs
index b21f0b5..2363f27 100644
--- a/src/GnomeSubtitles/Core/Command/SynchronizeTimingsCommand.cs
+++ b/src/GnomeSubtitles/Core/Command/SynchronizeTimingsCommand.cs
@@ -40,7 +40,7 @@ public class SynchronizeTimingsCommand : FixedMultipleSelectionCommand {
 
 	protected override bool ChangeValues () {
 		Ui.View.Subtitles subtitles = Base.Document.Subtitles;
-		
+
 		if (lastTimes == null) {
 			int[] subtitleRange = GetSubtitleRange(subtitles);
 			Times[] timesToStore = GetCurrentTimes(subtitleRange, subtitles);
diff --git a/src/SubLib/Core/Domain/Frames.cs b/src/SubLib/Core/Domain/Frames.cs
index e2778bf..552512c 100644
--- a/src/SubLib/Core/Domain/Frames.cs
+++ b/src/SubLib/Core/Domain/Frames.cs
@@ -1,6 +1,6 @@
 /*
  * This file is part of SubLib.
- * Copyright (C) 2005-2008 Pedro Castro
+ * Copyright (C) 2005-2009 Pedro Castro
  *
  * SubLib is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,6 +17,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+using SubLib.Core.Timing;
 using System;
 
 namespace SubLib.Core.Domain {
@@ -104,10 +105,11 @@ public class Frames {
 		set { end = start + value; }
 	}
 	
-	internal void Scale (double factor, int baseFrame) {	
-		PreciseStart = baseFrame + ((PreciseStart - baseFrame) * factor);
-		PreciseEnd = baseFrame + ((PreciseEnd - baseFrame) * factor);
+	internal void Scale (double factor, int baseFrame) {
 		
+		PreciseStart = SyncUtil.Scale(PreciseStart, baseFrame, factor);
+		PreciseEnd = SyncUtil.Scale(PreciseEnd, baseFrame, factor);
+
 		subtitle.UpdateTimesFromFrames();	
 	}
 
diff --git a/src/SubLib/Core/Domain/Times.cs b/src/SubLib/Core/Domain/Times.cs
index d653555..f934c9e 100644
--- a/src/SubLib/Core/Domain/Times.cs
+++ b/src/SubLib/Core/Domain/Times.cs
@@ -17,6 +17,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+using SubLib.Core.Timing;
 using System;
 
 namespace SubLib.Core.Domain {
@@ -110,15 +111,8 @@ public class Times {
 	}
 	
 	internal void Scale (double factor, TimeSpan baseTime) {
-		double baseMilliseconds = baseTime.TotalMilliseconds;
-	
-		double start = PreciseStart.TotalMilliseconds;
-		double newStart = baseMilliseconds + ((start - baseMilliseconds) * factor);
-		PreciseStart = TimeSpan.FromMilliseconds(newStart);
-		
-		double end = PreciseEnd.TotalMilliseconds;
-		double newEnd = baseMilliseconds + ((end - baseMilliseconds) * factor);
-		PreciseEnd = TimeSpan.FromMilliseconds(newEnd);
+		PreciseStart = SyncUtil.Scale(PreciseStart, baseTime, factor);
+		PreciseEnd = SyncUtil.Scale(PreciseEnd, baseTime, factor);
 
 		subtitle.UpdateFramesFromTimes();	
 	}
diff --git a/src/SubLib/Core/Timing/AdjustOperator.cs b/src/SubLib/Core/Timing/AdjustOperator.cs
index 088b124..aa9ce20 100644
--- a/src/SubLib/Core/Timing/AdjustOperator.cs
+++ b/src/SubLib/Core/Timing/AdjustOperator.cs
@@ -1,6 +1,6 @@
 /*
  * This file is part of SubLib.
- * Copyright (C) 2006-2008 Pedro Castro
+ * Copyright (C) 2006-2010 Pedro Castro
  *
  * SubLib is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@ public class AdjustOperator {
 	/// <param name="endTime">The correct start time for the last subtitle.</param>
 	/// <returns>Whether the subtitles could be adjusted.</returns>
 	public bool Adjust (int startIndex, TimeSpan startTime, int endIndex, TimeSpan endTime) {
-		return SyncUtil.Sync(subtitles, startIndex, startTime, endIndex, endTime);
+		return SyncUtil.Sync(subtitles, startIndex, startTime, endIndex, endTime, true);
 	}
 	
 	/// <summary>Auto adjusts the subtitles given the correct frames for the first and last subtitle.</summary>
@@ -77,7 +77,7 @@ public class AdjustOperator {
 	/// <param name="endFrame">The correct start frame for the last subtitle.</param>
 	/// <returns>Whether the subtitles could be adjusted.</returns>
 	public bool Adjust (int startIndex, int startFrame, int endIndex, int endFrame) {
-		return SyncUtil.Sync(subtitles, startIndex, startFrame, endIndex, endFrame);
+		return SyncUtil.Sync(subtitles, startIndex, startFrame, endIndex, endFrame, true);
 	}
 
 }
diff --git a/src/SubLib/Core/Timing/SyncUtil.cs b/src/SubLib/Core/Timing/SyncUtil.cs
index 05152ec..8a75c50 100644
--- a/src/SubLib/Core/Timing/SyncUtil.cs
+++ b/src/SubLib/Core/Timing/SyncUtil.cs
@@ -1,6 +1,6 @@
 /*
  * This file is part of SubLib.
- * Copyright (C) 2009 Pedro Castro
+ * Copyright (C) 2009-2010 Pedro Castro
  *
  * SubLib is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,8 +24,8 @@ namespace SubLib.Core.Timing {
 
 public class SyncUtil {
 
-	public static bool Sync (Subtitles subtitles, SyncPoint start, SyncPoint end) {
-		return Sync(subtitles, start.SubtitleNumber, start.Correct.Time, end.SubtitleNumber, end.Correct.Time);
+	public static bool Sync (Subtitles subtitles, SyncPoint start, SyncPoint end, bool syncLast) {
+		return Sync(subtitles, start.SubtitleNumber, start.Correct.Time, end.SubtitleNumber, end.Correct.Time, syncLast);
 	}
 
 	/// <summary>Auto syncs a range of subtitles given their first and last correct times.</summary>
@@ -36,23 +36,27 @@ public class SyncUtil {
 	/// <param name="startTime">The correct start time for the first subtitle.</param>
 	/// <param name="endIndex">The subtitle index to end the adjustment with.</param>
 	/// <param name="endTime">The correct start time for the last subtitle.</param>
+	/// <param name="syncLast">Whether to sync the last subtitle.</param>
 	/// <returns>Whether the subtitles could be adjusted.</returns>
-	public static bool Sync (Subtitles subtitles, int startIndex, TimeSpan startTime, int endIndex, TimeSpan endTime) {
+	public static bool Sync (Subtitles subtitles, int startIndex, TimeSpan startTime, int endIndex, TimeSpan endTime, bool syncLast) {
 		if (!AreSyncArgsValid(subtitles, startIndex, startTime, endIndex, endTime))
 			return false;
 
-		/* Shift subtitles to the start point */
+		/* Perform initial calculations */
+		int syncEndIndex = (syncLast ? endIndex : endIndex - 1);
 		Subtitle startSubtitle = subtitles.Collection.Get(startIndex);
 		TimeSpan shift = startTime - startSubtitle.Times.PreciseStart;
+		Subtitle endSubtitle = subtitles.Collection.Get(endIndex);
+		double factor = (endTime - startTime).TotalMilliseconds / (endSubtitle.Times.PreciseStart - startSubtitle.Times.PreciseStart).TotalMilliseconds;
+
+		/* Shift subtitles to the start point */
 		if (shift != TimeSpan.Zero) {
 			ShiftOperator shiftOp = new ShiftOperator(subtitles);
-			shiftOp.Shift(shift, startIndex, endIndex);
+			shiftOp.Shift(shift, startIndex, syncEndIndex);
 		}
 		
-		/* Auto adjust timings with proportion */
-		Subtitle endSubtitle = subtitles.Collection.Get(endIndex);
-		double factor = (endTime - startTime).TotalMilliseconds / (endSubtitle.Times.PreciseStart - startTime).TotalMilliseconds;
-		for (int index = startIndex ; index <= endIndex ; index++) {
+		/* Sync timings with proportion */
+		for (int index = startIndex ; index <= syncEndIndex ; index++) {
 			Subtitle subtitle = subtitles.Collection.Get(index);
 			subtitle.Times.Scale(factor, startTime);
 		}
@@ -67,28 +71,44 @@ public class SyncUtil {
 	/// <param name="startFrame">The correct start frame for the first subtitle.</param>
 	/// <param name="endIndex">The subtitle index to end the adjustment with.</param>
 	/// <param name="endFrame">The correct start frame for the last subtitle.</param>
+	/// <param name="syncLast">Whether to sync the last subtitle.</param>
 	/// <returns>Whether the subtitles could be adjusted.</returns>
-	public static bool Sync (Subtitles subtitles, int startIndex, int startFrame, int endIndex, int endFrame) {
+	public static bool Sync (Subtitles subtitles, int startIndex, int startFrame, int endIndex, int endFrame, bool syncLast) {
 		if (!AreSyncArgsValid(subtitles, startIndex, startFrame, endIndex, endFrame))
 			return false;
 
-		/* Shift subtitles to the start point */
+		/* Perform initial calculations */
+		int syncEndIndex = (syncLast ? endIndex : endIndex - 1);
 		Subtitle startSubtitle = subtitles.Collection.Get(startIndex);
 		int shift = (int)(startFrame - startSubtitle.Frames.PreciseStart);
+		Subtitle endSubtitle = subtitles.Collection.Get(endIndex);
+		double factor = (endFrame - startFrame) / (endSubtitle.Frames.PreciseStart - startFrame);
+
+		/* Shift subtitles to the start point */
 		if (shift != 0) {
 			ShiftOperator shiftOp = new ShiftOperator(subtitles);
-			shiftOp.Shift(shift, startIndex, endIndex);
+			shiftOp.Shift(shift, startIndex, syncEndIndex);
 		}
 		
 		/* Auto adjust timings with proportion */
-		Subtitle endSubtitle = subtitles.Collection.Get(endIndex);
-		double factor = (endFrame - startFrame) / (endSubtitle.Frames.PreciseStart - startFrame);
-		for (int index = startIndex ; index <= endIndex ; index++) {
+		for (int index = startIndex ; index <= syncEndIndex ; index++) {
 			Subtitle subtitle = subtitles.Collection.Get(index);
 			subtitle.Frames.Scale(factor, startFrame);
 		}
 		return true;
 	}
+
+	public static TimeSpan Scale (TimeSpan currentTime, TimeSpan baseTime, double factor) {
+		double baseMilliseconds = baseTime.TotalMilliseconds;
+	
+		double time = currentTime.TotalMilliseconds;
+		double newTime = baseMilliseconds + ((time - baseMilliseconds) * factor);
+		return TimeSpan.FromMilliseconds(newTime);
+	}
+
+	public static double Scale (double currentFrame, double baseFrame, double factor) {
+		return baseFrame + ((currentFrame - baseFrame) * factor);
+	}
 	
 	/* Private members */
 	
diff --git a/src/SubLib/Core/Timing/SynchronizeOperator.cs b/src/SubLib/Core/Timing/SynchronizeOperator.cs
index d5383f6..1030423 100644
--- a/src/SubLib/Core/Timing/SynchronizeOperator.cs
+++ b/src/SubLib/Core/Timing/SynchronizeOperator.cs
@@ -1,6 +1,6 @@
 /*
  * This file is part of SubLib.
- * Copyright (C) 2008-2009 Pedro Castro
+ * Copyright (C) 2008-2010 Pedro Castro
  *
  * SubLib is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,13 +34,14 @@ public class SynchronizeOperator {
 	
 	public bool Sync (SyncPoints syncPoints, bool toSyncAll) {
 		SyncPoints pointsToUse = AdaptForOperation(syncPoints, toSyncAll);
-		if (!AreSyncArgsValid(pointsToUse))
+		if (!AreSyncArgsValid(pointsToUse)) {
 			return false;
-
+		}
 		SyncPoint previous = pointsToUse[0];
 		for (int index = 1 ; index < pointsToUse.Count ; index++) {
+			bool syncLast = (index == pointsToUse.Count - 1);
 			SyncPoint current = pointsToUse[index];
-			SyncUtil.Sync(subtitles, previous, current);
+			SyncUtil.Sync(subtitles, previous, current, syncLast);
 		
 			previous = current;
 		}
@@ -50,29 +51,49 @@ public class SynchronizeOperator {
 	
 	
 	/* Private members */
-	
+
 	private SyncPoints AdaptForOperation (SyncPoints syncPoints, bool toSyncAll) {
-		if ((syncPoints == null) || (!toSyncAll))
+		if ((syncPoints == null) || (!toSyncAll) || (toSyncAll && (syncPoints.Count < 2)))
 			return syncPoints;
 		
 		SyncPoints adapted = syncPoints.Clone();
-		
+
 		/* Add the first subtitle if possible */
 		int firstSubtitleNumber = 0;
 		if ((subtitles.Collection.Count > 0) && (!adapted.Contains(firstSubtitleNumber))) {
+			SyncPoint firstSyncPoint = adapted[0];
+			Subtitle firstSyncSubtitle = subtitles.Collection[firstSyncPoint.SubtitleNumber];
 			Subtitle firstSubtitle = subtitles.Collection[firstSubtitleNumber];
-			Domain.Timing firstSubtitleTiming = new Domain.Timing(firstSubtitle.Frames.Start, firstSubtitle.Times.Start);
-			SyncPoint firstSyncPoint = new SyncPoint(firstSubtitleNumber, firstSubtitleTiming, firstSubtitleTiming);
-			adapted.Add(firstSyncPoint);
+
+			double scaleFactor = firstSyncPoint.Correct.Time.TotalMilliseconds / firstSyncSubtitle.Times.Start.TotalMilliseconds;
+			TimeSpan firstSubtitleNewTime = SyncUtil.Scale(firstSubtitle.Times.PreciseStart, TimeSpan.Zero, scaleFactor);
+			int firstSubtitleNewFrame = (int)TimingUtil.TimeToFrames(firstSubtitleNewTime, subtitles.Properties.CurrentFrameRate);
+			Domain.Timing firstSubtitleNewTiming = new Domain.Timing(firstSubtitleNewFrame, firstSubtitleNewTime);
+			
+			Domain.Timing firstSubtitleCurrentTiming = new Domain.Timing(firstSubtitle.Frames.Start, firstSubtitle.Times.Start);
+			SyncPoint newFirstSyncPoint = new SyncPoint(firstSubtitleNumber, firstSubtitleCurrentTiming, firstSubtitleNewTiming);
+			adapted.Add(newFirstSyncPoint);
 		}
 		
 		/* Add last subtitle if possible */
 		int lastSubtitleNumber = subtitles.Collection.Count - 1;
 		if ((subtitles.Collection.Count > 1) && (!adapted.Contains(lastSubtitleNumber))) {
-			Subtitle lastSubtitle = subtitles.Collection[lastSubtitleNumber - 1];
-			Domain.Timing lastSubtitleTiming = new Domain.Timing(lastSubtitle.Frames.Start, lastSubtitle.Times.Start);
-			SyncPoint lastSyncPoint = new SyncPoint(lastSubtitleNumber, lastSubtitleTiming, lastSubtitleTiming);
-			adapted.Add(lastSyncPoint);
+
+			/* Calculate sync factor using the last 2 sync points */
+			SyncPoint penultSyncPoint = adapted[adapted.Count - 2];			
+			SyncPoint lastSyncPoint = adapted[adapted.Count - 1];
+			Subtitle penultSyncPointSubtitle = subtitles.Collection[penultSyncPoint.SubtitleNumber];
+			Subtitle lastSyncPointSubtitle = subtitles.Collection[lastSyncPoint.SubtitleNumber];
+			double factor = (lastSyncPoint.Correct.Time - penultSyncPoint.Correct.Time).TotalMilliseconds / (lastSyncPointSubtitle.Times.PreciseStart - penultSyncPointSubtitle.Times.PreciseStart).TotalMilliseconds;
+
+			/* Calculate new time */
+			Subtitle lastSubtitle = subtitles.Collection[lastSubtitleNumber];
+			TimeSpan lastSubtitleNewTime = SyncUtil.Scale(lastSubtitle.Times.Start, lastSyncPoint.Correct.Time, factor);
+			int lastSubtitleNewFrame = (int)TimingUtil.TimeToFrames(lastSubtitleNewTime, subtitles.Properties.CurrentFrameRate);
+			Domain.Timing lastSubtitleNewTiming = new Domain.Timing(lastSubtitleNewFrame, lastSubtitleNewTime);
+			Domain.Timing lastSubtitleCurrentTiming = new Domain.Timing(lastSubtitle.Frames.Start, lastSubtitle.Times.Start);
+			SyncPoint newLastSyncPoint = new SyncPoint(lastSubtitleNumber, lastSubtitleCurrentTiming, lastSubtitleNewTiming);
+			adapted.Add(newLastSyncPoint);
 		}
 		
 		return adapted;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]