public string NameFromStrings(TuningStrings tuning, bool isBass, bool inBem = true) { List <Int32> Notes = new List <Int32>(); List <String> NoteNames = new List <String>(); String[] notesNames = new String[] { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; String[] notesNamesHi = new String[] { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" }; for (Byte s = 0; s < 6; s++) { Notes.Add(Sng2014FileWriter.GetMidiNote(tuning.ToShortArray(), s, 0, isBass, 0)); } foreach (var mNote in Notes) { if (inBem) { NoteNames.Add(notesNamesHi[mNote % 12]); //oct = mNote / 12 - 1 } else { NoteNames.Add(notesNames[mNote % 12]); //oct = mNote / 12 - 1 } } return(String.Format("{0}{1}{2}{3}{4}{5}", NoteNames[0], NoteNames[1], NoteNames[2], NoteNames[3], NoteNames[4], NoteNames[5])); }
public static Sng2014File ConvertXML(string xmlPath, ArrangementType type, string cdata = null) { if (type == ArrangementType.Vocal) { return(Sng2014FileWriter.ReadVocals(xmlPath, cdata)); } return(Sng2014File.ConvertSong(xmlPath)); }
public Showlights Genegate(string xmlFile) { var midiNotes = new List <Showlight>(); var chordNotes = new List <Showlight>(); var ShowL = new Showlights(); var song = Song2014.LoadFromFile(xmlFile); // If vocals if (song.Phrases == null || song.Tuning == null) { return(null); } //Generate ShowlightList var tuning = song.Tuning.ToShortArray(); if (song.Levels != null) { foreach (var lvl in song.Levels) { for (int i = 0; i + 1 <= lvl.Notes.Count(); i++) { var mNote = Sng2014FileWriter.GetMidiNote(tuning, (Byte)lvl.Notes[i].String, (Byte)lvl.Notes[i].Fret, song.Arrangement == "Bass", song.Capo); midiNotes.Add(new Showlight() { Time = lvl.Notes[i].Time, Note = mNote }); } for (int i = 0; i + 1 <= lvl.Chords.Count(); i++) { if (lvl.Chords[i].HighDensity == 1) { continue; //speedhack } int mNote = Sng2014FileWriter.getChordNote(tuning, lvl.Chords[i], song.ChordTemplates, song.Arrangement == "Bass", song.Capo); chordNotes.Add(new Showlight() { Time = lvl.Chords[i].Time, Note = mNote }); } } } ShowL.PopShList(midiNotes); ShowL.PopShList(chordNotes); ShowL.Count = ShowL.ShowlightList.Count; return(ShowL); }
static string NoteName(TuningStrings tuning, byte s, bool flats = false) { String[] notesNamesHi = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; String[] notesNamesLo = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" }; var id = Sng2014FileWriter.GetMidiNote(tuning.ToArray(), s, 0, false, 0) % 12; return(flats ? notesNamesLo[id] : notesNamesHi[id]); }
// this is platform independent SNG object public static Sng2014File ConvertSong(string xmlFile) { var song = Song2014.LoadFromFile(xmlFile); var parser = new Sng2014FileWriter(); var sng = new Sng2014File(); parser.ReadSong(song, sng); sng.NoteCount = parser.NoteCount; sng.DNACount = parser.DNACount; return(sng); }
public static Sng2014File ConvertXML(string xmlPath, ArrangementType type) { if (type != ArrangementType.Vocal) { return(Sng2014File.ConvertSong(xmlPath)); } else { return(Sng2014FileWriter.ReadVocals(xmlPath)); } }
public static void PopFontPath(this Sng2014File vox, string dlcname) { var path = String.Format("assets/ui/lyrics/{0}/lyrics_{0}.dds", dlcname); if (vox.Vocals != null) { if (vox.Vocals.Count > 0 && vox.SymbolsTexture.Count > 0) { Sng2014FileWriter.readString(path, vox.SymbolsTexture.SymbolsTextures[0].Font); vox.SymbolsTexture.SymbolsTextures[0].FontpathLength = path.Length; } } }
static int[] GetTuning(Song2014 arrangement) { // Guitar Pro expects the tuning as Midi note values // In Rocksmith, the tuning is given as the difference in half steps // from standard tuning for each string, so we need to convert that. bool isBass = arrangement.Title.ToLower() == "bass"; int[] tuning = new int[6]; for (byte s = 0; s < tuning.Length; ++s) { tuning[s] = Sng2014FileWriter.GetMidiNote(arrangement.Tuning.ToArray(), s, 0, isBass, 0); } return(tuning); }
/// <summary> /// Showlights Generator Rev3 /// using arrangement and level with most notes and chords /// </summary> /// <param name="xmlFile">Xml file.</param> private void Generate(string xmlFile, int maxLevelNdx) { var midiNotes = new List <Showlight>(); var chordNotes = new List <Showlight>(); var song = Song2014.LoadFromFile(xmlFile); // error checking if (song.Phrases == null || song.Levels == null || song.Tuning == null) { throw new Exception("Arrangement: " + xmlFile + Environment.NewLine + "Contains no phrases, levels and/or tuning."); } // tuning used to get proper midi notes var tuning = song.Tuning.ToArray(); foreach (var note in song.Levels[maxLevelNdx].Notes) { // make showlights changes occure on the beat/measure var measOffset = song.Ebeats.Where(eb => eb.Measure != -1 && eb.Time <= note.Time).Last(); // forcing midi notes for guitar gives more consistent results even with bass arrangements var mNote = Sng2014FileWriter.GetMidiNote(tuning, (Byte)note.String, (Byte)note.Fret, false, song.Capo); // varying midi notes gives more color changes // var mNote = Sng2014FileWriter.GetMidiNote(tuning, (Byte)note.String, (Byte)note.Fret, song.Arrangement == "Bass", song.Capo); midiNotes.Add(new Showlight { Time = measOffset.Time, Note = mNote }); } foreach (var chord in song.Levels[maxLevelNdx].Chords) { if (chord.HighDensity == 1) { continue; //speedhack } // make showlights occure on the beat/measure var measOffset = song.Ebeats.Where(eb => eb.Measure != -1 && eb.Time <= chord.Time).Last(); // forcing midi notes for guitar gives more consistent results even with bass arrangements var mNote = Sng2014FileWriter.getChordNote(tuning, chord, song.ChordTemplates, false, song.Capo); // varying midi notes gives more color changes //var mNote = Sng2014FileWriter.getChordNote(tuning, chord, song.ChordTemplates, song.Arrangement == "Bass", song.Capo); chordNotes.Add(new Showlight { Time = measOffset.Time, Note = mNote }); } ShowlightList = new List <Showlight>(); AddShowlights(midiNotes); AddShowlights(chordNotes); }
/// <summary> /// Showlights Generator Rev2 /// max difficulty with most notes and chords /// </summary> /// <param name="xmlFile">Xml file.</param> public Showlights Generate(string xmlFile) { var midiNotes = new List <Showlight>(); var chordNotes = new List <Showlight>(); var song = Song2014.LoadFromFile(xmlFile); // If vocals if (song.Phrases == null || song.Tuning == null) { return(null); } //Generate ShowlightList var tuning = song.Tuning.ToArray(); if (song.Levels != null) { var mf = new ManifestFunctions(GameVersion.RS2014); int maxDif = mf.GetMaxDifficulty(song); for (int i = 0; i < song.Levels[maxDif].Notes.Length; i++) { var mNote = Sng2014FileWriter.GetMidiNote(tuning, (Byte)song.Levels[maxDif].Notes[i].String, (Byte)song.Levels[maxDif].Notes[i].Fret, song.Arrangement == "Bass", song.Capo); midiNotes.Add(new Showlight { Time = song.Levels[maxDif].Notes[i].Time, Note = mNote }); } for (int i = 0; i < song.Levels[maxDif].Chords.Length; i++) { if (song.Levels[maxDif].Chords[i].HighDensity == 1) { continue; //speedhack } int mNote = Sng2014FileWriter.getChordNote(tuning, song.Levels[maxDif].Chords[i], song.ChordTemplates, song.Arrangement == "Bass", song.Capo); chordNotes.Add(new Showlight { Time = song.Levels[maxDif].Chords[i].Time, Note = mNote }); } } PopShList(midiNotes); PopShList(chordNotes); return(this); }
private static string GetTuningName(TuningStrings tuning, bool isBass, int capo, bool inBem = true) { List <Int32> Notes = new List <Int32>(); List <String> NoteNames = new List <String>(); String[] notesNames = new String[] { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; String[] notesNamesHi = new String[] { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" }; for (Byte s = 0; s < (isBass ? 4 : 6); s++) { Notes.Add(Sng2014FileWriter.GetMidiNote(tuning.ToShortArray(), s, 0, isBass, capo)); } foreach (var mNote in Notes) { if (inBem) { NoteNames.Add(notesNamesHi[mNote % 12]); //oct = mNote / 12 - 1 } else { NoteNames.Add(notesNames[mNote % 12]); //oct = mNote / 12 - 1 } } return(String.Join(" ", NoteNames)); }
/// <summary> /// Loads required DLC info from folder. /// </summary> /// <returns>The DLCPackageData info.</returns> /// <param name="unpackedDir">Unpacked dir.</param> /// <param name="targetPlatform">Target platform.</param> /// <param name = "sourcePlatform"></param> /// <param name="ignoreMultitoneEx">Ignore multitone exceptions</param> public static DLCPackageData LoadFromFolder(string unpackedDir, Platform targetPlatform, Platform sourcePlatform = null, bool ignoreMultitoneEx = false) { var data = new DLCPackageData(); data.GameVersion = GameVersion.RS2014; data.SignatureType = PackageMagic.CON; if (sourcePlatform == null) { sourcePlatform = unpackedDir.GetPlatform(); } //Arrangements / Tones data.Arrangements = new List <Arrangement>(); data.TonesRS2014 = new List <Tone2014>(); //Load files var jsonFiles = Directory.EnumerateFiles(unpackedDir, "*.json", SearchOption.AllDirectories).ToArray(); foreach (var json in jsonFiles) { var attr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.ToArray()[0].Value.ToArray()[0].Value; var xmlName = attr.SongXml.Split(':')[3]; var xmlFile = Directory.EnumerateFiles(unpackedDir, xmlName + ".xml", SearchOption.AllDirectories).FirstOrDefault(); if (attr.Phrases != null) { if (data.SongInfo == null) { // Fill Package Data data.Name = attr.DLCKey; data.Volume = (attr.SongVolume == 0 ? -12 : attr.SongVolume); //FIXME: too low song volume issue, revert to -6 to fix. data.PreviewVolume = (attr.PreviewVolume ?? data.Volume); // Fill SongInfo data.SongInfo = new SongInfo { SongDisplayName = attr.SongName, SongDisplayNameSort = attr.SongNameSort, Album = attr.AlbumName, AlbumSort = attr.AlbumNameSort, SongYear = attr.SongYear ?? 0, Artist = attr.ArtistName, ArtistSort = attr.ArtistNameSort, AverageTempo = (int)attr.SongAverageTempo }; } // Adding Arrangement data.Arrangements.Add(new Arrangement(attr, xmlFile, ignoreMultitoneEx)); // make a list of tone names used in arrangements var toneNames = new List <string>(); foreach (var arr in data.Arrangements) { if (!String.IsNullOrEmpty(arr.ToneA)) { toneNames.Add(arr.ToneA); } if (!String.IsNullOrEmpty(arr.ToneB)) { toneNames.Add(arr.ToneB); } if (!String.IsNullOrEmpty(arr.ToneC)) { toneNames.Add(arr.ToneC); } if (!String.IsNullOrEmpty(arr.ToneD)) { toneNames.Add(arr.ToneD); } if (!String.IsNullOrEmpty(arr.ToneBase)) { toneNames.Add(arr.ToneBase); } } // Adding Tones foreach (var jsonTone in attr.Tones) { if (jsonTone == null) { continue; } var key = jsonTone.Key; if (data.TonesRS2014.All(t => t.Key != key)) { // fix tones names that do not have the correct alphacase for cross matching if (attr.Tone_Base.ToLower() == jsonTone.Name.ToLower() && attr.Tone_Base != jsonTone.Name) { jsonTone.Name = attr.Tone_Base; } if (attr.Tone_A != null && attr.Tone_A.ToLower() == jsonTone.Name.ToLower() && attr.Tone_A != jsonTone.Name) { jsonTone.Name = attr.Tone_A; } if (attr.Tone_B != null && attr.Tone_B.ToLower() == jsonTone.Name.ToLower() && attr.Tone_B != jsonTone.Name) { jsonTone.Name = attr.Tone_B; } if (attr.Tone_C != null && attr.Tone_C.ToLower() == jsonTone.Name.ToLower() && attr.Tone_C != jsonTone.Name) { jsonTone.Name = attr.Tone_C; } if (attr.Tone_D != null && attr.Tone_D.ToLower() == jsonTone.Name.ToLower() && attr.Tone_D != jsonTone.Name) { jsonTone.Name = attr.Tone_D; } // this is part of multitone exception handling auto convert to single tone arrangment // make data.TonesRS2014 consistent with data.Arragment.Tones (toneNames) if (toneNames.Contains(jsonTone.Name)) { data.TonesRS2014.Add(jsonTone); } } } } else if (xmlFile.ToLower().Contains("_vocals")) { var voc = new Arrangement { Name = attr.JapaneseVocal == true ? ArrangementName.JVocals : ArrangementName.Vocals, ArrangementType = ArrangementType.Vocal, ScrollSpeed = 20, SongXml = new SongXML { File = xmlFile }, SongFile = new SongFile { File = "" }, CustomFont = attr.JapaneseVocal == true }; // Get symbols stuff from _vocals.xml var fontSng = Path.Combine(unpackedDir, xmlName + ".sng"); var vocSng = Sng2014FileWriter.ReadVocals(xmlFile); if (vocSng.IsCustomFont()) { voc.CustomFont = true; voc.FontSng = fontSng; vocSng.WriteChartData(fontSng, new Platform(GamePlatform.Pc, GameVersion.None)); } voc.Sng2014 = Sng2014File.ConvertXML(xmlFile, ArrangementType.Vocal, voc.FontSng); // Adding Arrangement data.Arrangements.Add(voc); } } //ShowLights XML var xmlShowLights = Directory.EnumerateFiles(unpackedDir, "*_showlights.xml", SearchOption.AllDirectories).FirstOrDefault(); if (!String.IsNullOrEmpty(xmlShowLights)) { var shl = new Arrangement { ArrangementType = ArrangementType.ShowLight, Name = ArrangementName.ShowLights, SongXml = new SongXML { File = xmlShowLights }, SongFile = new SongFile { File = "" } }; // Adding ShowLights data.Arrangements.Add(shl); data.Showlights = true; } //Get DDS Files var ddsFiles = Directory.EnumerateFiles(unpackedDir, "album_*.dds", SearchOption.AllDirectories).ToArray(); if (ddsFiles.Any()) { var ddsFilesC = new List <DDSConvertedFile>(); foreach (var file in ddsFiles) { switch (Path.GetFileNameWithoutExtension(file).Split('_')[2]) { case "256": data.AlbumArtPath = file; ddsFilesC.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; case "128": ddsFilesC.Add(new DDSConvertedFile() { sizeX = 128, sizeY = 128, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; case "64": ddsFilesC.Add(new DDSConvertedFile() { sizeX = 64, sizeY = 64, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; } } data.ArtFiles = ddsFilesC; } // Lyric Art var lyricArt = Directory.EnumerateFiles(unpackedDir, "lyrics_*.dds", SearchOption.AllDirectories).ToArray(); if (lyricArt.Any()) { data.LyricArtPath = lyricArt.FirstOrDefault(); } //Get other files //Audio files var targetAudioFiles = new List <string>(); var sourceAudioFiles = Directory.EnumerateFiles(unpackedDir, "*.wem", SearchOption.AllDirectories).ToArray(); foreach (var file in sourceAudioFiles) { var newFile = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), Path.GetExtension(file))); if (targetPlatform.IsConsole != (sourcePlatform = file.GetAudioPlatform()).IsConsole) { OggFile.ConvertAudioPlatform(file, newFile); targetAudioFiles.Add(newFile); } else { targetAudioFiles.Add(file); } } if (!targetAudioFiles.Any()) { throw new InvalidDataException("Audio files not found."); } string audioPath = null, audioPreviewPath = null; var a = new FileInfo(targetAudioFiles[0]); if (targetAudioFiles.Count == 2) { var b = new FileInfo(targetAudioFiles[1]); if (a.Length > b.Length) { audioPath = a.FullName; audioPreviewPath = b.FullName; } else { audioPath = b.FullName; audioPreviewPath = a.FullName; } } else { audioPath = a.FullName; } data.OggPath = audioPath; //Make Audio preview with expected name when rebuild if (!String.IsNullOrEmpty(audioPreviewPath)) { var newPreviewFileName = Path.Combine(Path.GetDirectoryName(audioPath), String.Format("{0}_preview{1}", Path.GetFileNameWithoutExtension(audioPath), Path.GetExtension(audioPath))); File.Move(audioPreviewPath, newPreviewFileName); data.OggPreviewPath = newPreviewFileName; } //AppID var appidFile = Directory.EnumerateFiles(unpackedDir, "*.appid", SearchOption.AllDirectories).FirstOrDefault(); if (appidFile != null) { data.AppId = File.ReadAllText(appidFile); } // Package Info var versionFile = Directory.EnumerateFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories).FirstOrDefault(); if (versionFile != null) { var tkInfo = GeneralExtensions.ReadToolkitInfo(versionFile); data.PackageVersion = tkInfo.PackageVersion; data.PackageComment = tkInfo.PackageComment; } else { data.PackageVersion = "1"; data.PackageComment = ""; } return(data); }
private static Score CreateSong(Song2014 song, IEnumerable <SongNoteChordWrapper> allSounds) { var score = new Score(); score.Album = song.AlbumName; score.Artist = song.ArtistName; //score.copyright //score.instructions //score.music score.Notices = "Created by RockSmith Tab Explorer"; //_score.subTitle //_score.tab score.Tempo = (int)song.AverageTempo; score.TempoLabel = "avg. bpm"; score.Title = song.Title + " (" + song.Arrangement + ")"; //_score.words bool isBass = song.Arrangement.ToLower() == "bass"; var track = new Track(); track.Name = song.Arrangement; track.Index = 1; int capo = track.Capo; track.TuningName = GetTuningName(song.Tuning, isBass, capo); track.ShortName = song.Arrangement; // Add string tunings in reverse order var tuning = new int[(isBass ? 4 : 6)]; for (Byte s = 0; s < tuning.Length; s++) { tuning[tuning.Length - 1 - s] = Sng2014FileWriter.GetMidiNote(song.Tuning.ToShortArray(), s, 0, isBass, capo); } track.Tuning.AddRange(tuning); score.AddTrack(track); foreach (var chordTemplate in song.ChordTemplates.Where(ct => ct.ChordId != null)) { var chord = new global::AlphaTab.Model.Chord(); track.Chords[chordTemplate.ChordId.ToString()] = chord; chord.Name = chordTemplate.ChordName; chord.Strings.Add(chordTemplate.Fret0); chord.Strings.Add(chordTemplate.Fret1); chord.Strings.Add(chordTemplate.Fret2); chord.Strings.Add(chordTemplate.Fret3); chord.Strings.Add(chordTemplate.Fret4); chord.Strings.Add(chordTemplate.Fret5); } List <eBeatWrapper> ebeatMeasures = new List <eBeatWrapper>(); eBeatWrapper currentMeasureBeat = null; foreach (var srcBeat in song.Ebeats) { if (srcBeat.Measure > 0) { currentMeasureBeat = new eBeatWrapper() { MeasureStartBeat = srcBeat, MeasureSubBeats = new List <SongEbeat>() }; ebeatMeasures.Add(currentMeasureBeat); } else { if (currentMeasureBeat == null) { System.Diagnostics.Debug.WriteLine("Invalid ebeats in source file. Sub measure is before first measure!?"); } else { currentMeasureBeat.MeasureSubBeats.Add(srcBeat); } } } var notesStack = new Stack <SongNoteChordWrapper>(allSounds.OrderByDescending(x => x.Time)); var currentNote = notesStack.Pop(); var nextNote = notesStack.Pop(); int prevMeasureId = 0; int i = 1; float prevMeasureDuration = 0; foreach (var measure in ebeatMeasures) { var nextmeasure = i < ebeatMeasures.Count ? ebeatMeasures[i] : null; if (measure.MeasureStartBeat.Measure > prevMeasureId) { var measureDuration = nextmeasure != null ? nextmeasure.MeasureStartBeat.Time - measure.MeasureStartBeat.Time : prevMeasureDuration; AddMasterBarToScore(score, measure.MeasureStartBeat.Time.ToString("n2"), measure); var voice = AddBarAndVoiceToTrack(track, isBass ? Clef.F4 : Clef.G2); bool firstNoteInBar = true; while (currentNote != null && (nextmeasure == null || currentNote.Time < nextmeasure.MeasureStartBeat.Time)) { if (currentNote.IsNote() && currentNote.AsNote().Bend != 0) { System.Diagnostics.Debug.WriteLine("Bent detected. Bend value: {0}. Measure: {1}", currentNote.AsNote().Bend, measure.MeasureStartBeat.Measure); } Duration duration = Duration.Quarter; if (firstNoteInBar && currentNote.Time > measure.MeasureStartBeat.Time) { var leadingSilenceTicks = Get64thsFromDuration(measure.MeasureStartBeat.Time, currentNote.Time, measureDuration); while (leadingSilenceTicks >= 1) { if (leadingSilenceTicks >= 32) { AddBeatAndSilenceToVoice(voice, Duration.Half); leadingSilenceTicks -= 32; } else if (leadingSilenceTicks >= 16) { AddBeatAndSilenceToVoice(voice, Duration.Quarter); leadingSilenceTicks -= 16; } else if (leadingSilenceTicks >= 8) { AddBeatAndSilenceToVoice(voice, Duration.Eighth); leadingSilenceTicks -= 8; } else if (leadingSilenceTicks >= 4) { AddBeatAndSilenceToVoice(voice, Duration.Sixteenth); leadingSilenceTicks -= 4; } else if (leadingSilenceTicks >= 2) { AddBeatAndSilenceToVoice(voice, Duration.ThirtySecond); leadingSilenceTicks -= 2; } else if (leadingSilenceTicks >= 1) { AddBeatAndSilenceToVoice(voice, Duration.SixtyFourth); leadingSilenceTicks -= 1; } } } Single durationTime = 0; if (nextNote != null) { duration = GetBeatDuration(currentNote.Time, nextNote.Time, measureDuration); durationTime = nextNote.Time - currentNote.Time; } else { durationTime = measureDuration; } if (currentNote.IsNote()) { AddBeatAndNoteToVoice(voice, currentNote.AsNote(), duration, durationTime); } else { AddBeatWithChordToVoice(voice, currentNote.AsChord(), duration, durationTime); } currentNote = nextNote; if (notesStack.Any()) { nextNote = notesStack.Pop(); } else { nextNote = null; } firstNoteInBar = false; } prevMeasureId = measure.MeasureStartBeat.Measure; prevMeasureDuration = measureDuration; } i++; } return(score); }
private static Score CreateSong(Song2014 song, IEnumerable <SongNoteChordWrapper> allSounds) { var score = new Score(); score.album = song.AlbumName; score.artist = song.ArtistName; //score.copyright //score.instructions //score.music score.notices = "Created by RockSmith Tab Explorer"; //_score.subTitle //_score.tab score.tempo = (int)song.AverageTempo; score.tempoLabel = "avg. bpm"; score.title = song.Title + " (" + song.Arrangement + ")"; //_score.words bool isBass = song.Arrangement.ToLower() == "bass"; var track = new Track(); track.name = song.Arrangement; track.index = 1; track.tuningName = GetTuningName(song.Tuning, isBass); track.shortName = song.Arrangement; for (Byte s = 0; s < (isBass ? 4 : 6); s++) { track.tuning[(isBass ? 3 : 5) - s] = Sng2014FileWriter.GetMidiNote(song.Tuning.ToShortArray(), s, 0, isBass); } score.addTrack(track); int chordId = 0; foreach (var chordTemplate in song.ChordTemplates) { var chord = new global::alphatab.model.Chord(); track.chords.set(chordId.ToString(), chord); chord.name = chordTemplate.ChordName; chord.strings[0] = chordTemplate.Fret0; chord.strings[1] = chordTemplate.Fret1; chord.strings[2] = chordTemplate.Fret2; chord.strings[3] = chordTemplate.Fret3; chord.strings[4] = chordTemplate.Fret4; chord.strings[5] = chordTemplate.Fret5; chordId++; } var ebeatMeasures = song.Ebeats.Where(x => x.Measure > 0).OrderBy(x => x.Measure).ToList(); var notesStack = new Stack <SongNoteChordWrapper>(allSounds.OrderByDescending(x => x.Time)); var currentNote = notesStack.Pop(); var nextNote = notesStack.Pop(); int prevMeasureId = 0; int i = 1; float prevMeasureDuration = 0; foreach (var measure in ebeatMeasures) { var nextmeasure = i < ebeatMeasures.Count ? ebeatMeasures[i] : null; if (measure.Measure > prevMeasureId) { var measureDuration = nextmeasure != null ? nextmeasure.Time - measure.Time : prevMeasureDuration; AddMasterBarToScore(score, measure.Time.ToString("n2")); var voice = AddBarAndVoiceToTrack(track, isBass ? Clef.F4 : Clef.G2); bool firstNoteInBar = true; while (currentNote != null && (nextmeasure == null || currentNote.Time < nextmeasure.Time)) { Duration duration = Duration.Quarter; if (firstNoteInBar && currentNote.Time > measure.Time) { var leadingSilenceTicks = Get64thsFromDuration(measure.Time, currentNote.Time, measureDuration); while (leadingSilenceTicks >= 1) { if (leadingSilenceTicks >= 32) { AddBeatAndNoteToVoice(voice, null, Duration.Half); leadingSilenceTicks -= 32; } else if (leadingSilenceTicks >= 16) { AddBeatAndNoteToVoice(voice, null, Duration.Quarter); leadingSilenceTicks -= 16; } else if (leadingSilenceTicks >= 8) { AddBeatAndNoteToVoice(voice, null, Duration.Eighth); leadingSilenceTicks -= 8; } else if (leadingSilenceTicks >= 4) { AddBeatAndNoteToVoice(voice, null, Duration.Sixteenth); leadingSilenceTicks -= 4; } else if (leadingSilenceTicks >= 2) { AddBeatAndNoteToVoice(voice, null, Duration.ThirtySecond); leadingSilenceTicks -= 2; } else if (leadingSilenceTicks >= 1) { AddBeatAndNoteToVoice(voice, null, Duration.SixtyFourth); leadingSilenceTicks -= 1; } } } if (nextNote != null) { duration = GetBeatDuration(currentNote.Time, nextNote.Time, measureDuration); } if (currentNote.IsNote()) { AddBeatAndNoteToVoice(voice, currentNote.AsNote(), duration); } else { AddBeatWithChordToVoice(voice, currentNote.AsChord(), duration); } currentNote = nextNote; if (notesStack.Any()) { nextNote = notesStack.Pop(); } else { nextNote = null; } firstNoteInBar = false; } prevMeasureId = measure.Measure; prevMeasureDuration = measureDuration; } i++; } return(score); }