From 2a94a9f1033fc3e5fee1746c10dcaad566f268f3 Mon Sep 17 00:00:00 2001 From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com> Date: Tue, 10 May 2022 02:10:39 -0500 Subject: [PATCH] Update comments and add CountBits unit test --- .../TestAudioFingerprinting.cs | 12 +++++++ .../Entrypoint.cs | 2 +- .../ScheduledTasks/FingerprinterTask.cs | 34 +++++++++++-------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/ConfusedPolarBear.Plugin.IntroSkipper.Tests/TestAudioFingerprinting.cs b/ConfusedPolarBear.Plugin.IntroSkipper.Tests/TestAudioFingerprinting.cs index a51542a..63bca3e 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper.Tests/TestAudioFingerprinting.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper.Tests/TestAudioFingerprinting.cs @@ -11,6 +11,18 @@ public class TestFPCalc Assert.True(FPCalc.CheckFPCalcInstalled()); } + [Theory] + [InlineData(0, 0)] + [InlineData(1, 1)] + [InlineData(5, 213)] + [InlineData(10, 56_021)] + [InlineData(16, 16_112_341)] + [InlineData(19, 2_465_585_877)] + public void TestBitCounting(int expectedBits, uint number) + { + Assert.Equal(expectedBits, FingerprinterTask.CountBits(number)); + } + [Fact] public void TestFingerprinting() { diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs index 8399b58..bf8c2de 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs @@ -82,7 +82,7 @@ public class Entrypoint : IServerEntryPoint private void QueueLibraryContents(string rawId) { - // FIXME: do smarterer + // FIXME: don't do this var query = new UserViewQuery() { diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs index 9fde572..e49d5a7 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; namespace ConfusedPolarBear.Plugin.IntroSkipper; /// -/// Fingerprint all queued episodes at the set time. +/// Fingerprint and analyze all queued episodes for common audio sequences. /// public class FingerprinterTask : IScheduledTask { @@ -24,12 +24,12 @@ public class FingerprinterTask : IScheduledTask private const double MaximumDifferences = 3; /// - /// Maximum time permitted between timestamps before they are considered non-contiguous. + /// Maximum time (in seconds) permitted between timestamps before they are considered non-contiguous. /// private const double MaximumDistance = 3.25; /// - /// Seconds of audio in one number from the fingerprint. Defined by Chromaprint. + /// Seconds of audio in one fingerprint point. This value is defined by the Chromaprint library and should not be changed. /// private const double SamplesToSeconds = 0.128; @@ -72,7 +72,7 @@ public class FingerprinterTask : IScheduledTask /// /// Analyze all episodes in the queue. /// - /// Progress. + /// Task progress. /// Cancellation token. /// Task. public Task ExecuteAsync(IProgress progress, CancellationToken cancellationToken) @@ -84,8 +84,11 @@ public class FingerprinterTask : IScheduledTask { var first = season.Value[0]; - // Don't analyze seasons with <= 1 episode or specials - if (season.Value.Count <= 1 || first.SeasonNumber == 0) + /* Don't analyze specials or seasons with an insufficient number of episodes. + * A season with only 1 episode can't be analyzed as it would compare the episode to itself, + * which would result in the entire episode being marked as an introduction, as the audio is identical. + */ + if (season.Value.Count < 2 || first.SeasonNumber == 0) { continue; } @@ -222,8 +225,6 @@ public class FingerprinterTask : IScheduledTask // TODO: if an episode fails but others in the season succeed, reanalyze it against two that succeeded. - // TODO: is this the optimal way to indicate that an intro couldn't be found? - // the goal here is to not waste time every task run reprocessing episodes that we know will fail. StoreIntro(lhsEpisode.EpisodeId, 0, 0); StoreIntro(rhsEpisode.EpisodeId, 0, 0); @@ -353,13 +354,13 @@ public class FingerprinterTask : IScheduledTask // Tweak the end timestamps just a bit to ensure as little content as possible is skipped over. if (lContiguous.Duration >= 90) { - lContiguous.End -= 6; - rContiguous.End -= 6; + lContiguous.End -= 2 * MaximumDistance; + rContiguous.End -= 2 * MaximumDistance; } else if (lContiguous.Duration >= 35) { - lContiguous.End -= 3; - rContiguous.End -= 3; + lContiguous.End -= MaximumDistance; + rContiguous.End -= MaximumDistance; } return (lContiguous, rContiguous); @@ -370,7 +371,7 @@ public class FingerprinterTask : IScheduledTask var intro = new Intro() { EpisodeId = episode, - Valid = introEnd > 0, + Valid = introEnd > 0, // don't test introStart here as the intro could legitimately happen at the start. IntroStart = introStart, IntroEnd = introEnd }; @@ -384,7 +385,12 @@ public class FingerprinterTask : IScheduledTask Plugin.Instance.Intros[episode] = intro; } - private static int CountBits(uint number) + /// + /// Count the number of bits that are set in the provided number. + /// + /// Number to count bits in. + /// Number of bits that are equal to 1. + public static int CountBits(uint number) { var count = 0;