Esempio n. 1
0
        public void ShouldMergeResults()
        {
            var aggregator = new StatefulRealtimeResultEntryAggregator(new QueryMatchLengthFilter(5d), 1.48d);

            var success  = new List <ResultEntry>();
            var filtered = new List <ResultEntry>();

            SimulateEmptyResults(aggregator, success, filtered);

            Assert.IsTrue(!success.Any());

            for (int i = 0; i < 10; ++i)
            {
                var entry      = new ResultEntry(GetTrack(), 0.01233, 0, DateTime.Now, 1.48d, 0d, 1.48d, 1.48d, 10d + i * 1.48d, -10d - i * 1.48d);
                var aggregated = aggregator.Consume(new[] { entry }, 1.48d);
                AddAll(aggregated.SuccessEntries, success);
                AddAll(aggregated.DidNotPassThresholdEntries, filtered);
            }

            SimulateEmptyResults(aggregator, success, filtered);

            Assert.AreEqual(2, success.Count);
            Assert.AreEqual(1, filtered.Count);
            Assert.IsTrue(success[0].CoverageWithPermittedGapsLength > 5d);
            Assert.IsTrue(success[1].CoverageWithPermittedGapsLength > 5d);
            Assert.IsTrue(filtered[0].CoverageWithPermittedGapsLength < 5d);
        }
        public void ShouldMergeResults()
        {
            double permittedGap = 1d;
            var    aggregator   = new StatefulRealtimeResultEntryAggregator(new QueryMatchLengthFilter(5d), permittedGap);

            var success  = new List <ResultEntry>();
            var filtered = new List <ResultEntry>();

            SimulateEmptyResults(aggregator, success, filtered);

            Assert.IsTrue(!success.Any());

            for (int i = 0; i < 10; ++i)
            {
                var entry      = new ResultEntry(GetTrack(), 0, DateTime.Now, TestUtilities.GetMatchedWith(new[] { i }, new[] { i }).EstimateCoverage(1, 10, 1, permittedGap));
                var aggregated = aggregator.Consume(new[] { entry }, 1);
                AddAll(aggregated.SuccessEntries, success);
                AddAll(aggregated.DidNotPassThresholdEntries, filtered);
            }

            SimulateEmptyResults(aggregator, success, filtered);

            Assert.AreEqual(1, success.Count);
            Assert.AreEqual(1, filtered.Count);
            Assert.IsTrue(success[0].TrackCoverageWithPermittedGapsLength > 5d);
            Assert.IsTrue(filtered[0].TrackCoverageWithPermittedGapsLength < 5d);
        }
        public void ShouldMergeResults()
        {
            double permittedGap = 2d;
            var aggregator = new StatefulRealtimeResultEntryAggregator(new TrackMatchLengthEntryFilter(5d), GetConfigWithPermittedGap(permittedGap));

            var success = new List<ResultEntry>();
            var filtered = new List<ResultEntry>();
            
            SimulateEmptyResults(aggregator, success, filtered);
            
            Assert.IsEmpty(success);
            Assert.IsEmpty(filtered);

            const int queryLength = 1;
            const int trackLength = 10;
            const int fingerprintLength = 1;
            for (int i = 0; i < 10; ++i)
            {
                var entry = new ResultEntry(GetTrack(trackLength), 0, DateTime.Now, TestUtilities.GetMatchedWith(new[] { 0 }, new[] { i }).EstimateCoverage(queryLength, trackLength, fingerprintLength, permittedGap));
                var aggregated = aggregator.Consume(new[] { entry }, queryLength, 0);
                AddAll(aggregated.SuccessEntries, success);
                AddAll(aggregated.DidNotPassThresholdEntries, filtered);
            }
            
            SimulateEmptyResults(aggregator, success, filtered);
            
            Assert.AreEqual(1, success.Count);
            Assert.AreEqual(1, filtered.Count);
            Assert.IsTrue(success[0].TrackCoverageWithPermittedGapsLength > 5d);
            Assert.IsTrue(filtered[0].TrackCoverageWithPermittedGapsLength < 5d);
        }
        public void ShouldWaitAsGapPermits()
        {
            double permittedGap = 5d;
            var aggregator = new StatefulRealtimeResultEntryAggregator(new TrackMatchLengthEntryFilter(10d), GetConfigWithPermittedGap(permittedGap));
            int firstQueryLength = 5;
            int trackLength = 5;
            var first = aggregator.Consume(new[]
            {
                new ResultEntry(GetTrack(trackLength), 100, DateTime.Now,  TestUtilities.GetMatchedWith(new[] {0, 1, 2, 3, 4}, new[] {0, 1, 2, 3, 4}).EstimateCoverage(firstQueryLength, trackLength, 1, permittedGap))
            }, firstQueryLength, 0);

            Assert.IsFalse(first.SuccessEntries.Any());
            Assert.IsFalse(first.DidNotPassThresholdEntries.Any());
            
            for (int i = 0; i < 5; ++i)
            {
                var second = aggregator.Consume(new ResultEntry[0], 1, 0);
                
                Assert.IsFalse(second.SuccessEntries.Any(), $"Iteration {i}");
                Assert.IsFalse(second.DidNotPassThresholdEntries.Any(), $"Iteration {i}");
            }

            var third = aggregator.Consume(new ResultEntry[0], 1, 0);
            
            Assert.IsFalse(third.SuccessEntries.Any());
            Assert.IsTrue(third.DidNotPassThresholdEntries.Any());
        }
 private static void SimulateEmptyResults(StatefulRealtimeResultEntryAggregator aggregator, ICollection <ResultEntry> success, ICollection <ResultEntry> filtered)
 {
     for (int i = 0; i < 10; ++i)
     {
         var aggregated = aggregator.Consume(new ResultEntry[0], 1.48d);
         AddAll(aggregated.SuccessEntries, success);
         AddAll(aggregated.DidNotPassThresholdEntries, filtered);
     }
 }
        public void ShouldNotFailWithNullObjectPass()
        {
            var aggregator = new StatefulRealtimeResultEntryAggregator(new QueryMatchLengthFilter(5d), 2d);

            var result = aggregator.Consume(null, 0d);

            Assert.IsFalse(result.SuccessEntries.Any());
            Assert.IsFalse(result.DidNotPassThresholdEntries.Any());
        }
        public void ShouldNotFailWithNullObjectPass()
        {
            var aggregator = new StatefulRealtimeResultEntryAggregator(new TrackMatchLengthEntryFilter(5d), GetConfigWithPermittedGap(2d));

            var result = aggregator.Consume(null, 0, 0);
            
            Assert.IsFalse(result.SuccessEntries.Any());
            Assert.IsFalse(result.DidNotPassThresholdEntries.Any());
        }
        private async Task <double> QueryAndHash(CancellationToken cancellationToken, IQueryFingerprintService service)
        {
            var realtimeSamplesAggregator = new RealtimeAudioSamplesAggregator(configuration.Stride, MinSamplesForOneFingerprint);
            var resultsAggregator         = new StatefulRealtimeResultEntryAggregator(configuration.ResultEntryFilter, configuration.PermittedGap);

            double queryLength = 0d;

            while (!realtimeCollection.IsFinished && !cancellationToken.IsCancellationRequested)
            {
                AudioSamples audioSamples;
                try
                {
                    if (!realtimeCollection.TryTake(out audioSamples, configuration.MillisecondsDelay, cancellationToken))
                    {
                        continue;
                    }
                }
                catch (OperationCanceledException)
                {
                    return(queryLength);
                }

                if (audioSamples.SampleRate != SupportedFrequency)
                {
                    throw new ArgumentException($"{nameof(audioSamples)} should be provided down sampled to {SupportedFrequency}Hz");
                }

                queryLength += audioSamples.Duration;

                var prefixed = realtimeSamplesAggregator.Aggregate(audioSamples);
                var hashes   = await CreateQueryFingerprints(fingerprintCommandBuilder, prefixed);

                InvokeHashedFingerprintsCallback(hashes);

                if (!TryQuery(service, hashes, out var queryResults))
                {
                    continue;
                }

                foreach (var queryResult in queryResults)
                {
                    var aggregatedResult = resultsAggregator.Consume(queryResult.ResultEntries, prefixed.Duration);
                    InvokeSuccessHandler(aggregatedResult);
                    InvokeDidNotPassFilterHandler(aggregatedResult);
                }
            }

            return(queryLength);
        }
