Inheritance: IDisposable
        /// <summary>
        /// Converts RS1 Song Object to *.sng File
        /// </summary>
        /// <param name="rs1Song"></param>
        /// <param name="outputPath"></param>
        /// <returns>Path to binary *.sng file</returns>
        public string SongToSngFilePath(Song rs1Song, string outputPath)
        {
            string rs1XmlPath;

            using (var obj = new Rs1Converter())
                rs1XmlPath = obj.SongToXml(rs1Song, outputPath, true);

            ArrangementType arrangementType;

            if (rs1Song.Arrangement.ToLower() == "bass")
            {
                arrangementType = ArrangementType.Bass;
            }
            else
            {
                arrangementType = ArrangementType.Guitar;
            }

            var sngFilePath = Path.ChangeExtension(rs1XmlPath, ".sng");

            SngFileWriter.Write(rs1XmlPath, sngFilePath, arrangementType, new Platform(GamePlatform.Pc, GameVersion.None));

            if (File.Exists(rs1XmlPath))
            {
                File.Delete(rs1XmlPath);
            }

            return(sngFilePath);
        }
        /// <summary>
        /// Converts RS1 Song Object to *.sng File
        /// </summary>
        /// <param name="rs1Song"></param>
        /// <param name="outputPath"></param>
        /// <returns>Path to binary *.sng file</returns>
        public string SongToSngFilePath(Song rs1Song, string outputPath)
        {
            string rs1XmlPath;
            using (var obj = new Rs1Converter())
                rs1XmlPath = obj.SongToXml(rs1Song, outputPath, true);

            ArrangementType arrangementType;
            if (rs1Song.Arrangement.ToLower() == "bass")
                arrangementType = ArrangementType.Bass;
            else
                arrangementType = ArrangementType.Guitar;

            var sngFilePath = Path.ChangeExtension(rs1XmlPath, ".sng");
            SngFileWriter.Write(rs1XmlPath, sngFilePath, arrangementType, new Platform(GamePlatform.Pc, GameVersion.None));

            if (File.Exists(rs1XmlPath)) File.Delete(rs1XmlPath);

            return sngFilePath;
        }
        public string SongFile2Song2014File(string songFilePath, bool overWrite)
        {
            Song2014 song2014;
            using (var obj = new Rs1Converter())
                song2014 = obj.SongToSong2014(Song.LoadFromFile(songFilePath));

            if (!overWrite)
            {
                var srcDir = Path.GetDirectoryName(songFilePath);
                var srcName = Path.GetFileNameWithoutExtension(songFilePath);
                var backupSrcPath = String.Format("{0}_{1}.xml", Path.Combine(srcDir, srcName), "RS1");

                // backup original RS1 file
                File.Copy(songFilePath, backupSrcPath);
            }

            // write converted RS1 file
            using (FileStream stream = new FileStream(songFilePath, FileMode.Create))
                song2014.Serialize(stream, true);

            return songFilePath;
        }
