Beispiel #1
0
        private static float GetGapSize(ResultEntry left, float fingerprintLength)
        {
            var   lastMatch = left.Coverage.BestPath.Last();
            float endsAt    = lastMatch.QueryMatchAt + fingerprintLength;

            return((float)left.Coverage.QueryLength - endsAt);
        }
Beispiel #2
0
        private static double CalculateNewQueryLength(ResultEntry a, ResultEntry b)
        {
            if (Math.Abs(a.TrackMatchStartsAt - b.TrackMatchStartsAt) < 0.0001)
            {
                // same start
                return(a.QueryLength);
            }

            // t --------------
            // a      ---------
            // b   --------
            if (a.TrackMatchStartsAt > b.TrackMatchStartsAt)
            {
                double diff = a.TrackMatchStartsAt - b.TrackMatchStartsAt;
                if (diff > b.TrackMatchStartsAt)
                {
                    return(a.QueryLength + b.QueryLength);
                }

                return(diff + a.QueryLength);
            }
            else
            {
                // t -------------
                // a  ------
                // b      -----
                double diff = b.TrackMatchStartsAt - a.TrackMatchStartsAt;
                if (diff > a.QueryLength)
                {
                    return(a.QueryLength + b.QueryLength);
                }

                return(diff + b.QueryLength);
            }
        }
Beispiel #3
0
        public static ResultEntry MergeWith(this ResultEntry entry, ResultEntry with)
        {
            if (!entry.Track.Equals(with.Track))
            {
                throw new ArgumentException($"{nameof(with)} merging entries should correspond to the same track");
            }

            double avgConfidence = Math.Min((entry.Confidence + with.Confidence) / 2, 1d);

            var queryMatchStartsAt = entry.TrackMatchStartsAt < with.TrackMatchStartsAt ? entry.QueryMatchStartsAt : with.QueryMatchStartsAt;
            var trackMatchStartsAt = entry.TrackMatchStartsAt < with.TrackMatchStartsAt ? entry.TrackMatchStartsAt : with.TrackMatchStartsAt;
            var trackStartsAt      = entry.TrackMatchStartsAt < with.TrackMatchStartsAt ? entry.TrackStartsAt : with.TrackStartsAt;
            var matchedAt          = entry.MatchedAt < with.MatchedAt ? entry.MatchedAt : with.MatchedAt;

            return(new ResultEntry(entry.Track,
                                   avgConfidence,
                                   entry.Score + with.Score,
                                   matchedAt,
                                   CalculateNewQueryLength(entry, with),
                                   queryMatchStartsAt,
                                   CalculateNewQueryCoverage(entry, with),
                                   CalculateNewMatchLength(entry, with),
                                   trackMatchStartsAt,
                                   trackStartsAt));
        }
        public PendingResultEntry Wait(double length)
        {
            var newCoverage = new Coverage(Entry.Coverage.BestPath, Entry.QueryLength + length, Entry.Coverage.TrackLength, Entry.Coverage.FingerprintLength, Entry.Coverage.PermittedGap);
            var resultEntry = new ResultEntry(Entry.Track, Entry.Score, Entry.MatchedAt, newCoverage);

            return(new PendingResultEntry(resultEntry, waiting + length));
        }
