public FingerprintSignature CreateAudioFingerprint(string key, string filename, int startPositionInMS, int toReadInMS) { SpectrogramConfig spectrogramConfig = new DefaultSpectrogramConfig(); AudioSamples samples = null; try { // First read audio file and downsample it to mono 5512hz samples = audioEngine.ReadMonoFromFile(filename, spectrogramConfig.SampleRate, startPositionInMS, toReadInMS); } catch { return(null); } // No slice the audio is chunks seperated by 11,6 ms (5512hz 11,6ms = 64 samples!) // An with length of 371ms (5512kHz 371ms = 2048 samples [rounded]) FingerprintSignature fingerprint = audioEngine.CreateFingerprint(samples, spectrogramConfig); if (fingerprint != null) { fingerprint.Reference = key; } return(fingerprint); }
/// <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 = 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 = SimilarityUtility.HammingDistance(f1.SubFingerprint(i), f2.SubFingerprint(i)); if (bits > 0) { BER += bits; } } // for i return(BER); }
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); }
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; } }