예제 #1
0
        /// <summary>
        /// Gets song data via song_id
        /// </summary>
        /// <param name="song_id">song_id in DataBase</param>
        public TransferDataFFT GetSongData(int song_id)
        {
            TransferDataSong tds   = new TransferDataSong();
            TransferDataFFT  tdf   = new TransferDataFFT();
            string           query = "SELECT data FROM songs WHERE song_id=" + song_id;

            using (SQLiteConnection connection = new SQLiteConnection(cb.ConnectionString))
            {
                connection.Open();
                using (SQLiteCommand command = new SQLiteCommand(connection))
                {
                    command.CommandText = query;
                    command.CommandType = CommandType.Text;
                    using (SQLiteDataReader Reader = command.ExecuteReader())
                    {
                        while (Reader.Read())
                        {
                            int    DataRowNumber = Reader.GetOrdinal("data");
                            byte[] buffer        = new byte[Reader.GetBytes(DataRowNumber, 0, null, 0, int.MaxValue)];
                            Reader.GetBytes(DataRowNumber, 0, buffer, 0, buffer.Length);
                            tds.data = buffer;
                            tdf      = tds.DeserializeData();
                        }
                    }
                }
            }
            return(tdf);
        }
        public int[] GetSongsBySpectra(FrequencyState[] State, int NumberOfSongsToShow = 20)
        {
            List <TransferDataSong> list = db.GetAllRecords();
            int size = list.Count;

            TransferDataFFT[] arr     = new TransferDataFFT[size];
            int[]             Score   = new int[size];
            int[]             indexes = new int[size];
            for (int i = 0; i < size; i++)
            {
                arr[i]     = list[i].DeserializeData();
                indexes[i] = list[i].id;
            }
            int FreqCount = (arr[0].meanF.Length - 1) / State.Length;

            for (int j = 0; j < State.Length; j++)
            {
                if (State[j] != FrequencyState.Off)
                {
                    double   sum;
                    int[]    ind = Enumerable.Range(0, size).ToArray();
                    double[] Freq = new double[size];
                    int      le = j * FreqCount, re = le + FreqCount;
                    for (int i = 0; i < size; i++)
                    {
                        sum = 0;
                        for (int k = le; k < re; k++)
                        {
                            sum += arr[i].meanF[k] / FreqCount;
                        }
                        Freq[i] = sum;
                    }
                    if (State[j] == FrequencyState.Min)
                    {
                        Array.Sort(Freq, ind);
                        for (int i = 0; i < size; i++)
                        {
                            Score[ind[i]] += size - i - 1;
                        }
                    }
                    else
                    {
                        Array.Sort(Freq, ind);
                        for (int i = 0; i < size; i++)
                        {
                            Score[ind[i]] += i;
                        }
                    }
                }
            }

            Array.Sort(Score, indexes);
            Array.Reverse(indexes);
            return(indexes.Take(NumberOfSongsToShow).ToArray());
        }
        public int[] GetSimilarSongs(int song_id, int MethodId = 1, int NumberOfSongsToShow = 20)
        {
            List <TransferDataSong> list = db.GetAllRecords();
            int size = list.Count;

            TransferDataFFT[] arr     = new TransferDataFFT[size];
            int[]             indexes = new int[size];
            for (int i = 0; i < size; i++)
            {
                arr[i]     = list[i].DeserializeData();
                indexes[i] = list[i].id;
            }
            int song_number = Array.IndexOf(indexes, song_id);

            double[] sim = new double[size];
            for (int i = 0; i < size; i++)
            {
                sim[i] = GetSimilarity(arr[i], arr[song_number], MethodId);
            }
            Array.Sort(sim, indexes);
            return(indexes.Skip(1).Take(NumberOfSongsToShow).ToArray());
        }
        public double GetSimilarity(TransferDataFFT sample1, TransferDataFFT sample2, int MethodId)
        {
            double res        = 0;
            int    FreqNumber = sample1.meanF.Length;

            switch (MethodId)
            {
            case 1:
                for (int i = 0; i < FreqNumber; i++)
                {
                    res += Math.Pow(sample1.meanF[i] - sample2.meanF[i], 2) / Math.Pow(sample1.meanF[i] + sample2.meanF[i], 2);
                }
                break;

            case 2:
                for (int i = 0; i < FreqNumber; i++)
                {
                    res += Math.Pow(sample1.meanF[i] - sample2.meanF[i], 2) / Math.Pow(sample1.meanF[i] + sample2.meanF[i], 2) +
                           Math.Pow(sample1.medianF[i] - sample2.medianF[i], 2) / Math.Pow(sample1.medianF[i] + sample2.medianF[i], 2) +
                           Math.Pow(sample1.stdF[i] - sample2.stdF[i], 2) / Math.Pow(sample1.stdF[i] + sample2.stdF[i], 2);
                }
                break;

            case 3:
                res = 1;
                for (int i = 0; i < FreqNumber; i++)
                {
                    if (sample1.meanF[i] > sample2.meanF[i])
                    {
                        res *= sample1.meanF[i] / sample2.meanF[i];
                    }
                    else
                    {
                        res *= sample2.meanF[i] / sample1.meanF[i];
                    }
                }
                break;

            case 4:
                int size = sample1.meanF.Length;
                res = 1;
                for (int i = 0; i < size; i++)
                {
                    if (sample1.meanF[i] > sample2.meanF[i])
                    {
                        res *= sample1.meanF[i] / sample2.meanF[i];
                    }
                    else
                    {
                        res *= sample2.meanF[i] / sample1.meanF[i];
                    }
                }
                int[]    indexes1 = Enumerable.Range(1, size).ToArray();
                int[]    indexes2 = Enumerable.Range(1, size).ToArray();
                double[] sig1     = sample1.meanF;
                double[] sig2     = sample2.meanF;
                Array.Sort(sig1, indexes1);
                Array.Sort(sig2, indexes2);
                int sum = 1;
                for (int i = 0; i < size; i++)
                {
                    sum += Math.Abs(indexes1[i] - indexes2[i]);
                }
                res = res * sum;
                break;
            }

            return(res);
        }