/// <summary>
        /// Parses the .arff file output from bextract.
        /// </summary>
        /// <param name="arffFile">Full path to .arff file to parse.</param>
        /// <returns>List of SongDataDTOs containing extracted features.</returns>
        public static List <SongDataDTO> parseArff(string arffFile)
        {
            List <SongDataDTO> result = new List <SongDataDTO>();
            string             arff   = File.ReadAllText(arffFile);

            string[] tokens = arff.Split(new[] { "% filename " }, StringSplitOptions.None);

            //Go through each of the songs (skip the first token, that has the bextract attribute comments)
            for (int i = 1; i < tokens.Length; i++)
            {
                string      songInfo = tokens[i];
                SongDataDTO dto      = parseSongInfo(songInfo);
                result.Add(dto);
            }
            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Classify the given songs and output a JSON string with the results.
        /// </summary>
        /// <remarks>
        /// Results will be in the following format:
        ///
        ///     { "ClassifierResults":
        ///         [ { "song":
        ///             {
        ///                 "title": "path\to\file\1.mp3",
        ///                 "energy": 0.40120655758066681,
        ///                 "positivity": 0.47041366490774172
        ///             }
        ///           },
        ///           { "song":
        ///             {
        ///                 "title": "path\to\file\2.mp3",
        ///                 "energy": 0.34171391252526506,
        ///                 "positivity": 0.28074189017885803
        ///             }
        ///           },
        ///           ...
        ///         ]
        ///     }
        /// </remarks>
        ///
        ///
        /// <param name="songPaths">Paths to the songs to classify.</param>
        public string Classify(string[] songPaths)
        {
            if (posSvm == null || energySvm == null)
            {
                throw new Exception("SVMs have not yet been trained!");
            }

            //Get features for all the songs
            List <SongDataDTO> songsWithFeatures = getFeatures(songPaths);

            //Classify each song
            List <ClassifierResult> classifierResults = new List <ClassifierResult>();

            ConsoleManager.Show();
            for (int i = 0; i < songsWithFeatures.Count; i++)
            {
                SongDataDTO songData = songsWithFeatures[i];

                ClassifierResult result = new ClassifierResult();
                Song             song   = new Song();
                //song.title = songData.getFilename(); Turns the database into .wavs
                song.title = songPaths[i];

                //Convert dto to double arrays (so svm can use them)
                double[] posFeatures    = new double[bextractPosCols.Count()];
                double[] energyFeatures = new double[bextractEnergyCols.Count()];
                ConvertSongDataDtoToDoubleArrays(songData, ref posFeatures, ref energyFeatures);

                //Run classification
                song.positivity = posSvm.Score(posFeatures);
                song.energy     = energySvm.Score(energyFeatures);

                result.song = song;
                //Fun Debugging info

                Console.WriteLine("Song: {0}\n Positivity: {1}\n Energy: {2} \n\n", song.title, song.positivity, song.energy);
                classifierResults.Add(result);
            }
            Console.WriteLine("Press Enter to continue");
            Console.ReadLine();
            ConsoleManager.Hide();

            EmotionSpaceDTOList emotionSpaceDtoList = new EmotionSpaceDTOList();

            emotionSpaceDtoList.ClassifierResults = classifierResults;
            return(JsonSerializer.serializeToJson(emotionSpaceDtoList));
        }
Beispiel #3
0
        public static List <SongDataDTO> parseArff(string arffFile)
        {
            List <SongDataDTO> result = new List <SongDataDTO>();


            string arff = File.ReadAllText(arffFile);

            string[] tokens = arff.Split(new[] { "% filename " }, StringSplitOptions.None);

            //Go through each of the songs (skip the first token, that has the bextract attribute comments)
            for (int i = 1; i < tokens.Length; i++)
            {
                string token = tokens[i];

                string[] lines    = token.Split('\n');
                string   filename = lines[0].Trim(new[] { '\n', '\r' });
                List <List <Double> > extractedFeatures = new List <List <Double> >();
                //Line two is the sampling rate, which we do not use

                //Go through each of the lines of the bextract features
                for (int j = 2; j < lines.Length; j++)
                {
                    string        feature_line = lines[j];
                    string[]      feature_strs = feature_line.Split(',');
                    List <Double> features     = new List <Double>();

                    //Convert each feature into a double, add to the double array
                    //Skip the last one, it will be 'music'
                    for (int k = 0; k < feature_strs.Length - 1; k++)
                    {
                        string feature_str = feature_strs[k];
                        Double feature     = Double.Parse(feature_str);
                        features.Add(feature);
                    }
                    extractedFeatures.Add(features);
                }
                SongDataDTO dto = new SongDataDTO(filename, extractedFeatures);
                result.Add(dto);
            }
            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Extract the data from the SongDataDTO object and place into arrays of doubles. This is needed for training.
        /// </summary>
        /// <remarks>
        /// Only pulls out the bextract columns for positivity/energy.
        /// This function will allocate the arrays.
        /// </remarks>
        /// <param name="songData">SongDataDTO object containing the bextract data to use for training.</param>
        /// <param name="posFeatures">Reference to double array to store the features needed for training positivity.</param>
        /// <param name="energyFeatures">Reference to double array to store the features needed for training energy.</param>
        private void ConvertSongDataDtoToDoubleArrays(SongDataDTO songData, ref double[] posFeatures, ref double[] energyFeatures)
        {
            //Stick them in double arrays
            List <List <Double> > features    = songData.getFeatures();
            List <Double>         featureList = features[0]; //Just pull the first row of features for now

            posFeatures    = new double[bextractPosCols.Count() + 1];
            energyFeatures = new double[bextractEnergyCols.Count() + 1];

            //Pull out relevant bextract columns
            for (int i = 1; i < bextractPosCols.Count(); i++)
            {
                int col = bextractPosCols.ElementAt(i);
                posFeatures[i] = featureList[col];
            }
            for (int i = 1; i < bextractEnergyCols.Count(); i++)
            {
                int col = bextractEnergyCols.ElementAt(i);
                energyFeatures[i] = featureList[col];
            }
        }
        /// <summary>
        /// Parses a song's section from the .arff file output of.
        /// </summary>
        /// <param name="songInfo">The song section of the .arff file. Between "% filename " tokens.</param>
        /// <returns>SongDataDTO containing extracted features</returns>
        private static SongDataDTO parseSongInfo(string songInfo)
        {
            string[] lines = songInfo.Split('\n');

            //Line 1 is the filename
            string filename = lines[0].Trim(new[] { '\n', '\r' });

            //Line two is the sampling rate, which we do not use

            //Following lines are extracted features for each sample of the song
            List <List <Double> > extractedFeatures = new List <List <Double> >();

            for (int i = 2; i < lines.Length; i++)
            {
                string        featureLine = lines[i];
                List <Double> features    = parseFeatureLine(featureLine);
                extractedFeatures.Add(features);
            }
            SongDataDTO dto = new SongDataDTO(filename, extractedFeatures);

            return(dto);
        }