コード例 #1
0
        public void ShouldMergeLongSequences()
        {
            DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo("en-US").DateTimeFormat;
            var first  = new List <HashedFingerprint>();
            var second = new List <HashedFingerprint>();

            float one = 8192f / 5512;

            for (int i = 0; i < 100; ++i)
            {
                first.Add(new HashedFingerprint(new[] { 1 }, (uint)i, i * one));
                second.Add(new HashedFingerprint(new[] { 2 }, (uint)i, i * one));
            }

            var r = new Random();
            var a = new TimedHashes(first.OrderBy(x => r.Next()).ToList(), DateTime.Parse("01/15/2019 10:00:00", dtfi));
            var b = new TimedHashes(second.OrderBy(x => r.Next()).ToList(), DateTime.Parse("01/15/2019 10:00:01.3", dtfi));

            Assert.IsTrue(a.MergeWith(b, out var c));
            for (int i = 0; i < 200; ++i)
            {
                Assert.AreEqual(i, c.HashedFingerprints[i].SequenceNumber);
                if (i % 2 == 0)
                {
                    Assert.AreEqual(one * (i / 2), c.HashedFingerprints[i].StartsAt, 0.0001);
                    CollectionAssert.AreEqual(new[] { 1 }, c.HashedFingerprints[i].HashBins);
                }
                else
                {
                    Assert.AreEqual(1.3f + one * (i / 2), c.HashedFingerprints[i].StartsAt, 0.0001);
                    CollectionAssert.AreEqual(new[] { 2 }, c.HashedFingerprints[i].HashBins);
                }
            }
        }
コード例 #2
0
        public void ShouldMerge()
        {
            DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo("en-US").DateTimeFormat;
            float one = 8192f / 5512;
            var   a   = new TimedHashes(new List <HashedFingerprint>
            {
                new HashedFingerprint(new[] { 1 }, 1, one),
                new HashedFingerprint(new[] { 1 }, 2, 2 * one),
                new HashedFingerprint(new[] { 1 }, 0, 0),
            },
                                        DateTime.Parse("01/15/2019 10:00:00", dtfi));

            var b = new TimedHashes(new List <HashedFingerprint>
            {
                new HashedFingerprint(new[] { 2 }, 1, one),
                new HashedFingerprint(new[] { 2 }, 2, 2 * one),
                new HashedFingerprint(new[] { 2 }, 0, 0)
            },
                                    DateTime.Parse("01/15/2019 10:00:01", dtfi));

            Assert.IsTrue(a.MergeWith(b, out var result));
            Assert.AreEqual(0, result.HashedFingerprints[0].StartsAt);
            Assert.AreEqual(1f, result.HashedFingerprints[1].StartsAt, 0.0001);
            Assert.AreEqual(one, result.HashedFingerprints[2].StartsAt, 0.0001);
            Assert.AreEqual(1 + one, result.HashedFingerprints[3].StartsAt, 0.0001);
            Assert.AreEqual(2 * one, result.HashedFingerprints[4].StartsAt, 0.0001);
            Assert.AreEqual(1 + 2 * one, result.HashedFingerprints[5].StartsAt, 0.0001);
        }
コード例 #3
0
        private static byte[] Serialize(TimedHashes timed)
        {
            byte[] buffer;
            using (var stream = new MemoryStream())
            {
                Serializer.SerializeWithLengthPrefix(stream, timed, PrefixStyle.Fixed32);
                stream.Flush();
                buffer = stream.GetBuffer();
            }

            return(buffer);
        }
コード例 #4
0
        private TimedHashes StoreDowntimeEntries(List <HashedFingerprint> hashes, DateTime relativeTo)
        {
            double length      = downtimeHashes.Sum(hash => hash.TotalSeconds);
            var    timedHashes = new TimedHashes(hashes, relativeTo);

            if (length <= configuration.DowntimeCapturePeriod)
            {
                downtimeHashes.Enqueue(timedHashes);
                return(TimedHashes.Empty);
            }

            return(timedHashes);
        }
コード例 #5
0
        public async Task HashesShouldMatchExactlyWhenAggregated()
        {
            var audioService = new SoundFingerprintingAudioService();
            var modelService = new InMemoryModelService();

            int count = 20, testWaitTime = 40000;
            var data         = GenerateRandomAudioChunks(count, 1);
            var concatenated = Concatenate(data);
            var hashes       = await FingerprintCommandBuilder.Instance
                               .BuildFingerprintCommand()
                               .From(concatenated)
                               .WithFingerprintConfig(config =>
            {
                config.Stride = new IncrementalStaticStride(512);
                return(config);
            })
                               .UsingServices(audioService)
                               .Hash();

            var collection = SimulateRealtimeQueryData(data, false, TimeSpan.FromSeconds);
            var cancellationTokenSource = new CancellationTokenSource(testWaitTime);
            var list = new List <TimedHashes>();

            await QueryCommandBuilder.Instance.BuildRealtimeQueryCommand()
            .From(collection)
            .WithRealtimeQueryConfig(config =>
            {
                config.QueryFingerprintsCallback += timedHashes => list.Add(timedHashes);
                config.Stride = new IncrementalStaticStride(512);
                return(config);
            })
            .UsingServices(modelService)
            .Query(cancellationTokenSource.Token);

            Assert.AreEqual(hashes.Count, list.Select(entry => entry.HashedFingerprints.Count).Sum());
            var merged = TimedHashes.Aggregate(list, 20d).ToList();

            Assert.AreEqual(2, merged.Count);
            Assert.AreEqual(hashes.Count, merged.Select(entry => entry.HashedFingerprints.Count).Sum());

            var aggregated = TimedHashes.Aggregate(list, double.MaxValue).ToList();

            Assert.AreEqual(1, aggregated.Count);
            Assert.AreEqual(hashes.Count, aggregated[0].HashedFingerprints.Count);
            foreach (var zipped in hashes.OrderBy(h => h.SequenceNumber).Zip(aggregated[0].HashedFingerprints, (a, b) => new { a, b }))
            {
                Assert.AreEqual(zipped.a.StartsAt, zipped.b.StartsAt, 0.5d);
                Assert.AreEqual(zipped.a.SequenceNumber, zipped.b.SequenceNumber);
                CollectionAssert.AreEqual(zipped.a.HashBins, zipped.b.HashBins);
            }
        }
