public static SongPhrase[] Parse(Sng2014HSL.PhraseSection sngPhraseSection)
        {
            var phrases = new SongPhrase[sngPhraseSection.Count];

            for (int i = 0; i < sngPhraseSection.Count; i++)
            {
                var phrase = new SongPhrase();
                phrase.Disparity     = sngPhraseSection.Phrases[i].Disparity;
                phrase.Ignore        = sngPhraseSection.Phrases[i].Ignore;
                phrase.MaxDifficulty = sngPhraseSection.Phrases[i].MaxDifficulty;
                phrase.Name          = sngPhraseSection.Phrases[i].Name.ToNullTerminatedAscii();
                phrase.Solo          = sngPhraseSection.Phrases[i].Solo;
                phrases[i]           = phrase;
            }
            return(phrases);
        }
        internal static SongPhrase[] Parse(List <DLCPackage.Manifest.Phrase> phraseList)
        {
            var phrases = new SongPhrase[phraseList.Count];

            for (int i = 0; i < phraseList.Count; i++)
            {
                var phrase = new SongPhrase();
                //phrase.Disparity = 0;
                //phrase.Ignore = 0;
                phrase.MaxDifficulty = phraseList[i].MaxDifficulty;
                phrase.Name          = phraseList[i].Name;
                phrase.Solo          = (byte)(phraseList[i].Name.ToLower().Contains("solo") ? 1 : 0);
                phrases[i]           = phrase;
            }
            return(phrases);
        }
        public Song2014(Sng2014HSL.Sng sngData, Attributes2014 attr = null)
        {
            Version    = "7";
            CrowdSpeed = "1";

            if (attr != null)
            {
                // If manifest is passed, fill general song information
                Title                  = attr.SongName;
                Arrangement            = ((ArrangementName)attr.ArrangementType).ToString();
                Part                   = (short)attr.SongPartition;
                Offset                 = (float)attr.SongOffset;
                CentOffset             = Convert.ToString(attr.CentOffset);
                SongLength             = (float)attr.SongLength;
                SongNameSort           = attr.SongNameSort;
                AverageTempo           = attr.SongAverageTempo;
                Tuning                 = attr.Tuning;
                Capo                   = Convert.ToByte(attr.CapoFret);
                ArtistName             = attr.ArtistName;
                ArtistNameSort         = attr.ArtistNameSort;
                AlbumName              = attr.AlbumName;
                AlbumNameSort          = attr.AlbumNameSort;
                AlbumYear              = Convert.ToString(attr.SongYear) ?? "";
                AlbumArt               = attr.AlbumArt;
                ArrangementProperties  = attr.ArrangementProperties;
                LastConversionDateTime = attr.LastConversionDateTime;

                ToneBase = attr.Tone_Base;
                ToneA    = attr.Tone_A;
                ToneB    = attr.Tone_B;
                ToneC    = attr.Tone_C;
                ToneD    = attr.Tone_D;
            }
            else
            {
                Part                   = sngData.Metadata.Part;
                SongLength             = sngData.Metadata.SongLength;
                Tuning                 = new TuningStrings(sngData.Metadata.Tuning);
                Capo                   = (byte)((sngData.Metadata.CapoFretId == 0xFF) ? 0x00 : sngData.Metadata.CapoFretId);
                LastConversionDateTime = sngData.Metadata.LastConversionDateTime.ToNullTerminatedAscii();
            }

            Tones = SongTone2014.Parse(sngData.Tones, attr);
            if (attr == null)
            {
                // Fix tones slots for fake tone names if manifest was not entered
                foreach (var tone in Tones)
                {
                    if (tone.Name.EndsWith("_0"))
                    {
                        ToneBase = tone.Name;
                    }
                    if (tone.Name.EndsWith("_1"))
                    {
                        ToneA = ToneBase;
                        ToneB = tone.Name;
                    }
                    if (tone.Name.EndsWith("_2"))
                    {
                        ToneC = tone.Name;
                    }
                    if (tone.Name.EndsWith("_3"))
                    {
                        ToneD = tone.Name;
                    }
                }
            }

            //Sections can be obtained from manifest or sng file (manifest preferred)
            Sections = (attr != null) ? SongSection.Parse(attr.Sections) : SongSection.Parse(sngData.Sections);

            //Can be obtained from manifest or sng file (sng preferred)
            Phrases          = SongPhrase.Parse(sngData.Phrases);
            PhraseIterations = SongPhraseIteration2014.Parse(sngData.PhraseIterations);

            //Can be obtained from manifest or sng file (combined preferred)
            ChordTemplates = SongChordTemplate2014.Parse(sngData.Chords); // Only SNG have all ChordTemplates, manifest have only chord templates with name
            if (attr != null)
            {
                SongChordTemplate2014.AddChordIds(ChordTemplates, attr.ChordTemplates); // Only manifest has chordIds
            }

            //Only in SNG
            Ebeats    = SongEbeat.Parse(sngData.BPMs);
            StartBeat = sngData.BPMs.BPMs[0].Time;
            Events    = SongEvent.Parse(sngData.Events);
            Levels    = SongLevel2014.Parse(sngData);

            //Not used in RS2014 customs at this time. Need to check official files
            NewLinkedDiff         = SongNewLinkedDiff.Parse(sngData.NLD);
            PhraseProperties      = SongPhraseProperty.Parse(sngData.PhraseExtraInfo);
            LinkedDiffs           = new SongLinkedDiff[0];
            FretHandMuteTemplates = new SongFretHandMuteTemplate[0];
            //ddc
            TranscriptionTrack = TranscriptionTrack2014.GetDefault();
        }
        // COMPLETE
        private static void WriteRocksmithSngPhrases(EndianBinaryWriter w, SongPhrase[] phrases, SongPhraseIteration[] phraseIterations)
        {
            // Sample: begins at position 7,208 in NumberThirteen_Lead.sng

            // output header
            if (phrases == null || phrases.Length == 0)
            {
                w.Write(new byte[4]); // empty header
                return;
            }

            // output header count
            w.Write(phrases.Length);

            // output phrases
            for (int i = 0; i < phrases.Length; i++)
            {
                // solo
                w.Write(phrases[i].Solo == 1 ? true : false);

                // disparity
                w.Write(phrases[i].Disparity == 1 ? true : false);

                // ignore
                w.Write(phrases[i].Ignore == 1 ? true : false);

                // unused padding
                w.Write(new byte());

                // maxDifficulty tag
                w.Write(phrases[i].MaxDifficulty);

                // count of usage in iterations
                int phraseIterationCount = 0;
                for (int i2 = 0; i2 < phraseIterations.Length; i2++)
                {
                    if (phraseIterations[i2].PhraseId == i)
                    {
                        phraseIterationCount++;
                    }
                }
                w.Write(phraseIterationCount);

                // name tag
                string name = phrases[i].Name;
                if (name.Length > 32)
                {
                    name = name.Substring(0, 32);
                }
                foreach (char c in name)
                {
                    w.Write(Convert.ToByte(c));
                }
                // padding after name
                w.Write(new byte[32 - name.Length]);
            }
        }
 internal static SongPhrase[] Parse(List<DLCPackage.Manifest.Phrase> phraseList)
 {
     var phrases = new SongPhrase[phraseList.Count];
     for (int i = 0; i < phraseList.Count; i++) {
         var phrase = new SongPhrase();
         //phrase.Disparity = 0;
         //phrase.Ignore = 0;
         phrase.MaxDifficulty = phraseList[i].MaxDifficulty;
         phrase.Name = phraseList[i].Name;
         phrase.Solo = (byte)(phraseList[i].Name.ToLower().Contains("solo") ? 1 : 0);
         phrases[i] = phrase;
     }
     return phrases;
 }
 public static SongPhrase[] Parse(Sng2014HSL.PhraseSection sngPhraseSection)
 {
     var phrases = new SongPhrase[sngPhraseSection.Count];
     for (int i = 0; i < sngPhraseSection.Count; i++) {
         var phrase = new SongPhrase();
         phrase.Disparity = sngPhraseSection.Phrases[i].Disparity;
         phrase.Ignore = sngPhraseSection.Phrases[i].Ignore;
         phrase.MaxDifficulty = sngPhraseSection.Phrases[i].MaxDifficulty;
         phrase.Name = sngPhraseSection.Phrases[i].Name.ToNullTerminatedAscii();
         phrase.Solo = sngPhraseSection.Phrases[i].Solo;
         phrases[i] = phrase;
     }
     return phrases;
 }