public static Scms FromBytes(byte [] buf)
        {
            var scms = new Scms(Analyzer.MFCC_COEFFICIENTS);

            FromBytes(buf, scms);
            return(scms);
        }
示例#2
0
        /// <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);
        }
        // Manual deserialization of an Scms from a LittleEndian byte array
        public static void FromBytes(byte[] buf, Scms s)
        {
            byte [] buf4  = new byte[4];
            int     buf_i = 0;

            s.dim  = GetInt32(buf, buf_i, buf4);
            buf_i += 4;

            for (int i = 0; i < s.mean.Length; i++)
            {
                s.mean[i] = GetFloat(buf, buf_i, buf4);
                buf_i    += 4;
            }

            for (int i = 0; i < s.cov.Length; i++)
            {
                s.cov[i] = GetFloat(buf, buf_i, buf4);
                buf_i   += 4;
            }

            for (int i = 0; i < s.icov.Length; i++)
            {
                s.icov[i] = GetFloat(buf, buf_i, buf4);
                buf_i    += 4;
            }
        }
示例#4
0
        public static float CosineSimilarity(Scms s1, Scms s2)
        {
            float mean = 1 - CosineSimilarity(s1.mean, s2.mean);
            float cov  = 1 - CosineSimilarity(s1.cov, s2.cov);

            //float icov = CosineSimilarity(s1.icov, s2.icov) * 100;
            return(mean + cov);           // + icov;
        }
        /** Function to compute the spectral distance between two song models.
         *  This is a fast implementation of the symmetrized Kullback Leibler
         *  Divergence.
         */
        public static float Distance(Scms s1, Scms s2, ScmsConfiguration c)
        {
            float val = 0;
            int i;
            int k;
            int idx = 0;
            int dim = c.Dimension;
            int covlen = c.CovarianceLength;
            float tmp1;

            unsafe {
                fixed (float* s1cov = s1.cov, s2icov = s2.icov,
                        s1icov = s1.icov, s2cov = s2.cov,
                        s1mean = s1.mean, s2mean = s2.mean,
                        mdiff = c.MeanDiff, aicov = c.AddInverseCovariance)
                {
                    for (i = 0; i < covlen; i++) {
                        aicov[i] = s1icov[i] + s2icov[i];
                    }

                    for (i = 0; i < dim; i++) {
                        idx = i*dim - (i*i+i)/2;
                        val += s1cov[idx+i] * s2icov[idx+i] +
                            s2cov[idx+i] * s1icov[idx+i];

                        for (k = i+1; k < dim; k++) {
                            val += 2*s1cov[idx+k] * s2icov[idx+k] +
                                2*s2cov[idx+k] * s1icov[idx+k];
                        }
                    }

                    for (i = 0; i < dim; i++) {
                        mdiff[i] = s1mean[i] - s2mean[i];
                    }

                    for (i = 0; i < dim; i++) {
                        idx = i - dim;
                        tmp1 = 0;

                        for (k = 0; k <= i; k++) {
                            idx += dim - k;
                            tmp1 += aicov[idx] * mdiff[k];
                        }
                        for (k = i + 1; k < dim; k++) {
                            idx++;
                            tmp1 += aicov[idx] * mdiff[k];
                        }
                        val += tmp1 * mdiff[i];
                    }
                }
            }

            // FIXME: fix the negative return values
            //val = Math.Max(0.0f, (val/2 - s1.cov.dim));
            val = val / 4 - c.Dimension / 2;

            return val;
        }
示例#6
0
		/// <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;
		}
示例#7
0
        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)));
        }