Esempio n. 9
0
        private async Task <double> QueryAndHash(CancellationToken cancellationToken, IQueryFingerprintService service)
        {
            var realtimeSamplesAggregator = new RealtimeAudioSamplesAggregator(configuration.Stride, MinSamplesForOneFingerprint);
            var resultsAggregator         = new StatefulRealtimeResultEntryAggregator(configuration.ResultEntryFilter, configuration.QueryConfiguration);

            double       queryLength = 0d;
            AudioSamples?audioSamples;

            while ((audioSamples = await realtimeCollection.TryReadAsync(cancellationToken)) != null)
            {
                if (audioSamples.SampleRate != SupportedFrequency)
                {
                    throw new ArgumentException($"{nameof(audioSamples)} should be provided down sampled to {SupportedFrequency}Hz");
                }

                queryLength += audioSamples.Duration;

                var prefixed = realtimeSamplesAggregator.Aggregate(audioSamples);
                var hashes   = await CreateQueryFingerprints(fingerprintCommandBuilder, prefixed);

                InvokeHashedFingerprintsCallback(hashes);

                if (!TryQuery(service, hashes, out var queryResults))
                {
                    continue;
                }

                foreach (var queryResult in queryResults)
                {
                    var aggregatedResult = resultsAggregator.Consume(queryResult.ResultEntries, hashes.DurationInSeconds, audioSamples.Duration - prefixed.Duration);
                    InvokeSuccessHandler(aggregatedResult);
                    InvokeDidNotPassFilterHandler(aggregatedResult);
                }
            }

            var purged = resultsAggregator.Consume(Enumerable.Empty <ResultEntry>(), 0, 0);

            InvokeSuccessHandler(purged);
            InvokeDidNotPassFilterHandler(purged);
            return(queryLength);
        }
