private static void ParseMultiVoice(string Input, List<string> InputList, bool InSlur) { Voice[] NWVoice = new Voice[2]; NoteInfo[] Notes = new NoteInfo[2]; Notes[0] = new NoteInfo(); Notes[1] = new NoteInfo(); bool VoiceOneFirst = true; string DynVar = ""; string Command = GetCommand(ref Input); if (Input.IndexOf("Stem=") < 0) { InputList.Add("% Multi length chord or rest with no stem direction"); //Don't think this will occur } if (InputList[InputList.Count - 1].IndexOf("DynamicVariance") >= 0) { // We need to remove the variance and move it until before the first note of the voice with the most notes (!) // and also ensure that the end is on the same voice, and that any reset to the style occurs on the same voice. DynVar = InputList[InputList.Count - 1]; InputList.RemoveAt(InputList.Count - 1); } if (Input.IndexOf("Stem=Down") >= 0) { // The second Noteworthy "note" goes to voice 1 VoiceOneFirst = false; } Notes[0] = GetNoteInfo(Input, Command, ""); Notes[1] = GetNoteInfo(Input, Command, "2"); NWVoice[0] = new Voice(); NWVoice[1] = new Voice(); if (VoiceOneFirst) { // The first note read from Noteworthy goes to Voice One NWVoice[0].NoteList.Add(Notes[0].ToString()); NWVoice[1].NoteList.Add(Notes[1].ToString()); } else { NWVoice[0].NoteList.Add(Notes[1].ToString()); NWVoice[1].NoteList.Add(Notes[0].ToString()); } int ShorterDur; // The next bit is to work out which on the voices has the shorter duration and therefore needs more notes adding if (VoiceOneFirst) { if (Notes[0].dDur > Notes[1].dDur) { ShorterDur = 1; } else { ShorterDur = 0; } } else { if (Notes[0].dDur > Notes[1].dDur) { ShorterDur = 0; } else { ShorterDur = 1; } } int LongerDur = Math.Abs(ShorterDur - 1); decimal MinDur = Math.Min(Notes[0].dDur, Notes[1].dDur); decimal MaxDur = Math.Max(Notes[0].dDur, Notes[1].dDur); while (Math.Round(MinDur, 5) < Math.Round(MaxDur, 5)) { Input = Console.In.ReadLine(); Command = GetCommand(ref Input); if (Command != "Note" && Command != "Chord" && Command != "Rest") { NWVoice[ShorterDur].NoteList.Add("|" + Command + "|" + Input); } else { NoteInfo NextNote = new NoteInfo(); NextNote = GetNoteInfo(Input, Command, ""); NWVoice[ShorterDur].NoteList.Add(NextNote.ToString()); MinDur += NextNote.dDur; } } if (InSlur) { // We need to do some complex counting back and adding extra notes to the front of the note lists :-( int OriginalListLength = InputList.Count; for (int i = OriginalListLength; i >= 0; i--) { string PrevLine = InputList[i - 1]; string CopyLine = PrevLine; Command = GetCommand(ref PrevLine); if (Command != "Note" && Command != "Chord" && Command != "Rest") // Here is a bug - need to account for rests here. { NWVoice[0].NoteList.Insert(0, CopyLine); NWVoice[1].NoteList.Insert(0, CopyLine); } else { NoteInfo LastNote = new NoteInfo(); LastNote = GetNoteInfo(PrevLine, Command, ""); if (LastNote.Duration.IndexOf("Slur") < 0) { break; } NWVoice[ShorterDur].NoteList.Insert(0, LastNote.ToString()); string RestLength = LastNote.Duration; int CommaPos = RestLength.IndexOf(","); if (CommaPos > 0) { RestLength = RestLength.Substring(0, CommaPos); } NWVoice[LongerDur].NoteList.Insert(0, "|Rest|Dur:" + RestLength + "|Visibility:Never"); } InputList.RemoveAt(i - 1); } } string FinalNote; int VoiceLen = NWVoice[ShorterDur].NoteList.Count; FinalNote = NWVoice[ShorterDur].NoteList[VoiceLen - 1]; string FinalDur = GetPar("Dur", FinalNote, true); if (FinalDur.IndexOf("Slur") >= 0) { //The final note we read still has a slur, so we need to keep adding notes to the voices until they don't NoteInfo LastNote = new NoteInfo(); string LastNoteDur; do { Input = Console.In.ReadLine(); string CopyInput = Input; Command = GetCommand(ref Input); if (Command != "Note" && Command != "Chord" && Command != "Rest") // And also here - bug alert! { NWVoice[0].NoteList.Add(CopyInput); if (Command != "Dynamic") // Don't want them written to both voices { NWVoice[1].NoteList.Add(CopyInput); } } else { if (Input.IndexOf("Dur2") > -1) { Notes[0] = GetNoteInfo(Input, Command, ""); Notes[1] = GetNoteInfo(Input, Command, "2"); LastNote = Notes[0]; NWVoice[ShorterDur].NoteList.Add(Notes[0].ToString()); MinDur += Notes[0].dDur; NWVoice[LongerDur].NoteList.Add(Notes[1].ToString()); MaxDur += Notes[1].dDur; while (MinDur < MaxDur) { Input = Console.In.ReadLine(); Command = GetCommand(ref Input); if (Command != "Note" && Command != "Chord" && Command != "Rest") { NWVoice[ShorterDur].NoteList.Add("|" + Command + "|" + Input); } else { NoteInfo NextNote = new NoteInfo(); NextNote = GetNoteInfo(Input, Command, ""); NWVoice[ShorterDur].NoteList.Add(NextNote.ToString()); MinDur += NextNote.dDur; } } } else { LastNote = GetNoteInfo(Input, Command, ""); NWVoice[ShorterDur].NoteList.Add(LastNote.ToString()); MinDur += LastNote.dDur; string RestLength = LastNote.Duration; int CommaPos = RestLength.IndexOf(","); if (CommaPos > 0) { RestLength = RestLength.Substring(0, CommaPos); } NWVoice[LongerDur].NoteList.Add("|Rest|Dur:" + RestLength + "|Visibility:Never"); MaxDur += LastNote.dDur; } } LastNoteDur = LastNote.Duration; // Now checking this if (LastNoteDur == null) LastNoteDur = "Slur"; // Reckon this is here to allow for non-note commands } while (LastNoteDur.IndexOf("Slur") >= 0 && Console.In.Peek() >= 0); } // So we now have a pair of voices, with all the notes included, so they just need writing out InputList.Add("|Voicestart"); if (ShorterDur == 0 && DynVar.Length > 0) { InputList.Add(DynVar); } for (int i = 0; i < NWVoice[0].NoteList.Count; i++) { InputList.Add(NWVoice[0].NoteList[i]); } InputList.Add("|Voicebreak"); if (ShorterDur == 1 && DynVar.Length > 0) { InputList.Add(DynVar); } for (int i = 0; i < NWVoice[1].NoteList.Count; i++) { InputList.Add(NWVoice[1].NoteList[i]); } InputList.Add("|Voiceend"); }
private static NoteInfo GetNoteInfo(string NoteInput, string Command, string BlankOr2) { NoteInfo NoteResult = new NoteInfo(); Decimal dMult = 1M; string RealDur; if (Command == "Bar") { return NoteResult; } NoteResult.Duration = GetPar("Dur" + BlankOr2, NoteInput, true); if (NoteResult.Duration.IndexOf(",DblDotted") >= 0) { dMult = 1.75M; NoteResult.Duration = NoteResult.Duration.Replace(",DblDotted", ""); NoteResult.Dots = ",DblDotted"; } else if (NoteResult.Duration.IndexOf(",Dotted") >= 0) { dMult = 1.5M; NoteResult.Duration = NoteResult.Duration.Replace(",Dotted", ""); NoteResult.Dots = ",Dotted"; } if (NoteResult.Duration.IndexOf("Triplet") >= 0) { dMult = 2M / 3; } NoteResult.Position = GetPar("Pos" + BlankOr2, NoteInput, true); RealDur = GetDur(NoteResult.Duration, NoteInput, true); RealDur = RealDur.Replace(".", ""); NoteResult.dDur = (decimal)1 / int.Parse(RealDur); NoteResult.dDur *= dMult; if (BlankOr2 == "") { NoteResult.Opts = GetPar("Opts", NoteInput, true); } dMult = 1M; NoteResult.Command = Command; if (NoteResult.Command == "RestChord") { if (BlankOr2 == "") { NoteResult.Command = "Rest"; } else { if (NoteResult.Position.IndexOf(",") >= 0) { NoteResult.Command = "Chord"; } else { NoteResult.Command = "Note"; } } } return NoteResult; }