public List <bool[]> CreateFingerprintsFromAudioSamples(float[] samples, WorkUnitParameterObject param, out double[][] logSpectrogram) { IFingerprintingConfiguration configuration = param.FingerprintingConfiguration; AudioServiceConfiguration audioServiceConfiguration = new AudioServiceConfiguration { LogBins = configuration.LogBins, LogBase = configuration.LogBase, MaxFrequency = configuration.MaxFrequency, MinFrequency = configuration.MinFrequency, Overlap = configuration.Overlap, SampleRate = configuration.SampleRate, WindowSize = configuration.WindowSize, NormalizeSignal = configuration.NormalizeSignal, UseDynamicLogBase = configuration.UseDynamicLogBase }; // store the log spectrogram in the out variable logSpectrogram = AudioService.CreateLogSpectrogram( samples, configuration.WindowFunction, audioServiceConfiguration); return(this.CreateFingerprintsFromLogSpectrum( logSpectrogram, configuration.Stride, configuration.FingerprintLength, configuration.Overlap, configuration.TopWavelets)); }
public List <bool[]> CreateFingerprintsFromAudioFile(WorkUnitParameterObject param, out double[][] logSpectrogram) { float[] samples = AudioService.ReadMonoFromFile( param.PathToAudioFile, param.FingerprintingConfiguration.SampleRate, param.MillisecondsToProcess, param.StartAtMilliseconds); return(CreateFingerprintsFromAudioSamples(samples, param, out logSpectrogram)); }
/// <summary> /// Find Similar Tracks using passed audio samples as input and return a Dictionary /// </summary> /// <param name="lshHashTables">Number of hash tables from the database</param> /// <param name="lshGroupsPerKey">Number of groups per hash table</param> /// <param name="thresholdTables">Minimum number of hash tables that must be found for one signature to be considered a candidate (0 and 1 = return all candidates, 2+ = return only exact matches)</param> /// <param name="param">Audio File Work Unit Parameter Object</param> /// <returns>a dictionary of perceptually similar tracks</returns> public Dictionary <Track, double> FindSimilarFromAudioSamples( int lshHashTables, int lshGroupsPerKey, int thresholdTables, WorkUnitParameterObject param) { DbgTimer t = new DbgTimer(); t.Start(); // Get fingerprints double[][] logSpectrogram; List <bool[]> signatures = fingerprintService.CreateFingerprintsFromAudioSamples(param.AudioSamples, param, out logSpectrogram); long elapsedMiliseconds = 0; // Query the database using Min Hash Dictionary <int, QueryStats> allCandidates = QueryFingerprintManager.QueryOneSongMinHash( signatures, dbService, minHash, lshHashTables, lshGroupsPerKey, thresholdTables, ref elapsedMiliseconds); IEnumerable <int> ids = allCandidates.Select(p => p.Key); IList <Track> tracks = dbService.ReadTrackById(ids); // Order by Hamming Similarity // Using PLINQ //OrderedParallelQuery<KeyValuePair<int, QueryStats>> order = allCandidates.AsParallel() IOrderedEnumerable <KeyValuePair <int, QueryStats> > order = allCandidates .OrderBy((pair) => pair.Value.OrderingValue = pair.Value.HammingDistance / pair.Value.NumberOfTotalTableVotes + 0.4 * pair.Value.MinHammingDistance); // Join on the ID properties. var joined = from o in order join track in tracks on o.Key equals track.Id select new { track, o.Value.Similarity }; Dictionary <Track, double> stats = joined.ToDictionary(Key => Key.track, Value => Value.Similarity); Dbg.WriteLine("Find Similar From Audio Samples - Total Execution Time: {0} ms", t.Stop().TotalMilliseconds); return(stats); }
/// <summary> /// Find Similar Tracks using passed audio file as input /// </summary> /// <param name="lshHashTables">Number of hash tables from the database</param> /// <param name="lshGroupsPerKey">Number of groups per hash table</param> /// <param name="thresholdTables">Threshold percentage [0.07 for 20 LHash Tables, 0.17 for 25 LHashTables]</param> /// <param name="param">Audio File Work Unit Parameter Object</param> /// <param name="splashScreen">The "please wait" splash screen (or null)</param> /// <returns>a dictionary of perceptually similar tracks</returns> public Dictionary <Track, QueryStats> FindSimilarFromAudioFile( int lshHashTables, int lshGroupsPerKey, int thresholdTables, WorkUnitParameterObject param) { // Get fingerprints // TODO: Note that this method might return too few samples double[][] LogSpectrogram; List <bool[]> signatures = fingerprintService.CreateFingerprintsFromAudioFile(param, out LogSpectrogram); long elapsedMiliseconds = 0; // Query the database using Min Hash Dictionary <int, QueryStats> allCandidates = QueryFingerprintManager.QueryOneSongMinHash( signatures, dbService, minHash, lshHashTables, lshGroupsPerKey, thresholdTables, ref elapsedMiliseconds); IEnumerable <int> ids = allCandidates.Select(p => p.Key); IList <Track> tracks = dbService.ReadTrackById(ids); // Order by Hamming Similarity // Using PLINQ //OrderedParallelQuery<KeyValuePair<int, QueryStats>> order = allCandidates.AsParallel() IOrderedEnumerable <KeyValuePair <int, QueryStats> > order = allCandidates .OrderBy((pair) => pair.Value.OrderingValue = pair.Value.HammingDistance / pair.Value.NumberOfTotalTableVotes + 0.4 * pair.Value.MinHammingDistance); // Join on the ID properties. var joined = from o in order join track in tracks on o.Key equals track.Id select new { track, o.Value }; Dictionary <Track, QueryStats> stats = joined.ToDictionary(Key => Key.track, Value => Value.Value); return(stats); }
public WorkUnit(WorkUnitParameterObject workUnitParameterObject) { this.workUnitParameterObject = workUnitParameterObject; }
/// <summary> /// Insert track into database /// </summary> /// <param name="track">Track</param> /// <param name="hashTables">Number of hash tables (e.g. 25)</param> /// <param name="hashKeys">Number of hash keys (e.g. 4)</param> /// <param name="param">WorkUnitParameterObject parameters</param> /// <param name="logSpectrogram">Return the log spectrogram in an out parameter</param> /// <param name="fingerprints">Return the fingerprints in an out parameter</param> /// <returns></returns> public bool InsertTrackInDatabaseUsingSamples(Track track, int hashTables, int hashKeys, WorkUnitParameterObject param, out double[][] logSpectrogram, out List <bool[]> fingerprints) { if (dbService.InsertTrack(track)) { // return both logSpectrogram and fingerprints in the out variables fingerprints = fingerprintService.CreateFingerprintsFromAudioSamples(param.AudioSamples, param, out logSpectrogram); List <Fingerprint> inserted = AssociateFingerprintsToTrack(fingerprints, track.Id); if (dbService.InsertFingerprint(inserted)) { return(HashFingerprintsUsingMinHash(inserted, track, hashTables, hashKeys)); } else { return(false); } } else { logSpectrogram = null; fingerprints = null; return(false); } }
/// <summary> /// Find Similar Tracks using passed audio samples as input and return a List /// </summary> /// <param name="lshHashTables">Number of hash tables from the database</param> /// <param name="lshGroupsPerKey">Number of groups per hash table</param> /// <param name="thresholdTables">Minimum number of hash tables that must be found for one signature to be considered a candidate (0 and 1 = return all candidates, 2+ = return only exact matches)</param> /// <param name="param">Audio File Work Unit Parameter Object</param> /// <param name="optimizeSignatureCount">Reduce the number of signatures in order to increase the search performance</param> /// <param name="doSearchEverything">disregard the local sensitivity hashes and search the whole database</param> /// <param name="splashScreen">The "please wait" splash screen (or null)</param> /// <returns>a list of perceptually similar tracks</returns> public List <FindSimilar.QueryResult> FindSimilarFromAudioSamplesList( int lshHashTables, int lshGroupsPerKey, int thresholdTables, WorkUnitParameterObject param, bool optimizeSignatureCount, bool doSearchEverything, SplashSceenWaitingForm splashScreen) { DbgTimer t = new DbgTimer(); t.Start(); if (splashScreen != null) { splashScreen.SetProgress(2, "Creating fingerprints from audio samples ..."); } // Get fingerprints double[][] logSpectrogram; List <bool[]> fingerprints = fingerprintService.CreateFingerprintsFromAudioSamples(param.AudioSamples, param, out logSpectrogram); #if DEBUG // Save debug images using fingerprinting methods //Analyzer.SaveFingerprintingDebugImages(param.FileName, logSpectrogram, fingerprints, fingerprintService, param.FingerprintingConfiguration); #endif if (splashScreen != null) { splashScreen.SetProgress(3, String.Format("Successfully created {0} fingerprints.", fingerprints.Count)); } // If the number of signatures is to big, only keep the first MAX_SIGNATURE_COUNT to avoid a very time consuming search if (optimizeSignatureCount && fingerprints.Count > MAX_SIGNATURE_COUNT) { if (splashScreen != null) { splashScreen.SetProgress(4, String.Format("Only using the first {0} fingerprints out of {1}.", MAX_SIGNATURE_COUNT, fingerprints.Count)); } fingerprints.RemoveRange(MAX_SIGNATURE_COUNT, fingerprints.Count - MAX_SIGNATURE_COUNT); Dbg.WriteLine("Only using the first {0} fingerprints.", MAX_SIGNATURE_COUNT); } long elapsedMiliseconds = 0; // Query the database using Min Hash Dictionary <int, QueryStats> allCandidates = QueryFingerprintManager.QueryOneSongMinHash( fingerprints, dbService, minHash, lshHashTables, lshGroupsPerKey, thresholdTables, ref elapsedMiliseconds, doSearchEverything, splashScreen); if (splashScreen != null) { splashScreen.SetProgress(91, String.Format("Found {0} candidates.", allCandidates.Count)); } IEnumerable <int> ids = allCandidates.Select(p => p.Key); IList <Track> tracks = dbService.ReadTrackById(ids); if (splashScreen != null) { splashScreen.SetProgress(95, String.Format("Reading {0} tracks.", tracks.Count)); } // Order by Hamming Similarity // TODO: What does the 0.4 number do here? // there doesn't seem to be any change using another number?! /* * // Using PLINQ * IOrderedEnumerable<KeyValuePair<int, QueryStats>> order = allCandidates * .OrderBy((pair) => pair.Value.OrderingValue = * pair.Value.HammingDistance / pair.Value.NumberOfTotalTableVotes + 0.4 * pair.Value.MinHammingDistance); + + + var fingerprintList = (from o in order + join track in tracks on o.Key equals track.Id + select new FindSimilar.QueryResult { + Id = track.Id, + Path = track.FilePath, + Duration = track.TrackLengthMs, + Similarity = o.Value.Similarity + }).ToList(); */ // http://msdn.microsoft.com/en-us/library/dd460719(v=vs.110).aspx // http://stackoverflow.com/questions/2767709/c-sharp-joins-where-with-linq-and-lambda // Lambda query to order the candidates var order = allCandidates.AsParallel() .OrderBy((pair) => pair.Value.OrderingValue = pair.Value.HammingDistance / pair.Value.NumberOfTotalTableVotes + 0.4 * pair.Value.MinHammingDistance) .Take(200); // TODO: Be able to create the above query as a LINQ query // Join on the ID properties. var fingerprintList = (from o in order.AsParallel() join track in tracks.AsParallel() on o.Key equals track.Id select new FindSimilar.QueryResult { Id = track.Id, Path = track.FilePath, Duration = track.TrackLengthMs, Similarity = o.Value.Similarity }) .OrderByDescending((ord) => ord.Similarity) .ToList(); if (splashScreen != null) { splashScreen.SetProgress(100, "Ready!"); } Dbg.WriteLine("FindSimilarFromAudioSamplesList - Total Execution Time: {0} ms", t.Stop().TotalMilliseconds); return(fingerprintList); }
public CompareAudioForm() { // // The InitializeComponent() call is required for Windows Forms designer support. // InitializeComponent(); // // TODO: Add constructor code after the InitializeComponent() call. // // Instansiate Soundfingerprinting Repository FingerprintService fingerprintService = Analyzer.GetSoundfingerprintingService(); this.databaseService = DatabaseService.Instance; IPermutations permutations = new LocalPermutations("Soundfingerprinting\\perms.csv", ","); //IPermutations permutations = new LocalPermutations("Soundfingerprinting\\perms-new.csv", ","); IFingerprintingConfiguration fingerprintingConfigCreation = new FullFrequencyFingerprintingConfiguration(); repository = new Repository(permutations, databaseService, fingerprintService); ImageService imageService = new ImageService(fingerprintService.SpectrumService, fingerprintService.WaveletService); FileInfo filePathAudio1 = new FileInfo(@"C:\Users\perivar.nerseth\Music\Test Samples Database\VDUB1 Snare 004.wav"); FileInfo filePathAudio2 = new FileInfo(@"C:\Users\perivar.nerseth\Music\Test Samples Search\VDUB1 Snare 004 - Start.wav"); int fingerprintsPerRow = 2; double[][] logSpectrogram1 = null; double[][] logSpectrogram2 = null; List <bool[]> fingerprints1 = null; List <bool[]> fingerprints2 = null; WorkUnitParameterObject file1Param = Analyzer.GetWorkUnitParameterObjectFromAudioFile(filePathAudio1); if (file1Param != null) { file1Param.FingerprintingConfiguration = fingerprintingConfigCreation; // Get fingerprints fingerprints1 = fingerprintService.CreateFingerprintsFromAudioSamples(file1Param.AudioSamples, file1Param, out logSpectrogram1); pictureBox1.Image = imageService.GetSpectrogramImage(logSpectrogram1, logSpectrogram1.Length, logSpectrogram1[0].Length); pictureBoxWithInterpolationMode1.Image = imageService.GetImageForFingerprints(fingerprints1, file1Param.FingerprintingConfiguration.FingerprintLength, file1Param.FingerprintingConfiguration.LogBins, fingerprintsPerRow); } WorkUnitParameterObject file2Param = Analyzer.GetWorkUnitParameterObjectFromAudioFile(filePathAudio2); if (file2Param != null) { file2Param.FingerprintingConfiguration = fingerprintingConfigCreation; // Get fingerprints fingerprints2 = fingerprintService.CreateFingerprintsFromAudioSamples(file2Param.AudioSamples, file2Param, out logSpectrogram2); pictureBox2.Image = imageService.GetSpectrogramImage(logSpectrogram2, logSpectrogram2.Length, logSpectrogram2[0].Length); pictureBoxWithInterpolationMode2.Image = imageService.GetImageForFingerprints(fingerprints2, file2Param.FingerprintingConfiguration.FingerprintLength, file2Param.FingerprintingConfiguration.LogBins, fingerprintsPerRow); } MinHash minHash = repository.MinHash; // only use the first signatures bool[] signature1 = fingerprints1[0]; bool[] signature2 = fingerprints2[0]; if (signature1 != null && signature2 != null) { int hammingDistance = MinHash.CalculateHammingDistance(signature1, signature2); double jaqSimilarity = MinHash.CalculateJaqSimilarity(signature1, signature2); lblSimilarity.Text = String.Format("Hamming: {0} JAQ: {1}", hammingDistance, jaqSimilarity); } }