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
        }
Ejemplo n.º 2
0
        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
        }