private void Run_Click(object sender, RoutedEventArgs e)
        {
            if (_data.Count <= 0)
            {
                MessageBox.Show(this, "You cannot run an analysis without input", "Error", MessageBoxButton.OK,
                                MessageBoxImage.Error);
                return;
            }

            Forms.FolderBrowserDialog folderDialog = new Forms.FolderBrowserDialog()
            {
                Description         = "Song Directory",
                ShowNewFolderButton = false,
            };
            Forms.DialogResult dialogResult = folderDialog.ShowDialog();
            if (dialogResult == Forms.DialogResult.OK)
            {
                string selectedSongPath = folderDialog.SelectedPath;
                var    list             = _data.Select(sd => _analysisTypeContextSelected ? sd.Context : sd.Theme);
                var    uniqueList       = list.Distinct().ToList();
                // put this in a new thread
                _musicAnalysis = new MusicAnalyzer(uniqueList);
                // load

                int epoch = 0;
                int.TryParse(TxbEpoch.Text, out epoch);
                object arguments = new MusicArg
                {
                    Analyzer  = _musicAnalysis,
                    Epoch     = epoch,
                    SongData  = _data,
                    IsContext = _analysisTypeContextSelected,
                    FilePath  = selectedSongPath
                };
                // var objRef = _backgroundWorker.CreateObjRef(typeof(MusicAnalyzer));

                _backgroundWorker.RunWorkerAsync(arguments);

                // new Thread(new ThreadStart(Analyze))
                BtnRun.IsEnabled    = false;
                LblProgress.Content = "Running...";
            }
        }
        private void Worker_Work(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bw = sender as BackgroundWorker;

            MusicArg args = (MusicArg)e.Argument;

            Random r = new Random();

            if (args.Epoch <= 0)
            {
                double error = double.PositiveInfinity;
                double previous;
                do
                {
                    Shuffle(args.SongData, r);
                    previous = error;
                    error    = 0;
                    for (int j = 0; j < args.SongData.Count; j++)
                    {
                        SongData song = args.SongData[j];

                        string songFile = System.IO.Path.Combine(args.FilePath, song.Source, song.Name + ".wav");
                        //// Console.WriteLine("Trying to load file...{0}", file);
                        AudioEngineCSharp.AudioEngine.Audio audio = AudioEngineCSharp.AudioEngine.Load(songFile, false, false);
                        //// load up the file


                        unsafe
                        {
                            // error += args.Analyzer.AddData(audio.RawData, audio.DataSize, args.IsContext ? song.Context : song.Theme, true);
                        }
                        //// _themeAnalyzer.AddData(a.Data, data.Theme);
                        audio.Dispose();

                        // float percent = ((float)(i * args.SongData.Count + (j + 1))) / totalNum;
                        // int progress = (int)(Math.Round(percent * 100));
                        Debug.WriteLine(string.Format("Finished ({0}) {1}", song.Source, song.Name));
                        // bw.ReportProgress(progress);
                    }
                    Debug.WriteLine(string.Format("Error: {0}, Previous: {1}", error, previous));
                    // } while (Math.Abs(previous - error) >= 1e-10 * previous);
                } while (Math.Abs(previous - error) >= 1e-4);
            }
            else
            {
                int totalNum = args.SongData.Count * args.Epoch;

                // prepreprocess
                for (int i = 0; i < args.SongData.Count; i++)
                {
                    SongData song     = args.SongData[i];
                    string   songFile = System.IO.Path.Combine(args.FilePath, song.Source, song.Name + ".wav");
                    AudioEngineCSharp.AudioEngine.Audio audio = AudioEngineCSharp.AudioEngine.Load(songFile, false, false);

                    unsafe
                    {
                        args.Analyzer.PreprocessAddData(audio.RawData, audio.DataSize);
                    }
                    audio.Dispose();
                }

                args.Analyzer.PreDeviation();

                for (int i = 0; i < args.SongData.Count; i++)
                {
                    SongData song     = args.SongData[i];
                    string   songFile = System.IO.Path.Combine(args.FilePath, song.Source, song.Name + ".wav");
                    AudioEngineCSharp.AudioEngine.Audio audio = AudioEngineCSharp.AudioEngine.Load(songFile, false, false);

                    unsafe
                    {
                        args.Analyzer.ProcessDeviation(audio.RawData, audio.DataSize);
                    }
                    audio.Dispose();
                }

                args.Analyzer.PreProcessData();

                for (int i = 0; i < args.Epoch; i++)
                {
                    Shuffle(args.SongData, r);

                    for (int j = 0; j < args.SongData.Count; j++)
                    {
                        SongData song = args.SongData[j];

                        string songFile = System.IO.Path.Combine(args.FilePath, song.Source, song.Name + ".wav");
                        //// Console.WriteLine("Trying to load file...{0}", file);
                        AudioEngineCSharp.AudioEngine.Audio audio = AudioEngineCSharp.AudioEngine.Load(songFile, false, false);
                        //// load up the file


                        unsafe
                        {
                            args.Analyzer.ProcessData(audio.RawData, audio.DataSize, args.IsContext ? song.Context : song.Theme);
                        }
                        //// _themeAnalyzer.AddData(a.Data, data.Theme);
                        audio.Dispose();

                        float percent  = ((float)(i * args.SongData.Count + (j + 1))) / totalNum;
                        int   progress = (int)(Math.Round(percent * 100));
                        Debug.WriteLine(string.Format("Percent: {0}, Finished ({1}) {2}", percent, song.Source, song.Name));
                        bw.ReportProgress(progress);
                    }
                }
            }
        }