Beispiel #5
0
        public PendingResultEntry Wait(double length)
        {
            var newQueryLength = Entry.QueryLength + length;
            var resultEntry    = new ResultEntry(Entry.Track, Entry.Confidence, Entry.Score,
                                                 Entry.MatchedAt, newQueryLength, Entry.QueryMatchStartsAt, Entry.CoverageWithPermittedGapsLength,
                                                 Entry.DiscreteCoverageLength, Entry.TrackMatchStartsAt, Entry.TrackStartsAt);

            return(new PendingResultEntry(resultEntry, waiting + length));
        }
        public ResultEntry Validate(
            ResultEntry result,
            IStride validationStride,
            string pathToAudioFile,
            IModelService modelService,
            IAudioService audioService,
            int topWavelets,
            int thresholdVotes)
        {
            double startAt = result.TrackStartsAt, length = result.QueryLength - result.TrackStartsAt;

            if (startAt + result.Track.Length < result.QueryLength)
            {
                length = result.Track.Length;
            }

            var newResult = queryCommandBuilder.BuildQueryCommand()
                            .From(pathToAudioFile, length, startAt).WithConfigs(
                config =>
            {
                config.Stride      = validationStride;
                config.TopWavelets = topWavelets;
            },
                queryConfig =>
            {
                queryConfig.ThresholdVotes = thresholdVotes;
            })
                            .UsingServices(modelService, audioService)
                            .Query()
                            .Result;

            if (!newResult.ContainsMatches)
            {
                return(result);
            }

            var newEntry = newResult.BestMatch;

            if (newEntry.Confidence > result.Confidence)
            {
                return(new ResultEntry(
                           newEntry.Track,
                           newEntry.QueryMatchStartsAt,
                           newEntry.QueryMatchLength,
                           newEntry.TrackMatchStartsAt,
                           newEntry.TrackStartsAt + result.TrackStartsAt,
                           newEntry.Confidence,
                           newEntry.HammingSimilaritySum,
                           newEntry.QueryLength,
                           newEntry.BestMatch));
            }

            return(result);
        }
        private static ResultEntry MergeWith(ResultEntry entry, ResultEntry with)
        {
            if (!entry.Track.Equals(with.Track))
            {
                throw new ArgumentException($"{nameof(with)} merging entries should correspond to the same track");
            }

            var mergedCoverage = MergeWith(entry.Coverage, with.Coverage);
            var matchedAt      = entry.MatchedAt < with.MatchedAt ? entry.MatchedAt : with.MatchedAt;

            return(new ResultEntry(entry.Track, entry.Score + with.Score, matchedAt, mergedCoverage));
        }
Beispiel #8
0
        private static double CalculateNewMatchLength(ResultEntry a, ResultEntry b)
        {
            var first  = a.TrackMatchStartsAt <= b.TrackMatchStartsAt ? a : b;
            var second = a.TrackMatchStartsAt <= b.TrackMatchStartsAt ? b : a;

            if (first.TrackMatchStartsAt + first.DiscreteCoverageLength >= second.TrackMatchStartsAt + second.DiscreteCoverageLength)
            {
                return(first.DiscreteCoverageLength);
            }

            if (first.TrackMatchStartsAt <= second.TrackMatchStartsAt && first.TrackMatchStartsAt + first.DiscreteCoverageLength >= second.TrackMatchStartsAt)
            {
                return(second.DiscreteCoverageLength - first.TrackMatchStartsAt + second.TrackMatchStartsAt);
            }

            return(first.DiscreteCoverageLength + second.DiscreteCoverageLength);
        }
        public ResultEntry Validate(
            ResultEntry result,
            IStride validationStride,
            string pathToAudioFile,
            IModelService modelService,
            IAudioService audioService)
        {
            double startAt = result.TrackStartsAt, length = result.QueryLength - result.TrackStartsAt;

            if (startAt + result.Track.Length < result.QueryLength)
            {
                length = result.Track.Length;
            }

            var newResult = queryCommandBuilder.BuildQueryCommand()
                                               .From(pathToAudioFile, length, startAt)
                                               .WithFingerprintConfig(config => config.Stride = validationStride)
                                               .UsingServices(modelService, audioService)
                                               .Query()
                                               .Result;

            if (!newResult.ContainsMatches)
            {
                return result;
            }

            var newEntry = newResult.BestMatch;
            if (newEntry.Confidence > result.Confidence)
            {
                return new ResultEntry(
                    newEntry.Track,
                    newEntry.QueryMatchStartsAt,
                    newEntry.QueryMatchLength,
                    newEntry.TrackMatchStartsAt,
                    newEntry.TrackStartsAt + result.TrackStartsAt,
                    newEntry.Confidence,
                    newEntry.HammingSimilaritySum,
                    newEntry.QueryLength,
                    newEntry.BestMatch);
            }

            return result;
        }
        private RealtimeQueryResult PurgeCompleted(IEnumerable <ResultEntry> entries, double queryLength, double queryOffset)
        {
            var set = new HashSet <string>(entries.Select(_ => _.Track.Id));

            foreach (var entry in trackEntries.Where(_ => !set.Contains(_.Key)))
            {
                var old     = entry.Value;
                var updated = new ResultEntry(old.Track, old.Score, old.MatchedAt, new Coverage(old.Coverage.BestPath, old.Coverage.QueryLength + queryLength + queryOffset, old.Coverage.TrackLength, old.Coverage.FingerprintLength, old.Coverage.PermittedGap));
                trackEntries.TryUpdate(entry.Key, updated, old);
            }

            var completed       = new List <ResultEntry>();
            var cantWaitAnymore = new HashSet <ResultEntry>();

            foreach (KeyValuePair <string, ResultEntry> pair in trackEntries)
            {
                if (!completionStrategy.CanContinueInNextQuery(pair.Value) && trackEntries.TryRemove(pair.Key, out var entry))
                {
                    // can't continue in the next query
                    if (realtimeResultEntryFilter.Pass(entry, false))
                    {
                        // passed entry filter
                        completed.Add(entry);
                    }
                    else
                    {
                        // did not pass filter
                        cantWaitAnymore.Add(entry);
                    }
                }
                else if (realtimeResultEntryFilter.Pass(pair.Value, true) && trackEntries.TryRemove(pair.Key, out _))
                {
                    // can continue, but realtime result entry filter takes precedence
                    completed.Add(pair.Value);
                }
            }

            return(new RealtimeQueryResult(Sorted(completed), Sorted(cantWaitAnymore)));
        }