示例#8
0
        /// <summary>
        /// Computes a Scms model from the MFCC representation of a song.
        /// </summary>
        /// <param name="mfcc">Comirva.Audio.Util.Maths.Matrix mfcc</param>
        /// <returns></returns>
        public static Scms GetScmsNoInverse(Comirva.Audio.Util.Maths.Matrix mfccs, string name)
        {
            DbgTimer t = new DbgTimer();

            t.Start();

            Comirva.Audio.Util.Maths.Matrix mean = mfccs.Mean(2);

                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    mean.WriteText(name + "_mean.txt");
                }
                mean.DrawMatrixGraph(name + "_mean.png");
            }
                        #endif

            // Covariance
            Comirva.Audio.Util.Maths.Matrix covarMatrix = mfccs.Cov(mean);
                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    covarMatrix.WriteText(name + "_covariance.txt");
                }
                covarMatrix.DrawMatrixGraph(name + "_covariance.png");
            }
                        #endif

            Comirva.Audio.Util.Maths.Matrix covarMatrixInv = new Comirva.Audio.Util.Maths.Matrix(covarMatrix.Rows, covarMatrix.Columns);

            // Store the Mean, Covariance, Inverse Covariance in an optimal format.
            int  dim = mean.Rows;
            Scms s   = new Scms(dim);
            int  l   = 0;
            for (int i = 0; i < dim; i++)
            {
                s.mean[i] = (float)mean.MatrixData[i][0];
                for (int j = i; j < dim; j++)
                {
                    s.cov[l]  = (float)covarMatrix.MatrixData[i][j];
                    s.icov[l] = (float)covarMatrixInv.MatrixData[i][j];
                    l++;
                }
            }

            Dbg.WriteLine("GetScmsNoInverse - Execution Time: {0} ms", t.Stop().TotalMilliseconds);
            return(s);
        }
示例#9
0
		/// <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;
		}
示例#10
0
        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());
        }
        public static Scms Analyze(string file_path)
        {
            DbgTimer t = new DbgTimer();

            t.Start();

            Matrix stftdata = ad.Decode(file_path);
            Matrix mfccdata = mfcc.Apply(ref stftdata);
            Scms   scms     = Scms.GetScms(mfccdata);

            long stop = 0;

            t.Stop(ref stop);
            Dbg.WriteLine("Mirage - Total Execution Time: {0}ms", stop);

            return(scms);
        }
        // Computes a Scms model from the MFCC representation of a song.
        public static Scms GetScms(Matrix mfcc)
        {
            DbgTimer t = new DbgTimer();

            t.Start();

            // Mean
            Vector m = mfcc.Mean();

            // Covariance
            Matrix c = mfcc.Covariance(m);

            // Inverse Covariance
            Matrix ic;

            try {
                ic = c.Inverse();
            } catch (MatrixSingularException) {
                throw new ScmsImpossibleException();
            }

            // Store the Mean, Covariance, Inverse Covariance in an optimal format.
            int  dim = m.rows;
            Scms s   = new Scms(dim);
            int  l   = 0;

            for (int i = 0; i < dim; i++)
            {
                s.mean[i] = m.d[i, 0];
                for (int j = i; j < dim; j++)
                {
                    s.cov[l]  = c.d[i, j];
                    s.icov[l] = ic.d[i, j];
                    l++;
                }
            }


            long stop = 0;

            t.Stop(ref stop);
            Dbg.WriteLine("Mirage - scms created in: {0}ms", stop);

            return(s);
        }
        public override IEnumerable<float> Distance(Scms from)
        {
            if (from == null) {
                yield return float.MaxValue;
                yield break;
            }

            bool any_seeds = false;
            float last_weight = -99;

            foreach (var seed in seeds) {
                var distance = Scms.Distance (seed.Scms, from, Config);
                if (distance < 0) {
                    // Ignore negative distance values
                    continue;
                }

                if (distance < min_distance) {
                    min_distance = distance;
                    best_scms = from;
                } else if (distance > max_distance) {
                    max_distance = distance;
                }

                float weighted_distance = distance / seed.Weight;
                if (debug) {
                    if (seed.Weight != last_weight) {
                        last_weight = seed.Weight;
                        Console.WriteLine ("    {0} seeds (weight {1,3:N1})", last_weight == ShuffledWeight ? "Shuffled" : last_weight == PlayedWeight ? "Played" : last_weight == SelectedWeight ? "Manually Selected" : "Skipped/Discarded", last_weight);
                    }

                    Console.WriteLine ("      distance: {0,4:N1}, weighted: {1,4:N1} from artist_id {2,4}, uri {3}",
                                       distance, weighted_distance, seed.ArtistId, seed.Uri);
                }
                yield return weighted_distance;
                any_seeds = true;
            }

            if (!any_seeds) {
                // Return the highest distance possible
                yield return Single.MaxValue;
            }
        }
