/// <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 <uint, int[]> CreateLookupDictionary(FingerprintSignature fs, bool filterNoneRandomHashes = true)
        {
            Dictionary <uint, int[]> subFingerLookup = new Dictionary <uint, int[]>(fs.SubFingerprintCount);

            for (int index = 0; index < fs.SubFingerprintCount; index++)
            {
                uint h = BitConverter.ToUInt32(fs.Signature, index * 4);
                if (filterNoneRandomHashes)
                {
                    int bits = AudioFingerprint.Math.SimilarityUtility.HammingDistance(h, 0);
                    if (bits < 10 || bits > 22) // 5 27  (10 22)
                    {
                        // try further in the fingerprint
                        continue;
                    }
                }
                int[] data = new int[1] {
                    index
                };

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

            return(subFingerLookup);
        }
        public static MMHashtable CreateMMHashtable(FingerprintSignature fs, bool filterNoneRandomHashes = true)
        {
            Dictionary <uint, int[]> dict = CreateLookupDictionary(fs, filterNoneRandomHashes);
            MMHashtable mh = new MMHashtable(fs.SubFingerprintCount, fs.SubFingerprintCount);

            foreach (KeyValuePair <uint, int[]> entry in dict)
            {
                mh.Add(entry.Key, entry.Value);
            } //foreach
            byte[] byteArray = mh.HashtableAsByteArray;

            return(mh);
        }
        /// <summary>
        /// Calculate the BER between 2 fingerprints
        /// </summary>
        public static int BER(FingerprintSignature f1, FingerprintSignature f2)
        {
            if (f1.SubFingerprintCount != f2.SubFingerprintCount)
            {
                return(-1);
            }

            // length of both needs to be equal!
            int BER = 0; // Bit Error Rate

            for (int i = 0; i < f1.SubFingerprintCount; i++)
            {
                int bits = AudioFingerprint.Math.SimilarityUtility.HammingDistance(f1.SubFingerprint(i), f2.SubFingerprint(i));
                if (bits > 0)
                {
                    BER += bits;
                }
            } // for i

            return(BER);
        }
        /// <summary>
        /// Creates a lookup dictionary from the fingatprintsignature. 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 <uint, int[]> CreateLookupDictionary(FingerprintSignature fs)
        {
            Dictionary <uint, int[]> subFingerLookup = new Dictionary <uint, int[]>(fs.SubFingerprintCount);

            for (int index = 0; index < fs.SubFingerprintCount; index++)
            {
                uint  h    = BitConverter.ToUInt32(fs.Signature, index * 4);
                int[] data = new int[1] {
                    index
                };

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

            return(subFingerLookup);
        }
        public static FingerprintSignature ReadHashFromText(string filename)
        {
            filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(filename), System.IO.Path.GetFileNameWithoutExtension(filename));

            List <uint>   data = new List <uint>();
            List <byte[]> r    = new List <byte[]>();

            using (System.IO.StreamReader reader = new System.IO.StreamReader(System.IO.File.Open(filename + ".hash", System.IO.FileMode.Open)))
            {
                bool   doHash = true;
                long   countR = 0;
                byte[] tmpR   = new byte[32];

                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();
                    if (line.Length > 0)
                    {
                        if (line == "---")
                        {
                            doHash = false;
                            continue; // op naar volgende regel voor reliabilty
                        }

                        if (doHash)
                        {
                            data.Add(Convert.ToUInt32(line));
                        }
                        else
                        {
                            if (countR >= 32)
                            {
                                r.Add(tmpR);
                                tmpR   = new byte[32];
                                countR = 0;
                            }

                            tmpR[countR] = Convert.ToByte(line);
                            countR++;
                        }
                    }
                } //while

                if (countR > 0)
                {
                    r.Add(tmpR);
                    tmpR   = null;
                    countR = 0;
                }
            } //using

            byte[] signature = new byte[data.Count * sizeof(uint)];
            for (int i = 0; i < data.Count; i++)
            {
                byte[] b = BitConverter.GetBytes(data[i]);
                Buffer.BlockCopy(b, 0, signature, i * sizeof(uint), b.Length);
            } //for i

            byte[] reliabilities = new byte[r.Count * 32];
            for (int i = 0; i < r.Count; i++)
            {
                Buffer.BlockCopy(r[i], 0, reliabilities, i * 32, r[i].Length);
            } //for i

            FingerprintSignature fs = new FingerprintSignature(System.IO.Path.GetFileNameWithoutExtension(filename), 0, signature, (long)(signature.Length * 11.6));

            fs.reliabilities = reliabilities;

            return(fs);
        }
Example #6
0
        public FingerprintSignature CreateFingerprint(AudioSamples audioSamples, SpectrogramConfig configuration)
        {
            absEnergy      = new double[(Frequencies.Length - 1) * 4];   // number of frequencies bands (33)
            lowpassFilters = new LowpassFilters(Frequencies.Length - 1); // 33 bands
            try
            {
                int width = (audioSamples.Samples.Length - configuration.WdftSize) / configuration.Overlap;  // WdftSize=2048 / Overlap=64
                if (width < 1)
                {
                    return(null);
                }

                // reserve memory for 32 bit fingerprint hashes
                byte[] hashes        = new byte[width * sizeof(uint)];
                byte[] reliabilities = new byte[width * 32]; // elke subfinger (32 bits) heeft voor elke bit een waarde tussen 0 en 31 voor relibility (dus 5 bits), we ronden dit af naar 1 byte
                FingerprintSignature fingerprintSignature = new FingerprintSignature(null, 0, hashes, (long)(width * 11.6));
                fingerprintSignature.Reliabilities = reliabilities;

                // Calculate a hamming windows
                float[] hammingWindow = new float[configuration.WdftSize];
                for (int i = 0; i < hammingWindow.Length; i++)
                {
                    // Hamming (watch it peak is at beginning not as in real hamming in the middle)
                    hammingWindow[i] = 0.54f + 0.46f * (float)System.Math.Cos((6.283f * (float)i / hammingWindow.Length));
                    //hammingWindow[i] = 0.54f - (0.46f * (float)System.Math.Cos(((6.283f * (float)i) / (hammingWindow.Length - 1))));  // real hamming window
                } //for

                int[]   frequenciesRange = Frequencies; // 34 freqencies
                float[] samples          = new float[configuration.WdftSize];

                for (int i = 0; i < width; i++)
                {
                    if (((samples.Length - 1) + (i * configuration.Overlap)) >= audioSamples.Samples.Length)
                    {
                        // we hebben niet voldoende data meer!
                        // dus we stoppen nu en nemen het "laaste" stukje niet mee!
                        break;
                    }

                    for (int j = 0; j < samples.Length; j++)
                    {
                        samples[j] = audioSamples.Samples[j + (i * configuration.Overlap)] * hammingWindow[j];
                    } // for j

                    float[] complexSignal = fftService.FFTForward(samples, 0, configuration.WdftSize);
                    byte[]  reliability;
                    uint    subFingerprint = CalculateSubFingerprint(complexSignal, frequenciesRange, 5512, out reliability);

                    Buffer.BlockCopy(BitConverter.GetBytes(subFingerprint), 0, hashes, i * sizeof(uint), sizeof(uint));
                    Buffer.BlockCopy(reliability, 0, reliabilities, i * reliability.Length, reliability.Length);
                    // sequencenumber = i;
                    // timestamp = (i / audioSamples.Samples.Length) * configuration.SampleRate
                } //for

                return(fingerprintSignature);
            }
            finally
            {
                absEnergy      = null;
                lowpassFilters = null;
            }
        }