Beispiel #11
0
        private static double CalculateNewQueryCoverage(ResultEntry a, ResultEntry b)
        {
            var first  = a.TrackMatchStartsAt <= b.TrackMatchStartsAt ? a : b;
            var second = a.TrackMatchStartsAt <= b.TrackMatchStartsAt ? b : a;

            if (first.TrackMatchStartsAt + first.CoverageWithPermittedGapsLength >= second.TrackMatchStartsAt + second.CoverageWithPermittedGapsLength)
            {
                // a ---------
                // b   -----
                return(first.CoverageWithPermittedGapsLength);
            }

            if (first.TrackMatchStartsAt <= second.TrackMatchStartsAt && first.TrackMatchStartsAt + first.CoverageWithPermittedGapsLength >= second.TrackMatchStartsAt)
            {
                // a     -------
                // b          -------
                return(second.CoverageWithPermittedGapsLength - first.TrackMatchStartsAt + second.TrackMatchStartsAt);
            }

            // a  -------
            // b            ------
            // not glued on purpose
            return(first.CoverageWithPermittedGapsLength + second.CoverageWithPermittedGapsLength);
        }
Beispiel #12
0
 private bool ContainsSequenceInfo(ResultEntry bestMatch)
 {
     return(!bestMatch.SequenceStart.Equals(0) && !bestMatch.SequenceLength.Equals(0));
 }
Beispiel #13
0
 public PendingResultEntry(ResultEntry entry, double waiting = 0)
 {
     Entry        = entry;
     InternalUid  = Guid.NewGuid().ToString();
     this.waiting = waiting;
 }
Beispiel #14
0
 private bool CanSwallow(ResultEntry next)
 {
     return(Entry.TrackMatchStartsAt <= next.TrackMatchStartsAt && TrackMatchEndsAt >= next.TrackMatchStartsAt + next.CoverageWithPermittedGapsLength);
 }
Beispiel #15
0
 private bool TrackMatchOverlaps(ResultEntry next, double permittedGap)
 {
     return(TrackMatchEndsAt >= next.TrackMatchStartsAt - permittedGap && next.TrackMatchStartsAt + permittedGap >= TrackMatchEndsAt);
 }
 private bool ContainsSequenceInfo(ResultEntry bestMatch)
 {
     return !bestMatch.SequenceStart.Equals(0) && !bestMatch.SequenceLength.Equals(0);
 }