コード例 #6
0
        public void ShouldMergeCorrectly()
        {
            float acc      = 8192 / 5512f;
            var   a        = TimedHashes.Empty;
            var   dateTime = DateTime.Now;
            var   b        = new TimedHashes(new List <HashedFingerprint>(new[] { new HashedFingerprint(new[] { 1 }, 0, 0) }), dateTime);
            var   c        = new TimedHashes(new List <HashedFingerprint>(new[] { new HashedFingerprint(new[] { 2 }, 0, 0f) }), dateTime.AddSeconds(acc));
            var   d        = new TimedHashes(new List <HashedFingerprint>(new[] { new HashedFingerprint(new[] { 3 }, 0, 0f) }), dateTime.AddSeconds(2 * acc));

            Assert.IsTrue(a.MergeWith(b, out var x));
            Assert.IsTrue(x.MergeWith(c, out var y));
            Assert.IsTrue(y.MergeWith(d, out var z));

            Assert.AreEqual(dateTime, z.StartsAt);
            Assert.AreEqual(3, z.HashedFingerprints.Count);
            Assert.AreEqual(3 * acc, z.TotalSeconds, 0.001);
        }
コード例 #7
0
        public void CantMergeSinceTheGapIsTooBig()
        {
            var dtfi = CultureInfo.GetCultureInfo("en-US").DateTimeFormat;
            var a    = new TimedHashes(new List <HashedFingerprint>
            {
                new HashedFingerprint(new[] { 1 }, 0, 0)
            },
                                       DateTime.Parse("01/15/2019 10:00:00", dtfi));

            var b = new TimedHashes(new List <HashedFingerprint>
            {
                new HashedFingerprint(new[] { 2 }, 0, 0)
            },
                                    DateTime.Parse("01/15/2019 10:01:00", dtfi));

            Assert.IsFalse(a.MergeWith(b, out _));
        }
コード例 #8
0
        public async Task QueryingWithAggregatedHashesShouldResultInTheSameMatches()
        {
            var audioService = new SoundFingerprintingAudioService();
            var modelService = new InMemoryModelService();

            int count = 20, testWaitTime = 5000;
            var data         = GenerateRandomAudioChunks(count, 1);
            var concatenated = Concatenate(data);
            var hashes       = await FingerprintCommandBuilder.Instance
                               .BuildFingerprintCommand()
                               .From(concatenated)
                               .WithFingerprintConfig(config => config)
                               .UsingServices(audioService)
                               .Hash();

            modelService.Insert(new TrackInfo("312", "Bohemian Rhapsody", "Queen"), hashes);

            var collection = SimulateRealtimeQueryData(data, false, TimeSpan.FromMilliseconds);
            var cancellationTokenSource = new CancellationTokenSource(testWaitTime);
            var fingerprints            = new List <TimedHashes>();
            var entries = new List <ResultEntry>();

            await QueryCommandBuilder.Instance.BuildRealtimeQueryCommand()
            .From(collection)
            .WithRealtimeQueryConfig(config =>
            {
                config.QueryFingerprintsCallback += timedHashes => fingerprints.Add(timedHashes);
                config.SuccessCallback            = entry => entries.Add(entry);
                config.ResultEntryFilter          = new CoverageLengthEntryFilter(0.8d);
                return(config);
            })
            .UsingServices(modelService)
            .Query(cancellationTokenSource.Token);

            Assert.IsTrue(entries.Any());
            Assert.AreEqual(1, entries.Count);
            var aggregated = TimedHashes.Aggregate(fingerprints, 60d).ToList();
            var result     = await QueryCommandBuilder.Instance.BuildQueryCommand()
                             .From(new Hashes(aggregated[0].HashedFingerprints, aggregated[0].TotalSeconds))
                             .UsingServices(modelService, audioService)
                             .Query(aggregated[0].StartsAt);

            Assert.IsTrue(result.ContainsMatches);
            Assert.AreEqual(entries[0].MatchedAt, result.BestMatch.MatchedAt);
        }
コード例 #9
0
        public void CanSerializeAndDeserialize()
        {
            var list = GetHashedFingerprints();

            var timed        = new TimedHashes(list, DateTime.Now);
            var buffer       = Serialize(timed);
            var deserialized = Deserialize(buffer);

            Assert.AreEqual(timed.HashedFingerprints.Count, deserialized.HashedFingerprints.Count);
            Assert.AreEqual(timed.StartsAt, deserialized.StartsAt);

            for (int i = 0; i < timed.HashedFingerprints.Count; ++i)
            {
                HashedFingerprint a = timed.HashedFingerprints[i];
                HashedFingerprint b = deserialized.HashedFingerprints[i];

                Assert.AreEqual(a.StartsAt, b.StartsAt);
                Assert.AreEqual(a.SequenceNumber, b.SequenceNumber);
                CollectionAssert.AreEqual(a.HashBins, b.HashBins);
            }
        }
コード例 #10
0
 private void InvokeExceptionCallback(Exception e, TimedHashes timedHashes)
 {
     configuration?.ErrorCallback(e, timedHashes);
 }