示例#14
0
        /// <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);
        }
        /** Function to compute the spectral distance between two song models.
         *  This is a fast implementation of the symmetrized Kullback Leibler
         *  Divergence.
         */
        public static float Distance(Scms s1, Scms s2, ScmsConfiguration c)
        {
            float val = 0;
            int   i;
            int   k;
            int   idx    = 0;
            int   dim    = c.Dimension;
            int   covlen = c.CovarianceLength;
            float tmp1;

            unsafe
            {
                fixed(float *s1cov = s1.cov, s2icov    = s2.icov,
                      s1icov       = s1.icov, s2cov    = s2.cov,
                      s1mean       = s1.mean, s2mean   = s2.mean,
                      mdiff        = c.MeanDiff, aicov = c.AddInverseCovariance)
                {
                    for (i = 0; i < covlen; i++)
                    {
                        aicov[i] = s1icov[i] + s2icov[i];
                    }

                    for (i = 0; i < dim; i++)
                    {
                        idx  = i * dim - (i * i + i) / 2;
                        val += s1cov[idx + i] * s2icov[idx + i] +
                               s2cov[idx + i] * s1icov[idx + i];

                        for (k = i + 1; k < dim; k++)
                        {
                            val += 2 * s1cov[idx + k] * s2icov[idx + k] +
                                   2 * s2cov[idx + k] * s1icov[idx + k];
                        }
                    }

                    for (i = 0; i < dim; i++)
                    {
                        mdiff[i] = s1mean[i] - s2mean[i];
                    }

                    for (i = 0; i < dim; i++)
                    {
                        idx  = i - dim;
                        tmp1 = 0;

                        for (k = 0; k <= i; k++)
                        {
                            idx  += dim - k;
                            tmp1 += aicov[idx] * mdiff[k];
                        }
                        for (k = i + 1; k < dim; k++)
                        {
                            idx++;
                            tmp1 += aicov[idx] * mdiff[k];
                        }
                        val += tmp1 * mdiff[i];
                    }
                }
            }

            // FIXME: fix the negative return values
            //val = Math.Max(0.0f, (val/2 - s1.cov.dim));
            val = val / 4 - c.Dimension / 2;

            return(val);
        }
示例#16
0
 public static float CosineSimilarity(Scms s1, Scms s2)
 {
     float mean = 1 - CosineSimilarity(s1.mean, s2.mean);
     float cov = 1 - CosineSimilarity(s1.cov, s2.cov);
     //float icov = CosineSimilarity(s1.icov, s2.icov) * 100;
     return mean + cov;// + icov;
 }
示例#17
0
        /// <summary>
        /// Computes a Scms model from the MFCC representation of a song.
        /// </summary>
        /// <param name="mfcc">Mirage.Matrix mfcc</param>
        /// <returns></returns>
        public static Scms GetScms(Matrix mfcc, string name)
        {
            DbgTimer t = new DbgTimer();
            t.Start();

            // Mean
            Vector m = mfcc.Mean();

            #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE) {
                m.WriteText(name + "_mean_orig.txt");
                m.DrawMatrixGraph(name + "_mean_orig.png");
            }
            #endif

            // Covariance
            Matrix c = mfcc.Covariance(m);

            #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE) {
                c.WriteText(name + "_covariance_orig.txt");
                c.DrawMatrixGraph(name + "_covariance_orig.png");
            }
            #endif

            // Inverse Covariance
            Matrix ic;
            try {
                ic = c.Inverse();
            } catch (MatrixSingularException) {
                //throw new ScmsImpossibleException();
                Dbg.WriteLine("MatrixSingularException - Scms failed!");
                return null;
            }

            #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE) {
                ic.WriteAscii(name + "_inverse_covariance_orig.txt");
                ic.DrawMatrixGraph(name + "_inverse_covariance_orig.png");
            }
            #endif

            // Store the Mean, Covariance, Inverse Covariance in an optimal format.
            int dim = m.rows;
            Scms s = new Scms(dim);
            int l = 0;
            for (int i = 0; i < dim; i++) {
                s.mean[i] = m.d[i, 0];
                for (int j = i; j < dim; j++) {
                    s.cov[l] = c.d[i, j];
                    s.icov[l] = ic.d[i, j];
                    l++;
                }
            }

            Dbg.WriteLine("(Mirage) - scms created in: {0} ms", t.Stop().TotalMilliseconds);

            return s;
        }
