Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
 public WorkUnit(WorkUnitParameterObject workUnitParameterObject)
 {
     this.workUnitParameterObject = workUnitParameterObject;
 }
Ejemplo n.º 6
0
        /// <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);
            }
        }
Ejemplo n.º 7
0
        /// <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);
        }
Ejemplo n.º 8
0
        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);
            }
        }