Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        private void DetectAudio(float[] inputAudioSample, int inputSampleRate, int inputChannels)
        {
            TimeSpan wait = (DateTime.Now - waitUntil);

            if (wait.TotalDays < 0 && wait.TotalSeconds < 0)
            {
                return;
            }

            // Run separeted task, ignore when one is allready running
            lock (lockObject)
            {
                // if detection task is runnign don't run a new one (otherwhise als er al een detectie draait dan niet verder gaan
                if (detectTask != null)
                {
                    return;
                }

                detectTask = new WSRecognize();
            } //lock


            Task task = Task.Factory.StartNew(() =>
            {
                using (AudioEngine ae = new AudioEngine())
                {
                    AudioSamples audio = new AudioSamples();
                    audio.Channels     = inputChannels;
                    audio.SampleRate   = inputSampleRate;
                    audio.Samples      = inputAudioSample;
                    audio.Origin       = "MEMORY";

                    if (doTimeStretching)
                    {
                        Console.WriteLine("Timestretching with " + timeStretchRateFactor.ToString("#0.00") + "f");
                        audio = ae.TimeStretch(audio.Samples, audio.SampleRate, audio.Channels, timeStretchRateFactor);
                    }
                    audio = ae.Resample(audio.Samples, audio.SampleRate, audio.Channels, 5512);
                    FingerprintSignature fsQuery = ae.CreateFingerprint(audio, SpectrogramConfig.Default);
                    switch (webServiceCall)
                    {
                    case "SLOW":
                        detectTask.DetectAudioFragmentSlow(fsQuery, null, REST_ResultFingerDetect);
                        break;

                    default:
                        detectTask.DetectAudioFragmentFast(fsQuery, null, REST_ResultFingerDetect);
                        break;
                    }
                    //detectTask.DetectAudioFragment(fsQuery, null, REST_ResultFingerDetect);
                } //using
            });
        }
Esempio n. 3
0
        public void ScanDirectoryAndFingerprint(string directory)
        {
            // Expand directory to full directory path.
            // We needed to remove filename part because GetFullPath doesn't suppport wildcards
            string wildcard = Path.GetFileName(directory);

            directory = Path.GetDirectoryName(directory);
            directory = Path.GetFullPath(directory);
            directory = Path.Combine(directory, wildcard);

            foreach (string f in Directory.GetFiles(Path.GetDirectoryName(directory), Path.GetFileName(directory)))
            {
                Console.WriteLine(Path.GetFileName(f));

                // For best result you should return the same key for the same file. Muziekweb.nl uses an cataloguenumber (some chars and a number, 7 or 8 char long in total)
                // then we added the track number. (Fieldname: TITELNUMMERTRACK)
                string referenceKey = GenerateCRC32Key(f);


                FingerprintAcoustID  fingerprint    = MakeAcoustIDFinger(referenceKey, f);
                FingerprintSignature subFingerprint = MakeSubFingerID(referenceKey, f);

                // Fill with some subdata
                if (subFingerprint != null && fingerprint != null)
                {
                    // AcoustID
                    fingerprint.AudioSource       = Path.GetExtension(f).Replace(".", "").ToUpper();
                    fingerprint.Lokatie           = f;             // Path.GetDirectoryName(f);
                    fingerprint.DateRelease       = DateTime.Now.Date;
                    fingerprint.CatalogusCode     = "POPULAIR";    // POPULAIR or CLASSICAL
                    fingerprint.UniformeTitleLink = "";            // used in muziekweb.nl database to find the same track on different albums
                                                                   // Subfinger
                    subFingerprint.AudioSource       = Path.GetExtension(f).Replace(".", "").ToUpper();
                    subFingerprint.Lokatie           = f;          // Path.GetDirectoryName(f);
                    subFingerprint.DateRelease       = DateTime.Now.Date;
                    subFingerprint.CatalogusCode     = "POPULAIR"; // POPULAIR or CLASSICAL
                    subFingerprint.UniformeTitleLink = "";         // used in muziekweb.nl database to find the same track on different albums
                }

                // Store the data in de MySQL Database, this will later be used to create an inverted index using lucene.
                int titelnummertrackID;
                Exec_MySQL_SUBFINGERID_IU(subFingerprint.Reference.ToString(), subFingerprint.CatalogusCode, subFingerprint.DateRelease,
                                          subFingerprint.UniformeTitleLink, subFingerprint.AudioSource, subFingerprint.Lokatie, subFingerprint.DurationInMS, subFingerprint.Signature, out titelnummertrackID);
                Exec_MySQL_FINGERID_IU(fingerprint.Reference.ToString(), fingerprint.CatalogusCode, fingerprint.DateRelease,
                                       fingerprint.UniformeTitleLink, fingerprint.AudioSource, fingerprint.Lokatie, fingerprint.DurationInMS, fingerprint.Signature, out titelnummertrackID);
            } //foreach
        }