示例#18
0
        /// <summary>
        /// Computes a Scms model from the MFCC representation of a song.
        /// </summary>
        /// <param name="mfcc">Comirva.Audio.Util.Maths.Matrix mfcc</param>
        /// <returns></returns>
        public static Scms GetScms(Comirva.Audio.Util.Maths.Matrix mfccs, string name)
        {
            DbgTimer t = new DbgTimer();
            t.Start();

            Comirva.Audio.Util.Maths.Matrix mean = mfccs.Mean(2);

            #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE) {
                mean.WriteText(name + "_mean.txt");
                mean.DrawMatrixGraph(name + "_mean.png");
            }
            #endif

            // Covariance
            Comirva.Audio.Util.Maths.Matrix covarMatrix = mfccs.Cov(mean);
            #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE) {
                covarMatrix.WriteText(name + "_covariance.txt");
                covarMatrix.DrawMatrixGraph(name + "_covariance.png");
            }
            #endif

            // Inverse Covariance
            Comirva.Audio.Util.Maths.Matrix covarMatrixInv;
            try {
                covarMatrixInv = covarMatrix.InverseGausJordan();
            } catch (Exception) {
                Dbg.WriteLine("MatrixSingularException - Scms failed!");
                return null;
            }
            #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE) {
                covarMatrixInv.WriteAscii(name + "_inverse_covariance.ascii");
                covarMatrixInv.DrawMatrixGraph(name + "_inverse_covariance.png");
            }
            #endif

            // Store the Mean, Covariance, Inverse Covariance in an optimal format.
            int dim = mean.Rows;
            Scms s = new Scms(dim);
            int l = 0;
            for (int i = 0; i < dim; i++) {
                s.mean[i] = (float) mean.MatrixData[i][0];
                for (int j = i; j < dim; j++) {
                    s.cov[l] = (float) covarMatrix.MatrixData[i][j];
                    s.icov[l] = (float) covarMatrixInv.MatrixData[i][j];
                    l++;
                }
            }

            Dbg.WriteLine("(Comirva) - scms created in: {0} ms", t.Stop().TotalMilliseconds);

            return s;
        }
示例#19
0
        /// <summary>
        /// Manual deserialization of an Scms from a LittleEndian byte array
        /// </summary>
        /// <param name="buf">byte array</param>
        /// <param name="s">song model</param>
        public static void FromBytes(byte[] buf, Scms s)
        {
            byte [] buf4 = new byte[4];
            int buf_i = 0;

            s.dim = GetInt32(buf, buf_i, buf4);
            buf_i += 4;

            for (int i = 0; i < s.mean.Length; i++) {
                s.mean[i] = GetFloat(buf, buf_i, buf4);
                buf_i += 4;
            }

            for (int i = 0; i < s.cov.Length; i++) {
                s.cov[i] = GetFloat(buf, buf_i, buf4);
                buf_i += 4;
            }

            for (int i = 0; i < s.icov.Length; i++) {
                s.icov[i] = GetFloat(buf, buf_i, buf4);
                buf_i += 4;
            }
        }
示例#20
0
 /// <summary>
 /// Manual deserialization a byte array to a Scms object
 /// </summary>
 /// <param name="buf">byte array</param>
 /// <returns>Song model</returns>
 public static Scms FromBytes(byte[] buf)
 {
     var scms = new Scms(Analyzer.MFCC_COEFFICIENTS);
     FromBytes(buf, scms);
     return scms;
 }
