Beispiel #1
0
        public List <Match> FindMatches(SubFingerprintHash hash)
        {
            List <Match> matches = new List <Match>();
            List <SubFingerprintLookupEntry> entries = collisionMap.GetValues(hash);

            //Debug.WriteLine("Finding matches...");

            // compare each track with each other
            int cycle = 1;

            for (int x = 0; x < entries.Count; x++)
            {
                SubFingerprintLookupEntry entry1 = entries[x];
                for (int y = cycle; y < entries.Count; y++)
                {
                    SubFingerprintLookupEntry entry2 = entries[y];
                    if (entry1.AudioTrack != entry2.AudioTrack)   // don't compare tracks with themselves
                    //Debug.WriteLine("Comparing " + entry1.AudioTrack.Name + " with " + entry2.AudioTrack.Name + ":");
                    {
                        if (store[entry1.AudioTrack].Count - entry1.Index < fingerprintSize ||
                            store[entry2.AudioTrack].Count - entry2.Index < fingerprintSize)
                        {
                            // the end of at least one track has been reached and there are not enough hashes left
                            // to do a fingerprint comparison
                            continue;
                        }

                        // sum up the bit errors
                        List <SubFingerprintHash> track1Hashes = store[entry1.AudioTrack];
                        List <SubFingerprintHash> track2Hashes = store[entry2.AudioTrack];
                        uint bitErrors = 0;
                        for (int s = 0; s < fingerprintSize; s++)
                        {
                            SubFingerprintHash track1Hash = track1Hashes[entry1.Index + s];
                            SubFingerprintHash track2Hash = track2Hashes[entry2.Index + s];
                            if (track1Hash.Value == 0 || track2Hash.Value == 0)
                            {
                                bitErrors = (uint)fingerprintSize * 32;
                                break;
                            }
                            // skip fingerprints with hashes that are zero, since it is probably from
                            // a track section with silence
                            // by setting the bitErrors to the maximum, the match will not be added
                            bitErrors += track1Hash.HammingDistance(track2Hash);
                        }

                        float bitErrorRate = bitErrors / (float)(fingerprintSize * 32); // sub-fingerprints * 32 bits
                        //Debug.WriteLine("BER: " + bitErrorRate + " <- " + (bitErrorRate < threshold ? "MATCH!!!" : "no match"));
                        if (bitErrorRate < threshold)
                        {
                            matches.Add(new Match {
                                Similarity = 1 - bitErrorRate,
                                Track1     = entry1.AudioTrack,
                                Track1Time = SubFingerprintIndexToTimeSpan(entry1.Index),
                                Track2     = entry2.AudioTrack,
                                Track2Time = SubFingerprintIndexToTimeSpan(entry2.Index),
                                Source     = matchSourceName
                            });
                        }
                    }
                }
                cycle++;
            }

            //Debug.WriteLine("finished");
            return(matches);
        }