public static Composition Read(string filename, Fraction?prec = null) { var reader = new StreamReader(filename); MelodyPartList list = new MelodyPartList(MelodyPartList.Type.Voice); while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line == "") { continue; } var values = line.Split(','); if (values.Length != 2) { throw new Exception($"The line `{line}` must contain exactly two values."); } int note = int.Parse(values[0].Trim()); Fraction duration = Fraction.Parse(values[1].Trim()); NoteWithDuration nwd = new NoteWithDuration(60 + note, duration); list.Add(nwd); } Composition composition = new Composition(); composition.millisecondsPerNote = 500; // todo: arbitrary tempo composition.AddVoice(list); return(composition); }
public override IEnumerable <NoteWithDuration> Notes() { foreach (NoteSequence seq in sequences) { foreach (var note in melody.Notes()) { int number = seq[note.note].note; Note currNote = note; NoteWithDuration?noteReturn = null, noteTail = null; do { Alteration alter = (Alteration)((int)currNote.alter + (int)seq[currNote.note].alter); if (noteReturn == null) { noteReturn = noteTail = new NoteWithDuration(number, alter, note.Duration); } else { //noteTail.va.otherNote = new NoteWithDuration(number, alter, note.Duration); //noteTail = noteTail.otherNote as NoteWithDuration; } //currNote = currNote.otherNote; } while (false); yield return(noteReturn.Value); } } }
public override IEnumerable <NoteWithDuration> Notes() { List <NoteWithDuration> current = new List <NoteWithDuration>(); foreach (var component in components) { Fraction fractSum = component.melody.Duration; foreach (var nwd in component.melody.Anacrusis) { fractSum = fractSum - nwd.Duration; } Debug.Assert(fractSum.p > 0); foreach (var nwd in current) { fractSum = fractSum - nwd.Duration; if (fractSum.p < 0) { Fraction dur = nwd.Duration + fractSum; Debug.Assert(dur.p > 0); yield return(new NoteWithDuration(nwd.note, dur)); break; } yield return(nwd); if (fractSum.p == 0) { break; } } foreach (var nwd in component.melody.Anacrusis) { yield return(new NoteWithDuration(nwd.note + component.alterations[0], nwd.Duration)); } current = new List <NoteWithDuration>(); if (component.melody.StartPause.p != 0) { current.Add(NoteWithDuration.MakePause(component.melody.StartPause)); } foreach (var nwd in component.melody.Notes(component.alterations)) { // todo: this might be a kludge int alter = component.alterations.Length == 1 ? component.alterations[0] : 0; current.Add(new NoteWithDuration(nwd.note + alter, nwd.Duration)); } } foreach (var nwd in current) { yield return(nwd); } }
private static void AddNote(MelodyPartList list, NoteWithDuration nwd, Fraction?prec = null, long absoluteTime = 0) { if (prec != null) { Fraction times = (nwd.Duration / prec.Value); if (!times.IsWhole()) { throw new Exception($"Duration of Note {nwd} not divisible by {prec.Value} at absoluteTime={absoluteTime}"); } } list.Add(nwd); }
public void Play(int offset = 0) { int?previousNote = null; foreach (NoteWithDuration note in GetNotes()) { if (previousNote.HasValue) { StaticAndExtensionMethods.midiOut.Send(MidiMessage.StopNote(previousNote.Value + offset, 100, 1).RawData); } previousNote = note.IsPause ? null : (int?)(note.note); NoteWithDuration noteToPlay = note + offset; Debug.Assert(noteToPlay.IsPause || noteToPlay.note > 10 && noteToPlay.note < 100); if (!noteToPlay.IsPause) { StaticAndExtensionMethods.midiOut.Send(MidiMessage.StartNote(noteToPlay.note, 100, 1).RawData); } var fract = note.Duration; Thread.Sleep(15 * 1000 * fract.p / fract.q / 60); } }
public override IEnumerable <NoteWithDuration> Notes() { foreach (var nwd in Anacrusis) { yield return(nwd); } int i = 0; foreach (var fract in rhythm.Notes()) { if (notes[i] is string) { Note note = new Note(notes[i] as string); NoteWithDuration notewd = new NoteWithDuration(note.note, note.alter, fract); yield return(notewd); } else { yield return(new NoteWithDuration((int)notes[i], fract)); } i++; } }
static NoteWithDuration Transform(NoteWithDuration note, Func <NoteWithDuration, NoteWithDuration> trans) { NoteWithDuration noteReturn = trans(note); return(noteReturn); }