Esempio n. 10
0
        public void ShouldWaitAsGapPermits()
        {
            var aggregator = new StatefulRealtimeResultEntryAggregator(new QueryMatchLengthFilter(10d), 2d);
            var first      = aggregator.Consume(new[] { new ResultEntry(GetTrack(), .95d, 120, DateTime.Now, 5d, 0d, 2d, 2d, 10d, -10d) }, 5d);

            Assert.IsFalse(first.SuccessEntries.Any());
            Assert.IsFalse(first.DidNotPassThresholdEntries.Any());

            for (int i = 0; i < 10; ++i)
            {
                var second = aggregator.Consume(new ResultEntry[0], 0.2d);

                Assert.IsFalse(second.SuccessEntries.Any());
                Assert.IsFalse(second.DidNotPassThresholdEntries.Any());
            }

            var third = aggregator.Consume(new ResultEntry[0], 0.2d);

            Assert.IsFalse(third.SuccessEntries.Any());
            Assert.IsTrue(third.DidNotPassThresholdEntries.Any());
        }
        public void ShouldWaitAsGapPermits()
        {
            double permittedGap = 2d;
            var    aggregator   = new StatefulRealtimeResultEntryAggregator(new QueryMatchLengthFilter(10d), permittedGap);
            var    first        = aggregator.Consume(new[] { new ResultEntry(GetTrack(), 100, DateTime.Now, TestUtilities.GetMatchedWith(new[] { 1, 2, 3 }, new[] { 1, 2, 3 }).EstimateCoverage(5, 3, 1, permittedGap)) }, 5d);

            Assert.IsFalse(first.SuccessEntries.Any());
            Assert.IsFalse(first.DidNotPassThresholdEntries.Any());

            for (int i = 0; i < 10; ++i)
            {
                var second = aggregator.Consume(new ResultEntry[0], 0.2d);

                Assert.IsFalse(second.SuccessEntries.Any());
                Assert.IsFalse(second.DidNotPassThresholdEntries.Any());
            }

            var third = aggregator.Consume(new ResultEntry[0], 0.2d);

            Assert.IsFalse(third.SuccessEntries.Any());
            Assert.IsTrue(third.DidNotPassThresholdEntries.Any());
        }
        private async Task <double> QueryAndHash(CancellationToken cancellationToken, IQueryFingerprintService service)
        {
            var realtimeSamplesAggregator = new RealtimeAudioSamplesAggregator(configuration.Stride, MinSamplesForOneFingerprint);
            var resultsAggregator         = new StatefulRealtimeResultEntryAggregator(configuration.ResultEntryFilter, configuration.QueryConfiguration);

            double queryLength = 0d;

            await foreach (var audioSamples in realtimeCollection.WithCancellation(cancellationToken))
            {
                if (audioSamples.SampleRate != SupportedFrequency)
                {
                    throw new ArgumentException($"{nameof(audioSamples)} should be provided down sampled to {SupportedFrequency}Hz");
                }

                queryLength += audioSamples.Duration;

                var prefixed = realtimeSamplesAggregator.Aggregate(audioSamples);
                var hashes   = (await CreateQueryFingerprints(fingerprintCommandBuilder, prefixed)).WithStreamId(streamId);
                hashes = hashesInterceptor(hashes).WithTimeOffset(audioSamples.Duration - hashes.DurationInSeconds);

                if (!TryQuery(service, hashes, out var queryResults))
                {
                    continue;
                }

                foreach (var queryResult in queryResults)
                {
                    var aggregatedResult = resultsAggregator.Consume(queryResult.ResultEntries, queryResult.QueryHashes.DurationInSeconds, queryResult.QueryHashes.TimeOffset);
                    InvokeSuccessHandler(aggregatedResult);
                    InvokeDidNotPassFilterHandler(aggregatedResult);
                }
            }

            var purged = resultsAggregator.Purge();

            InvokeSuccessHandler(purged);
            InvokeDidNotPassFilterHandler(purged);
            return(queryLength);
        }