Esempio n. 4
0
        /// <summary>
        /// Test the subfinger fingerprints, by trying to find a 15 second audio in 3 different bitrates.
        ///
        /// Needed are:
        /// 1. MySQL database
        /// 2. CreateAudioFingerprint (Fills the MySQL database with fingerprints)
        /// 3. CreateInversedFingerprintIndex (Create a lucene reversed search index, needed to identity a fingerprint)
        /// 4. This program to find a 15 second fragment of audio
        /// </summary>
        public void RunSubFingerTest()
        {
            Console.WriteLine("SubFinger test.");
            if (!System.IO.Directory.Exists(subFingerLookupPath))
            {
                Console.WriteLine("SubFinger path not found.");
                return;
            }

            Console.WriteLine("Opening index. With larges indexes this can take a while.");
            IndexSearcher indexSubFingerLookup = new IndexSearcher(IndexReader.Open(FSDirectory.Open(new System.IO.DirectoryInfo(subFingerLookupPath)), true));

            indexSubFingerLookup.Similarity = new CDR.Indexer.DefaultSimilarityExtended2();
            Console.WriteLine("Ready opening index.");

            SubFingerprintQuery  query   = new SubFingerprintQuery(indexSubFingerLookup);
            FingerprintSignature fsQuery = null;
            Resultset            answer  = null;

            fsQuery = CreateSubFingerprintFromAudio(@"..\..\..\Audio\Samples\JK147510-0002-224Sample-45s-60s.mp3");
            answer  = query.MatchAudioFingerprint(fsQuery);
            if (!retrieveMetadataFromMuziekweb)
            {
                ThrowIfInvalidAnswer(answer, "A5D062DE");
            }
            PrintAnswer(answer);
            Console.WriteLine();

            fsQuery = CreateSubFingerprintFromAudio(@"..\..\..\Audio\Samples\JK147510-0002-128Sample-45s-60s.mp3");
            answer  = query.MatchAudioFingerprint(fsQuery);
            if (!retrieveMetadataFromMuziekweb)
            {
                ThrowIfInvalidAnswer(answer, "A5D062DE");
            }
            PrintAnswer(answer);
            Console.WriteLine();

            fsQuery = CreateSubFingerprintFromAudio(@"..\..\..\Audio\Samples\JK147510-0002-64Sample-45s-60s.mp3");
            answer  = query.MatchAudioFingerprint(fsQuery);
            if (!retrieveMetadataFromMuziekweb)
            {
                ThrowIfInvalidAnswer(answer, "A5D062DE");
            }
            PrintAnswer(answer);
            Console.WriteLine();
        }
