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 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 }