示例#21
0
		/// <summary>
		/// Find Similar Tracks to one or many audio files using their unique database id(s)
		/// </summary>
		/// <param name="id">an array of unique database ids for the audio files to search for similar matches</param>
		/// <param name="exclude">an array of unique database ids to ignore (normally the same as the id array)</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(int[] id, int[] exclude, Db db, Analyzer.AnalysisMethod analysisMethod, int numToTake=25, double percentage=0.2, AudioFeature.DistanceType distanceType = AudioFeature.DistanceType.KullbackLeiblerDivergence) {

			AudioFeature[] seedAudioFeatures = null;
			AudioFeature[] audioFeatures = null;
			switch (analysisMethod) {
				case Analyzer.AnalysisMethod.MandelEllis:
					seedAudioFeatures = new MandelEllis[id.Length];
					audioFeatures = new MandelEllis[100];
					break;
				case Analyzer.AnalysisMethod.SCMS:
					seedAudioFeatures = new Scms[id.Length];
					audioFeatures = new Scms[100];
					break;
			}
			
			for (int i = 0; i < seedAudioFeatures.Length; i++) {
				seedAudioFeatures[i] = db.GetTrack(id[i], analysisMethod);
			}
			
			// Get all tracks from the DB except the seedSongs
			IDataReader r = db.GetTracks(exclude, seedAudioFeatures[0].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 d;
			double dcur;
			float count;
			
			while (read > 0) {
				read = db.GetNextTracks(ref r, ref audioFeatures, ref mapping, 100, analysisMethod);
				for (int i = 0; i < read; i++) {
					
					d = 0;
					count = 0;
					for (int j = 0; j < seedAudioFeatures.Length; j++) {
						dcur = seedAudioFeatures[j].GetDistance(audioFeatures[i], distanceType);
						
						// convert to positive values
						dcur = Math.Abs(dcur);

						d += dcur;
						count++;
					}
					if (d > 0) {
						QueryResult queryResult = new QueryResult();
						queryResult.Id = mapping[i];
						queryResult.Path = audioFeatures[i].Name;
						queryResult.Duration = audioFeatures[i].Duration;
						queryResult.Similarity = d/count;
						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;
		}
示例#22
0
		/// <summary>
		/// Find Similar Tracks to one or many audio files using their unique database id(s)
		/// </summary>
		/// <param name="id">an array of unique database ids for the audio files to search for similar matches</param>
		/// <param name="exclude">an array of unique database ids to ignore (normally the same as the id array)</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(int[] id, int[] exclude, Db db, Analyzer.AnalysisMethod analysisMethod, int numToTake=25, double percentage=0.2, AudioFeature.DistanceType distanceType = AudioFeature.DistanceType.KullbackLeiblerDivergence)
		{
			DbgTimer t = new DbgTimer();
			t.Start();
			
			AudioFeature[] seedAudioFeatures = null;
			AudioFeature[] audioFeatures = null;
			switch (analysisMethod) {
				case Analyzer.AnalysisMethod.MandelEllis:
					seedAudioFeatures = new MandelEllis[id.Length];
					audioFeatures = new MandelEllis[100];
					break;
				case Analyzer.AnalysisMethod.SCMS:
					seedAudioFeatures = new Scms[id.Length];
					audioFeatures = new Scms[100];
					break;
			}
			
			for (int i = 0; i < seedAudioFeatures.Length; i++) {
				seedAudioFeatures[i] = db.GetTrack(id[i], analysisMethod);
			}
			
			// Get all tracks from the DB except the seedSongs
			IDataReader r = db.GetTracks(exclude, seedAudioFeatures[0].Duration, percentage);
			
			// store results in a dictionary
			var NameDictionary = new Dictionary<KeyValuePair<int, string>, double>();
			
			int[] mapping = new int[100];
			int read = 1;
			double d;
			double dcur;
			float count;
			
			while (read > 0) {
				read = db.GetNextTracks(ref r, ref audioFeatures, ref mapping, 100, analysisMethod);
				for (int i = 0; i < read; i++) {
					
					d = 0;
					count = 0;
					for (int j = 0; j < seedAudioFeatures.Length; j++) {
						dcur = seedAudioFeatures[j].GetDistance(audioFeatures[i], distanceType);
						
						// convert to positive values
						dcur = Math.Abs(dcur);

						d += dcur;
						count++;
					}
					if (d > 0) {
						NameDictionary.Add(new KeyValuePair<int,string>(mapping[i], audioFeatures[i].Name), d/count);
						//NameDictionary.Add(new KeyValuePair<int,string>(mapping[i], String.Format("{0} ({1} ms)", audioFeatures[i].Name, audioFeatures[i].Duration)), d/count);
					}
				}
			}
			
			// 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", String.Join(",", seedAudioFeatures.Select(p=>p.Name)), t.Stop().TotalMilliseconds));
			return sortedDict;
		}
示例#23
0
        /// <summary>
        /// Computes a Scms model from the MFCC representation of a song.
        /// </summary>
        /// <param name="mfcc">Comirva.Audio.Util.Maths.Matrix mfcc</param>
        /// <returns></returns>
        public static Scms GetScms(Comirva.Audio.Util.Maths.Matrix mfccs, string name)
        {
            DbgTimer t = new DbgTimer();

            t.Start();

            Comirva.Audio.Util.Maths.Matrix mean = mfccs.Mean(2);

                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    mean.WriteText(name + "_mean.txt");
                }
                mean.DrawMatrixGraph(name + "_mean.png");
            }
                        #endif

            // Covariance
            Comirva.Audio.Util.Maths.Matrix covarMatrix = mfccs.Cov(mean);
                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    covarMatrix.WriteText(name + "_covariance.txt");
                }
                covarMatrix.DrawMatrixGraph(name + "_covariance.png");
            }
                        #endif

            // Inverse Covariance
            Comirva.Audio.Util.Maths.Matrix covarMatrixInv;
            try {
                covarMatrixInv = covarMatrix.InverseGausJordan();
            } catch (Exception) {
                Dbg.WriteLine("MatrixSingularException - Scms failed!");
                return(null);
            }
                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    covarMatrixInv.WriteAscii(name + "_inverse_covariance.ascii");
                }
                covarMatrixInv.DrawMatrixGraph(name + "_inverse_covariance.png");
            }
                        #endif

            // Store the Mean, Covariance, Inverse Covariance in an optimal format.
            int  dim = mean.Rows;
            Scms s   = new Scms(dim);
            int  l   = 0;
            for (int i = 0; i < dim; i++)
            {
                s.mean[i] = (float)mean.MatrixData[i][0];
                for (int j = i; j < dim; j++)
                {
                    s.cov[l]  = (float)covarMatrix.MatrixData[i][j];
                    s.icov[l] = (float)covarMatrixInv.MatrixData[i][j];
                    l++;
                }
            }

            Dbg.WriteLine("Compute Scms - Execution Time: {0} ms", t.Stop().TotalMilliseconds);
            return(s);
        }
