public static List <RhythmValue> GetRhythm(List <float> noteDurations, int measureDuration, int beatDuration) { float sum = noteDurations.Sum(); float scaling = measureDuration / sum; var noteEnds = new List <float>(); float total = 0; for (int i = 0; i < noteDurations.Count; ++i) { noteDurations[i] *= scaling; total += noteDurations[i]; noteEnds.Add(total); } MatchRhythm(noteEnds, 0, noteEnds.Count, 0, measureDuration, beatDuration); // determine final note values var ret = new List <RhythmValue>(); float offset = 0; foreach (var end in noteEnds) { var rhythm = new RhythmValue() { Duration = (int)Math.Round(end - offset), NoteIndex = ret.Count }; offset = end; ret.Add(rhythm); } SplitDurations(ret, measureDuration, beatDuration); return(ret); }
public static List<RhythmValue> GetRhythm(List<float> noteDurations, int measureDuration, int beatDuration) { float sum = noteDurations.Sum(); float scaling = measureDuration / sum; var noteEnds = new List<float>(); float total = 0; for (int i = 0; i < noteDurations.Count; ++i) { noteDurations[i] *= scaling; total += noteDurations[i]; noteEnds.Add(total); } MatchRhythm(noteEnds, 0, noteEnds.Count, 0, measureDuration, beatDuration); // determine final note values var ret = new List<RhythmValue>(); float offset = 0; foreach (var end in noteEnds) { var rhythm = new RhythmValue() { Duration = (int)Math.Round(end - offset), NoteIndex = ret.Count }; offset = end; ret.Add(rhythm); } SplitDurations(ret, measureDuration, beatDuration); return ret; }
static void SplitDurations(List <RhythmValue> durations, int measureDuration, int beatLength) { // This function takes care of note values that cannot (or should not) be represented // by a single note, and it also tries to split up the rhythm in a more or less // readable way. This means e.g. that triplet notes should not stand alone. // (Although the algorithm may not be perfect in prevent single triplets.) int curPos = 0; for (int i = 0; i < durations.Count; ++i) { if (durations[i].Duration <= 1) { continue; } if (PrintableDurations.Contains(durations[i].Duration)) { curPos += durations[i].Duration; continue; } //Console.WriteLine(" At pos {0}, trying to split duration {1}...", curPos, durations[i].Duration); bool done = false; int curBeat = beatLength; int noteEnd = curPos + durations[i].Duration; int n = 2; int d = 3; while (!done && curBeat >= 2) { int maxMult = noteEnd / curBeat; for (int j = maxMult; j >= 1; --j) { int remaining = noteEnd - j * curBeat; if (remaining < 2 && remaining != 0) { break; } int duration = durations[i].Duration - remaining; if (PrintableDurations.Contains(duration)) { durations[i].Duration = duration; if (remaining != 0) { durations.Insert(i + 1, new RhythmValue() { Duration = remaining, NoteIndex = durations[i].NoteIndex }); } done = true; break; } } // try next smaller even / triplet beat curBeat = curBeat * n / d; if (n == 2) { n = 3; d = 4; } else { n = 2; d = 3; } } if (!PrintableDurations.Contains(durations[i].Duration)) { Console.WriteLine(" Warning: Failed to split note duration {0} properly, splitting in half...", durations[i].Duration); var newNote = new RhythmValue() { Duration = durations[i].Duration / 2, NoteIndex = durations[i].NoteIndex }; durations[i].Duration -= newNote.Duration; durations.Insert(i + 1, newNote); --i; } else { curPos += durations[i].Duration; } } }
static void SplitDurations(List<RhythmValue> durations, int measureDuration, int beatLength) { // This function takes care of note values that cannot (or should not) be represented // by a single note, and it also tries to split up the rhythm in a more or less // readable way. This means e.g. that triplet notes should not stand alone. // (Although the algorithm may not be perfect in prevent single triplets.) int curPos = 0; for (int i = 0; i < durations.Count; ++i) { if (durations[i].Duration <= 1) continue; if (PrintableDurations.Contains(durations[i].Duration)) { curPos += durations[i].Duration; continue; } //Console.WriteLine(" At pos {0}, trying to split duration {1}...", curPos, durations[i].Duration); bool done = false; int curBeat = beatLength; int noteEnd = curPos + durations[i].Duration; int n = 2; int d = 3; while (!done && curBeat >= 2) { int maxMult = noteEnd / curBeat; for (int j = maxMult; j >= 1; --j) { int remaining = noteEnd - j * curBeat; if (remaining < 2 && remaining != 0) break; int duration = durations[i].Duration - remaining; if (PrintableDurations.Contains(duration)) { durations[i].Duration = duration; if (remaining != 0) { durations.Insert(i + 1, new RhythmValue() { Duration = remaining, NoteIndex = durations[i].NoteIndex }); } done = true; break; } } // try next smaller even / triplet beat curBeat = curBeat * n / d; if (n == 2) { n = 3; d = 4; } else { n = 2; d = 3; } } if (!PrintableDurations.Contains(durations[i].Duration)) { Console.WriteLine(" Warning: Failed to split note duration {0} properly, splitting in half...", durations[i].Duration); var newNote = new RhythmValue() { Duration = durations[i].Duration / 2, NoteIndex = durations[i].NoteIndex }; durations[i].Duration -= newNote.Duration; durations.Insert(i + 1, newNote); --i; } else { curPos += durations[i].Duration; } } }