Esempio n. 4
0
        /// <summary>
        /// Song2014 to ASCII Tablature
        /// </summary>
        /// <param name="rs2014Song"></param>
        /// <param name="outputDir"></param>
        /// <param name="allDif"></param>
        public void Song2014ToAsciiTab(Song2014 rs2014Song, string outputDir, bool allDif)
        {
            if (rs2014Song == null || String.IsNullOrEmpty(outputDir))
            {
                return;
            }
            // convert to Song
            Song rs1Song;

            using (var obj = new Rs2014Converter())
                rs1Song = obj.Song2014ToSong(rs2014Song);
            Console.WriteLine("Converted Song2014 To Song");

            if (false) // write Xml files for debugging
            {
                using (Rs2014Converter obj = new Rs2014Converter())
                    obj.Song2014ToXml(rs2014Song, outputDir);
                using (Rs1Converter obj = new Rs1Converter())
                    obj.SongToXml(rs1Song, outputDir);
            }

            // convert to SngFile
            string rs1SngFilePath;

            using (var obj = new Rs1Converter())
                rs1SngFilePath = obj.SongToSngFilePath(rs1Song, outputDir);
            Console.WriteLine("Converted Song To SngFile");

            // convert to AsciiTab
            using (var s2Tab = new Sng2Tab())
                s2Tab.Convert(rs1SngFilePath, outputDir, allDif);
            Console.WriteLine("Converted SngFile To AsciiTab");

            if (File.Exists(rs1SngFilePath))
            {
                File.Delete(rs1SngFilePath);
            }
        }
        private void convertButton_Click(object sender, EventArgs e)
        {
            IList<string> sourceFilePaths;
            allDif = difficultyAll.Checked;

            // Input file(s)
            using (var ofd = new OpenFileDialog())
            {
                if (rbAsciiTab.Checked)
                    ofd.Filter = "RS1 (*.dat, *.sng, *.xml) or RS2014 (*.psarc) files|*.dat;*.sng;*.xml;*.psarc";
                else
                    ofd.Filter = "RS2014 (*.psarc, *.xml) files|*.psarc;*.xml";

                ofd.Title = "Select RS1 and/or RS2014 CDLC files to convert";
                ofd.Multiselect = true;
                ofd.FileOk += OpenFileDialog_FileLimit; // Event handler

                if (ofd.ShowDialog() != DialogResult.OK)
                    return;
                sourceFilePaths = ofd.FileNames;
            }

            using (var fbd = new FolderBrowserDialog())
            {
                fbd.Description = "Select a folder for storing converted files.";
                fbd.ShowNewFolderButton = true;
                fbd.SelectedPath = outputDir;
                // fbd.SelectedPath = "D:\\Temp"; // for testing
                if (fbd.ShowDialog() != DialogResult.OK)
                    return;

                outputDir = fbd.SelectedPath;
            }

            Cursor.Current = Cursors.WaitCursor;
            foreach (var inputFilePath in sourceFilePaths)
            {
                string fileExtension = Path.GetExtension(inputFilePath).ToLower();
                switch (fileExtension)
                {
                    case ".xml":
                        if (rbGp5.Checked)
                        {
                            using (var obj = new Gp5Converter())
                                obj.XmlToGp5(inputFilePath, outputDir);
                        }
                        else
                        {
                        var fileName = Path.GetFileNameWithoutExtension(inputFilePath);
                        var splitPoint = fileName.LastIndexOf('_');
                        var arrangement = fileName.Substring(splitPoint + 1);
                        // skip any files for vocals and/or showlights
                        if (arrangement.ToLower() == "vocals" || arrangement.ToLower() == "showlights")
                            break;
                        Song rs1Song;
                        using (var obj = new Rs1Converter())
                            rs1Song = obj.XmlToSong(inputFilePath);
                        string sngFilePath;
                        using (var obj = new Rs1Converter())
                            sngFilePath = obj.SongToSngFilePath(rs1Song, Path.Combine(outputDir, Path.GetFileName(inputFilePath)));
                        using (var obj = new Sng2Tab())
                            obj.Convert(sngFilePath, outputDir, allDif);
                        if (File.Exists(sngFilePath))
                            File.Delete(sngFilePath);
                }
                break;
                    case ".dat":
                        using (var obj = new Sng2Tab())
                            obj.ExtractBeforeConvert(inputFilePath, outputDir, allDif);
                        break;
                    case ".sng":
                        using (var obj = new Sng2Tab())
                            obj.Convert(inputFilePath, outputDir, allDif);
                        break;
                    case ".psarc":
                        if (rbSongList.Checked)
                        {
                            using (var obj = new Rs2014Converter())
                                obj.PsarcSongList(inputFilePath, outputDir);
                            break;
                        }
                        var fileInfo = new FileInfo(inputFilePath);
                        // give user chance to abort big files
                        if (fileInfo.Length / 1000 > 15000)
                        {
                            if (MessageBox.Show(string.Format("{0} file size is {1:N00} KB{2}It may take a long time to extract and convert that much data.{2}{2}Do you want to continue?", Path.GetFileName(inputFilePath), (fileInfo.Length / 1000), Environment.NewLine), MESSAGEBOX_CAPTION, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                                return;
                        }
                        using (var obj = new Rs2014Converter())
                            songList = obj.PsarcSongList(inputFilePath);
                        if (rbAsciiTab.Checked)
                        {
                            using (var form = new SongInfoForm())
                            {
                                form.PopSongInfo(songList);
                                do
                                    // waiting for user selection(s)
                                    form.ShowDialog();
                                while (form.SongListShort.Count == 0);
                                this.Refresh();
                                if (form.SongListShort[0].Identifier == "User Aborted")
                                    break;
                                Cursor.Current = Cursors.WaitCursor;
                                foreach (var song in form.SongListShort)
                                {
                                    Song2014 rs2014Song;
                                    using (var obj = new Rs2014Converter())
                                    {
                                        rs2014Song = obj.PsarcToSong2014(inputFilePath, song.Identifier, song.Arrangement);
                                        obj.Song2014ToAsciiTab(rs2014Song, outputDir, allDif);
                                    }
                                }
                            }
                            break;
                        }
                        // convert to *.gp5 file(s) optimized code for dll usage
                        if (!allDif && songList.Count == 1)
                            using (var obj = new Gp5Converter())
                                obj.PsarcToGp5(inputFilePath, outputDir);
                        else
                            if (!allDif && songList.Count > 1)
                            {
                                using (var form = new SongInfoForm())
                                {
                                    form.PopSongOnly(songList);
                                    //  songs only (merge all arrangements into single GP file)
                                    //  form.PopSongInfo(songList); // choose songs and arrangements
                                    do
                                        // waiting for user selection(s)
                                        form.ShowDialog();
                                    while (form.SongListShort.Count == 0);
                                    this.Refresh();
                                    if (form.SongListShort[0].Identifier == "User Aborted")
                                        break;
                                    Cursor.Current = Cursors.WaitCursor;
                                    using (var obj = new Gp5Converter())
                                        obj.PsarcToGp5(inputFilePath, outputDir, form.SongListShort);
                                }
                            }
                            // give user the option to select specific songs and arrangements
                            else
                                if (allDif)
                                {
                                    using (var form = new SongInfoForm())
                                    {
                                        form.PopSongInfo(songList);
                                        // choose songs and arrangements
                                        do
                                            // waiting for user selection(s)
                                            form.ShowDialog();
                                        while (form.SongListShort.Count == 0);
                                        this.Refresh();
                                        if (form.SongListShort[0].Identifier == "User Aborted")
                                            break;
                                        Cursor.Current = Cursors.WaitCursor;
                                        using (var obj = new Gp5Converter())
                                            obj.PsarcToGp5(inputFilePath, outputDir, form.SongListShort, "gp5", true);
                                    }
                                }
                        break;
                }
                Refresh();
            }

            Cursor.Current = Cursors.Default;

            if (MessageBox.Show("The conversion is complete.." + Environment.NewLine +
                "Would you like to open the folder?", MESSAGEBOX_CAPTION,
                MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                Process.Start(outputDir);
        }
        // Load RS1 CDLC into PackageCreator
        public static DLCPackageData RS1LoadFromFolder(string unpackedDir, Platform targetPlatform, bool convert)
        {
            var data = new DLCPackageData();
            data.Arrangements = new List<Arrangement>();
            data.TonesRS2014 = new List<Tone2014>();
            data.Tones = new List<Tone>();

            data.GameVersion = (convert ? GameVersion.RS2014 : GameVersion.RS2012);
            data.SignatureType = PackageMagic.CON;
            // set default volumes
            data.Volume = -6.5F; // default maybe too quite
            data.PreviewVolume = data.Volume;

            //Load song manifest
            var songsManifestJson = Directory.GetFiles(unpackedDir, "songs.manifest.json", SearchOption.AllDirectories);
            if (songsManifestJson.Length < 1)
                throw new DataException("No songs.manifest.json file found.");
            if (songsManifestJson.Length > 1)
                throw new DataException("More than one songs.manifest.json file found.");

            var attr = new List<Attributes>();
            var songsManifest = Manifest.Manifest.LoadFromFile(songsManifestJson[0]).Entries.ToArray();

            for (int smIndex = 0; smIndex < songsManifest.Count(); smIndex++)
            {
                var smData = songsManifest[smIndex].Value.ToArray()[0].Value;
                attr.Add(smData);
            }

            if (attr.FirstOrDefault() == null)
                throw new DataException("songs.manifest.json file did not parse correctly.");

            // Fill SongInfo
            data.SongInfo = new SongInfo();
            data.SongInfo.SongDisplayName = attr.FirstOrDefault().SongName;
            data.SongInfo.SongDisplayNameSort = attr.FirstOrDefault().SongNameSort;
            data.SongInfo.Album = attr.FirstOrDefault().AlbumName;
            data.SongInfo.SongYear = (attr.FirstOrDefault().SongYear == 0 ? 2012 : attr.FirstOrDefault().SongYear);
            data.SongInfo.Artist = attr.FirstOrDefault().ArtistName;
            data.SongInfo.ArtistSort = attr.FirstOrDefault().ArtistNameSort;
            data.Name = attr.FirstOrDefault().SongKey;

            //Load tone manifest, even poorly formed tone_bass.manifest.json
            var toneManifestJson = Directory.GetFiles(unpackedDir, "*tone*.manifest.json", SearchOption.AllDirectories);
            if (toneManifestJson.Length < 1)
                throw new DataException("No tone.manifest.json file found.");

            // toolkit produces multiple tone.manifest.json files when packing RS1 CDLC files
            // rather than change toolkit behavior just merge manifest files for now
            if (toneManifestJson.Length > 1)
            {
                var mergeSettings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Union };
                JObject toneObject1 = new JObject();

                foreach (var tone in toneManifestJson)
                {
                    JObject toneObject2 = JObject.Parse(File.ReadAllText(tone));
                    //(toneObject1.SelectToken("Entries") as JArray).Merge(toneObject2.SelectToken("Entries"));
                    toneObject1.Merge(toneObject2, mergeSettings);
                }

                toneManifestJson = new string[1];
                toneManifestJson[0] = Path.Combine(unpackedDir, "merged.tone.manifest.json");
                string json = JsonConvert.SerializeObject(toneObject1, Formatting.Indented);
                File.WriteAllText(toneManifestJson[0], json);
            }

            var tones2014 = new List<Tone2014>();
            var tones = new List<Tone>();
            var toneManifest = Manifest.Tone.Manifest.LoadFromFile(toneManifestJson[0]);

            for (int tmIndex = 0; tmIndex < toneManifest.Entries.Count(); tmIndex++)
            {
                var tmData = toneManifest.Entries[tmIndex];
                tones.Add(tmData);
            }

            data.Tones = tones;

            // Load AggregateGraph.nt 
            var songDir = Path.Combine(unpackedDir, data.Name);
            if (targetPlatform.platform == GamePlatform.XBox360)
                songDir = Path.Combine(unpackedDir, "Root", data.Name);

            var aggFile = Directory.GetFiles(songDir, "*.nt", SearchOption.TopDirectoryOnly)[0];
            var aggGraphData = AggregateGraph.AggregateGraph.ReadFromFile(aggFile);

            // Load Exports\Songs\*.xblock
            var xblockDir = Path.Combine(songDir, "Exports\\Songs");
            var xblockFile = Directory.GetFiles(xblockDir, "*.xblock", SearchOption.TopDirectoryOnly)[0];
            // xblockFile = "D:\\Temp\\Mapping\\songs.xblock";
            var songsXblock = XblockX.LoadFromFile(xblockFile);

            // create project map for cross referencing arrangements with tones
            var projectMap = AggregateGraph.AggregateGraph.ProjectMap(aggGraphData, songsXblock, toneManifest);

            // Load xml arrangements
            var xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories);
            if (xmlFiles.Length <= 0)
                throw new DataException("Can not find any XML arrangement files");

            foreach (var xmlFile in xmlFiles)
            {
                if (xmlFile.ToLower().Contains("metadata")) // skip DeadFox file
                    continue;

                // some poorly formed RS1 CDLC use just "vocal"
                if (xmlFile.ToLower().Contains("vocal"))
                {
                    // Add Vocal Arrangement
                    data.Arrangements.Add(new Arrangement
                    {
                        Name = ArrangementName.Vocals,
                        ArrangementType = ArrangementType.Vocal,
                        ScrollSpeed = 20,
                        SongXml = new SongXML { File = xmlFile },
                        SongFile = new SongFile { File = "" },
                        CustomFont = false
                    });
                }
                else
                {
                    var attr2014 = new Attributes2014();
                    var rsSong = new Song();
                    var rsSong2014 = new Song2014();

                    // optimized tone matching effort using project mapping algo
                    var result = projectMap.First(m => String.Equals(Path.GetFileName(m.SongXmlPath), Path.GetFileName(xmlFile), StringComparison.CurrentCultureIgnoreCase));
                    if (result.Tones.Count != 1)
                        throw new DataException("Invalid RS1 CDLC Tones Data");

                    var arrangement = attr.First(s => s.SongXml.ToLower().Contains(result.LLID));
                    var tone = tones.First(t => t.Key == result.Tones[0]);

                    using (var obj1 = new Rs1Converter())
                    {
                        rsSong = obj1.XmlToSong(xmlFile);
                        data.SongInfo.AverageTempo = (int)obj1.AverageBPM(rsSong);
                    }

                    if (arrangement.Tuning == "E Standard")
                        rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 };
                    else if (arrangement.Tuning == "DropD")
                        rsSong.Tuning = new TuningStrings { String0 = -2, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 };
                    else if (arrangement.Tuning == "OpenG")
                        rsSong.Tuning = new TuningStrings { String0 = -2, String1 = -2, String2 = 0, String3 = 0, String4 = 0, String5 = -2 };
                    else if (arrangement.Tuning == "EFlat")
                        rsSong.Tuning = new TuningStrings { String0 = -1, String1 = -1, String2 = -1, String3 = -1, String4 = -1, String5 = -1 };
                    else // default to standard tuning
                    {
                        arrangement.Tuning = "E Standard";
                        rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 };
                    }

                    // save/write the changes to xml file
                    using (var obj1 = new Rs1Converter())
                        obj1.SongToXml(rsSong, xmlFile, true);

                    if (convert)
                        using (var obj1 = new Rs1Converter())
                            tones2014.Add(obj1.ToneToTone2014(tone, rsSong));

                    // load attr2014 with RS1 mapped values for use by Arrangement()
                    attr2014.Tone_Base = tone.Name;
                    attr2014.ArrangementName = arrangement.ArrangementName;
                    attr2014.CentOffset = 0;
                    attr2014.DynamicVisualDensity = new List<float>() { 2 };
                    attr2014.SongPartition = arrangement.SongPartition;
                    attr2014.PersistentID = IdGenerator.Guid().ToString();
                    attr2014.MasterID_RDV = RandomGenerator.NextInt();
                    attr2014.ArrangementProperties = new SongArrangementProperties2014();

                    // processing order is important - CAREFUL
                    // RouteMask  None = 0, Lead = 1, Rhythm = 2, Any = 3, Bass = 4
                    // XML file names are usually meaningless to arrangement determination

                    if (arrangement.ArrangementName.ToLower().Contains("lead") ||
                        rsSong.Arrangement.ToLower().Contains("lead"))
                    {
                        attr2014.ArrangementName = "Lead";
                        attr2014.ArrangementType = (int)ArrangementType.Guitar;
                        attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Lead;
                        attr2014.ArrangementProperties.PathLead = 1;
                        attr2014.ArrangementProperties.PathRhythm = 0;
                        attr2014.ArrangementProperties.PathBass = 0;
                    }
                    else if (arrangement.ArrangementName.ToLower().Contains("rhythm") ||
                        rsSong.Arrangement.ToLower().Contains("rhythm"))
                    // || rsSong.Arrangement.ToLower().Contains("guitar"))
                    {
                        attr2014.ArrangementName = "Rhythm";
                        attr2014.ArrangementType = (int)ArrangementType.Guitar;
                        attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Rhythm;
                        attr2014.ArrangementProperties.PathLead = 0;
                        attr2014.ArrangementProperties.PathRhythm = 1;
                        attr2014.ArrangementProperties.PathBass = 0;
                    }
                    else if (arrangement.ArrangementName.ToLower().Contains("combo") ||
                        rsSong.Arrangement.ToLower().Contains("combo"))
                    {
                        attr2014.ArrangementName = "Combo";
                        attr2014.ArrangementType = (int)ArrangementType.Guitar;
                        attr2014.ArrangementProperties.RouteMask = arrangement.EffectChainName.ToLower().Contains("lead") ? (int)RouteMask.Lead : (int)RouteMask.Rhythm;
                        attr2014.ArrangementProperties.PathLead = arrangement.EffectChainName.ToLower().Contains("lead") ? 1 : 0;
                        attr2014.ArrangementProperties.PathRhythm = arrangement.EffectChainName.ToLower().Contains("lead") ? 0 : 1;
                        attr2014.ArrangementProperties.PathBass = 0;
                    }
                    else if (arrangement.ArrangementName.ToLower().Contains("bass") ||
                        rsSong.Arrangement.ToLower().Contains("bass"))
                    {
                        attr2014.ArrangementName = "Bass";
                        attr2014.ArrangementType = (int)ArrangementType.Bass;
                        attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Bass;
                        attr2014.ArrangementProperties.PathLead = 0;
                        attr2014.ArrangementProperties.PathRhythm = 0;
                        attr2014.ArrangementProperties.PathBass = 1;
                    }
                    else
                    {
                        // default to Lead arrangment
                        attr2014.ArrangementName = "Lead";
                        attr2014.ArrangementType = (int)ArrangementType.Guitar;
                        attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Lead;
                        attr2014.ArrangementProperties.PathLead = 1;
                        attr2014.ArrangementProperties.PathRhythm = 0;
                        attr2014.ArrangementProperties.PathBass = 0;

                        Console.WriteLine("RS1->RS2 CDLC Conversion defaulted to 'Lead' arrangment");
                    }

                    if (convert) // RS1 -> RS2 magic
                    {
                        using (var obj1 = new Rs1Converter())
                            rsSong2014 = obj1.SongToSong2014(rsSong);

                        // update ArrangementProperties
                        rsSong2014.ArrangementProperties.RouteMask = attr2014.ArrangementProperties.RouteMask;
                        rsSong2014.ArrangementProperties.PathLead = attr2014.ArrangementProperties.PathLead;
                        rsSong2014.ArrangementProperties.PathRhythm = attr2014.ArrangementProperties.PathRhythm;
                        rsSong2014.ArrangementProperties.PathBass = attr2014.ArrangementProperties.PathBass;
                        rsSong2014.ArrangementProperties.StandardTuning = (arrangement.Tuning == "E Standard" ? 1 : 0);

                        // <note time="58.366" linkNext="0" accent="0" bend="0" fret="7" hammerOn="0" harmonic="0" hopo="0" ignore="0" leftHand="-1" mute="0" palmMute="0" pluck="-1" pullOff="0" slap="-1" slideTo="-1" string="3" sustain="0.108" tremolo="0" harmonicPinch="0" pickDirection="0" rightHand="-1" slideUnpitchTo="-1" tap="0" vibrato="0" />
                        if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Bend != 0)))
                            rsSong2014.ArrangementProperties.Bends = 1;
                        if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Hopo != 0)))
                            rsSong2014.ArrangementProperties.Hopo = 1;
                        if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.SlideTo != -1)))
                            rsSong2014.ArrangementProperties.Slides = 1;
                        if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Sustain > 0)))
                            rsSong2014.ArrangementProperties.Sustain = 1;

                        // fixing times that are off
                        var lastEbeatsTime = rsSong2014.Ebeats[rsSong2014.Ebeats.Length - 1].Time;
                        var lastPhraseIterationsTime = rsSong2014.PhraseIterations[rsSong2014.PhraseIterations.Length - 1].Time;

                        // tested ... not source of in game hangs
                        // confirm last PhraseIterations time is less than last Ebeats time
                        if (lastPhraseIterationsTime > lastEbeatsTime)
                        {
                            rsSong2014.PhraseIterations[rsSong2014.PhraseIterations.Length - 1].Time = lastEbeatsTime;
                            rsSong2014.Sections[rsSong2014.Sections.Length - 1].StartTime = lastEbeatsTime;
                        }

                        // tested ... not source of in game hangs
                        // confirm SongLength at least equals last Ebeats time
                        if (rsSong2014.SongLength < lastEbeatsTime)
                            rsSong2014.SongLength = lastEbeatsTime;

                        using (var obj2 = new Rs2014Converter())
                            obj2.Song2014ToXml(rsSong2014, xmlFile, true);
                    }

                    // Adding Song Arrangement
                    try
                    {
                        data.Arrangements.Add(new Arrangement(attr2014, xmlFile));
                    }
                    catch (Exception ex)
                    {
                        // mainly for the benifit of convert2012 CLI users
                        Console.WriteLine(@"This CDLC could not be auto converted." + Environment.NewLine + "You can still try manually adding the arrangements and assests." + Environment.NewLine + ex.Message);
                    }
                }
            }
            if (convert)
            {
                // get rid of duplicate tone names
                tones2014 = tones2014.Where(p => p.Name != null)
                    .GroupBy(p => p.Name).Select(g => g.First()).ToList();
                data.TonesRS2014 = tones2014;
            }

            //Get Album Artwork DDS Files
            var artFiles = Directory.GetFiles(unpackedDir, "*.dds", SearchOption.AllDirectories);
            if (artFiles.Length < 1)
                throw new DataException("No Album Artwork file found.");
            if (artFiles.Length > 1)
                throw new DataException("More than one Album Artwork file found.");

            var targetArtFiles = new List<DDSConvertedFile>();
            data.AlbumArtPath = artFiles[0];
            targetArtFiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = artFiles[0], destinationFile = artFiles[0].CopyToTempFile(".dds") });
            data.ArtFiles = targetArtFiles;

            //Audio files
            var targetAudioFiles = new List<string>();
            var audioFiles = Directory.GetFiles(unpackedDir, "*.ogg", SearchOption.AllDirectories);
            if (audioFiles.Length < 1)
                throw new DataException("No Audio file found.");
            if (audioFiles.Length > 2)
                throw new DataException("Too many Audio files found.");

            int i;
            for (i = 0; i < audioFiles.Length; i++)
            {
                if (convert && audioFiles[i].Contains("_fixed.ogg")) // use it
                    break;
                if (!convert && !audioFiles[i].Contains("_fixed.ogg"))
                    break;
            }
            // FIXME: platform specific decode is broken
            var sourcePlatform = unpackedDir.GetPlatform();
            if (targetPlatform.IsConsole != (sourcePlatform = audioFiles[i].GetAudioPlatform()).IsConsole)
            {
                var newFile = Path.Combine(Path.GetDirectoryName(audioFiles[i]), String.Format("{0}_cap.ogg", Path.GetFileNameWithoutExtension(audioFiles[i])));
                OggFile.ConvertAudioPlatform(audioFiles[i], newFile);
                audioFiles[i] = newFile;
            }

            targetAudioFiles.Add(audioFiles[i]);

            if (!targetAudioFiles.Any())
                throw new DataException("Audio file not found.");

            var a = new FileInfo(audioFiles[i]);
            data.OggPath = a.FullName;

            //AppID
            if (!sourcePlatform.IsConsole)
            {
                if (!convert)
                {
                    var appidFile = Directory.GetFiles(unpackedDir, "*APP_ID*", SearchOption.AllDirectories);
                    if (appidFile.Length > 0)
                        data.AppId = File.ReadAllText(appidFile[0]);
                }
                else
                    data.AppId = "248750";
            }

            try
            {//TODO: validate that rs1 songs have no this file
                //Package version
                var versionFile = Directory.GetFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories);
                if (versionFile.Length > 0)
                    data.PackageVersion = GeneralExtensions.ReadPackageVersion(versionFile[0]);
                else data.PackageVersion = "1";
            }
            catch {}

            if (convert)
                data.Tones = null;

            return data;
        }
        /// <summary>
        /// Song2014 to ASCII Tablature
        /// </summary>
        /// <param name="rs2014Song"></param>
        /// <param name="outputDir"></param>
        /// <param name="allDif"></param>
        public void Song2014ToAsciiTab(Song2014 rs2014Song, string outputDir, bool allDif)
        {
            if (rs2014Song == null || String.IsNullOrEmpty(outputDir)) return;
            // convert to Song
            Song rs1Song;
            using (var obj = new Rs2014Converter())
                rs1Song = obj.Song2014ToSong(rs2014Song);
            Console.WriteLine("Converted Song2014 To Song");

            //if (false) // write Xml files for debugging
            //{
            //    using (Rs2014Converter obj = new Rs2014Converter())
            //        obj.Song2014ToXml(rs2014Song, outputDir, true);
            //    using (Rs1Converter obj = new Rs1Converter())
            //        obj.SongToXml(rs1Song, outputDir, true);
            //}

            // convert to SngFile
            string rs1SngFilePath;
            using (var obj = new Rs1Converter())
                rs1SngFilePath = obj.SongToSngFilePath(rs1Song, outputDir);
            Console.WriteLine("Converted Song To SngFile");

            // convert to AsciiTab
            using (var s2Tab = new Sng2Tab())
                s2Tab.Convert(rs1SngFilePath, outputDir, allDif);
            Console.WriteLine("Converted SngFile To AsciiTab");

            if (File.Exists(rs1SngFilePath)) File.Delete(rs1SngFilePath);
        }
        public bool LoadXmlArrangement(string xmlFilePath)
        {
            if (isAlreadyAdded(xmlFilePath))
            {
                MessageBox.Show(@"XML Arrangement: " + Path.GetFileName(xmlFilePath) + "   " + Environment.NewLine +
                    @"has already been added.  Please choose a new file. ",
                    DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }

            try
            {
                bool isVocal = false;
                bool isShowlight = false;
                try
                {
                    xmlSong = Song2014.LoadFromFile(xmlFilePath);
                    Arrangement.XmlComments = Song2014.ReadXmlComments(xmlFilePath);
                }
                catch (Exception ex)
                {
                    if (ex.InnerException.Message.ToLower().Contains("<vocals"))
                        isVocal = true;
                    else if (ex.InnerException.Message.ToLower().Contains("<showlights"))
                        isShowlight = true;
                    else
                    {
                        MessageBox.Show(@"Unable to get information from XML arrangement:  " + Environment.NewLine +
                            Path.GetFileName(xmlFilePath) + Environment.NewLine +
                            @"It may not be a valid arrangment or " + Environment.NewLine +
                            @"your version of the EOF may be out of date." + Environment.NewLine +
                            ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return false;
                    }
                }

                // SETUP FIELDS
                if (isVocal)
                {
                    arrangementTypeCombo.SelectedItem = ArrangementType.Vocal;
                    _arrangement.ArrangementType = ArrangementType.Vocal;
                }
                else if (isShowlight)
                {
                    arrangementTypeCombo.SelectedItem = ArrangementType.ShowLight;
                    _arrangement.ArrangementType = ArrangementType.ShowLight;
                }
                else
                {
                    var version = GameVersion.None;
                    //Detect arrangement GameVersion
                    if (xmlSong != null && xmlSong.Version != null)
                    {
                        var verAttrib = Convert.ToInt32(xmlSong.Version);
                        if (verAttrib <= 6) version = GameVersion.RS2012;
                        else if (verAttrib >= 7) version = GameVersion.RS2014;
                    }
                    else if (currentGameVersion == GameVersion.RS2012)
                    {
                        // add missing XML elements
                        xmlSong.Version = "4";
                        xmlSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 };
                        xmlSong.ArrangementProperties = new SongArrangementProperties2014 { StandardTuning = 1 };
                        version = GameVersion.RS2012;
                    }
                    else if (currentGameVersion == GameVersion.None)
                    {
                        using (var obj = new Rs1Converter())
                        {
                            xmlSong = null;
                            xmlSong = obj.SongToSong2014(Song.LoadFromFile(XmlFilePath.Text));
                        }
                        currentGameVersion = GameVersion.RS2014;
                    }
                    else
                        MessageBox.Show("Your version of EOF may be out of date, please update.", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);

                    // TODO: fix error checking logic for new types of conversion
                    if (currentGameVersion != version && version != GameVersion.None)
                    {
                        Debug.WriteLine(String.Format("Please choose valid Rocksmith {0} arrangement file!", currentGameVersion));
                        //XmlFilePath.Text = "";
                        //return;
                    }

                    // SONG AND ARRANGEMENT INFO / ROUTE MASK
                    BonusCheckBox.Checked = Equals(xmlSong.ArrangementProperties.BonusArr, 1);
                    MetronomeCb.Checked = Equals(xmlSong.ArrangementProperties.Metronome, 2);
                    if (!EditMode)
                    {
                        string arr = xmlSong.Arrangement.ToLowerInvariant();
                        if (arr.Contains("guitar") || arr.Contains("lead") || arr.Contains("rhythm") || arr.Contains("combo"))
                        {
                            arrangementTypeCombo.SelectedItem = ArrangementType.Guitar;

                            if (arr.Contains("combo"))
                            {
                                arrangementNameCombo.SelectedItem = ArrangementName.Combo;
                                if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead;
                            }
                            else if (arr.Contains("guitar_22") || arr.Contains("lead") || Equals(xmlSong.ArrangementProperties.PathLead, 1))
                            {
                                arrangementNameCombo.SelectedItem = ArrangementName.Lead;
                                if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead;
                            }
                            else if (arr.Contains("guitar") || arr.Contains("rhythm") || Equals(xmlSong.ArrangementProperties.PathRhythm, 1))
                            {
                                arrangementNameCombo.SelectedItem = ArrangementName.Rhythm;
                                if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Rhythm;
                            }

                        }
                        else if (arr.Contains("bass"))
                        {
                            arrangementTypeCombo.SelectedItem = ArrangementType.Bass;

                            //SetTuningCombo(xmlSong.Tuning, true);
                            Picked.Checked = Equals(xmlSong.ArrangementProperties.BassPick, 1);
                            if (currentGameVersion != GameVersion.RS2012)
                            {
                                RouteMask = RouteMask.Bass;
                                //Low tuning fix for bass, If lowstring is B and bass fix not applied
                                if (xmlSong.Tuning.String0 < -4 && this.frequencyTB.Text == "440")
                                    bassFix |= MessageBox.Show("Your tuning is too low, would you like to apply \"Low Tuning Fix?\"\n" + "Note, that this won't work if you re-save arangement in EOF.\n", "Low Tuning Fix Required!", MessageBoxButtons.YesNo) == DialogResult.Yes;
                            }
                        }
                    }

                    if (currentGameVersion != GameVersion.RS2012)
                    {
                        //Tones setup
                        Arrangement.ToneBase = xmlSong.ToneBase;
                        Arrangement.ToneA = xmlSong.ToneA;
                        Arrangement.ToneB = xmlSong.ToneB;
                        Arrangement.ToneC = xmlSong.ToneC;
                        Arrangement.ToneD = xmlSong.ToneD;
                        Arrangement.ToneMultiplayer = null;

                        SetupTones(Arrangement);

                        //Apply bass Fix, refactor me.
                        if (bassFix)
                        {
                            bassFix = false;
                            Arrangement.SongXml.File = XmlFilePath.Text;
                            parentControl.ApplyBassFix(Arrangement);
                        }
                    }

                    // Setup tuning
                    var selectedType = new ArrangementType();
                    if (xmlSong.Arrangement.ToLower() == "bass")
                        selectedType = ArrangementType.Bass;
                    else
                        selectedType = ArrangementType.Guitar;

                    FillTuningCombo(selectedType, currentGameVersion);

                    // find tuning in tuningComboBox list and make selection
                    int foundTuning = -1;
                    for (int tcbIndex = 0; tcbIndex < tuningComboBox.Items.Count; tcbIndex++)
                    {
                        tuningComboBox.SelectedIndex = tcbIndex;
                        TuningDefinition tuning = (TuningDefinition)tuningComboBox.Items[tcbIndex];
                        if (tuning.Tuning == xmlSong.Tuning)
                        {
                            foundTuning = tcbIndex;
                            break;
                        }
                    }

                    if (foundTuning == -1 && selectedType != ArrangementType.Bass)
                        ShowTuningForm(selectedType, new TuningDefinition { Tuning = xmlSong.Tuning, Custom = true, GameVersion = currentGameVersion });
                    else
                    {
                        if (selectedType == ArrangementType.Bass)
                        {
                            MessageBox.Show(@"Remember to set the correct tuning using Edit for" + Environment.NewLine +
                                @"Bass Arrangement: " + Path.GetFileName(xmlFilePath),
                                DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);

                            tuningComboBox.SelectedIndex = 0;
                        }
                        else
                            tuningComboBox.SelectedIndex = foundTuning;
                    }

                    tuningComboBox.Refresh();

                    Arrangement.Tuning = tuningComboBox.SelectedItem.ToString();
                    Arrangement.TuningStrings = xmlSong.Tuning;
                    Arrangement.CapoFret = xmlSong.Capo;
                    frequencyTB.Text = Arrangement.TuningPitch.ToString();
                    UpdateCentOffset();

                    // save converted RS1 to RS2014 Song2014 XML
                    if (version == GameVersion.None)
                    {
                        var srcDir = Path.GetDirectoryName(XmlFilePath.Text);
                        var srcName = Path.GetFileNameWithoutExtension(XmlFilePath.Text);
                        var backupSrcPath = String.Format("{0}_{1}.xml", Path.Combine(srcDir, srcName), "RS1");

                        // backup original RS1 file
                        File.Copy(XmlFilePath.Text, backupSrcPath);

                        // write converted RS1 file
                        using (FileStream stream = new FileStream(XmlFilePath.Text, FileMode.Create))
                            xmlSong.Serialize(stream, true);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(@"Unable to get information from XML arrangement:  " + Environment.NewLine +
                    Path.GetFileName(xmlFilePath) + Environment.NewLine +
                    @"It may not be a valide arrangment or " + Environment.NewLine +
                    @"your version of the EOF may be out of date." + Environment.NewLine +
                    ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }
        public bool LoadXmlArrangement(string xmlFilePath)
        {
            if (IsAlreadyAdded(xmlFilePath))
            {
                MessageBox.Show(@"XML Arrangement: " + Path.GetFileName(xmlFilePath) + @"   " + Environment.NewLine +
                    @"has already been added.  Please choose a new file. ",
                    DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }

            try
            {
                bool isVocal = false;
                bool isShowlight = false;
                try
                {
                    xmlSong = Song2014.LoadFromFile(xmlFilePath);
                    Arrangement.XmlComments = Song2014.ReadXmlComments(xmlFilePath);
                }
                catch (Exception ex)
                {
                    if (ex.InnerException.Message.ToLower().Contains("<vocals"))
                        isVocal = true;
                    else if (ex.InnerException.Message.ToLower().Contains("<showlights"))
                        isShowlight = true;
                    else
                    {
                        MessageBox.Show(@"Unable to get information from XML arrangement:  " + Environment.NewLine +
                            Path.GetFileName(xmlFilePath) + Environment.NewLine +
                            @"It may not be a valid arrangement or " + Environment.NewLine +
                            @"your version of the EOF may be out of date." + Environment.NewLine +
                            ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return false;
                    }
                }

                // SETUP FIELDS
                if (isVocal)
                {
                    arrangementTypeCombo.SelectedItem = ArrangementType.Vocal;
                    _arrangement.ArrangementType = ArrangementType.Vocal;
                }
                else if (isShowlight)
                {
                    arrangementTypeCombo.SelectedItem = ArrangementType.ShowLight;
                    _arrangement.ArrangementType = ArrangementType.ShowLight;
                }
                else
                {
                    var version = GameVersion.None;
                    //Detect arrangement GameVersion
                    if (xmlSong != null && xmlSong.Version != null)
                    {
                        var verAttrib = Convert.ToInt32(xmlSong.Version);
                        if (verAttrib <= 6) version = GameVersion.RS2012;
                        else if (verAttrib >= 7) version = GameVersion.RS2014;
                    }
                    else switch (currentGameVersion)
                    {
                        case GameVersion.RS2012:
                            // add missing XML elements
                            xmlSong.Version = "4";
                            xmlSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 };
                            xmlSong.ArrangementProperties = new SongArrangementProperties2014 { StandardTuning = 1 };
                            version = GameVersion.RS2012;
                            break;
                        case GameVersion.None:
                            using (var obj = new Rs1Converter())
                            {
                                xmlSong = null;
                                xmlSong = obj.SongToSong2014(Song.LoadFromFile(XmlFilePath.Text));
                            }
                            currentGameVersion = GameVersion.RS2014;
                            break;
                        default:
                            MessageBox.Show("Your version of EOF may be out of date, please update.", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            break;
                    }

                    // TODO: fix error checking logic for new types of conversion
                    if (currentGameVersion != version && version != GameVersion.None)
                    {
                        Debug.WriteLine("Please choose valid Rocksmith {0} arrangement file!", currentGameVersion);
                        //XmlFilePath.Text = "";
                        //return;
                    }

                    // SONG AND ARRANGEMENT INFO / ROUTE MASK
                    BonusCheckBox.Checked = Equals(xmlSong.ArrangementProperties.BonusArr, 1);
                    MetronomeCb.Checked = Equals(xmlSong.ArrangementProperties.Metronome, 2);
                    Arrangement.ArrangementPropeties = xmlSong.ArrangementProperties;
                    Arrangement.CapoFret = xmlSong.Capo;

                    if (!EditMode)
                    {
                        string arr = xmlSong.Arrangement.ToLowerInvariant();
                        if (arr.Contains("guitar") || arr.Contains("lead") || arr.Contains("rhythm") || arr.Contains("combo"))
                        {
                            arrangementTypeCombo.SelectedItem = ArrangementType.Guitar;

                            if (arr.Contains("combo"))
                            {
                                arrangementNameCombo.SelectedItem = ArrangementName.Combo;
                                if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead;
                            }
                            else if (arr.Contains("guitar_22") || arr.Contains("lead") || Equals(xmlSong.ArrangementProperties.PathLead, 1))
                            {
                                arrangementNameCombo.SelectedItem = ArrangementName.Lead;
                                if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead;
                            }
                            else if (arr.Contains("guitar") || arr.Contains("rhythm") || Equals(xmlSong.ArrangementProperties.PathRhythm, 1))
                            {
                                arrangementNameCombo.SelectedItem = ArrangementName.Rhythm;
                                if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Rhythm;
                            }
                        }
                        else if (arr.Contains("bass"))
                        {
                            arrangementTypeCombo.SelectedItem = ArrangementType.Bass;
                            Picked.Checked = Equals(xmlSong.ArrangementProperties.BassPick, 1);

                            if (currentGameVersion != GameVersion.RS2012)
                            {
                                RouteMask = RouteMask.Bass;
                                //Low tuning fix for bass, If lowest string is B and bass fix not applied TODO:applyonly when 'generate'
                                if (xmlSong.Tuning.String0 < -4 && Arrangement.TuningPitch != 220)
                                    bassFix |= MessageBox.Show(@"The bass tuning may be too low.  Apply Low Bass Tuning Fix?" + Environment.NewLine +
                                                               @"Note: The fix will revert if bass arrangement is re-saved in EOF.  ",
                                                               @"Warning ... Low Bass Tuning", MessageBoxButtons.YesNo) == DialogResult.Yes;
                            }
                        }
                    }

                    if (currentGameVersion != GameVersion.RS2012)
                    {
                        //Tones setup //TODO: add parsing tones events
                        Arrangement.ToneBase = xmlSong.ToneBase;
                        Arrangement.ToneA = xmlSong.ToneA;
                        Arrangement.ToneB = xmlSong.ToneB;
                        Arrangement.ToneC = xmlSong.ToneC;
                        Arrangement.ToneD = xmlSong.ToneD;
                        Arrangement.ToneMultiplayer = null;
                        SetupTones(Arrangement);

                        // Fix Low Bass Tuning
                        if (bassFix)
                        {
                            bassFix = false;
                            Arrangement.SongXml.File = XmlFilePath.Text;

                            if (Arrangement.TuningStrings == null)
                            {
                                // need to load tuning here from the xml arrangement
                                Arrangement.TuningStrings = new TuningStrings();
                                Arrangement.TuningStrings = xmlSong.Tuning;
                            }

                            if (!TuningFrequency.ApplyBassFix(Arrangement))
                                MessageBox.Show("This bass arrangement is already at 220Hz pitch.  ", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            else
                            {
                                var commentsList = Arrangement.XmlComments.ToList();
                                commentsList.Add(new XComment("Low Bass Tuning Fixed"));
                                Arrangement.XmlComments = commentsList;
                            }

                            xmlSong.Tuning = Arrangement.TuningStrings;
                        }
                    }

                    // Setup tuning
                    ArrangementType selectedType;
                    if (xmlSong.Arrangement.ToLower() == "bass")
                        selectedType = ArrangementType.Bass;
                    else
                        selectedType = ArrangementType.Guitar;

                    FillTuningCombo(selectedType, currentGameVersion);

                    // find tuning in tuningComboBox list and make selection
                    int foundTuning = -1;
                    for (int tcbIndex = 0; tcbIndex < tuningComboBox.Items.Count; tcbIndex++)
                    {
                        tuningComboBox.SelectedIndex = tcbIndex;
                        TuningDefinition tuning = (TuningDefinition)tuningComboBox.Items[tcbIndex];
                        if (tuning.Tuning == xmlSong.Tuning)
                        {
                            foundTuning = tcbIndex;
                            break;
                        }
                    }

                    if (foundTuning == -1 && selectedType != ArrangementType.Bass)
                    {
                        tuningComboBox.SelectedIndex = 0;
                        ShowTuningForm(selectedType, new TuningDefinition(xmlSong.Tuning, currentGameVersion)); //FIXME: Don't use this for QuickAdd call
                    }

                    // E Standard, Drop D, and Open E tuning are now the same for both guitar and bass
                    if (foundTuning == -1 && selectedType == ArrangementType.Bass)
                    {
                        tuningComboBox.SelectedIndex = 0;
                        MessageBox.Show("Toolkit was not able to automatically set tuning for" + Environment.NewLine +
                                        "Bass Arrangement: " + Path.GetFileName(xmlFilePath) + Environment.NewLine +
                                        "Use the tuning selector dropdown or Tuning Editor" + Environment.NewLine +
                                        "to customize bass tuning (as defined for six strings).  ", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }

                    tuningComboBox.Refresh();
                    Arrangement.Tuning = tuningComboBox.SelectedItem.ToString();
                    Arrangement.TuningStrings = xmlSong.Tuning;
                    Arrangement.CapoFret = xmlSong.Capo;
                    frequencyTB.Text = Arrangement.TuningPitch.ToString(CultureInfo.InvariantCulture);

                    // bastard bass hack
                    if (Arrangement.Tuning.ToLower().Contains("fixed"))
                        frequencyTB.Text = "220";

                    //UpdateCentOffset();//bad way to update tuning info, IMO

                    // save converted RS1 to RS2014 Song2014 XML
                    if (version == GameVersion.None)
                    {
                        var srcDir = Path.GetDirectoryName(XmlFilePath.Text);
                        var srcName = Path.GetFileNameWithoutExtension(XmlFilePath.Text);
                        var backupSrcPath = String.Format("{0}_{1}.xml", Path.Combine(srcDir, srcName), "RS1");

                        // backup original RS1 file
                        File.Copy(XmlFilePath.Text, backupSrcPath);

                        // write converted RS1 file
                        using (var stream = new FileStream(XmlFilePath.Text, FileMode.Create))
                            xmlSong.Serialize(stream, true);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(@"Unable to get information from XML arrangement:  " + Environment.NewLine +
                    Path.GetFileName(xmlFilePath) + Environment.NewLine +
                    @"It may not be a valid arrangement or " + Environment.NewLine +
                    @"your version of the EOF may be out of date." + Environment.NewLine +
                    ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }