public void DeleteTrackByIdTest() { string name = MethodBase.GetCurrentMethod().Name; const int FakeId = int.MinValue; Album album = new Album(FakeId, name, 1986); dalManager.InsertAlbum(album); Assert.AreNotEqual(FakeId, album.Id); Track track = new Track(FakeId, name, name, album.Id); dalManager.InsertTrack(track); Assert.AreNotEqual(FakeId, track.Id); dalManager.DeleteTrack(track.Id); Assert.AreEqual(null, dalManager.ReadAlbumById(album.Id)); Assert.AreEqual(null, dalManager.ReadTrackById(track.Id)); }
public void InsertReadHashBinNeuralHashesTest() { string name = MethodBase.GetCurrentMethod().Name; Album album = dalManager.ReadUnknownAlbum(); Track track = new Track(0, name, name, album.Id); dalManager.InsertTrack(track); Fingerprint finger = new Fingerprint(0, GenericFingerprint, track.Id, 0); dalManager.InsertFingerprint(finger); const long Hashbin = 100000; const int Hashtable = 20; List<HashBinNeuralHasher> list = new List<HashBinNeuralHasher>(); const int Count = 20; for (int i = 0; i < Count; i++) { HashBinNeuralHasher hashbinminhash = new HashBinNeuralHasher(0, Hashbin, Hashtable, track.Id); list.Add(hashbinminhash); } dalManager.InsertHashBin(list); List<int> result = dalManager.ReadTrackIdByHashBinAndHashTableNeuralHasher(Hashbin, Hashtable); Assert.IsNotNull(result); Assert.AreEqual(Count, result.Count); dalManager.DeleteTrack(track.Id); }
/// <summary> /// Method to analyze and add using the soundfingerprinting methods /// </summary> /// <param name="filePath">full file path</param> /// <param name="repository">Soundfingerprinting Repository</param> /// <param name="doOutputDebugInfo">decide whether to output debug info like spectrogram and audiofile (default value can be set)</param> /// <param name="useHaarWavelet">decide whether to use haar wavelet compression or DCT compression</param> /// <returns>true if successful</returns> public static bool AnalyzeAndAddSoundfingerprinting(FileInfo filePath, Repository repository, bool doOutputDebugInfo=DEFAULT_DEBUG_INFO, bool useHaarWavelet = true) { DbgTimer t = new DbgTimer(); t.Start (); // get work config from the audio file WorkUnitParameterObject param = GetWorkUnitParameterObjectFromAudioFile(filePath); param.FingerprintingConfiguration = fingerprintingConfigCreation; string fileName = param.FileName; // build track Track track = new Track(); track.Title = param.FileName; track.TrackLengthMs = (int) param.DurationInMs; track.FilePath = param.PathToAudioFile; track.Tags = param.Tags; track.Id = -1; // this will be set by the insert method // Get fingerprint signatures using the Soundfingerprinting methods double[][] logSpectrogram; List<bool[]> fingerprints; List<double[][]> spectralImages; if (repository.InsertTrackInDatabaseUsingSamples(track, param.FingerprintingConfiguration.NumberOfHashTables, param.FingerprintingConfiguration.NumberOfKeys, param, out logSpectrogram, out fingerprints, out spectralImages)) { // store logSpectrogram as Matrix Comirva.Audio.Util.Maths.Matrix logSpectrogramMatrix = new Comirva.Audio.Util.Maths.Matrix(logSpectrogram); logSpectrogramMatrix = logSpectrogramMatrix.Transpose(); #region Debug for Soundfingerprinting Method if (doOutputDebugInfo) { // Image Service ImageService imageService = new ImageService(repository.FingerprintService.SpectrumService, repository.FingerprintService.WaveletService); imageService.GetLogSpectralImages(logSpectrogram, fingerprintingConfigCreation.Stride, fingerprintingConfigCreation.FingerprintLength, fingerprintingConfigCreation.Overlap, 2).Save(fileName + "_specgram_logimages.png"); logSpectrogramMatrix.DrawMatrixImageLogValues(fileName + "_specgram_logimage.png", true); if (DEBUG_OUTPUT_TEXT) { logSpectrogramMatrix.WriteCSV(fileName + "_specgram_log.csv", ";"); } } #endregion } else { // failed Console.Out.WriteLine("Failed! Could not compute the soundfingerprint {0}!", fileName); return false; } Dbg.WriteLine ("AnalyzeAndAddSoundfingerprinting - Total Execution Time: {0} ms", t.Stop().TotalMilliseconds); return true; }
/// <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> public bool InsertTrackInDatabaseUsingSamples(Track track, int hashTables, int hashKeys, WorkUnitParameterObject param, out double[][] logSpectrogram) { if (dbService.InsertTrack(track)) { List<bool[]> images = fingerprintService.CreateFingerprintsFromAudioSamples(param.AudioSamples, param, out logSpectrogram); List<Fingerprint> inserted = AssociateFingerprintsToTrack(images, track.Id); if (dbService.InsertFingerprint(inserted)) { return HashFingerprintsUsingMinHash(inserted, track, hashTables, hashKeys); } else { return false; } } else { logSpectrogram = null; return false; } }
public static AudioFeature AnalyzeSoundfingerprinting(FileInfo filePath, bool doOutputDebugInfo=DEFAULT_DEBUG_INFO, bool useHaarWavelet = true) { DbgTimer t = new DbgTimer(); t.Start (); float[] audiodata = AudioFileReader.Decode(filePath.FullName, SAMPLING_RATE, SECONDS_TO_ANALYZE); if (audiodata == null || audiodata.Length == 0) { Dbg.WriteLine("Error! - No Audio Found"); return null; } // Read TAGs using BASS FindSimilar.AudioProxies.BassProxy bass = FindSimilar.AudioProxies.BassProxy.Instance; Un4seen.Bass.AddOn.Tags.TAG_INFO tag_info = bass.GetTagInfoFromFile(filePath.FullName); // Name of file being processed string name = StringUtils.RemoveNonAsciiCharacters(Path.GetFileNameWithoutExtension(filePath.Name)); #if DEBUG if (Analyzer.DEBUG_INFO_VERBOSE) { if (DEBUG_OUTPUT_TEXT) WriteAscii(audiodata, name + "_audiodata.ascii"); if (DEBUG_OUTPUT_TEXT) WriteF3Formatted(audiodata, name + "_audiodata.txt"); } #endif if (doOutputDebugInfo) { DrawGraph(MathUtils.FloatToDouble(audiodata), name + "_audiodata.png"); } // Calculate duration in ms double duration = (double) audiodata.Length / SAMPLING_RATE * 1000; // zero pad if the audio file is too short to perform a mfcc if (audiodata.Length < (fingerprintingConfig.WdftSize + fingerprintingConfig.Overlap)) { int lenNew = fingerprintingConfig.WdftSize + fingerprintingConfig.Overlap; Array.Resize<float>(ref audiodata, lenNew); } // Get fingerprint signatures using the Soundfingerprinting methods // Get database DatabaseService databaseService = DatabaseService.Instance; IPermutations permutations = new LocalPermutations("Soundfingerprinting\\perms.csv", ","); Repository repository = new Repository(permutations, databaseService, fingerprintService); // Image Service ImageService imageService = new ImageService( fingerprintService.SpectrumService, fingerprintService.WaveletService); // work config WorkUnitParameterObject param = new WorkUnitParameterObject(); param.FingerprintingConfiguration = fingerprintingConfig; param.AudioSamples = audiodata; param.PathToAudioFile = filePath.FullName; param.MillisecondsToProcess = SECONDS_TO_ANALYZE * 1000; param.StartAtMilliseconds = 0; // build track Track track = new Track(); track.Title = name; track.TrackLengthMs = (int) duration; track.FilePath = filePath.FullName; track.Id = -1; // this will be set by the insert method #region parse tag_info if (tag_info != null) { Dictionary<string, string> tags = new Dictionary<string, string>(); //if (tag_info.title != string.Empty) tags.Add("title", tag_info.title); if (tag_info.artist != string.Empty) tags.Add("artist", tag_info.artist); if (tag_info.album != string.Empty) tags.Add("album", tag_info.album); if (tag_info.albumartist != string.Empty) tags.Add("albumartist", tag_info.albumartist); if (tag_info.year != string.Empty) tags.Add("year", tag_info.year); if (tag_info.comment != string.Empty) tags.Add("comment", tag_info.comment); if (tag_info.genre != string.Empty) tags.Add("genre", tag_info.genre); if (tag_info.track != string.Empty) tags.Add("track", tag_info.track); if (tag_info.disc != string.Empty) tags.Add("disc", tag_info.disc); if (tag_info.copyright != string.Empty) tags.Add("copyright", tag_info.copyright); if (tag_info.encodedby != string.Empty) tags.Add("encodedby", tag_info.encodedby); if (tag_info.composer != string.Empty) tags.Add("composer", tag_info.composer); if (tag_info.publisher != string.Empty) tags.Add("publisher", tag_info.publisher); if (tag_info.lyricist != string.Empty) tags.Add("lyricist", tag_info.lyricist); if (tag_info.remixer != string.Empty) tags.Add("remixer", tag_info.remixer); if (tag_info.producer != string.Empty) tags.Add("producer", tag_info.producer); if (tag_info.bpm != string.Empty) tags.Add("bpm", tag_info.bpm); //if (tag_info.filename != string.Empty) tags.Add("filename", tag_info.filename); tags.Add("channelinfo", tag_info.channelinfo.ToString()); //if (tag_info.duration > 0) tags.Add("duration", tag_info.duration.ToString()); if (tag_info.bitrate > 0) tags.Add("bitrate", tag_info.bitrate.ToString()); if (tag_info.replaygain_track_gain != -100f) tags.Add("replaygain_track_gain", tag_info.replaygain_track_gain.ToString()); if (tag_info.replaygain_track_peak != -1f) tags.Add("replaygain_track_peak", tag_info.replaygain_track_peak.ToString()); if (tag_info.conductor != string.Empty) tags.Add("conductor", tag_info.conductor); if (tag_info.grouping != string.Empty) tags.Add("grouping", tag_info.grouping); if (tag_info.mood != string.Empty) tags.Add("mood", tag_info.mood); if (tag_info.rating != string.Empty) tags.Add("rating", tag_info.rating); if (tag_info.isrc != string.Empty) tags.Add("isrc", tag_info.isrc); foreach(var nativeTag in tag_info.NativeTags) { string[] keyvalue = nativeTag.Split('='); tags.Add(keyvalue[0], keyvalue[1]); } track.Tags = tags; } #endregion AudioFeature audioFeature = null; double[][] logSpectrogram; if (repository.InsertTrackInDatabaseUsingSamples(track, 25, 4, param, out logSpectrogram)) { if (doOutputDebugInfo) { imageService.GetLogSpectralImages(logSpectrogram, fingerprintingConfig.Stride, fingerprintingConfig.FingerprintLength, fingerprintingConfig.Overlap, 2).Save(name + "_specgram_logimages.png"); Comirva.Audio.Util.Maths.Matrix logSpectrogramMatrix = new Comirva.Audio.Util.Maths.Matrix(logSpectrogram); logSpectrogramMatrix = logSpectrogramMatrix.Transpose(); logSpectrogramMatrix.DrawMatrixImageLogValues(name + "_specgram_logimage.png", true); if (DEBUG_OUTPUT_TEXT) { logSpectrogramMatrix.WriteCSV(name + "_specgram_log.csv", ";"); } } audioFeature = new DummyAudioFeature(); // Store duration audioFeature.Duration = (long) duration; // Store file name audioFeature.Name = filePath.FullName; } else { // failed } Dbg.WriteLine ("Soundfingerprinting - Total Execution Time: {0} ms", t.Stop().TotalMilliseconds); return audioFeature; }
/// <summary> /// Hash Fingerprints using Neural hasher component for solving k-nearest neighbor problem /// </summary> /// <param name = "listOfFingerprintsToHash">List of fingerprints already inserted in the database</param> /// <param name = "track">Track of the corresponding fingerprints</param> private void HashFingerprintsUsingNeuralHasher(IEnumerable<Fingerprint> listOfFingerprintsToHash, Track track) { List<HashBinNeuralHasher> listToInsert = new List<HashBinNeuralHasher>(); foreach (Fingerprint fingerprint in listOfFingerprintsToHash) { _ensemble.ComputeHash(FingerprintManager.DecodeFingerprint(fingerprint.Signature)); long[] hashbins = _ensemble.ExtractHashBins(); for (int i = 0; i < hashbins.Length; i++) { HashBinNeuralHasher hash = new HashBinNeuralHasher(i, hashbins[i], i, track.Id); listToInsert.Add(hash); } } _dalManager.InsertHashBin(listToInsert); }
public int DeleteTrack(Track track) { throw new NotImplementedException(); }
public Track ReadTrackById(int id) { IDbCommand dbcmd; lock (dbcon) { dbcmd = dbcon.CreateCommand(); } dbcmd.CommandText = "SELECT albumid, length, artist, title, filepath FROM [tracks] WHERE [id] = @id"; dbcmd.Parameters.Add(new SQLiteParameter("@id") { Value = id }); dbcmd.CommandType = CommandType.Text; dbcmd.Prepare(); IDataReader reader = dbcmd.ExecuteReader(); if (!reader.Read()) { return null; } Track track = new Track(); track.Id = id; track.AlbumId = reader.GetInt32(0); track.TrackLengthMs = reader.GetInt32(1); if (!reader.IsDBNull(2)) { track.Artist = reader.GetString(2); } track.Title = reader.GetString(3); track.FilePath = reader.GetString(4); reader.Close(); dbcmd.Dispose(); return track; }
public void ReadFingerprintByMultipleTrackIdTest1() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway manager = dalManager; Album album = new Album(0, name, 1986); manager.InsertAlbum(album); const int NumberOfTracks = 1153; const int NumberOfFingerprintsPerTrack = 10; List<Track> listTrack = new List<Track>(); List<Fingerprint> listOfFingerprints = new List<Fingerprint>(); for (int i = 0; i < NumberOfTracks; i++) { Track track0 = new Track(0, name, name, album.Id, 360); listTrack.Add(track0); manager.InsertTrack(track0); for (int j = 0; j < NumberOfFingerprintsPerTrack; j++) { Fingerprint f0 = new Fingerprint(0, GenericFingerprint, track0.Id, 0); listOfFingerprints.Add(f0); } } manager.InsertFingerprint(listOfFingerprints); Dictionary<int, List<Fingerprint>> dict = manager.ReadFingerprintsByMultipleTrackId(listTrack, 0); Assert.AreNotEqual(null, dict); Assert.AreEqual(NumberOfTracks, dict.Keys.Count); foreach (Track track in listTrack) { Assert.AreEqual(true, dict.ContainsKey(track.Id)); Assert.AreEqual(NumberOfFingerprintsPerTrack, dict[track.Id].Count); } }
public void ReadFingerprintByMultipleTrackIdTest() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway manager = dalManager; Album album = new Album(0, name, 1986); manager.InsertAlbum(album); Track track0 = new Track(0, name, name, album.Id, 360); manager.InsertTrack(track0); Track track1 = new Track(0, name, name, album.Id, 360); manager.InsertTrack(track1); Track track2 = new Track(0, name, name, album.Id, 360); manager.InsertTrack(track2); Fingerprint f0 = new Fingerprint(0, GenericFingerprint, track0.Id, 0); manager.InsertFingerprint(f0); Fingerprint f1 = new Fingerprint(0, GenericFingerprint, track0.Id, 1); manager.InsertFingerprint(f1); Fingerprint f2 = new Fingerprint(0, GenericFingerprint, track1.Id, 2); manager.InsertFingerprint(f2); Fingerprint f3 = new Fingerprint(0, GenericFingerprint, track1.Id, 3); manager.InsertFingerprint(f3); Fingerprint f4 = new Fingerprint(0, GenericFingerprint, track2.Id, 4); manager.InsertFingerprint(f4); Fingerprint f5 = new Fingerprint(0, GenericFingerprint, track2.Id, 5); manager.InsertFingerprint(f5); Fingerprint f6 = new Fingerprint(0, GenericFingerprint, track0.Id, 6); manager.InsertFingerprint(f6); Fingerprint f7 = new Fingerprint(0, GenericFingerprint, track1.Id, 7); manager.InsertFingerprint(f7); Fingerprint f8 = new Fingerprint(0, GenericFingerprint, track2.Id, 8); manager.InsertFingerprint(f8); Dictionary<int, List<Fingerprint>> dict = manager.ReadFingerprintsByMultipleTrackId(new List<Track> { track0, track1, track2 }, 0); Assert.AreNotEqual(null, dict); Assert.AreEqual(3, dict.Keys.Count); foreach (KeyValuePair<int, List<Fingerprint>> item in dict) { Assert.AreEqual(3, item.Value.Count); } Assert.AreEqual(true, dict.ContainsKey(track0.Id)); Assert.AreEqual(true, dict.ContainsKey(track1.Id)); Assert.AreEqual(true, dict.ContainsKey(track2.Id)); foreach (KeyValuePair<int, List<Fingerprint>> pair in dict) { Assert.AreEqual(3, pair.Value.Count); } }
public void ReadFingerprintByIdTest() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway manager = dalManager; const int fakeId = int.MinValue; Album album = new Album(fakeId, name, 1986); manager.InsertAlbum(album); Assert.AreNotEqual(fakeId, album); Track track = new Track(fakeId, name, name, album.Id, 360); manager.InsertTrack(track); Assert.AreNotEqual(fakeId, track.Id); Fingerprint f = new Fingerprint(fakeId, GenericFingerprint, track.Id, 0); manager.InsertFingerprint(f); Assert.AreNotEqual(fakeId, f.Id); Fingerprint readF = manager.ReadFingerprintById(f.Id); Assert.AreEqual(f.Id, readF.Id); Assert.AreEqual(f.Signature.Length, readF.Signature.Length); for (int i = 0; i < f.Signature.Length; i++) { Assert.AreEqual(f.Signature[i], readF.Signature[i]); } Assert.AreEqual(f.TrackId, readF.TrackId); }
public void InsertTrackWithBadAlbumIdForeignKeyReference() { string name = MethodBase.GetCurrentMethod().Name; Album a = new Album(int.MinValue, name, 1990); Track track = new Track(int.MinValue, name, name, a.Id); dalManager.InsertTrack(track); }
public void CheckTrackLengthConstraints() { Track track = new Track { TrackLength = int.MinValue }; }
public void InsertReadTrackTest() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway manager = dalManager; Album album = new Album(int.MinValue, name, 1986); manager.InsertAlbum(album); Assert.AreNotEqual(int.MinValue, album.Id); Track track = new Track(int.MinValue, name, name, album.Id, 360); manager.InsertTrack(track); Assert.AreNotEqual(int.MinValue, track.Id); List<Track> listOfTracks = manager.ReadTracks(); bool found = false; foreach (Track temp in listOfTracks) { Assert.IsTrue(temp.Id > 0); if (temp.Id == track.Id) { found = true; break; } } Assert.AreEqual(true, found); Track t = manager.ReadTrackById(track.Id); Assert.AreEqual(track.Id, t.Id); Assert.AreEqual(track.AlbumId, t.AlbumId); Assert.AreEqual(track.Artist, t.Artist); Assert.AreEqual(track.Title, t.Title); Assert.AreEqual(track.TrackLength, t.TrackLength); List<Album> listAlbums = new List<Album>(); for (int i = 0; i < 10; i++) { Album a = new Album(int.MinValue, name + i, i + 1986); listAlbums.Add(a); } manager.InsertAlbum(listAlbums); foreach (Album a in listAlbums) { Assert.AreNotEqual(int.MinValue, a.Id); } List<Track> listTracks = new List<Track>(); List<int> lId = new List<int>(); for (int i = 0; i < 10; i++) { Track a = new Track(int.MinValue, name + i, name + i, listAlbums[i].Id); listTracks.Add(a); } manager.InsertTrack(listTracks); foreach (Track item in listTracks) { Assert.AreNotEqual(int.MinValue, item.Id); } List<Track> readTracks = manager.ReadTracks(); List<int> lReadIds = readTracks.Select(a => a.Id).ToList(); foreach (int i in lId) { Assert.AreEqual(true, lReadIds.Contains(i)); } }
public bool InsertTrack(Track track) { IDbDataParameter dbAlbumIdParam = new SQLiteParameter("@albumid", DbType.Int64); IDbDataParameter dbLengthParam = new SQLiteParameter("@length", DbType.Int32); IDbDataParameter dbArtistParam = new SQLiteParameter("@artist", DbType.String); IDbDataParameter dbTitleParam = new SQLiteParameter("@title", DbType.String); IDbDataParameter dbFilePathParam = new SQLiteParameter("@filepath", DbType.String); IDbDataParameter dbTagsParam = new SQLiteParameter("@tags", DbType.String); IDbCommand dbcmd; lock (dbcon) { dbcmd = dbcon.CreateCommand(); } dbcmd.CommandText = "INSERT INTO tracks (albumid, length, artist, title, filepath, tags) " + "VALUES (@albumid, @length, @artist, @title, @filepath, @tags); SELECT last_insert_rowid();"; dbcmd.Parameters.Add(dbAlbumIdParam); dbcmd.Parameters.Add(dbLengthParam); dbcmd.Parameters.Add(dbArtistParam); dbcmd.Parameters.Add(dbTitleParam); dbcmd.Parameters.Add(dbFilePathParam); dbcmd.Parameters.Add(dbTagsParam); dbAlbumIdParam.Value = track.AlbumId; dbLengthParam.Value = track.TrackLengthMs; dbArtistParam.Value = track.Artist; dbTitleParam.Value = track.Title; dbFilePathParam.Value = track.FilePath; dbTagsParam.Value = string.Join(";", track.Tags.Select(x => x.Key + "=" + x.Value)); try { dbcmd.Prepare(); track.Id = Convert.ToInt32(dbcmd.ExecuteScalar()); dbcmd.Dispose(); } catch (Exception e) { throw e; } return true; }
public void ReadFingerprintByTrackIdTest() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway manager = dalManager; Album album = new Album(0, name, 1986); manager.InsertAlbum(album); Track track = new Track(0, name, name, album.Id, 360); manager.InsertTrack(track); Fingerprint f = new Fingerprint(0, GenericFingerprint, track.Id, 0); manager.InsertFingerprint(f); List<Fingerprint> list = manager.ReadFingerprintsByTrackId(track.Id, 0); Fingerprint readF = list.FirstOrDefault(temp => temp.Id == f.Id); Assert.AreNotEqual(null, readF); Assert.AreEqual(f.Id, readF.Id); Assert.AreEqual(f.Signature.Length, readF.Signature.Length); for (int i = 0; i < f.Signature.Length; i++) { Assert.AreEqual(f.Signature[i], readF.Signature[i]); } Assert.AreEqual(f.TrackId, readF.TrackId); }
public IList<Track> ReadTracks(string whereClause) { var tracks = new List<Track>(); IDbCommand dbcmd; lock (dbcon) { dbcmd = dbcon.CreateCommand(); } string query = "SELECT id, albumid, length, artist, title, filepath FROM [tracks]"; if (whereClause != null && whereClause != "") { query = string.Format("{0} {1}", query, whereClause); } dbcmd.CommandText = query; dbcmd.CommandType = CommandType.Text; IDataReader reader = dbcmd.ExecuteReader(); while (reader.Read()) { Track track = new Track(); track.Id = reader.GetInt32(0); track.AlbumId = reader.GetInt32(1); track.TrackLengthMs = reader.GetInt32(2); if (!reader.IsDBNull(3)) { track.Artist = reader.GetString(3); } track.Title = reader.GetString(4); track.FilePath = reader.GetString(5); tracks.Add(track); } reader.Close(); dbcmd.Dispose(); return tracks; }
public void ReadFingerprintsByMultipleIdsTest() { string name = MethodBase.GetCurrentMethod().Name; List<Fingerprint> listOfFingers = new List<Fingerprint>(); Album album = dalManager.ReadUnknownAlbum(); Track track = new Track(0, name, name, album.Id); dalManager.InsertTrack(track); const int Count = 100; List<int> listOfGuids = new List<int>(); const int FakeId = int.MinValue; for (int i = 0; i < Count; i++) { listOfFingers.Add(new Fingerprint(FakeId, GenericFingerprint, track.Id, 0)); } dalManager.InsertFingerprint(listOfFingers); listOfGuids.AddRange(listOfFingers.Select((f) => f.Id)); List<Fingerprint> readFingers = dalManager.ReadFingerprintById(listOfGuids); Assert.AreEqual(readFingers.Count, listOfFingers.Count); }
public IList<Track> ReadTrackById(IEnumerable<int> ids) { var tracks = new List<Track>(); IDbCommand dbcmd; lock (dbcon) { dbcmd = dbcon.CreateCommand(); } String statementValueTags = String.Join(",", ids); String query = String.Format("SELECT id, albumid, length, artist, title, filepath FROM [tracks] WHERE (id IN ({0}));", statementValueTags); dbcmd.CommandText = query; dbcmd.CommandType = CommandType.Text; dbcmd.Prepare(); IDataReader reader = dbcmd.ExecuteReader(); while (reader.Read()) { Track track = new Track(); track.Id = reader.GetInt32(0); track.AlbumId = reader.GetInt32(1); track.TrackLengthMs = reader.GetInt32(2); if (!reader.IsDBNull(3)) { track.Artist = reader.GetString(3); } track.Title = reader.GetString(4); track.FilePath = reader.GetString(5); tracks.Add(track); } reader.Close(); dbcmd.Dispose(); return tracks; }
public void ReadFingerprintsTest() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway target = new DaoGateway(connectionstring); Album album = target.ReadUnknownAlbum(); Track t = new Track(0, name, name, album.Id); target.InsertTrack(t); Fingerprint f = new Fingerprint(0, GenericFingerprint, t.Id, 10); target.InsertFingerprint(f); List<Fingerprint> actual = target.ReadFingerprints(); Assert.IsTrue(actual.Count >= 1); }
/// <summary> /// Actual synchronous insert in the database /// </summary> /// <param name = "start">Start index</param> /// <param name = "end">End index</param> private void InsertInDatabase(int start, int end) { BassProxy proxy = new BassProxy(); //Proxy used to read from file IStride stride = null; Invoke(new Action(() => { stride = WinUtils.GetStride((StrideType) _cmbStrideType.SelectedIndex, //Get stride according to the underlying combo box selection (int) _nudStride.Value, 0, _fingerManager.SamplesPerFingerprint); }), null); Action actionInterface = () => { _pbTotalSongs.PerformStep(); _nudProcessed.Value = _processed; _nudLeft.Value = _left; _nudBadFiles.Value = _badFiles; _nudDetectedDuplicates.Value = _duplicates; }; Action<object[], Color> actionAddItems = (parameters, color) => { int index = _dgvFillDatabase.Rows.Add(parameters); _dgvFillDatabase.FirstDisplayedScrollingRowIndex = index; if (color != Color.Empty) _dgvFillDatabase.Rows[index].DefaultCellStyle.BackColor = color; }; for (int i = start; i < end; i++) //Process the corresponding files { if (_stopFlag) return; TAG_INFO tags = proxy.GetTagInfoFromFile(_fileList[i]); //Get Tags from file if (tags == null) { //TAGS are null _badFiles++; Invoke(actionAddItems, new Object[] {"TAGS ARE NULL", _fileList[i], 0, 0}, Color.Red); continue; } string artist = tags.artist; //Artist string title = tags.title; //Title double duration = tags.duration; //Duration if (duration < MIN_TRACK_LENGTH || duration > MAX_TRACK_LENGTH) //Check whether the duration is ok { //Duration too small _badFiles++; Invoke(actionAddItems, new Object[] {"BAD DURATION", _fileList[i], 0, 0}, Color.Red); continue; } if (String.IsNullOrEmpty(artist) || String.IsNullOrEmpty(title)) //Check whether the tags are properly defined { //Title or Artist tag is null _badFiles++; Invoke(actionAddItems, new Object[] {"TAGS MISSING", _fileList[i], 0, 0}, Color.Red); continue; } Album album = GetCoresspondingAlbum(tags); //Get Album (whether new or unknown or aborted) if (album == null) //Check whether the user aborted return; Track track = null; lock (this) { try { if (_dalManager.ReadTrackByArtistAndTitleName(artist, title) != null) // Check if this file is already in the database { _duplicates++; //There is such file in the database continue; } track = new Track(-1, artist, title, album.Id, (int) duration); //Create New Track _dalManager.InsertTrack(track); //Insert new Track in the database } catch (Exception e) { //catch any exception and abort the insertion MessageBox.Show(e.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } int count = 0; try { List<bool[]> images = _fingerManager.CreateFingerprints(proxy, _fileList[i], stride); //Create Fingerprints and insert them in database List<Fingerprint> inserted = Fingerprint.AssociateFingerprintsToTrack(images, track.Id); _dalManager.InsertFingerprint(inserted); count = inserted.Count; switch (_hashAlgorithm) //Hash if there is a need in doing so { case HashAlgorithm.LSH: //LSH + Min Hash has been chosen HashFingerprintsUsingMinHash(inserted, track, _hashTables, _hashKeys); break; case HashAlgorithm.NeuralHasher: HashFingerprintsUsingNeuralHasher(inserted, track); break; case HashAlgorithm.None: break; } } catch (Exception e) { //catch any exception and abort the insertion MessageBox.Show(e.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Invoke(actionAddItems, new Object[] {artist, title, album.Name, duration, count}, Color.Empty); _left--; _processed++; Invoke(actionInterface); } }
public void ReadTrackByArtistAndTitle() { string name = MethodBase.GetCurrentMethod().Name; Album album = dalManager.ReadUnknownAlbum(); string artistName = name; string titleName = name; const int FakeId = int.MinValue; Track track = new Track(FakeId, artistName, titleName, album.Id); dalManager.InsertTrack(track); Assert.AreNotEqual(FakeId, track.Id); Track readTrack = dalManager.ReadTrackByArtistAndTitleName(artistName, titleName); Assert.IsNotNull(readTrack); Assert.AreEqual(artistName, readTrack.Artist); Assert.AreEqual(titleName, readTrack.Title); }
//private static Mfcc mfccOptimized = new Mfcc(WINDOW_SIZE, SAMPLING_RATE, MEL_COEFFICIENTS, MFCC_COEFFICIENTS); //private static MFCC mfccComirva = new MFCC(SAMPLING_RATE, WINDOW_SIZE, MFCC_COEFFICIENTS, true, 20.0, SAMPLING_RATE/2, MEL_COEFFICIENTS); #endif #region Methods public static bool AnalyzeAndAdd(FileInfo filePath, Db db, DatabaseService databaseService, bool doOutputDebugInfo=DEFAULT_DEBUG_INFO, bool useHaarWavelet = true) { DbgTimer t = new DbgTimer(); t.Start (); float[] audiodata = AudioFileReader.Decode(filePath.FullName, SAMPLING_RATE, SECONDS_TO_ANALYZE); if (audiodata == null || audiodata.Length == 0) { Dbg.WriteLine("Error! - No Audio Found"); return false; } // Read TAGs using BASS FindSimilar.AudioProxies.BassProxy bass = FindSimilar.AudioProxies.BassProxy.Instance; Un4seen.Bass.AddOn.Tags.TAG_INFO tag_info = bass.GetTagInfoFromFile(filePath.FullName); // Name of file being processed string name = StringUtils.RemoveNonAsciiCharacters(Path.GetFileNameWithoutExtension(filePath.Name)); #if DEBUG if (Analyzer.DEBUG_INFO_VERBOSE) { if (DEBUG_OUTPUT_TEXT) WriteAscii(audiodata, name + "_audiodata.ascii"); if (DEBUG_OUTPUT_TEXT) WriteF3Formatted(audiodata, name + "_audiodata.txt"); } #endif if (doOutputDebugInfo) { DrawGraph(MathUtils.FloatToDouble(audiodata), name + "_audiodata.png"); } // Calculate duration in ms double duration = (double) audiodata.Length / SAMPLING_RATE * 1000; // Explode samples to the range of 16 bit shorts (–32,768 to 32,767) // Matlab multiplies with 2^15 (32768) // e.g. if( max(abs(speech))<=1 ), speech = speech * 2^15; end; MathUtils.Multiply(ref audiodata, AUDIO_MULTIPLIER); // 65536 // zero pad if the audio file is too short to perform a mfcc if (audiodata.Length < (fingerprintingConfig.WdftSize + fingerprintingConfig.Overlap)) { int lenNew = fingerprintingConfig.WdftSize + fingerprintingConfig.Overlap; Array.Resize<float>(ref audiodata, lenNew); } // Get fingerprint signatures using the Soundfingerprinting methods IPermutations permutations = new LocalPermutations("Soundfingerprinting\\perms.csv", ","); Repository repository = new Repository(permutations, databaseService, fingerprintService); // Image Service ImageService imageService = new ImageService( fingerprintService.SpectrumService, fingerprintService.WaveletService); // work config WorkUnitParameterObject param = new WorkUnitParameterObject(); param.FingerprintingConfiguration = fingerprintingConfig; param.AudioSamples = audiodata; param.PathToAudioFile = filePath.FullName; param.MillisecondsToProcess = SECONDS_TO_ANALYZE * 1000; param.StartAtMilliseconds = 0; // build track Track track = new Track(); track.Title = name; track.TrackLengthMs = (int) duration; track.FilePath = filePath.FullName; track.Id = -1; // this will be set by the insert method #region parse tag_info if (tag_info != null) { Dictionary<string, string> tags = new Dictionary<string, string>(); //if (tag_info.title != string.Empty) tags.Add("title", tag_info.title); if (tag_info.artist != string.Empty) tags.Add("artist", tag_info.artist); if (tag_info.album != string.Empty) tags.Add("album", tag_info.album); if (tag_info.albumartist != string.Empty) tags.Add("albumartist", tag_info.albumartist); if (tag_info.year != string.Empty) tags.Add("year", tag_info.year); if (tag_info.comment != string.Empty) tags.Add("comment", tag_info.comment); if (tag_info.genre != string.Empty) tags.Add("genre", tag_info.genre); if (tag_info.track != string.Empty) tags.Add("track", tag_info.track); if (tag_info.disc != string.Empty) tags.Add("disc", tag_info.disc); if (tag_info.copyright != string.Empty) tags.Add("copyright", tag_info.copyright); if (tag_info.encodedby != string.Empty) tags.Add("encodedby", tag_info.encodedby); if (tag_info.composer != string.Empty) tags.Add("composer", tag_info.composer); if (tag_info.publisher != string.Empty) tags.Add("publisher", tag_info.publisher); if (tag_info.lyricist != string.Empty) tags.Add("lyricist", tag_info.lyricist); if (tag_info.remixer != string.Empty) tags.Add("remixer", tag_info.remixer); if (tag_info.producer != string.Empty) tags.Add("producer", tag_info.producer); if (tag_info.bpm != string.Empty) tags.Add("bpm", tag_info.bpm); //if (tag_info.filename != string.Empty) tags.Add("filename", tag_info.filename); tags.Add("channelinfo", tag_info.channelinfo.ToString()); //if (tag_info.duration > 0) tags.Add("duration", tag_info.duration.ToString()); if (tag_info.bitrate > 0) tags.Add("bitrate", tag_info.bitrate.ToString()); if (tag_info.replaygain_track_gain != -100f) tags.Add("replaygain_track_gain", tag_info.replaygain_track_gain.ToString()); if (tag_info.replaygain_track_peak != -1f) tags.Add("replaygain_track_peak", tag_info.replaygain_track_peak.ToString()); if (tag_info.conductor != string.Empty) tags.Add("conductor", tag_info.conductor); if (tag_info.grouping != string.Empty) tags.Add("grouping", tag_info.grouping); if (tag_info.mood != string.Empty) tags.Add("mood", tag_info.mood); if (tag_info.rating != string.Empty) tags.Add("rating", tag_info.rating); if (tag_info.isrc != string.Empty) tags.Add("isrc", tag_info.isrc); foreach(var nativeTag in tag_info.NativeTags) { string[] keyvalue = nativeTag.Split('='); tags.Add(keyvalue[0], keyvalue[1]); } track.Tags = tags; } #endregion double[][] logSpectrogram; if (repository.InsertTrackInDatabaseUsingSamples(track, 25, 4, param, out logSpectrogram)) { // store logSpectrogram as Matrix Comirva.Audio.Util.Maths.Matrix logSpectrogramMatrix = new Comirva.Audio.Util.Maths.Matrix(logSpectrogram); logSpectrogramMatrix = logSpectrogramMatrix.Transpose(); #region Debug for Soundfingerprinting Method if (doOutputDebugInfo) { imageService.GetLogSpectralImages(logSpectrogram, fingerprintingConfig.Stride, fingerprintingConfig.FingerprintLength, fingerprintingConfig.Overlap, 2).Save(name + "_specgram_logimages.png"); logSpectrogramMatrix.DrawMatrixImageLogValues(name + "_specgram_logimage.png", true); if (DEBUG_OUTPUT_TEXT) { logSpectrogramMatrix.WriteCSV(name + "_specgram_log.csv", ";"); } } #endregion #region Insert Statistical Cluster Model Similarity Audio Feature as well Comirva.Audio.Util.Maths.Matrix scmsMatrix = null; if (useHaarWavelet) { #region Wavelet Transform int lastHeight = 0; int lastWidth = 0; scmsMatrix = mfccMirage.ApplyWaveletCompression(ref logSpectrogramMatrix, out lastHeight, out lastWidth); #if DEBUG if (Analyzer.DEBUG_INFO_VERBOSE) { if (DEBUG_OUTPUT_TEXT) scmsMatrix.WriteAscii(name + "_waveletdata.ascii"); } #endif if (doOutputDebugInfo) { scmsMatrix.DrawMatrixImageLogValues(name + "_waveletdata.png", true); } #if DEBUG if (Analyzer.DEBUG_INFO_VERBOSE) { #region Inverse Wavelet // try to do an inverse wavelet transform Comirva.Audio.Util.Maths.Matrix stftdata_inverse_wavelet = mfccMirage.InverseWaveletCompression(ref scmsMatrix, lastHeight, lastWidth, logSpectrogramMatrix.Rows, logSpectrogramMatrix.Columns); if (DEBUG_OUTPUT_TEXT) stftdata_inverse_wavelet.WriteCSV(name + "_specgramlog_inverse_wavelet.csv", ";"); stftdata_inverse_wavelet.DrawMatrixImageLogValues(name + "_specgramlog_inverse_wavelet.png", true); #endregion } #endif #endregion } else { #region DCT Transform // It seems the Mirage way of applying the DCT is slightly faster than the // Comirva way due to less loops scmsMatrix = mfccMirage.ApplyDCT(ref logSpectrogramMatrix); #if DEBUG if (Analyzer.DEBUG_INFO_VERBOSE) { if (DEBUG_OUTPUT_TEXT) scmsMatrix.WriteAscii(name + "_mfccdata.ascii"); } #endif if (doOutputDebugInfo) { scmsMatrix.DrawMatrixImageLogValues(name + "_mfccdata.png", true); } #if DEBUG if (Analyzer.DEBUG_INFO_VERBOSE) { #region Inverse MFCC // try to do an inverse mfcc Comirva.Audio.Util.Maths.Matrix stftdata_inverse_mfcc = mfccMirage.InverseDCT(ref scmsMatrix); if (DEBUG_OUTPUT_TEXT) stftdata_inverse_mfcc.WriteCSV(name + "_stftdata_inverse_mfcc.csv", ";"); stftdata_inverse_mfcc.DrawMatrixImageLogValues(name + "_specgramlog_inverse_mfcc.png", true); #endregion } #endif #endregion } // Store in a Statistical Cluster Model Similarity class. // A Gaussian representation of a song Scms audioFeature = Scms.GetScms(scmsMatrix, name); if (audioFeature != null) { // Store image if debugging if (doOutputDebugInfo) { audioFeature.Image = scmsMatrix.DrawMatrixImageLogValues(name + "_featuredata.png", true, false, 0, 0, true); } // Store bitstring hash as well string hashString = GetBitString(scmsMatrix); audioFeature.BitString = hashString; // Store duration audioFeature.Duration = (long) duration; // Store file name audioFeature.Name = filePath.FullName; int id = track.Id; if (db.AddTrack(ref id, audioFeature) == -1) { Console.Out.WriteLine("Failed! Could not add audioFeature to database {0}!", name); } } #endregion } else { // failed return false; } Dbg.WriteLine ("AnalyzeAndAdd - Total Execution Time: {0} ms", t.Stop().TotalMilliseconds); return true; }
public void ReadTrackByFingerprintInexistantIdTest() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway manager = dalManager; const int FakeId = int.MinValue; Album album = new Album(FakeId, name, 1986); manager.InsertAlbum(album); Track track = new Track(FakeId, name, name, album.Id, 360); manager.InsertTrack(track); Fingerprint f = new Fingerprint(FakeId, GenericFingerprint, track.Id, 0); List<Track> list = manager.ReadTrackByFingerprint(f.Id); Assert.AreEqual(null, list); }
public void GetInsertTrackCommandTest() { string name = MethodBase.GetCurrentMethod().Name; DaoStoredProcedureBuilder target = new DaoStoredProcedureBuilder(); Track track = new Track(0, name, name, 0, 230); DbConnection connection = Dbf.CreateConnection(); IDbCommand actual = target.GetInsertTrackCommand(track, connection); Assert.AreEqual(SP_INSERT_TRACK, actual.CommandText); Assert.AreEqual(CommandType.StoredProcedure, actual.CommandType); Assert.IsNotNull(actual.Connection); Assert.AreEqual(ConnectionState.Closed, actual.Connection.State); Assert.AreEqual(4, actual.Parameters.Count); }
public void ReadTrackByFingerprintTest() { string name = MethodBase.GetCurrentMethod().Name; DaoGateway manager = dalManager; Album album = new Album(int.MinValue, name, 1986); manager.InsertAlbum(album); Track track = new Track(int.MinValue, name, name, album.Id, 360); manager.InsertTrack(track); const int FakeId = int.MinValue; Fingerprint f = new Fingerprint(FakeId, GenericFingerprint, track.Id, int.MinValue); manager.InsertFingerprint(f); Assert.AreNotEqual(FakeId, f.Id); List<Track> list = manager.ReadTrackByFingerprint(f.Id); Track readT = list.FirstOrDefault(temp => temp.Id == track.Id); Assert.AreNotEqual(null, readT); Assert.AreEqual(track.Id, readT.Id); Assert.AreEqual(track.AlbumId, readT.AlbumId); Assert.AreEqual(track.Artist, readT.Artist); Assert.AreEqual(track.Title, readT.Title); Assert.AreEqual(track.TrackLength, readT.TrackLength); }
/// <summary> /// Hash Fingerprints using Min-Hash algorithm /// </summary> /// <param name="listOfFingerprintsToHash">List of fingerprints already inserted in the database</param> /// <param name="track">Track of the corresponding fingerprints</param> /// <param name="hashTables">Number of hash tables (e.g. 25)</param> /// <param name="hashKeys">Number of hash keys (e.g. 4)</param> private bool HashFingerprintsUsingMinHash(IEnumerable<Fingerprint> listOfFingerprintsToHash, Track track, int hashTables, int hashKeys) { List<HashBinMinHash> listToInsert = new List<HashBinMinHash>(); foreach (Fingerprint fingerprint in listOfFingerprintsToHash) { int[] hashBins = minHash.ComputeMinHashSignature(fingerprint.Signature); //Compute Min Hashes Dictionary<int, long> hashTable = minHash.GroupMinHashToLSHBuckets(hashBins, hashTables, hashKeys); foreach (KeyValuePair<int, long> item in hashTable) { HashBinMinHash hash = new HashBinMinHash(-1, item.Value, item.Key, track.Id, fingerprint.Id); listToInsert.Add(hash); } } return dbService.InsertHashBin(listToInsert); }
public void ReadTrackIdByHashBinAndHashTableTest() { Album album = dalManager.ReadUnknownAlbum(); Track track = new Track( 0, "#ReadTrackIdByHashBinAndHashTableTest", "#ReadTrackIdByHashBinAndHashTableTest", album.Id); dalManager.InsertTrack(track); List<HashBinNeuralHasher> list = new List<HashBinNeuralHasher>(); const int Count = 20; long[] hashbins = new long[Count]; int[] hashtables = new int[Count]; Random rand = new Random(); const int FakeId = int.MinValue; for (int i = 0; i < Count; i++) { hashbins[i] = rand.Next(); hashtables[i] = i; list.Add(new HashBinNeuralHasher(FakeId, hashbins[i], hashtables[i], track.Id)); } dalManager.InsertHashBin(list); foreach (HashBinNeuralHasher item in list) { Assert.AreNotEqual(FakeId, item.Id); } Dictionary<int, int> result = dalManager.ReadTrackIdCandidatesByHashBinAndHashTableNeuralHasher( hashbins, hashtables); Assert.IsNotNull(result); Assert.AreEqual(true, result.ContainsKey(track.Id)); Assert.AreEqual(Count, result[track.Id]); }
/// <summary> /// Get a command to insert track in the database /// </summary> /// <param name = "track">Track to be inserted</param> /// <param name = "connection">Connection used to insert the track</param> /// <returns>Command to be executed</returns> public DbCommand GetInsertTrackCommand(Track track, DbConnection connection) { DbCommand command = GetStoredProcedureCommand(SP_INSERT_TRACK, connection); DbParameter param = command.CreateParameter(); param.ParameterName = PARAM_TRACK_ARTIST; param.DbType = DbType.String; param.Value = track.Artist; command.Parameters.Add(param); param = command.CreateParameter(); param.ParameterName = PARAM_TRACK_TITLE; param.DbType = DbType.String; param.Value = track.Title; command.Parameters.Add(param); param = command.CreateParameter(); param.ParameterName = PARAM_TRACK_ALBUM_ID; param.DbType = DbType.Int32; param.Value = track.AlbumId; command.Parameters.Add(param); param = command.CreateParameter(); param.ParameterName = PARAM_TRACK_LENGTH_SEC; param.DbType = DbType.Int32; param.Value = track.TrackLength; command.Parameters.Add(param); return command; }
public void InsertReadHashBinMinHashTest() { string name = MethodBase.GetCurrentMethod().Name; Album album = dalManager.ReadUnknownAlbum(); Track track = new Track(0, name, name, album.Id); dalManager.InsertTrack(track); Fingerprint finger = new Fingerprint(0, GenericFingerprint, track.Id, 0); dalManager.InsertFingerprint(finger); const long Hashbin = 100000; const int Hashtable = 20; HashBinMinHash hashbinminhash = new HashBinMinHash(0, Hashbin, Hashtable, track.Id, finger.Id); dalManager.InsertHashBin(hashbinminhash); Dictionary<int, List<HashBinMinHash>> result = dalManager.ReadFingerprintsByHashBucketAndHashTableLSH(new[] { Hashbin }, new[] { Hashtable }); Assert.IsNotNull(result); Assert.AreEqual(1, result.Count); Assert.AreEqual(true, result.ContainsKey(finger.Id)); Assert.AreEqual(1, result[finger.Id].Count); Assert.AreEqual(hashbinminhash.Id, result[finger.Id][0].Id); dalManager.DeleteTrack(track.Id); }