private void Convert(string inputFile, string savePath, bool all)
        {
            SngFile sngFile = new SngFile(inputFile);

            if (String.IsNullOrEmpty(sngFile.Metadata.Arrangement))
                return; // Vocal

            int maxDifficulty = Common.getMaxDifficulty(sngFile);

            int[] difficulties;
            if (all)
                difficulties = Enumerable.Range(0, maxDifficulty + 1).ToArray();
            else // if (max)
                difficulties = new int[] { maxDifficulty };

            foreach (int d in difficulties)
            {
                TabFile tabFile = new TabFile(sngFile, d);

                var outputFileName = (sngFile != null && sngFile.Metadata != null) ? String.Format("{0} - ", sngFile.Metadata.SongTitle) : "";
                outputFileName += Path.GetFileNameWithoutExtension(inputFile);
                outputFileName += (difficulties.Length != 1) ? String.Format(" (level {0:00}).txt", d) : ".txt";
                var outputFilePath = Path.Combine(savePath, outputFileName);

                using (TextWriter tw = new StreamWriter(outputFilePath))
                {
                    tw.Write(tabFile.ToString());
                }
            }
        }
 public TabHeader(TabFile tabFile, SngFile sngFile)
 {
     TabFile = tabFile;
     Title = sngFile.Metadata.SongTitle;
     Artist = sngFile.Metadata.Artist;
     Length = Common.TimeToString(sngFile.Metadata.Length);
     TuningInfo = tabFile.TuningInfos[(Tuning)sngFile.Metadata.Tuning];
 }
 public void PhraseIterationsInOrder(SngFile song)
 {
     foreach (var pi in song.PhraseIterations)
     {
         Assert.LessOrEqual(pi.StartTime, pi.EndTime);
         Assert.Less(pi.StartTime, 2000);
         Assert.GreaterOrEqual(pi.StartTime, 0);
         Assert.Less(pi.EndTime, 2000);
         Assert.GreaterOrEqual(pi.EndTime, 0);
     }
 }
 public void VocalsInOrder(SngFile song)
 {
     Vocal lastVocal = null;
     foreach (var vocal in song._vocals)
     {
         if (lastVocal != null)
         {
             Assert.Less(lastVocal.Time, vocal.Time);
         }
         lastVocal = vocal;
     }
 }
 public TabChord(TabFile tabFile, Note note, SngFile sngFile)
     : base(tabFile, note)
 {
     ChordTemplate chord = sngFile.ChordTemplates[note.ChordId];
     ChordName = chord.Name;
     Frets = new int[TabFile.StringCount];
     Frets[0] = chord.Fret0;
     Frets[1] = chord.Fret1;
     Frets[2] = chord.Fret2;
     Frets[3] = chord.Fret3;
     Frets[4] = chord.Fret4;
     Frets[5] = chord.Fret5;
 }
        public void ControlsValid(SngFile song)
        {
            foreach (var control in song.Controls)
            {
                // These times can jump around (ex: TCAnchorZoneIntro_Lead)
                /*
                if (lastControl != null)
                {
                    Assert.LessOrEqual(lastControl.Time, control.Time);
                }
                 * */

                ValidString(control.Code);
                Assert.Less(control.Time, 2000);
                Assert.GreaterOrEqual(control.Time, 0);
            }
        }
        public void SongEventsValid(SngFile song)
        {
            SongEvent lastSongEvent = null;
            foreach (var songEvent in song.SongEvents)
            {
                if (lastSongEvent != null)
                {
                    Assert.LessOrEqual(lastSongEvent.Time, songEvent.Time);
                }
                 
                //Just make sure the time is sane
                Assert.Less(songEvent.Time, 2000);
                Assert.GreaterOrEqual(songEvent.Time, 0);

                ValidString(songEvent.Code);

                lastSongEvent = songEvent;
            }
        }
 public void BeatsInOrder(SngFile song)
 {
     Ebeat lastBeat = null;
     foreach (var beat in song.Beats)
     {
         if (lastBeat != null)
         {
             Assert.IsTrue(lastBeat.Time < beat.Time);
             if (lastBeat.Measure == beat.Measure)
             {
                 Assert.AreEqual(lastBeat.Beat + 1, beat.Beat);
             }
             else
             {
                 Assert.AreEqual(beat.Beat, 0);
                 Assert.LessOrEqual(lastBeat.Measure + 1, beat.Measure);
             }
         }
         lastBeat = beat;
     }
 }
        public void Convert(string sngFilePath, string outputDir, bool allDif)
        {
            SngFile sngFile = new SngFile(sngFilePath);

            if (String.IsNullOrEmpty(sngFile.Metadata.Arrangement))
                return; // Vocal

            int maxDifficulty = Common.getMaxDifficulty(sngFile);

            int[] difficulties;
            if (allDif)
                difficulties = Enumerable.Range(0, maxDifficulty + 1).ToArray();
            else // if (max)
                //  difficulties = new int[] { maxDifficulty };
                difficulties = new int[] { 255 };

            foreach (int d in difficulties)
            {
                TabFile tabFile = new TabFile(sngFile, d);

                var outputFileName = String.Empty;
                if (sngFile != null && sngFile.Metadata != null)
                    if (sngFile.Metadata.Artist == "DUMMY")
                        outputFileName = String.Format("{0}", sngFile.Metadata.SongTitle);
                    else
                        outputFileName = String.Format("{0} - {1}", sngFile.Metadata.Artist, sngFile.Metadata.SongTitle);
                else
                    outputFileName = String.Format("{0}", "Unknown Song");

                outputFileName += (difficulties.Length != 1) ? String.Format(" (level {0:D2})", d) : "";
                outputFileName = outputFileName.GetValidName(true);
                var outputFilePath = Path.Combine(outputDir, outputFileName + ".txt");

                using (TextWriter tw = new StreamWriter(outputFilePath))
                {
                    tw.Write(tabFile.ToString());
                }
            }
        }
        public TabFile(SngFile sngFile, int maxDifficulty)
        {
            StringCount = 6;

            _measureQueue = new List<TabMeasure>();
            _currentMeasure = null;
            Lines = new List<string>(); // holds text stream

            // Create the tuning information table
            TuningInfos = new Dictionary<Tuning, TuningInfo>();
            TuningInfos[Tuning.Standard] = new TuningInfo(this, Tuning.Standard, "Standard", new string[] { "e", "B", "G", "D", "A", "E" });
            TuningInfos[Tuning.DropD] = new TuningInfo(this, Tuning.DropD, "Drop D", new string[] { "e", "B", "G", "D", "A", "D" });
            TuningInfos[Tuning.EFlat] = new TuningInfo(this, Tuning.EFlat, "E Flat", new string[] { "eb", "Bb", "Gb", "Db", "Ab", "Eb" });
            TuningInfos[Tuning.OpenG] = new TuningInfo(this, Tuning.OpenG, "Open G", new string[] { "D", "B", "D", "G", "D", "G" });

            TuningInfo = TuningInfos[(Tuning)sngFile.Metadata.Tuning];

            // Start assembling the tab
            TabHeader header = new TabHeader(this, sngFile);

            /* Tab Entities are the parts that together make up a tab, i.e. notes, chords, measures and sections.
             * Since the notes and chords are all contained in a single array without any measure or section data,
             * the measure and section data needs to be merged with notes and chords so that all of that data can be
             * iterated over in the correct order. Entities get sorted by time index (the SortedList key).
             * Multiple entities (of different types) can have the same time index and need to be processed in the
             * correct order, i.e. sections before measures and measures before notes/chords. */
            SortedList<float, LinkedList<TabEntity>> entities = new SortedList<float, LinkedList<TabEntity>>();

            // Add SECTION entities
            foreach (SongSection s in sngFile.SongSections)
                addEntity(new TabSection(this, s), entities);

            // Add MEASURE entities
            float lastTime = sngFile.Beats[0].Time;
            int beatCount = 1;
            int lastMeasure = sngFile.Beats[0].Measure;

            for (int i = 1; i < sngFile.Beats.Length; i++)
            {
                Ebeat b = sngFile.Beats[i];
                // To indicate that the current beat is simply the next beat in the current measure and does not define
                // a new measure, either set b.Measure to -1 or to the same value as the beat before
                if (b.Measure == -1 || b.Measure == lastMeasure)
                    beatCount++;
                else
                {
                    addEntity(new TabMeasure(this, lastTime, b.Time, beatCount), entities);
                    lastTime = b.Time;
                    beatCount = 1;
                    lastMeasure = b.Measure;
                }
            }
            // Don't forget the final measure
            TabMeasure finalMeasure = new TabMeasure(this, lastTime, sngFile.Beats[sngFile.Beats.Length - 1].Time, beatCount);
            addEntity(finalMeasure, entities);

            MaxDifficulty = 0;
            // Add NOTE / CHORD entities
            foreach (PhraseIteration pi in sngFile.PhraseIterations)
            {
                Phrase p = sngFile.Phrases[pi.Id];
                if (MaxDifficulty < p.MaxDifficulty)
                    MaxDifficulty = p.MaxDifficulty;

                int level = Math.Min(maxDifficulty, p.MaxDifficulty);
                List<Note> notes = new List<Note>();

                foreach (Note n in sngFile.SongLevels[level].Notes)
                {
                    if (n.Time < pi.StartTime || n.Time > pi.EndTime)
                        continue;

                    if (n.ChordId != -1)
                        addEntity(new TabChord(this, n, sngFile), entities);
                    else
                        addEntity(new TabNote(this, n), entities);
                }
            }

            // Now that the entity list has been build, iterate over it and Apply every single entity to this TabFile,
            // which will format the entity's data and add it to the TabFile's output buffer.
            header.Apply(this, maxDifficulty);
            foreach (LinkedList<TabEntity> lle in entities.Values)
            {
                foreach (TabEntity e in lle)
                    e.Apply(this); // "this" contains a stream to make the tablature text
            }
            flushMeasureQueue(); // Don't forget, otherwise the last section's measures will be missing
        }
 public void SngGenerationControlsMatch(SngFile rsSng)
 {
     TestSngGeneration(rsSng, (toolkitSng, sb) =>
         AssertEx.PropertyValuesAreEqual("Controls", toolkitSng.Controls, rsSng.Controls, sb)
     );
 }
 private void TestSngGeneration(SngFile rsSng, Action<SngFile, StringBuilder> func)
 {
     var songKey = rsSng.Metadata.SongTitle + rsSng.Metadata.Arrangement + rsSng.Metadata.SongPart;
     if (songKey == "0")
     {
         return;
     }
     string xmlName = null, xmlLocation = null;
     if (rsXmlMappings.ContainsKey(songKey))
     {
         xmlName = rsXmlMappings[songKey];
         if (xmlName == null)
         {
             return;
         }
         xmlLocation = Path.Combine(@"C:\Projects\RS\RS XML Clean", Path.ChangeExtension(xmlName, "xml"));
     }
     if (!File.Exists(xmlLocation))
     {
         xmlName = rsSng.Metadata.SongTitle + " - " + rsSng.Metadata.Arrangement;
         xmlLocation = Path.Combine(@"C:\Projects\RS\RS XML Clean", Path.ChangeExtension(xmlName, "xml"));
     }
     if (!File.Exists(xmlLocation))
     {
         Assert.Fail("Couldn't find XML file for SNG: {0}", songKey);
     }
     var tmpSngLocation = Path.GetTempFileName();
     var arrangement = rsSng.Metadata.Arrangement == "Bass" ? ArrangementType.Bass : ArrangementType.Guitar;
     SngFileWriter.Write(xmlLocation, tmpSngLocation, arrangement, new Platform(GamePlatform.Pc, GameVersion.None));
     SngFile toolkitSng = new SngFile(tmpSngLocation);
     StringBuilder sb = new StringBuilder();
     func(toolkitSng, sb);
     try
     {
         File.Delete(tmpSngLocation);
     }
     catch { }
     if (sb.Length > 0)
     {
         Assert.Fail(sb.ToString());
     }
 }
 public void KnownVersion(SngFile song)
 {
     Assert.IsTrue(song.Version == 49 || song.Version == 51);
 }
 public void SngGenerationSongSectionsMatch(SngFile rsSng)
 {
     TestSngGeneration(rsSng, (toolkitSng, sb) =>
         AssertEx.PropertyValuesAreEqual("SongSections", toolkitSng.SongSections, rsSng.SongSections, sb)
     );
 }
 public void SongSectionsInOrder(SngFile song)
 {
     foreach (var songSection in song.SongSections)
     {
         Assert.LessOrEqual(songSection.StartTime, songSection.EndTime);
     }
 }
 public void SngGenerationPhrasesMatch(SngFile rsSng)
 {
     TestSngGeneration(rsSng, (toolkitSng, sb) =>
         AssertEx.PropertyValuesAreEqual("Phrases", toolkitSng.Phrases, rsSng.Phrases, sb)
     );
 }
 public void SngGenerationMetadataMatch(SngFile rsSng)
 {
     TestSngGeneration(rsSng, (toolkitSng, sb) =>
         AssertEx.PropertyValuesAreEqual("Metadata", toolkitSng.Metadata, rsSng.Metadata, sb)
     );
 }
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.Out.WriteLine("Syntax: sngtotab.exe [files]");
                return;
            }

            int difficulty = Common.MAX_DIFFICULTY_ONLY;

            try {
                foreach (string filename in args)
                {
                    if (filename.StartsWith("-l"))
                    {
                        string difficultyString = filename.Substring(2);
                        if (difficultyString.Equals("a", StringComparison.Ordinal))
                            difficulty = Common.ALL_DIFFICULTIES;
                        else if (difficultyString.Equals("m", StringComparison.Ordinal))
                            difficulty = Common.MAX_DIFFICULTY_ONLY;
                        else
                            difficulty = int.Parse(difficultyString);

                        continue;
                    }

                    SngFile sngFile = new SngFile(filename);

                    int maxDifficulty = Common.getMaxDifficulty(sngFile);

                    int[] difficulties;
                    switch (difficulty)
                    {
                        case Common.MAX_DIFFICULTY_ONLY:
                            difficulties = new int[] { maxDifficulty };
                            break;

                        case Common.ALL_DIFFICULTIES:
                            difficulties = Enumerable.Range(0, maxDifficulty + 1).ToArray();
                            break;

                        default:
                            difficulties = new int[] { difficulty };
                            break;
                    }

                    foreach (int d in difficulties)
                    {
                        TabFile tabFile = new TabFile(sngFile, d);

                        string outputFilename;
                        if (filename.EndsWith(".sng"))
                            outputFilename = filename.Substring(0, filename.Length - 4) + "." + d + ".txt";
                        else
                            outputFilename = filename + "." + d + ".txt";
                        TextWriter tw = new StreamWriter(outputFilename);
                        tw.Write(tabFile.ToString());
                        tw.Close();
                    }
                }
                Console.WriteLine("The conversion is complete.");
            } catch (Exception ex){
                Console.WriteLine("Error ocurred: " + ex.Message + Environment.NewLine + ex.InnerException);
            }
        }
 /// <summary>
 /// Converts RS1 Song Object to RS1 SngFile Object
 /// </summary>
 /// <param name="rs1Song"></param>
 /// <returns>SngFile</returns>
 public SngFile Song2SngFile(Song rs1Song, string outputDir)
 {
     var rs1SngPath = SongToSngFilePath(rs1Song, outputDir);
     SngFile sngFile = new SngFile(rs1SngPath);
     return sngFile;
 }
 public void NotesInOrder(SngFile song)
 {
     foreach (var level in song.SongLevels)
     {
         Note lastNote = null;
         foreach (var note in level.Notes)
         {
             if (lastNote != null)
             {
                 Assert.LessOrEqual(lastNote.Time, note.Time);
             }
             lastNote = note;
         }
     }
 }
        public static int getMaxDifficulty(SngFile sngFile)
        {
            int maxDifficulty = 0;
            foreach (PhraseIteration pi in sngFile.PhraseIterations)
            {
                Phrase p = sngFile.Phrases[pi.Id];
                if (p.MaxDifficulty > maxDifficulty)
                    maxDifficulty = p.MaxDifficulty;
            }

            return maxDifficulty;
        }
 public void SngGenerationEbeatsMatch(SngFile rsSng)
 {
     TestSngGeneration(rsSng, (toolkitSng, sb) =>
         AssertEx.PropertyValuesAreEqual("Ebeats", toolkitSng.Beats, rsSng.Beats, sb)
     );
 }