Esempio n. 1
0
        /// <summary>
        /// Creates a lookup dictionary from the fingerprintsignature. Key is the hash an value is an array of int
        /// pointing (index) to where the hash can be found using "SubFingerprint(int index)"
        /// </summary>
        public static Dictionary <int, int[]> CreateLookupDictionary(FingerprintAcoustID fs)
        {
            int[] hashes = fs.SignatureInt32;

            Dictionary <int, int[]> subFingerLookup = new Dictionary <int, int[]>(hashes.Length);

            for (int index = 0; index < hashes.Length; index++)
            {
                int h = hashes[index] & unchecked ((int)0xfffffff0);

                int[] data = new int[1] {
                    index
                };

                if (subFingerLookup.ContainsKey(h))
                {
                    subFingerLookup[h] = CombineArrays(subFingerLookup[h], data);
                }
                else
                {
                    subFingerLookup.Add(h, data);
                }
            } //foreach

            return(subFingerLookup);
        }
Esempio n. 2
0
        public static float MatchFingerprint(FingerprintAcoustID finger1, FingerprintAcoustID finger2, int maxoffset = 0)
        {
            float score = 0.0f;

            int[] f1     = finger1.SignatureInt32;
            int   f1size = f1.Length;

            int[] f2        = finger2.SignatureInt32;
            int   f2size    = f2.Length;
            int   numcounts = f1size + f2size + 1;

            ushort[] aoffsets = new ushort[MATCH_MASK + 1];
            ushort[] boffsets = new ushort[MATCH_MASK + 1];

            // Zorg dat er een limiet is
            if (f1size > aoffsets.Length)
            {
                f1size = aoffsets.Length;
            }
            if (f2size > boffsets.Length)
            {
                f2size = boffsets.Length;
            }

            // ------------------------------------------------------------
            // YN aanpassing 2015-11-02 gedaan (zoeken duurt anders te lang
            // zie titelnummer_id=944086
            // Lookup tabel aanmaken ????
            for (ushort i = 0; i < f1size; i++)
            {
                aoffsets[MatchStrip(f1[i])] = i;
            }
            for (ushort i = 0; i < f2size; i++)
            {
                boffsets[MatchStrip(f2[i])] = i;
            }
            // ------------------------------------------------------------


            int topcount  = 0;
            int topoffset = 0;

            ushort[] counts = new ushort[numcounts];
            for (int i = 0; i < MATCH_MASK; i++)
            {
                if (aoffsets[i] != 0 && boffsets[i] != 0)
                {
                    int offset = aoffsets[i] - boffsets[i];
                    if (maxoffset == 0 || (-maxoffset <= offset && offset <= maxoffset))
                    {
                        offset += f2size;
                        counts[offset]++;
                        if (counts[offset] > topcount)
                        {
                            topcount  = counts[offset];
                            topoffset = offset;
                        }
                    }
                }
            } //for i

            topoffset -= f2size;

            int f1Offset = 0;
            int f2Offset = 0;
            int minsize  = Math.Min(f1size, f2size) & ~1;

            if (topoffset < 0)
            {
                f2Offset -= topoffset;
                f2size    = Math.Max(0, f2size + topoffset);
            }
            else
            {
                f1Offset += topoffset;
                f1size    = Math.Max(0, f1size - topoffset);
            }

            int size = Math.Min(f1size, f2size) / 2;

            if (size == 0 || minsize == 0)
            {
                System.Diagnostics.Trace.WriteLine("acoustid_compare2: empty matching subfingerprint");
                return(0.0f);
            }


            ushort[] seen = aoffsets;

            int f1unique = 0;

            // clear
            for (int i = 0; i < UNIQ_MASK; i++)
            {
                seen[i] = 0;
            }
            for (int i = 0; i < f1size; i++)
            {
                int key = UniqueStrip(f1[i]);
                if (seen[key] == 0)
                {
                    f1unique++;
                    seen[key] = 1;
                }
            }

            int f2unique = 0;

            // clear
            for (int i = 0; i < UNIQ_MASK; i++)
            {
                seen[i] = 0;
            }
            for (int i = 0; i < f2size; i++)
            {
                int key = UniqueStrip(f2[i]);
                if (seen[key] == 0)
                {
                    f2unique++;
                    seen[key] = 1;
                }
            }

            float diversity = (float)Math.Min(Math.Min(1.0f, (float)(f1unique + 10) / f1size + 0.5f), Math.Min(1.0, (float)(f2unique + 10) / f2size + 0.5f));


            int BER = 0;

            for (int i = 0; i < size; i++)
            {
                int bits = AudioFingerprint.Math.SimilarityUtility.HammingDistance(unchecked ((uint)f1[i]), unchecked ((uint)f2[i]));
                if (bits > 0)
                {
                    BER += bits;
                }
            } //for i
            score = (size * 2.0f / minsize) * (1.0f - 2.0f * (float)BER / (64 * size));
            if (score < 0.0f)
            {
                score = 0.0f;
            }

            if (diversity < 1.0)
            {
                float newscore = (float)Math.Pow(score, 8.0f - 7.0f * diversity);
                System.Diagnostics.Trace.WriteLine(string.Format("acoustid_compare2: scaling score because of duplicate items, {0:#0:00} => {1:#0:00}", score, newscore));
                score = newscore;
            }

            return(score);
        }