示例#24
0
        // Computes a Scms model from the MFCC representation of a song.
        public static Scms GetScms(Matrix mfcc)
        {
            DbgTimer t = new DbgTimer();
            t.Start();

            // Mean
            Vector m = mfcc.Mean();

            // Covariance
            Matrix c = mfcc.Covariance(m);

            // Inverse Covariance
            Matrix ic;
            try {
                ic = c.Inverse();
            } catch (MatrixSingularException) {
                throw new ScmsImpossibleException();
            }

            // Store the Mean, Covariance, Inverse Covariance in an optimal format.
            int dim = m.rows;
            Scms s = new Scms(dim);
            int l = 0;
            for (int i = 0; i < dim; i++) {
                s.mean[i] = m.d[i, 0];
                for (int j = i; j < dim; j++) {
                    s.cov[l] = c.d[i, j];
                    s.icov[l] = ic.d[i, j];
                    l++;
                }
            }

            long stop = 0;
            t.Stop(ref stop);
            Dbg.WriteLine("Mirage - scms created in: {0}ms", stop);

            return s;
        }
示例#25
0
		/// <summary>
		/// Computes a Scms model from the MFCC representation of a song.
		/// </summary>
		/// <param name="mfcc">Comirva.Audio.Util.Maths.Matrix mfcc</param>
		/// <returns></returns>
		public static Scms GetScmsNoInverse(Comirva.Audio.Util.Maths.Matrix mfccs, string name) {
			DbgTimer t = new DbgTimer();
			t.Start();
			
			Comirva.Audio.Util.Maths.Matrix mean = mfccs.Mean(2);

			#if DEBUG
			if (Analyzer.DEBUG_INFO_VERBOSE) {
				if (Analyzer.DEBUG_OUTPUT_TEXT) mean.WriteText(name + "_mean.txt");
				mean.DrawMatrixGraph(name + "_mean.png");
			}
			#endif

			// Covariance
			Comirva.Audio.Util.Maths.Matrix covarMatrix = mfccs.Cov(mean);
			#if DEBUG
			if (Analyzer.DEBUG_INFO_VERBOSE) {
				if (Analyzer.DEBUG_OUTPUT_TEXT) covarMatrix.WriteText(name + "_covariance.txt");
				covarMatrix.DrawMatrixGraph(name + "_covariance.png");
			}
			#endif
			
			Comirva.Audio.Util.Maths.Matrix covarMatrixInv = new Comirva.Audio.Util.Maths.Matrix(covarMatrix.Rows, covarMatrix.Columns);
			
			// Store the Mean, Covariance, Inverse Covariance in an optimal format.
			int dim = mean.Rows;
			Scms s = new Scms(dim);
			int l = 0;
			for (int i = 0; i < dim; i++) {
				s.mean[i] = (float) mean.MatrixData[i][0];
				for (int j = i; j < dim; j++) {
					s.cov[l] = (float) covarMatrix.MatrixData[i][j];
					s.icov[l] = (float) covarMatrixInv.MatrixData[i][j];
					l++;
				}
			}

			Dbg.WriteLine("GetScmsNoInverse - Execution Time: {0} ms", t.Stop().TotalMilliseconds);
			return s;
		}