Esempio n. 5
0
        /// <summary>
        /// Read a audio file (remember for sub fingerprints no more than 15 seconds)
        /// Downsample it to mono and 5512Hz
        /// Use the samples to create a fingerprint
        ///
        /// return a fingerprint signature.
        /// </summary>
        private FingerprintSignature CreateSubFingerprintFromAudio(string filename)
        {
            DateTime          startTime         = DateTime.Now;
            SpectrogramConfig spectrogramConfig = new DefaultSpectrogramConfig();

            // First read audio file and downsample it to mono 5512hz
            AudioSamples samples = audioEngine.ReadMonoFromFile(filename, spectrogramConfig.SampleRate, 0, -1);

            Console.WriteLine(string.Format("Resample tot mono {0}hz : {1:##0.000} sec.", spectrogramConfig.SampleRate, (DateTime.Now - startTime).TotalMilliseconds / 1000));

            startTime = DateTime.Now;
            // Now slice the audio in chunks seperated by 11,6 ms (5512hz 11,6ms = 64 samples!)
            // An with length of 371ms (5512kHz 371ms = 2048 samples [rounded])
            FingerprintSignature fsQuery = audioEngine.CreateFingerprint(samples, spectrogramConfig);

            Console.WriteLine(string.Format("Hashing audio to fingerprint : {0:##0.000} sec.", (DateTime.Now - startTime).TotalMilliseconds / 1000));

            return(fsQuery);
        }
Esempio n. 6
0
        private FingerprintSignature MakeSubFingerID(string key, string filename)
        {
            FingerprintSignature fingerprint = null;

            AudioEngine audioEngine = new AudioEngine();

            try
            {
                SpectrogramConfig spectrogramConfig = new DefaultSpectrogramConfig();

                AudioSamples samples = null;
                try
                {
                    // First read audio file and downsample it to mono 5512hz
                    samples = audioEngine.ReadMonoFromFile(filename, spectrogramConfig.SampleRate, 0, -1);
                }
                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])
                fingerprint = audioEngine.CreateFingerprint(samples, spectrogramConfig);
                if (fingerprint != null)
                {
                    fingerprint.Reference = key;
                }
            }
            finally
            {
                if (audioEngine != null)
                {
                    audioEngine.Close();
                    audioEngine = null;
                }
            }

            return(fingerprint);
        }
