public override Model.Score Parse(string source) { var score = Score.CreateOneStaffScore(Clef.Treble, MajorScale.C); var splitted = source.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var element in splitted) { if (element.Contains("_")) { var pitchAndDuration = element.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries); var midiPitch = int.Parse(pitchAndDuration[1]); var denominator = int.Parse(pitchAndDuration[0].Replace(".", "")); var numberOfNotes = pitchAndDuration[0].ToCharArray().Where(c => c == '.').Count(); var denominatorAsPowerOfTwo = UsefulMath.Log2(denominator); var note = Note.FromMidiPitch(midiPitch, new RhythmicDuration(denominatorAsPowerOfTwo, numberOfNotes)); score.FirstStaff.Elements.Add(note); } else if (element == "|") { score.FirstStaff.Elements.Add(new Barline()); } else { var denominator = int.Parse(element.Replace(".", "")); var numberOfNotes = element.ToCharArray().Where(c => c == '.').Count(); var denominatorAsPowerOfTwo = UsefulMath.Log2(denominator); var rest = new Rest(new RhythmicDuration(denominatorAsPowerOfTwo, numberOfNotes)); score.FirstStaff.Elements.Add(rest); } } return(score); }
public static IEnumerable <Note> AddUniformRhythm(this IEnumerable <Pitch> pitches, int duration) { var durationAsPowerOfTwo = UsefulMath.Log2(duration); return(AddUniformRhythm(pitches, new RhythmicDuration(durationAsPowerOfTwo))); }
/// <summary> /// Performs rebeaming with simple rules /// </summary> /// <param name="notes">Notes to rebeam</param> /// <param name="hookDirectionAlgorithm">Algorithm for determining hook direction in beams</param> /// <returns>Rebeamed notes</returns> public IEnumerable <NoteOrRest> Rebeam(IEnumerable <NoteOrRest> notes, HookDirectionAlgorithm hookDirectionAlgorithm = HookDirectionAlgorithm.ProductionCandidate) { Note previousNote = null; Note currentNote = null; Note nextNote = null; var noteArray = notes.ToArray(); for (int i = 0; i < noteArray.Length; i++) { previousNote = i == 0 ? null : noteArray[i - 1] as Note; currentNote = noteArray[i] as Note; nextNote = i == noteArray.Length - 1 ? null : noteArray[i + 1] as Note; currentNote.BeamList.Clear(); var numberOfBeams = currentNote.BaseDuration > RhythmicDuration.Eighth ? 0 : UsefulMath.Log2((int)currentNote.BaseDuration.Denominator) - 2; var numberOfBeamsOnPreviousNote = previousNote == null || previousNote.BaseDuration > RhythmicDuration.Eighth ? 0 : UsefulMath.Log2((int)previousNote.BaseDuration.Denominator) - 2; var numberOfBeamsOnNextNote = nextNote == null || nextNote.BaseDuration > RhythmicDuration.Eighth ? 0 : UsefulMath.Log2((int)nextNote.BaseDuration.Denominator) - 2; for (var b = 0; b < numberOfBeams; b++) { if (previousNote == null) { if (nextNote != null && numberOfBeamsOnNextNote < b + 1) { currentNote.BeamList.Add(DetermineHookDirection(notes.ToList(), currentNote, hookDirectionAlgorithm)); } else { currentNote.BeamList.Add(NoteBeamType.Start); } } else if (nextNote == null) { if (previousNote != null && numberOfBeamsOnPreviousNote < b + 1) { currentNote.BeamList.Add(DetermineHookDirection(notes.ToList(), currentNote, hookDirectionAlgorithm)); } else { currentNote.BeamList.Add(NoteBeamType.End); } } else { if (numberOfBeamsOnPreviousNote >= b + 1 && numberOfBeamsOnNextNote >= b + 1) { currentNote.BeamList.Add(NoteBeamType.Continue); } else if (numberOfBeamsOnPreviousNote < b + 1 && numberOfBeamsOnNextNote < b + 1) { currentNote.BeamList.Add(DetermineHookDirection(notes.ToList(), currentNote, hookDirectionAlgorithm)); } else if (numberOfBeamsOnPreviousNote < b + 1) { currentNote.BeamList.Add(NoteBeamType.Start); } else if (numberOfBeamsOnNextNote < b + 1) { currentNote.BeamList.Add(NoteBeamType.End); } } } } return(notes); }