示例#26
0
        /// <summary>
        /// Computes a Scms model from the MFCC representation of a song.
        /// </summary>
        /// <param name="mfcc">Mirage.Matrix mfcc</param>
        /// <returns></returns>
        public static Scms GetScms(Matrix mfcc, string name)
        {
            DbgTimer t = new DbgTimer();

            t.Start();

            // Mean
            Vector m = mfcc.Mean();

                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    m.WriteText(name + "_mean_orig.txt");
                }
                m.DrawMatrixGraph(name + "_mean_orig.png");
            }
                        #endif

            // Covariance
            Matrix c = mfcc.Covariance(m);

                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    c.WriteText(name + "_covariance_orig.txt");
                }
                c.DrawMatrixGraph(name + "_covariance_orig.png");
            }
                        #endif

            // Inverse Covariance
            Matrix ic;
            try {
                ic = c.Inverse();
            } catch (MatrixSingularException) {
                //throw new ScmsImpossibleException();
                Dbg.WriteLine("MatrixSingularException - Scms failed!");
                return(null);
            }

                        #if DEBUG
            if (Analyzer.DEBUG_INFO_VERBOSE)
            {
                if (Analyzer.DEBUG_OUTPUT_TEXT)
                {
                    ic.WriteAscii(name + "_inverse_covariance_orig.txt");
                }
                ic.DrawMatrixGraph(name + "_inverse_covariance_orig.png");
            }
                        #endif

            // Store the Mean, Covariance, Inverse Covariance in an optimal format.
            int  dim = m.rows;
            Scms s   = new Scms(dim);
            int  l   = 0;
            for (int i = 0; i < dim; i++)
            {
                s.mean[i] = m.d[i, 0];
                for (int j = i; j < dim; j++)
                {
                    s.cov[l]  = c.d[i, j];
                    s.icov[l] = ic.d[i, j];
                    l++;
                }
            }

            Dbg.WriteLine("(Mirage) - scms created in: {0} ms", t.Stop().TotalMilliseconds);

            return(s);
        }
 public abstract IEnumerable<float> Distance(Scms from);