public static async Task <float> GetAverageAsync(List <FullTrack> playlist, AudioFeature feature) { var total = 0f; foreach (var playlistTrack in playlist) { var audioFeatures = await SpotifyEasyApiHandler.Api.GetAudioFeaturesAsync(playlistTrack.Id).ConfigureAwait(false); total += feature switch { AudioFeature.Acousticness => (int)Math.Round(audioFeatures.Acousticness * 100), AudioFeature.Danceability => (int)Math.Round(audioFeatures.Danceability * 100), AudioFeature.Energy => (int)Math.Round(audioFeatures.Energy * 100), AudioFeature.Instrumentalness => (int)Math.Round(audioFeatures.Instrumentalness * 100), AudioFeature.Loudness => (int)Math.Round(audioFeatures.Loudness), AudioFeature.Valence => (int)Math.Round(audioFeatures.Valence * 100), AudioFeature.Tempo => (int)Math.Round(audioFeatures.Tempo), _ => throw new ArgumentOutOfRangeException(nameof(feature), feature, null) }; } Console.WriteLine("Average: " + total / playlist.Count + " of type: " + feature); return(total / playlist.Count); } #endregion Methods }
/// <summary> /// Using the passed datareader pointer, fill the audio feature tracks array with content /// </summary> /// <param name="tracksIterator">datareader pointer</param> /// <param name="tracks">AudioFeature array</param> /// <param name="mapping">array of trackids</param> /// <param name="len">number of tracks to return</param> /// <param name="analysisMethod">analysis method (SCMS or MandelEllis)</param> /// <returns>number of tracks returned</returns> public int GetNextTracks(ref IDataReader tracksIterator, ref AudioFeature[] tracks, ref int[] mapping, int len, Analyzer.AnalysisMethod analysisMethod) { int i = 0; while ((i < len) && tracksIterator.Read()) { AudioFeature audioFeature = null; switch (analysisMethod) { case Analyzer.AnalysisMethod.MandelEllis: audioFeature = MandelEllis.FromBytes((byte[])tracksIterator.GetValue(0)); break; case Analyzer.AnalysisMethod.SCMS: audioFeature = Scms.FromBytes((byte[])tracksIterator.GetValue(0)); break; } mapping[i] = tracksIterator.GetInt32(1); audioFeature.Name = tracksIterator.GetString(2); audioFeature.Duration = tracksIterator.GetInt64(3); audioFeature.BitString = tracksIterator.GetString(4); tracks[i] = audioFeature; i++; } if (i == 0) { tracksIterator.Close(); tracksIterator = null; } return(i); }
private void FindByIdScms(int queryId) { if (queryId != -1) { int[] seedTrackIds = new int[] { queryId }; AudioFeature m1 = db.GetTrack(queryId, analysisMethod); if (m1 != null) { // Add the found similar tracks var similarTracks = Mir.SimilarTracksList(seedTrackIds, seedTrackIds, db, analysisMethod, DEFAULT_NUM_TO_TAKE, percentage, distanceType); // Add the one we are querying with at the top similarTracks.Insert(0, new QueryResult(queryId, m1.Name, m1.Duration, 0)); queryResultList = new BindingList <QueryResult>(similarTracks); bs.DataSource = queryResultList; dataGridView1.DataSource = queryResultList; this.dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; this.dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } else { MessageBox.Show("File-id does not exist!"); } } }
void DumpDebugInfoToolStripMenuItemClick(object sender, EventArgs e) { FileInfo fileInfo = new FileInfo(selectedFilePath); if (!fileInfo.Exists) { MessageBox.Show("File does not exist!"); } // TODO: Must also use right analyser, sound analyser missing completely AudioFeature feature = null; switch (analysisMethod) { case Analyzer.AnalysisMethod.MandelEllis: feature = Analyzer.AnalyzeMandelEllis(fileInfo, true); break; case Analyzer.AnalysisMethod.SCMS: feature = Analyzer.AnalyzeScms(fileInfo, true); break; } if (feature != null) { string text = String.Format("Name: {0}\nDuration: {1} ms", feature.Name, feature.Duration); MessageBox.Show(text, "Feature information"); } }
/// <summary> /// Compare to audio files using their audio ids and print the distance between them /// </summary> /// <param name="trackId1">audio 1 id</param> /// <param name="trackId2">audio 2 id</param> /// <param name="db">database</param> /// <param name="analysisMethod">analysis method (SCMS or MandelEllis)</param> public static void Compare(int trackId1, int trackId2, Db db, Analyzer.AnalysisMethod analysisMethod) { AudioFeature m1 = db.GetTrack(trackId1, analysisMethod); AudioFeature m2 = db.GetTrack(trackId2, analysisMethod); System.Console.Out.WriteLine("Similarity between m1 and m2 is: " + m1.GetDistance(m2)); }
/// <summary> /// Find Similar Tracks to an audio file using its file path /// </summary> /// <param name="searchForPath">audio file path</param> /// <param name="db">database</param> /// <param name="analysisMethod">analysis method (SCMS or MandelEllis)</param> /// <param name="numToTake">max number of entries to return</param> /// <param name="percentage">percentage below and above the duration in ms when querying (used if between 0.1 - 0.9)</param> /// <param name="distanceType">distance method to use (KullbackLeiblerDivergence is default)</param> /// <returns>a list of query results</returns> public static List<FindSimilar.QueryResult> SimilarTracksList(string searchForPath, Db db, Analyzer.AnalysisMethod analysisMethod, int numToTake=25, double percentage=0.2, AudioFeature.DistanceType distanceType = AudioFeature.DistanceType.KullbackLeiblerDivergence) { FileInfo fi = new FileInfo(searchForPath); AudioFeature seedAudioFeature = null; AudioFeature[] audioFeatures = null; switch (analysisMethod) { case Analyzer.AnalysisMethod.MandelEllis: seedAudioFeature = Analyzer.AnalyzeMandelEllis(fi); audioFeatures = new MandelEllis[100]; break; case Analyzer.AnalysisMethod.SCMS: seedAudioFeature = Analyzer.AnalyzeScms(fi); audioFeatures = new Scms[100]; break; } // Get all tracks from the DB except the seedSongs IDataReader r = db.GetTracks(null, seedAudioFeature.Duration, percentage); // store results in a query results list List<FindSimilar.QueryResult> queryResultList = new List<FindSimilar.QueryResult>(); int[] mapping = new int[100]; int read = 1; double dcur; while (read > 0) { read = db.GetNextTracks(ref r, ref audioFeatures, ref mapping, 100, analysisMethod); for (int i = 0; i < read; i++) { dcur = seedAudioFeature.GetDistance(audioFeatures[i], distanceType); // convert to positive values dcur = Math.Abs(dcur); QueryResult queryResult = new QueryResult(); queryResult.Id = mapping[i]; queryResult.Path = audioFeatures[i].Name; queryResult.Duration = audioFeatures[i].Duration; queryResult.Similarity = dcur; queryResultList.Add(queryResult); } } var sortedList = (from row in queryResultList orderby row.Similarity ascending select new QueryResult { Id = row.Id, Path = row.Path, Duration = row.Duration, Similarity = row.Similarity }).Take(numToTake).ToList(); return sortedList; }
public override double GetDistance(AudioFeature f) { if (!(f is Scms)) { new Exception("Can only handle AudioFeatures of type Scms, not of: " + f); return(-1); } Scms other = (Scms)f; return(Distance(this, other, new ScmsConfiguration(Analyzer.MFCC_COEFFICIENTS))); }
/// <summary> /// Find Similar Tracks to an audio file using its file path /// </summary> /// <param name="searchForPath">audio file path</param> /// <param name="db">database</param> /// <param name="analysisMethod">analysis method (SCMS or MandelEllis)</param> /// <param name="numToTake">max number of entries to return</param> /// <param name="percentage">percentage below and above the duration in ms when querying (used if between 0.1 - 0.9)</param> /// <param name="distanceType">distance method to use (KullbackLeiblerDivergence is default)</param> /// <returns>a dictinary list of key value pairs (filepath and distance)</returns> public static Dictionary<KeyValuePair<int, string>, double> SimilarTracks(string searchForPath, Db db, Analyzer.AnalysisMethod analysisMethod, int numToTake=25, double percentage=0.2, AudioFeature.DistanceType distanceType = AudioFeature.DistanceType.KullbackLeiblerDivergence) { DbgTimer t = new DbgTimer(); t.Start(); FileInfo fi = new FileInfo(searchForPath); AudioFeature seedAudioFeature = null; AudioFeature[] audioFeatures = null; switch (analysisMethod) { case Analyzer.AnalysisMethod.MandelEllis: seedAudioFeature = Analyzer.AnalyzeMandelEllis(fi); audioFeatures = new MandelEllis[100]; break; case Analyzer.AnalysisMethod.SCMS: seedAudioFeature = Analyzer.AnalyzeScms(fi); audioFeatures = new Scms[100]; break; } // Get all tracks from the DB except the seedSongs IDataReader r = db.GetTracks(null, seedAudioFeature.Duration, percentage); // store results in a dictionary var NameDictionary = new Dictionary<KeyValuePair<int, string>, double>(); int[] mapping = new int[100]; int read = 1; double dcur; while (read > 0) { read = db.GetNextTracks(ref r, ref audioFeatures, ref mapping, 100, analysisMethod); for (int i = 0; i < read; i++) { dcur = seedAudioFeature.GetDistance(audioFeatures[i], distanceType); // convert to positive values dcur = Math.Abs(dcur); NameDictionary.Add(new KeyValuePair<int,string>(mapping[i], audioFeatures[i].Name), dcur); } } // sort by non unique values var sortedDict = (from entry in NameDictionary orderby entry.Value ascending select entry) .Take(numToTake) .ToDictionary(pair => pair.Key, pair => pair.Value); Console.Out.WriteLine(String.Format("Found Similar to ({0}) in {1} ms", seedAudioFeature.Name, t.Stop().TotalMilliseconds)); return sortedDict; }
public override double GetDistance(AudioFeature f, AudioFeature.DistanceType t) { if (!(f is Scms)) { new Exception("Can only handle AudioFeatures of type Scms, not of: " + f); return(-1); } Scms other = (Scms)f; DistanceMeasure distanceMeasure = DistanceMeasure.Euclidean; switch (t) { case AudioFeature.DistanceType.Dtw_Euclidean: distanceMeasure = DistanceMeasure.Euclidean; break; case AudioFeature.DistanceType.Dtw_SquaredEuclidean: distanceMeasure = DistanceMeasure.SquaredEuclidean; break; case AudioFeature.DistanceType.Dtw_Manhattan: distanceMeasure = DistanceMeasure.Manhattan; break; case AudioFeature.DistanceType.Dtw_Maximum: distanceMeasure = DistanceMeasure.Maximum; break; case AudioFeature.DistanceType.UCR_Dtw: return(UCRCSharp.UCR.DTW(this.GetArray(), other.GetArray())); case AudioFeature.DistanceType.CosineSimilarity: return(CosineSimilarity(this, other)); case AudioFeature.DistanceType.BitStringHamming: return(Imghash.ImagePHash.HammingDistance(this.BitString, other.BitString)); case AudioFeature.DistanceType.KullbackLeiblerDivergence: default: return(Distance(this, other, new ScmsConfiguration(Analyzer.MFCC_COEFFICIENTS))); } Dtw dtw = new Dtw(this.GetArray(), other.GetArray(), distanceMeasure, true, true, null, null, null); return(dtw.GetCost()); }
/// <summary> /// Get a track from the database using its id /// </summary> /// <param name="trackid">id</param> /// <param name="analysisMethod">analysis method (SCMS or MandelEllis)</param> /// <returns>an AudioFeature object</returns> public AudioFeature GetTrack(int trackid, Analyzer.AnalysisMethod analysisMethod) { IDbCommand dbcmd; lock (dbcon) { dbcmd = dbcon.CreateCommand(); } dbcmd.CommandText = "SELECT audioFeature, name, duration, bitstring FROM mirage " + "WHERE trackid = " + trackid; IDataReader reader = dbcmd.ExecuteReader(); if (!reader.Read()) { return(null); } byte[] buf = (byte[])reader.GetValue(0); string name = reader.GetString(1); long duration = reader.GetInt64(2); string bitstring = reader.GetString(3); reader.Close(); AudioFeature audioFeature = null; switch (analysisMethod) { case Analyzer.AnalysisMethod.MandelEllis: audioFeature = MandelEllis.FromBytes(buf); break; case Analyzer.AnalysisMethod.SCMS: audioFeature = Scms.FromBytes(buf); break; } audioFeature.Name = name; audioFeature.Duration = duration; audioFeature.BitString = bitstring; return(audioFeature); }
/// <summary> /// Compare to audio files and print the distance between them /// </summary> /// <param name="path1">audio 1 file path</param> /// <param name="path2">audio 2 file path</param> /// <param name="analysisMethod">analysis method (SCMS or MandelEllis)</param> public static void Compare(string path1, string path2, Analyzer.AnalysisMethod analysisMethod) { AudioFeature m1 = null; AudioFeature m2 = null; FileInfo filePath1 = new FileInfo(path1); FileInfo filePath2 = new FileInfo(path2); switch (analysisMethod) { case Analyzer.AnalysisMethod.MandelEllis: m1 = Analyzer.AnalyzeMandelEllis(filePath1); m2 = Analyzer.AnalyzeMandelEllis(filePath2); break; case Analyzer.AnalysisMethod.SCMS: m1 = Analyzer.AnalyzeScms(filePath1); m2 = Analyzer.AnalyzeScms(filePath2); break; } System.Console.Out.WriteLine("Similarity between m1 and m2 is: " + m1.GetDistance(m2)); }
/// <summary> /// Add a track to the database /// </summary> /// <param name="audioFeature">the audiofeature object</param> /// <returns>-1 if failed otherwise the track-id passed</returns> public int AddTrack(AudioFeature audioFeature) { IDbDataParameter dbAudioFeatureParam = new SQLiteParameter("@audioFeature", DbType.Binary); IDbDataParameter dbNameParam = new SQLiteParameter("@name", DbType.String); IDbDataParameter dbDurationParam = new SQLiteParameter("@duration", DbType.Int64); IDbDataParameter dbBitStringParam = new SQLiteParameter("@bitstring", DbType.String); IDbCommand dbcmd; lock (dbcon) { dbcmd = dbcon.CreateCommand(); } dbcmd.CommandText = "INSERT INTO mirage (audioFeature, name, duration, bitstring) " + "VALUES (@audioFeature, @name, @duration, @bitstring); SELECT last_insert_rowid();"; dbcmd.Parameters.Add(dbAudioFeatureParam); dbcmd.Parameters.Add(dbNameParam); dbcmd.Parameters.Add(dbDurationParam); dbcmd.Parameters.Add(dbBitStringParam); dbAudioFeatureParam.Value = audioFeature.ToBytes(); dbNameParam.Value = audioFeature.Name; dbDurationParam.Value = audioFeature.Duration; dbBitStringParam.Value = audioFeature.BitString; int trackid = -1; try { dbcmd.Prepare(); //dbcmd.ExecuteNonQuery(); trackid = Convert.ToInt32(dbcmd.ExecuteScalar()); dbcmd.Dispose(); } catch (Exception) { return(-1); } return(trackid); }
/// <summary> /// Add a track to the database using the given track-id /// </summary> /// <param name="trackid">track-id to use</param> /// <param name="audioFeature">the audiofeature object</param> /// <returns>-1 if failed otherwise the track-id passed</returns> public int AddTrack(ref int trackid, AudioFeature audioFeature) { IDbDataParameter dbTrackIdParam = new SQLiteParameter("@trackid", DbType.Int64); IDbDataParameter dbAudioFeatureParam = new SQLiteParameter("@audioFeature", DbType.Binary); IDbDataParameter dbNameParam = new SQLiteParameter("@name", DbType.String); IDbDataParameter dbDurationParam = new SQLiteParameter("@duration", DbType.Int64); IDbDataParameter dbBitStringParam = new SQLiteParameter("@bitstring", DbType.String); dbTrackIdParam.Value = trackid; dbAudioFeatureParam.Value = audioFeature.ToBytes(); dbNameParam.Value = audioFeature.Name; dbDurationParam.Value = audioFeature.Duration; dbBitStringParam.Value = audioFeature.BitString; IDbCommand dbcmd; lock (dbcon) { dbcmd = dbcon.CreateCommand(); } dbcmd.CommandText = "INSERT INTO mirage (trackid, audioFeature, name, duration, bitstring) " + "VALUES (@trackid, @audioFeature, @name, @duration, @bitstring)"; dbcmd.Parameters.Add(dbTrackIdParam); dbcmd.Parameters.Add(dbAudioFeatureParam); dbcmd.Parameters.Add(dbNameParam); dbcmd.Parameters.Add(dbDurationParam); dbcmd.Parameters.Add(dbBitStringParam); try { dbcmd.ExecuteNonQuery(); } catch (SQLiteException) { return(-1); } //trackid++; return(trackid); }
public override double GetDistance(AudioFeature f) { throw new NotImplementedException(); }