private void AddPart() { var res = ShowRenamePartDialog(null); if (res.DialogResult.HasValue && res.DialogResult.Value) { var newPart = song.AddPart(res.PartName); this.StructureTree.SelectItem(newPart.Slides.First()); song.AddPartToOrder(newPart); } }
public void Read(Song song, Stream stream) { if (song == null) throw new ArgumentNullException("song"); if (stream == null) throw new ArgumentNullException("stream"); var doc = XDocument.Load(stream); if (doc.Root.Name != ns + "song") { throw new SongFormatException("File is not a valid OpenLyrics song."); } //var openLyricsVersion = new Version(doc.Root.Attribute("version").Value); //bool versionPre08 = openLyricsVersion < new Version(0, 8); var prop = doc.Root.Element(ns + "properties"); song.Title = prop.Element(ns + "titles").Elements(ns + "title").First().Value; var authors = prop.Elements(ns + "authors"); song.Copyright = authors.Any() ? String.Join(", ", authors.Single().Elements(ns + "author").Select(e => e.Value)) : String.Empty; if (prop.Elements(ns + "publisher").Any()) { var publisher = "Publisher: " + prop.Element(ns + "publisher").Value; song.Copyright = String.IsNullOrEmpty(song.Copyright) ? publisher : song.Copyright + "\n" + publisher; } if (prop.Elements(ns + "copyright").Any()) { var copyright = prop.Element(ns + "copyright").Value; if (!copyright.StartsWith("©") && !copyright.StartsWith("(c)")) copyright = "© " + copyright; song.Copyright = String.IsNullOrEmpty(song.Copyright) ? copyright : song.Copyright + "\n" + copyright; } song.CcliNumber = prop.Elements(ns + "ccliNo").Any() ? int.Parse(prop.Element(ns + "ccliNo").Value) : (int?)null; song.Category = prop.Elements(ns + "themes").Any() ? String.Join("; ", prop.Element(ns + "themes").Elements(ns + "theme").Select(e => e.Value)) : String.Empty; song.Comment = prop.Elements(ns + "comments").Any() ? String.Join("\n", prop.Element(ns + "comments").Elements(ns + "comment").Select(e => e.Value)) : String.Empty; if (prop.Elements(ns + "songbooks").Any()) { int number; song.SetSources(prop.Element(ns + "songbooks").Elements(ns + "songbook").Select(e => new SongSource(song) { Songbook = e.Attribute("name").Value, Number = e.Attributes("entry").Any() ? (int.TryParse(e.Attribute("entry").Value, out number) ? number : (int?)null) : null })); } var mappings = new Dictionary<string, string>(); foreach (var verse in doc.Root.Element(ns + "lyrics").Elements(ns + "verse")) { string originalName = verse.Attribute("name").Value; // add language key to part name (we don't know which one is the translation // and we can not automatically deal with more than 2 languages) string name = originalName + (verse.Attributes("lang").Any() ? " (" + verse.Attribute("lang").Value + ")" : String.Empty); if (!mappings.ContainsKey(originalName)) { // keep a mapping from original name to name with appended language to be used for the verse order mappings.Add(originalName, name); } var slides = verse.Elements(ns + "lines").Select(lines => { StringBuilder str = new StringBuilder(); ParseLines(lines, str); return new SongSlide(song) { Text = str.ToString() }; }); song.AddPart(new SongPart(song, name, slides)); } if (prop.Elements(ns + "verseOrder").Any()) { song.SetOrder(prop.Element(ns + "verseOrder").Value.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries).Select(n => mappings[n])); } else { // if we have no verseOrder element, use all verses from the mappings dictionary // (so multiple translations will appear only once) song.SetOrder(mappings.Values); } }
private void FinishPart(Song song, string key, List<LineGroup> lineGroups, LineGroup lastLineGroup) { if (lastLineGroup != null) lineGroups.Add(lastLineGroup); if (lineGroups.Count == 0) throw new SongFormatException("File is not a valid OpenSong song: Empty part"); foreach (var lg in lineGroups) { if (lg.Lines.Count == 0) lg.Lines.Add(new Line { Text = "" }); } var noNumbers = !lineGroups[0].Lines[0].Number.HasValue; if (noNumbers && lineGroups.Any(lg => lg.Lines.Any(l => l.Number.HasValue))) throw new SongFormatException("File is not a valid OpenSong song: Found mixed numbered and unnumbered lines."); int maxVerseNumber; if (noNumbers) { maxVerseNumber = 1; } else { maxVerseNumber = lineGroups.Max(lg => lg.Lines.Max(l => l.Number.Value)); } for (int i = 1; i <= maxVerseNumber; i++) { if (!noNumbers && !lineGroups.Any(lg => lg.Lines.Any(l => l.Number == i))) continue; string name; if (noNumbers) name = GetPartName(key); else name = GetPartName(key + i.ToString()); var part = new SongPart(song, name); var slide = new SongSlide(song); slide.Text = String.Join("\n", lineGroups. Where(lg => lg.Lines.Any(l => noNumbers || l.Number == i)). Select(lg => PrepareLine(lg.Lines.Where(l => noNumbers || l.Number == i).Single().Text, lg.Chords))); part.AddSlide(slide); // apply slide breaks int ind; while ((ind = slide.Text.IndexOf("||")) >= 0) { slide.Text = slide.Text.Remove(ind, 2); part.SplitSlide(slide, ind); } // apply line breaks foreach (var s in part.Slides) { s.Text = s.Text.Replace("|", "\n"); } song.AddPart(part); } }
/// <summary> /// Reads the song data from a stream. /// </summary> /// <param name="song">The song.</param> /// <param name="stream">The stream.</param> public void Read(Song song, Stream stream) { if (song == null) throw new ArgumentNullException("song"); if (stream == null) throw new ArgumentNullException("stream"); using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.Default, true)) { SongPart currentPart = null; string currentText = null; string currentTrans = null; string line; Dictionary<string, string> properties = new Dictionary<string, string>(); int langcount = 1; int linenum = 0; while ((line = reader.ReadLine()) != null) { if (currentPart == null) { line = line.Trim(); if (line.StartsWith("#")) { int i = line.IndexOf('='); string key = line.Substring(1, i - 1).ToLower(); string value = line.Substring(i + 1); properties.Add(key, value); } else if (line == "---") { PreProcessSongBeamerProperties(song, properties, out langcount); // langcount > 2 is not supported (text will be ignored) currentPart = new SongPart(song, FindUnusedPartName(song)); } } else { if (line == "---") { currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans }); currentText = null; song.AddPart(currentPart); currentPart = new SongPart(song, FindUnusedPartName(song)); linenum = 0; } else if (line == "--" || line == "--A") { currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans }); currentText = ""; linenum = 0; } else { if (currentText == null) // at the beginning of a new part { string name; if (IsSongBeamerPartName(line, out name)) { currentPart.Name = name; currentText = ""; linenum = 0; } else { currentText = line; linenum = 1; } } else { if (linenum % langcount == 0) // add line to text { if (linenum == 0) currentText = line; else currentText += "\n" + line; } else if (linenum % langcount == 1) // add line to translation { if (linenum == 1) currentTrans = line; else currentTrans += "\n" + line; } linenum++; } } } } currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans }); song.AddPart(currentPart); PostProcessSongBeamerProperties(song, properties); } }
public override void Read(Song song, Stream stream) { if (song == null) { throw new ArgumentNullException("song"); } if (stream == null) { throw new ArgumentNullException("stream"); } using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; int lineType = 0; List <string> verseLineList = null; string verseType = null; bool checkFirstLine = false; string copyright = null; while ((line = reader.ReadLine()) != null) { var cleanLine = line.Trim(); if (String.IsNullOrEmpty(cleanLine)) { if (lineType == 0) { continue; } else if (verseLineList != null) // empty line and there were lyrics before -> create part { var part = new SongPart(song, verseType); var slide = new SongSlide(song); slide.Text = String.Join("\n", verseLineList.ToArray()); part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); verseLineList = null; } } else // not an empty line { if (lineType == 0) // very first line -> song title { song.Title = cleanLine; lineType++; } else if (lineType == 1) // lyrics/parts { if (cleanLine.StartsWith("CCLI")) // end of lyrics, start of copyright information { lineType++; string num = cleanLine.Split(' ').Last(); song.CcliNumber = int.Parse(num); } else if (verseLineList == null) { verseType = GetPartName(cleanLine, out checkFirstLine); verseLineList = new List <string>(); } else { if (checkFirstLine) { if (!CheckFirstLine(cleanLine, ref verseType)) { // add text if it was not a part name verseLineList.Add(line); } checkFirstLine = false; } else { verseLineList.Add(line); } } } else if (lineType == 2) // copyright information { if (copyright == null) { copyright = cleanLine; } else { copyright += "\n" + cleanLine; } } } } song.Copyright = copyright; } }
// documentation taken from http://bazaar.launchpad.net/~openlp-core/openlp/trunk/view/head:/openlp/plugins/songs/lib/cclifileimport.py // [File] // USR file format first line // Type= // Indicates the file type // e.g. Type=SongSelect Import File // Version=3.0 // File format version // [S A2672885] // Contains the CCLI Song number e.g. 2672885 // Title= // Contains the song title (e.g. Title=Above All) // Author= // Contains a | delimited list of the song authors // e.g. Author=LeBlanc, Lenny | Baloche, Paul // Copyright= // Contains a | delimited list of the song copyrights // e.g. Copyright=1999 Integrity's Hosanna! Music | // LenSongs Publishing (Verwaltet von Gerth Medien // Musikverlag) // Admin= // Contains the song administrator // e.g. Admin=Gerth Medien Musikverlag // Themes= // Contains a /t delimited list of the song themes // e.g. Themes=Cross/tKingship/tMajesty/tRedeemer // Keys= // Contains the keys in which the music is played?? // e.g. Keys=A // Fields= // Contains a list of the songs fields in order /t delimited // e.g. Fields=Vers 1/tVers 2/tChorus 1/tAndere 1 // Words= // Contains the songs various lyrics in order as shown by the // Fields description // e.g. Words=Above all powers.... [/n = CR, /n/t = CRLF] public override void Read(Song song, Stream stream) { if (song == null) throw new ArgumentNullException("song"); if (stream == null) throw new ArgumentNullException("stream"); using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; string authors = null; string copyright = null; string[] fieldsList = null; string[] wordsList = null; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("[S ")) { // CCLI Song number int end = line.IndexOf(']'); if (end > 1) { string num = line.Substring(3, end - 3); if (num.StartsWith("A")) num = num.Substring(1); song.CcliNumber = int.Parse(num); } } else if (line.StartsWith("Title=")) { song.Title = line.Substring("Title=".Length).Trim(); } else if (line.StartsWith("Author=")) { var authorList = line.Substring("Author=".Length).Trim().Split('|').Select(s => s.Trim()).ToArray(); authors = String.Join(", ", authorList); } else if (line.StartsWith("Copyright=")) { copyright = line.Substring("Copyright=".Length).Trim(); } else if (line.StartsWith("Themes=")) { var themesList = line.Substring("Themes=".Length).Trim().Replace(" | ", "/t"). Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); song.Category = String.Join(", ", themesList); } else if (line.StartsWith("Fields=")) { fieldsList = line.Substring("Fields=".Length).Trim().Split(new string[] {"/t"}, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } else if (line.StartsWith("Words=")) { wordsList = line.Substring("Words=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } // Unhandled usr keywords: Type, Version, Admin, Keys } if (fieldsList == null || wordsList == null || authors == null || copyright == null) { throw new SongFormatException("Missing field in USR file."); } var partNum = (fieldsList.Length < wordsList.Length) ? fieldsList.Length : wordsList.Length; for (int i = 0; i < partNum; i++) { bool checkFirstLine; var partName = GetPartName(fieldsList[i], out checkFirstLine); string text = wordsList[i].Replace("/n", "\n").Replace(" | ", "\n").TrimEnd(); if (checkFirstLine) { var lines = text.Split('\n'); var firstLine = lines[0].Trim(); if (CheckFirstLine(firstLine, ref partName)) { text = text.Substring(text.IndexOf('\n') + 1); } } var part = new SongPart(song, partName); var slide = new SongSlide(song); slide.Text = text; part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); } song.Copyright = authors + "\n© " + copyright; } }
/// <summary> /// Reads the song data from a stream. /// </summary> /// <param name="song">The song.</param> /// <param name="stream">The stream.</param> public void Read(Song song, Stream stream) { XDocument doc = XDocument.Load(stream); XElement root = doc.Element("ppl"); song.Title = root.Element("general").Element("title").Value; var formatting = root.Element("formatting"); var video = root.Element("formatting").Element("background").Attribute("video"); if (video != null) { song.AddBackground(new SongBackground(video.Value, true), true); } else { foreach (var bg in root.Element("formatting").Element("background").Elements("file")) { song.AddBackground(ReadBackground(bg.Value), true); } } song.Formatting = new SongFormatting { MainText = ReadTextFormatting(formatting.Element("font").Element("maintext")), TranslationText = ReadTextFormatting(formatting.Element("font").Element("translationtext")), SourceText = ReadTextFormatting(formatting.Element("font").Element("sourcetext")), CopyrightText = ReadTextFormatting(formatting.Element("font").Element("copyrighttext")), TextLineSpacing = int.Parse(formatting.Element("linespacing").Element("main").Value), TranslationLineSpacing = int.Parse(formatting.Element("linespacing").Element("translation").Value), SourceBorderRight = int.Parse(formatting.Element("borders").Element("sourceright").Value), SourceBorderTop = int.Parse(formatting.Element("borders").Element("sourcetop").Value), CopyrightBorderBottom = int.Parse(formatting.Element("borders").Element("copyrightbottom").Value), HorizontalOrientation = (HorizontalTextOrientation)Enum.Parse(typeof(HorizontalTextOrientation), formatting.Element("textorientation").Element("horizontal").Value, true), VerticalOrientation = (VerticalTextOrientation)Enum.Parse(typeof(VerticalTextOrientation), formatting.Element("textorientation").Element("vertical").Value, true), BorderBottom = int.Parse(formatting.Element("borders").Element("mainbottom").Value), BorderTop = int.Parse(formatting.Element("borders").Element("maintop").Value), BorderLeft = int.Parse(formatting.Element("borders").Element("mainleft").Value), BorderRight = int.Parse(formatting.Element("borders").Element("mainright").Value), IsOutlineEnabled = bool.Parse(formatting.Element("font").Element("outline").Element("enabled").Value), OutlineColor = ParseColor(formatting.Element("font").Element("outline").Element("color").Value), IsShadowEnabled = bool.Parse(formatting.Element("font").Element("shadow").Element("enabled").Value), ShadowColor = ParseColor(formatting.Element("font").Element("shadow").Element("color").Value), ShadowDirection = int.Parse(formatting.Element("font").Element("shadow").Element("direction").Value), TranslationPosition = formatting.Element("textorientation").Element("transpos") != null ? (TranslationPosition)Enum.Parse(typeof(TranslationPosition), formatting.Element("textorientation").Element("transpos").Value, true) : TranslationPosition.Inline, CopyrightDisplayPosition = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("copyright").Element("position").Value, true), SourceDisplayPosition = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("source").Element("position").Value, true) }; var general = root.Element("general"); if (general.Element("category") != null) song.Category = general.Element("category").Value; if (general.Element("language") != null) song.Language = general.Element("language").Value; if (general.Element("translationlanguage") != null) song.TranslationLanguage = general.Element("translationlanguage").Value; if (general.Element("comment") != null) song.Comment = general.Element("comment").Value; else song.Comment = String.Empty; int ccli; if (general.Element("ccli") != null && int.TryParse(general.Element("ccli").Value, out ccli)) song.CcliNumber = ccli; else song.CcliNumber = null; foreach (var part in root.Element("songtext").Elements("part")) { song.AddPart(new SongPart(song, part.Attribute("caption").Value, from slide in part.Elements("slide") select new SongSlide(song) { Text = String.Join("\n", slide.Elements("line").Select(line => line.Value).ToArray())/*.Trim()*/, Translation = String.Join("\n", slide.Elements("translation").Select(line => line.Value).ToArray())/*.Trim()*/, BackgroundIndex = slide.Attribute("backgroundnr") != null ? int.Parse(slide.Attribute("backgroundnr").Value) : 0, Size = slide.Attribute("mainsize") != null ? int.Parse(slide.Attribute("mainsize").Value) : song.Formatting.MainText.Size } )); } song.SetOrder(from item in root.Element("order").Elements("item") select item.Value); song.Copyright = String.Join("\n", root.Element("information").Element("copyright").Element("text").Elements("line").Select(line => line.Value).ToArray()); song.SetSources(root.Element("information").Element("source").Element("text").Elements("line").Select(line => line.Value)); }
/// <summary> /// Reads the song data from a stream. /// </summary> /// <param name="song">The song.</param> /// <param name="stream">The stream.</param> public void Read(Song song, Stream stream) { XDocument doc = XDocument.Load(stream); XElement root = doc.Element("ppl"); song.Title = root.Element("general").Element("title").Value; var formatting = root.Element("formatting"); var video = root.Element("formatting").Element("background").Attribute("video"); if (video != null) { song.AddBackground(new SongBackground(video.Value, true), true); } else { foreach (var bg in root.Element("formatting").Element("background").Elements("file")) { song.AddBackground(ReadBackground(bg.Value), true); } } song.Formatting = new SongFormatting { MainText = ReadTextFormatting(formatting.Element("font").Element("maintext")), TranslationText = ReadTextFormatting(formatting.Element("font").Element("translationtext")), SourceText = ReadTextFormatting(formatting.Element("font").Element("sourcetext")), CopyrightText = ReadTextFormatting(formatting.Element("font").Element("copyrighttext")), TextLineSpacing = int.Parse(formatting.Element("linespacing").Element("main").Value), TranslationLineSpacing = int.Parse(formatting.Element("linespacing").Element("translation").Value), SourceBorderRight = int.Parse(formatting.Element("borders").Element("sourceright").Value), SourceBorderTop = int.Parse(formatting.Element("borders").Element("sourcetop").Value), CopyrightBorderBottom = int.Parse(formatting.Element("borders").Element("copyrightbottom").Value), HorizontalOrientation = (HorizontalTextOrientation)Enum.Parse(typeof(HorizontalTextOrientation), formatting.Element("textorientation").Element("horizontal").Value, true), VerticalOrientation = (VerticalTextOrientation)Enum.Parse(typeof(VerticalTextOrientation), formatting.Element("textorientation").Element("vertical").Value, true), BorderBottom = int.Parse(formatting.Element("borders").Element("mainbottom").Value), BorderTop = int.Parse(formatting.Element("borders").Element("maintop").Value), BorderLeft = int.Parse(formatting.Element("borders").Element("mainleft").Value), BorderRight = int.Parse(formatting.Element("borders").Element("mainright").Value), IsOutlineEnabled = bool.Parse(formatting.Element("font").Element("outline").Element("enabled").Value), OutlineColor = ParseColor(formatting.Element("font").Element("outline").Element("color").Value), IsShadowEnabled = bool.Parse(formatting.Element("font").Element("shadow").Element("enabled").Value), ShadowColor = ParseColor(formatting.Element("font").Element("shadow").Element("color").Value), ShadowDirection = int.Parse(formatting.Element("font").Element("shadow").Element("direction").Value), TranslationPosition = formatting.Element("textorientation").Element("transpos") != null ? (TranslationPosition)Enum.Parse(typeof(TranslationPosition), formatting.Element("textorientation").Element("transpos").Value, true) : TranslationPosition.Inline, CopyrightDisplayPosition = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("copyright").Element("position").Value, true), SourceDisplayPosition = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("source").Element("position").Value, true) }; var general = root.Element("general"); if (general.Element("category") != null) { song.Category = general.Element("category").Value; } if (general.Element("language") != null) { song.Language = general.Element("language").Value; } if (general.Element("translationlanguage") != null) { song.TranslationLanguage = general.Element("translationlanguage").Value; } if (general.Element("comment") != null) { song.Comment = general.Element("comment").Value; } else { song.Comment = String.Empty; } int ccli; if (general.Element("ccli") != null && int.TryParse(general.Element("ccli").Value, out ccli)) { song.CcliNumber = ccli; } else { song.CcliNumber = null; } foreach (var part in root.Element("songtext").Elements("part")) { song.AddPart(new SongPart(song, part.Attribute("caption").Value, from slide in part.Elements("slide") select new SongSlide(song) { Text = String.Join("\n", slide.Elements("line").Select(line => line.Value).ToArray()) /*.Trim()*/, Translation = String.Join("\n", slide.Elements("translation").Select(line => line.Value).ToArray()) /*.Trim()*/, BackgroundIndex = slide.Attribute("backgroundnr") != null ? int.Parse(slide.Attribute("backgroundnr").Value) : 0, Size = slide.Attribute("mainsize") != null ? int.Parse(slide.Attribute("mainsize").Value) : song.Formatting.MainText.Size } )); } song.SetOrder(from item in root.Element("order").Elements("item") select item.Value); song.Copyright = String.Join("\n", root.Element("information").Element("copyright").Element("text").Elements("line").Select(line => line.Value).ToArray()); song.SetSources(root.Element("information").Element("source").Element("text").Elements("line").Select(line => line.Value)); }
IEnumerator WaitAndPlay() { // TODO: Rename Song to SongDefinition and add Song as a new class. // Each SongDefinition describes how a song is played for ONE instrument only. The Song contains all the definitions. // Else, it is not possible to have different parts playing for the same instrument type. For example; There can be // multiple djembe's, krins or even multiple douns of the same type playing different parts. //var song = Soro.LoadSong(); ISong song; if (_customNotationEnabled) { var instrumentType = InstrumentType.Dununba; var customNotation = Notation.Notation.Parse("Custom", _customNotation, BeatType.Unknown, instrumentType); song = new Song(); song.AddPart(_customNotationRepeatCount > 0 ? _customNotationRepeatCount : 0, customNotation); } else { var songName = _songs.Keys.ToArray()[_selectedSongIndex]; song = _songs[songName](); } var players = new Dictionary <InstrumentType, InstrumentPlayer[]> { { InstrumentType.Djembe, new[] { _djembePlayer1, _djembePlayer2 } }, { InstrumentType.Kenkeni, new[] { _kenkeniPlayer } }, { InstrumentType.Sangban, new[] { _sangbanPlayer } }, { InstrumentType.Dununba, new[] { _dununbaPlayer } }, }; var noteIndex = 0f; var songPartIndex = 0; var songPartRepeatIndex = 0; var totalTime = 0f; var totalNotesSong = song.Parts.Sum(p => p.Notations.Max(n => n.TotalNotes)); while (true) { var interval = ((60000f / _bpm / song.NotesPerBeat) / 2f) / 1000f; var songPart = song.Parts[songPartIndex]; var notations = songPart.Notations; var djembeIndex = 0; foreach (var notation in notations) { var player = players[notation.InstrumentType]; var playerIndex = notation.InstrumentType == InstrumentType.Djembe ? djembeIndex : 0; var index = noteIndex % notation.TotalNotes; var note = notation.NoteAt(index); if (note != null && player[playerIndex].enabled) { foreach (var sound in note.Sounds) { player[playerIndex].PlaySound(sound); } } if (notation.InstrumentType == InstrumentType.Djembe) { djembeIndex++; } } if (noteIndex % song.NotesPerBeat == 0 && _metronomePlayer.enabled) { _metronomePlayer.PlaySound(); } yield return(new WaitForSecondsRealtime(interval)); totalTime += interval; if (noteIndex > songPart.TotalNotes - 1f) { noteIndex = 0f; if (songPartRepeatIndex >= songPart.RepeatCount) { songPartIndex++; songPartRepeatIndex = 0; } else { songPartRepeatIndex++; } if (songPartIndex >= song.Parts.Length) { StopCoroutine(_coroutine); _coroutine = null; break; } } else { noteIndex += .5f; } } }
// documentation taken from http://bazaar.launchpad.net/~openlp-core/openlp/trunk/view/head:/openlp/plugins/songs/lib/cclifileimport.py // [File] // USR file format first line // Type= // Indicates the file type // e.g. Type=SongSelect Import File // Version=3.0 // File format version // [S A2672885] // Contains the CCLI Song number e.g. 2672885 // Title= // Contains the song title (e.g. Title=Above All) // Author= // Contains a | delimited list of the song authors // e.g. Author=LeBlanc, Lenny | Baloche, Paul // Copyright= // Contains a | delimited list of the song copyrights // e.g. Copyright=1999 Integrity's Hosanna! Music | // LenSongs Publishing (Verwaltet von Gerth Medien // Musikverlag) // Admin= // Contains the song administrator // e.g. Admin=Gerth Medien Musikverlag // Themes= // Contains a /t delimited list of the song themes // e.g. Themes=Cross/tKingship/tMajesty/tRedeemer // Keys= // Contains the keys in which the music is played?? // e.g. Keys=A // Fields= // Contains a list of the songs fields in order /t delimited // e.g. Fields=Vers 1/tVers 2/tChorus 1/tAndere 1 // Words= // Contains the songs various lyrics in order as shown by the // Fields description // e.g. Words=Above all powers.... [/n = CR, /n/t = CRLF] public override void Read(Song song, Stream stream) { if (song == null) { throw new ArgumentNullException("song"); } if (stream == null) { throw new ArgumentNullException("stream"); } using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; string authors = null; string copyright = null; string[] fieldsList = null; string[] wordsList = null; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("[S ")) { // CCLI Song number int end = line.IndexOf(']'); if (end > 1) { string num = line.Substring(3, end - 3); if (num.StartsWith("A")) { num = num.Substring(1); } song.CcliNumber = int.Parse(num); } } else if (line.StartsWith("Title=")) { song.Title = line.Substring("Title=".Length).Trim(); } else if (line.StartsWith("Author=")) { var authorList = line.Substring("Author=".Length).Trim().Split('|').Select(s => s.Trim()).ToArray(); authors = String.Join(", ", authorList); } else if (line.StartsWith("Copyright=")) { copyright = line.Substring("Copyright=".Length).Trim(); } else if (line.StartsWith("Themes=")) { var themesList = line.Substring("Themes=".Length).Trim().Replace(" | ", "/t"). Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); song.Category = String.Join(", ", themesList); } else if (line.StartsWith("Fields=")) { fieldsList = line.Substring("Fields=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } else if (line.StartsWith("Words=")) { wordsList = line.Substring("Words=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } // Unhandled usr keywords: Type, Version, Admin, Keys } if (fieldsList == null || wordsList == null || authors == null || copyright == null) { throw new SongFormatException("Missing field in USR file."); } var partNum = (fieldsList.Length < wordsList.Length) ? fieldsList.Length : wordsList.Length; for (int i = 0; i < partNum; i++) { bool checkFirstLine; var partName = GetPartName(fieldsList[i], out checkFirstLine); string text = wordsList[i].Replace("/n", "\n").Replace(" | ", "\n").TrimEnd(); if (checkFirstLine) { var lines = text.Split('\n'); var firstLine = lines[0].Trim(); if (CheckFirstLine(firstLine, ref partName)) { text = text.Substring(text.IndexOf('\n') + 1); } } var part = new SongPart(song, partName); var slide = new SongSlide(song); slide.Text = text; part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); } song.Copyright = authors + "\n© " + copyright; } }
public override void Read(Song song, Stream stream) { if (song == null) throw new ArgumentNullException("song"); if (stream == null) throw new ArgumentNullException("stream"); using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; int lineType = 0; List<string> verseLineList = null; string verseType = null; bool checkFirstLine = false; string copyright = null; while ((line = reader.ReadLine()) != null) { var cleanLine = line.Trim(); if (String.IsNullOrEmpty(cleanLine)) { if (lineType == 0) { continue; } else if (verseLineList != null) // empty line and there were lyrics before -> create part { var part = new SongPart(song, verseType); var slide = new SongSlide(song); slide.Text = String.Join("\n", verseLineList.ToArray()); part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); verseLineList = null; } } else // not an empty line { if (lineType == 0) // very first line -> song title { song.Title = cleanLine; lineType++; } else if (lineType == 1) // lyrics/parts { if (cleanLine.StartsWith("CCLI")) // end of lyrics, start of copyright information { lineType++; string num = cleanLine.Split(' ').Last(); song.CcliNumber = int.Parse(num); } else if (verseLineList == null) { verseType = GetPartName(cleanLine, out checkFirstLine); verseLineList = new List<string>(); } else { if (checkFirstLine) { if (!CheckFirstLine(cleanLine, ref verseType)) { // add text if it was not a part name verseLineList.Add(line); } checkFirstLine = false; } else { verseLineList.Add(line); } } } else if (lineType == 2) // copyright information { if (copyright == null) { copyright = cleanLine; } else { copyright += "\n" + cleanLine; } } } } song.Copyright = copyright; } }
private void FinishPart(Song song, string key, List <LineGroup> lineGroups, LineGroup lastLineGroup) { if (lastLineGroup != null) { lineGroups.Add(lastLineGroup); } if (lineGroups.Count == 0) { throw new SongFormatException("File is not a valid OpenSong song: Empty part"); } foreach (var lg in lineGroups) { if (lg.Lines.Count == 0) { lg.Lines.Add(new Line { Text = "" }); } } var noNumbers = !lineGroups[0].Lines[0].Number.HasValue; if (noNumbers && lineGroups.Any(lg => lg.Lines.Any(l => l.Number.HasValue))) { throw new SongFormatException("File is not a valid OpenSong song: Found mixed numbered and unnumbered lines."); } int maxVerseNumber; if (noNumbers) { maxVerseNumber = 1; } else { maxVerseNumber = lineGroups.Max(lg => lg.Lines.Max(l => l.Number.Value)); } for (int i = 1; i <= maxVerseNumber; i++) { if (!noNumbers && !lineGroups.Any(lg => lg.Lines.Any(l => l.Number == i))) { continue; } string name; if (noNumbers) { name = GetPartName(key); } else { name = GetPartName(key + i.ToString()); } var part = new SongPart(song, name); var slide = new SongSlide(song); slide.Text = String.Join("\n", lineGroups. Where(lg => lg.Lines.Any(l => noNumbers || l.Number == i)). Select(lg => PrepareLine(lg.Lines.Where(l => noNumbers || l.Number == i).Single().Text, lg.Chords))); part.AddSlide(slide); // apply slide breaks int ind; while ((ind = slide.Text.IndexOf("||")) >= 0) { slide.Text = slide.Text.Remove(ind, 2); part.SplitSlide(slide, ind); } // apply line breaks foreach (var s in part.Slides) { s.Text = s.Text.Replace("|", "\n"); } song.AddPart(part); } }
public void Read(Song song, Stream stream) { if (song == null) { throw new ArgumentNullException("song"); } if (stream == null) { throw new ArgumentNullException("stream"); } var doc = XDocument.Load(stream); if (doc.Root.Name != ns + "song") { throw new SongFormatException("File is not a valid OpenLyrics song."); } //var openLyricsVersion = new Version(doc.Root.Attribute("version").Value); //bool versionPre08 = openLyricsVersion < new Version(0, 8); var prop = doc.Root.Element(ns + "properties"); song.Title = prop.Element(ns + "titles").Elements(ns + "title").First().Value; var authors = prop.Elements(ns + "authors"); song.Copyright = authors.Any() ? String.Join(", ", authors.Single().Elements(ns + "author").Select(e => e.Value)) : String.Empty; if (prop.Elements(ns + "publisher").Any()) { var publisher = "Publisher: " + prop.Element(ns + "publisher").Value; song.Copyright = String.IsNullOrEmpty(song.Copyright) ? publisher : song.Copyright + "\n" + publisher; } if (prop.Elements(ns + "copyright").Any()) { var copyright = prop.Element(ns + "copyright").Value; if (!copyright.StartsWith("©") && !copyright.StartsWith("(c)")) { copyright = "© " + copyright; } song.Copyright = String.IsNullOrEmpty(song.Copyright) ? copyright : song.Copyright + "\n" + copyright; } song.CcliNumber = prop.Elements(ns + "ccliNo").Any() ? int.Parse(prop.Element(ns + "ccliNo").Value) : (int?)null; song.Category = prop.Elements(ns + "themes").Any() ? String.Join("; ", prop.Element(ns + "themes").Elements(ns + "theme").Select(e => e.Value)) : String.Empty; song.Comment = prop.Elements(ns + "comments").Any() ? String.Join("\n", prop.Element(ns + "comments").Elements(ns + "comment").Select(e => e.Value)) : String.Empty; if (prop.Elements(ns + "songbooks").Any()) { int number; song.SetSources(prop.Element(ns + "songbooks").Elements(ns + "songbook").Select(e => new SongSource(song) { Songbook = e.Attribute("name").Value, Number = e.Attributes("entry").Any() ? (int.TryParse(e.Attribute("entry").Value, out number) ? number : (int?)null) : null })); } var mappings = new Dictionary <string, string>(); foreach (var verse in doc.Root.Element(ns + "lyrics").Elements(ns + "verse")) { string originalName = verse.Attribute("name").Value; // add language key to part name (we don't know which one is the translation // and we can not automatically deal with more than 2 languages) string name = originalName + (verse.Attributes("lang").Any() ? " (" + verse.Attribute("lang").Value + ")" : String.Empty); if (!mappings.ContainsKey(originalName)) { // keep a mapping from original name to name with appended language to be used for the verse order mappings.Add(originalName, name); } var slides = verse.Elements(ns + "lines").Select(lines => { StringBuilder str = new StringBuilder(); ParseLines(lines, str); return(new SongSlide(song) { Text = str.ToString() }); }); song.AddPart(new SongPart(song, name, slides)); } if (prop.Elements(ns + "verseOrder").Any()) { song.SetOrder(prop.Element(ns + "verseOrder").Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => mappings[n])); } else { // if we have no verseOrder element, use all verses from the mappings dictionary // (so multiple translations will appear only once) song.SetOrder(mappings.Values); } }
/// <summary> /// Reads the song data from a stream. /// </summary> /// <param name="song">The song.</param> /// <param name="stream">The stream.</param> public void Read(Song song, Stream stream) { if (song == null) { throw new ArgumentNullException("song"); } if (stream == null) { throw new ArgumentNullException("stream"); } using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.Default, true)) { SongPart currentPart = null; string currentText = null; string currentTrans = null; string line; Dictionary <string, string> properties = new Dictionary <string, string>(); int langcount = 1; int linenum = 0; while ((line = reader.ReadLine()) != null) { if (currentPart == null) { line = line.Trim(); if (line.StartsWith("#")) { int i = line.IndexOf('='); string key = line.Substring(1, i - 1).ToLower(); string value = line.Substring(i + 1); properties.Add(key, value); } else if (line == "---") { PreProcessSongBeamerProperties(song, properties, out langcount); // langcount > 2 is not supported (text will be ignored) currentPart = new SongPart(song, FindUnusedPartName(song)); } } else { if (line == "---") { currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans }); currentText = null; song.AddPart(currentPart); currentPart = new SongPart(song, FindUnusedPartName(song)); linenum = 0; } else if (line == "--" || line == "--A") { currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans }); currentText = ""; linenum = 0; } else { if (currentText == null) // at the beginning of a new part { string name; if (IsSongBeamerPartName(line, out name)) { currentPart.Name = name; currentText = ""; linenum = 0; } else { currentText = line; linenum = 1; } } else { if (linenum % langcount == 0) // add line to text { if (linenum == 0) { currentText = line; } else { currentText += "\n" + line; } } else if (linenum % langcount == 1) // add line to translation { if (linenum == 1) { currentTrans = line; } else { currentTrans += "\n" + line; } } linenum++; } } } } currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans }); song.AddPart(currentPart); PostProcessSongBeamerProperties(song, properties); } }
public void Read(Song song, Stream stream) { if (song == null) { throw new ArgumentNullException("song"); } if (stream == null) { throw new ArgumentNullException("stream"); } using (StreamReader reader = new StreamReader(stream, Encoding.Default, true)) { string line; bool inTab = false; SongPart chorusPart = null; string currentText = null; string nextPartName = null; string currentPartName = null; while ((line = reader.ReadLine()) != null) { var trimmed = line.Trim(); if (trimmed.StartsWith("#")) { continue; // ignore comment line } if (trimmed.StartsWith("{") && trimmed.EndsWith("}")) { var tag = trimmed.Substring(1, trimmed.Length - 2); if (tag.StartsWith("title:") || tag.StartsWith("t:")) { song.Title = tag.Substring(tag.IndexOf(':') + 1); nextPartName = null; continue; } else if (tag.StartsWith("subtitle:") || tag.StartsWith("st:")) { song.Copyright = tag.Substring(tag.IndexOf(':') + 1); nextPartName = null; continue; } else if (tag.StartsWith("comment:") || tag.StartsWith("c:") || tag.StartsWith("comment_italic:") || tag.StartsWith("ci:") || tag.StartsWith("comment_box:") || tag.StartsWith("cb:")) { if (tag.EndsWith(":") && chorusPart == null) { // we found a comment that might be a part name and we're not in the chorus // -> remember it for later use var name = tag.Substring(tag.IndexOf(':') + 1); nextPartName = name.Substring(0, name.Length - 1); } continue; } else if (tag.StartsWith("start_of_tab") || tag.StartsWith("sot")) { inTab = true; nextPartName = null; continue; } else if (tag.StartsWith("end_of_tab") || tag.StartsWith("eot")) { inTab = false; nextPartName = null; continue; } else if (tag.StartsWith("start_of_chorus") || tag.StartsWith("soc")) { var chorusName = "Chorus"; if (song.FindPartByName(chorusName) != null) { int i = 2; while (song.FindPartByName(chorusName + " " + i.ToString()) != null) { i++; } chorusName = chorusName + " " + i.ToString(); } chorusPart = new SongPart(song, chorusName); nextPartName = null; continue; } else if (tag.StartsWith("end_of_chorus") || tag.StartsWith("eoc")) { if (chorusPart != null) { // commit slide and part if (currentText != null) { chorusPart.AddSlide(new SongSlide(song) { Text = currentText }); currentText = null; } song.AddPart(chorusPart); chorusPart = null; } nextPartName = null; continue; } else if (tag.StartsWith("define")) { // ignore nextPartName = null; continue; } // else accept {...} as normal text } if (!inTab) { if (trimmed == String.Empty) { nextPartName = null; if (currentText != null) { if (chorusPart != null) // in chorus { // commit slide chorusPart.AddSlide(new SongSlide(song) { Text = currentText }); currentText = null; } else { // commit part var partName = currentPartName == null?FindUnusedPartName(song) : currentPartName; var part = new SongPart(song, partName); part.AddSlide(new SongSlide(song) { Text = currentText }); song.AddPart(part); currentText = null; } } } else { // actual text/chord line -> add to current text // need no further parsing because chords are already in correct format (square brackets) if (currentText == null) { currentText = trimmed; // use previously remembered part name for this part currentPartName = nextPartName; nextPartName = null; } else { currentText += "\n" + trimmed; } } } } // TODO: get rid of code duplication if (currentText != null) { if (chorusPart != null) // in chorus { // commit slide and part chorusPart.AddSlide(new SongSlide(song) { Text = currentText }); currentText = null; song.AddPart(chorusPart); } else { // commit part var partName = currentPartName == null?FindUnusedPartName(song) : currentPartName; var part = new SongPart(song, partName); part.AddSlide(new SongSlide(song) { Text = currentText }); song.AddPart(part); currentText = null; } } } // add each part to order foreach (SongPart part in song.Parts) { song.AddPartToOrder(part); } }
public void Read(Song song, Stream stream) { if (song == null) throw new ArgumentNullException("song"); if (stream == null) throw new ArgumentNullException("stream"); using (StreamReader reader = new StreamReader(stream, Encoding.Default, true)) { string line; bool inTab = false; SongPart chorusPart = null; string currentText = null; string nextPartName = null; string currentPartName = null; while ((line = reader.ReadLine()) != null) { var trimmed = line.Trim(); if (trimmed.StartsWith("#")) { continue; // ignore comment line } if (trimmed.StartsWith("{") && trimmed.EndsWith("}")) { var tag = trimmed.Substring(1, trimmed.Length - 2); if (tag.StartsWith("title:") || tag.StartsWith("t:")) { song.Title = tag.Substring(tag.IndexOf(':') + 1); nextPartName = null; continue; } else if (tag.StartsWith("subtitle:") || tag.StartsWith("st:")) { song.Copyright = tag.Substring(tag.IndexOf(':') + 1); nextPartName = null; continue; } else if (tag.StartsWith("comment:") || tag.StartsWith("c:") || tag.StartsWith("comment_italic:") || tag.StartsWith("ci:") || tag.StartsWith("comment_box:") || tag.StartsWith("cb:")) { if (tag.EndsWith(":") && chorusPart == null) { // we found a comment that might be a part name and we're not in the chorus // -> remember it for later use var name = tag.Substring(tag.IndexOf(':') + 1); nextPartName = name.Substring(0, name.Length - 1); } continue; } else if (tag.StartsWith("start_of_tab") || tag.StartsWith("sot")) { inTab = true; nextPartName = null; continue; } else if (tag.StartsWith("end_of_tab") || tag.StartsWith("eot")) { inTab = false; nextPartName = null; continue; } else if (tag.StartsWith("start_of_chorus") || tag.StartsWith("soc")) { var chorusName = "Chorus"; if (song.FindPartByName(chorusName) != null) { int i = 2; while (song.FindPartByName(chorusName + " " + i.ToString()) != null) { i++; } chorusName = chorusName + " " + i.ToString(); } chorusPart = new SongPart(song, chorusName); nextPartName = null; continue; } else if (tag.StartsWith("end_of_chorus") || tag.StartsWith("eoc")) { if (chorusPart != null) { // commit slide and part if (currentText != null) { chorusPart.AddSlide(new SongSlide(song) { Text = currentText }); currentText = null; } song.AddPart(chorusPart); chorusPart = null; } nextPartName = null; continue; } else if (tag.StartsWith("define")) { // ignore nextPartName = null; continue; } // else accept {...} as normal text } if (!inTab) { if (trimmed == String.Empty) { nextPartName = null; if (currentText != null) { if (chorusPart != null) // in chorus { // commit slide chorusPart.AddSlide(new SongSlide(song) { Text = currentText }); currentText = null; } else { // commit part var partName = currentPartName == null ? FindUnusedPartName(song) : currentPartName; var part = new SongPart(song, partName); part.AddSlide(new SongSlide(song) { Text = currentText }); song.AddPart(part); currentText = null; } } } else { // actual text/chord line -> add to current text // need no further parsing because chords are already in correct format (square brackets) if (currentText == null) { currentText = trimmed; // use previously remembered part name for this part currentPartName = nextPartName; nextPartName = null; } else { currentText += "\n" + trimmed; } } } } // TODO: get rid of code duplication if (currentText != null) { if (chorusPart != null) // in chorus { // commit slide and part chorusPart.AddSlide(new SongSlide(song) { Text = currentText }); currentText = null; song.AddPart(chorusPart); } else { // commit part var partName = currentPartName == null ? FindUnusedPartName(song) : currentPartName; var part = new SongPart(song, partName); part.AddSlide(new SongSlide(song) { Text = currentText }); song.AddPart(part); currentText = null; } } } // add each part to order foreach (SongPart part in song.Parts) { song.AddPartToOrder(part); } }