Esempio n. 7
0
        public bool CreateSubFingerLookupIndex(string luceneIndexPath)
        {
            DateTime startTime = DateTime.Now;
            DateTime endTime   = startTime;

            Console.WriteLine("Creating SubFingerLookup index.");

            int minID;
            int maxID;

            if (!Exec_MySQL_MinAndMax_IDS(out minID, out maxID) && minID >= 1)
            {
                return(false);
            }

            if (!System.IO.Directory.Exists(luceneIndexPath))
            {
                System.IO.Directory.CreateDirectory(luceneIndexPath);
            }
            ClearFolder(luceneIndexPath);


            Lucene.Net.Store.Directory directory = FSDirectory.Open(new System.IO.DirectoryInfo(luceneIndexPath));
            IndexWriter iw          = null;
            int         fingerCount = 0;

            try
            {
                iw = new IndexWriter(directory, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30), true, IndexWriter.MaxFieldLength.UNLIMITED);
                iw.UseCompoundFile = false;
                iw.SetSimilarity(new CDR.Indexer.DefaultSimilarityExtended());
                iw.MergeFactor = 10;                                          // default = 10
                iw.SetRAMBufferSizeMB(512 * 3);                               // use memory to do a flush
                iw.SetMaxBufferedDocs(IndexWriter.DISABLE_AUTO_FLUSH);        // only use memory as trigger to do a flush
                iw.SetMaxBufferedDeleteTerms(IndexWriter.DISABLE_AUTO_FLUSH); // only use memory as trigger to do a flush

                Document doc = new Document();
                doc.Add(new Field("FINGERID", "", Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field("SUBFINGER", "", Field.Store.NO, Field.Index.ANALYZED));

                Field fFingerID = doc.GetField("FINGERID");
                fFingerID.OmitNorms = true;
                fFingerID.OmitTermFreqAndPositions = true;

                Field fSubFinger = doc.GetField("SUBFINGER");
                fSubFinger.OmitNorms = true;
                fSubFinger.OmitTermFreqAndPositions = true;

                StringBuilder sb = new StringBuilder(256 * 1024);

                int start = minID;
                int count = 5000;
                while (start <= maxID)
                {
                    DataTable dt;
                    if (Exec_MySQL_LOADSUBFINGERIDS(start, (start + count - 1), out dt))
                    {
                        foreach (DataRow row in dt.Rows)
                        {
                            fingerCount++;
                            if ((fingerCount % 100) == 0 || fingerCount <= 1)
                            {
                                Console.Write("\rIndexing subfingerprint #" + fingerCount.ToString());
                            }

                            FingerprintSignature fingerprint = new FingerprintSignature((string)row["TITELNUMMERTRACK"], Convert.ToInt64(row["TITELNUMMERTRACK_ID"]), (byte[])row["SIGNATURE"], Convert.ToInt64(row["DURATIONINMS"]));

                            sb.Clear();
                            for (int i = 0; i < fingerprint.SubFingerprintCount; i++)
                            {
                                uint subFingerValue = fingerprint.SubFingerprint(i);
                                int  bits           = AudioFingerprint.Math.SimilarityUtility.HammingDistance(subFingerValue, 0);
                                if (bits < 10 || bits > 22) // 5 27
                                {
                                    continue;
                                }
                                sb.Append(subFingerValue.ToString());
                                sb.Append(' ');
                            }
                            fFingerID.SetValue(row["TITELNUMMERTRACK_ID"].ToString());
                            fSubFinger.SetValue(sb.ToString());

                            iw.AddDocument(doc);
                        } //foreach
                        Console.Write("\rIndexing subfingerprint #" + fingerCount.ToString());

                        start += count;
                    } //if
                    else
                    {
                        if (!RetryDatabaseError())
                        {
                            return(false);
                        }
                    }
                } // while alle fingerprints
            }
            finally
            {
                Console.WriteLine();
                Console.WriteLine("Optimizing.");
                if (iw != null)
                {
                    // Optimaliseer de index nu
                    iw.Commit();
                    iw.Optimize(1, true);
                    iw.Dispose();
                    iw = null;
                    GC.WaitForPendingFinalizers();
                }
            }


            endTime = DateTime.Now;
            TimeSpan ts = (endTime - startTime);

            Console.WriteLine(String.Format("Elapsed index time {0:00}:{1:00}:{2:00}.{3:000}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds));
            Console.WriteLine();

            return(true);
        }
Esempio n. 8
0
        public Message FingerprintRecognize(Stream stream)
        {
            string errorMessage;

            if (!UserAccountManager.HasAccess(UserAccountManager.CurrentAccessGroup, out errorMessage, true))
            {
                return(ServiceHelper.SendErrorMessage(ResultErrorCode.AuthorizationError, errorMessage));
            }
            UserAccountManager.GlobalNumberOfRequestsInc();

            XElement xResult = null;

            try
            {
                QueryString qs          = new QueryString(stream);
                string      fingerprint = qs["Fingerprint"];
                string      reliabilty  = qs["Reliabilities"];

                using (FingerprintSignature fsQuery = new FingerprintSignature("UNKNOWN", 0, System.Convert.FromBase64String(fingerprint), 0, true))
                {
                    fsQuery.Reliabilities = System.Convert.FromBase64String(reliabilty);

                    LuceneIndex subFingerIndex = LuceneIndexes.IndexSubFingerprint;
                    try
                    {
                        // We moeten hier al locken aangezien de audiofingerprint library geen weet heeft van onze
                        // LuceneIndex object
                        subFingerIndex.Lock();
                        using (SubFingerprintQuery query = new SubFingerprintQuery(subFingerIndex.Index))
                        {
                            Resultset answer = query.MatchAudioFingerprint(fsQuery, 2300);

                            if (answer != null)
                            {
                                xResult = ServiceHelper.CreateRoot(ResultErrorCode.OK);

                                xResult.Add(new XElement("RecognizeResult",
                                                         new XAttribute("RecognizeCode", 0),
                                                         "OK"));

                                XElement xTimeStatistics = new XElement("TimeStatistics");
                                xTimeStatistics.Add(new XElement("TotalQueryTime",
                                                                 new XAttribute("Unit", "ms"),
                                                                 (int)answer.QueryTime.TotalMilliseconds));
                                xTimeStatistics.Add(new XElement("SubFingerQueryTime",
                                                                 new XAttribute("Unit", "ms"),
                                                                 (int)answer.FingerQueryTime.TotalMilliseconds));
                                xTimeStatistics.Add(new XElement("FingerLoadTime",
                                                                 new XAttribute("Unit", "ms"),
                                                                 (int)answer.FingerLoadTime.TotalMilliseconds));
                                xTimeStatistics.Add(new XElement("MatchTime",
                                                                 new XAttribute("Unit", "ms"),
                                                                 (int)answer.MatchTime.TotalMilliseconds));
                                xResult.Add(xTimeStatistics);

                                XElement xFingerTracks = new XElement("FingerTracks",
                                                                      new XAttribute("Count", 0));
                                xResult.Add(xFingerTracks);
                                if (answer.ResultEntries.Count > 0)
                                {
                                    // Gets a NumberFormatInfo associated with the en-US culture.
                                    System.Globalization.NumberFormatInfo nfi = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
                                    nfi.CurrencySymbol           = "€";
                                    nfi.CurrencyDecimalDigits    = 2;
                                    nfi.CurrencyDecimalSeparator = ".";
                                    nfi.NumberGroupSeparator     = "";
                                    nfi.NumberDecimalSeparator   = ".";

                                    Dictionary <string, ResultEntry> dict = new Dictionary <string, ResultEntry>();
                                    int count = 0;
                                    foreach (ResultEntry item in answer.ResultEntries)
                                    {
                                        XElement xFingerTrack = new XElement("FingerTrack");
                                        xFingerTracks.Add(xFingerTrack);

                                        xFingerTrack.Add(new XAttribute("BER", item.Similarity.ToString()));
                                        xFingerTrack.Add(new XElement("DetectPosition",
                                                                      new XAttribute("Unit", "ms"),
                                                                      new XAttribute("InSec", string.Format(nfi, "{0:#0.000}", (item.Time.TotalMilliseconds / 1000))),
                                                                      (int)item.Time.TotalMilliseconds));

                                        XElement xSearchStrategy = new XElement("SearchStrategy");
                                        xFingerTrack.Add(xSearchStrategy);
                                        xSearchStrategy.Add(new XElement("IndexNumberInMatchList", item.IndexNumberInMatchList));
                                        xSearchStrategy.Add(new XElement("SubFingerCountHitInFingerprint", item.SubFingerCountHitInFingerprint));
                                        xSearchStrategy.Add(new XElement("SearchName", item.SearchStrategy.ToString()));
                                        xSearchStrategy.Add(new XElement("SearchIteration", item.SearchIteration));

                                        xFingerTrack.Add(new XElement("Reference", item.Reference.ToString()));
                                        xFingerTrack.Add(new XElement("FingerTrackID", item.FingerTrackID.ToString()));
                                        count++;
                                    } //foreach
                                    xFingerTracks.Attribute("Count").Value = count.ToString();
                                }
                            }
                            else
                            {
                                // Query geeft null waarde terug. Betekent dat er iets goed fout is gegaan
                                xResult = ServiceHelper.CreateRoot(ResultErrorCode.FAILED);
                            }

                            if (xResult != null)
                            {
                                return(Message.CreateMessage(MessageVersion.None, "", new XElementBodyWriter(xResult)));
                            }

                            // Als we hier komen dan hebben we geen resultaat
                            return(ServiceHelper.SendErrorMessage(ResultErrorCode.NoResultset, "No resultset"));
                        } //using
                    }
                    finally
                    {
                        subFingerIndex.UnLock();
                    }
                } //using
            }
            catch (Exception e)
            {
                CDRLogger.Logger.LogError(e);
                return(ServiceHelper.SendErrorMessage(ResultErrorCode.Exception, e.Message));
            }
            finally
            {
                GC.Collect();
            }
        }
Esempio n. 9
0
        public CancellationTokenSource DetectAudioFragmentSlow(FingerprintSignature fingerprint, object userState = null, REST_ResultFingerDetect callback = null)
        {
            if (fingerprint == null)
            {
                return(null);
            }

            CancellationTokenSource cancelTokenSource = new CancellationTokenSource();

            Task task = Task.Factory.StartNew(() =>
            {
                // Were we already canceled?
                cancelTokenSource.Token.ThrowIfCancellationRequested();

                DateTime startTime          = DateTime.Now;
                bool succes                 = true;
                RecognizeCode RecognizeCode = RecognizeCode.OK;
                string RecognizeResult      = "";
                try
                {
                    RestClient client = CreateFingerprintClient;

                    // Build search request
                    RestRequest request = new RestRequest("fingerprint/Recognize/Slow", Method.POST);
                    request.AddHeader("Accept-Encoding", "gzip,deflate");
                    StringBuilder sb = new StringBuilder(200 * 1024);
                    sb.Append("Fingerprint=");
                    sb.Append(RestSharp.Contrib.HttpUtility.UrlEncode(fingerprint.SignatureBase64));
                    sb.Append("&");
                    sb.Append("Reliabilities=");
                    sb.Append(RestSharp.Contrib.HttpUtility.UrlEncode(fingerprint.ReliabilitiesBase64));
                    request.AddParameter("application/x-www-form-urlencoded", sb.ToString(), ParameterType.RequestBody);

                    // Run and wait for result
                    IRestResponse response = client.Execute(request);
                    cancelTokenSource.Token.ThrowIfCancellationRequested();
                    if (response.ResponseStatus != ResponseStatus.Completed)
                    {
                        // error!
                        succes = false;

                        RecognizeCode   = RecognizeCode.EXCEPTION; // exception
                        RecognizeResult = response.ErrorMessage;
                        if (RecognizeResult.ToLower().Contains("timed out"))
                        {
                            RecognizeCode = RecognizeCode.TIMEOUT;
                        }
                        else if (RecognizeResult.ToLower().Contains("unable to connect"))
                        {
                            RecognizeCode = RecognizeCode.SERVERNOTFOUND;
                        }
                    }

                    // decode xml on the fly (must be done because xml can get new tags and attributes without notice
                    XmlDocument xmlDoc = null;
                    XmlElement xResult = null;
                    if (succes)
                    {
                        xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(response.Content);

                        xResult = xmlDoc.GetElementsByTagName("Result")[0] as XmlElement;
                        if (xResult == null || xResult.Attributes["ErrorCode"].Value != "0")
                        {
                            // error
                            succes = false;
                        }
                    }

                    if (succes)
                    {
                        ResultFingerprintRecognition resultRecognitions = new ResultFingerprintRecognition();
                        resultRecognitions.RecognizeCode   = 0;
                        resultRecognitions.RecognizeResult = "OK";
                        succes = resultRecognitions.ParseFingerprintRecognition(xResult);

                        // do something with the result
                        cancelTokenSource.Token.ThrowIfCancellationRequested();
                        if (callback != null)
                        {
                            DoCallback(callback, this, true, resultRecognitions, userState);
                        }
                        // we're ready
                        return;
                    }
                }
                catch (Exception e)
                {
                    RecognizeCode   = RecognizeCode.EXCEPTION; // exception
                    RecognizeResult = e.ToString();
                }

                // return error result when we get here
                if (callback != null)
                {
                    ResultFingerprintRecognition resultRecognitions = new ResultFingerprintRecognition();
                    resultRecognitions.RecognizeCode   = RecognizeCode;
                    resultRecognitions.RecognizeResult = RecognizeResult;
                    resultRecognitions.TimeStatistics.TotalQueryTime = DateTime.Now - startTime;

                    DoCallback(callback, this, false, resultRecognitions, userState);
                }
            }, cancelTokenSource.Token);

            return(cancelTokenSource);
        }