public Rhythm stick(double sprob) { Rhythm stuck = new Rhythm(work, duration); Rhythm_Element last = null; foreach (Rhythm_Element re in path) { if (last == null || last.denom != re.denom || rand.NextDouble() > sprob) { if (last != null) { last.reduce(); stuck.path.Add(last); } last = new Rhythm_Element(re.offset, re.duration, re.numer, re.denom); last.silent = re.silent; } else { last.numer += re.numer; last.duration += re.duration; last.silent &= re.silent; } } if (last != null) { last.reduce(); stuck.path.Add(last); } return(stuck); }
public void divide(Rhythm_Element e, double min_dur, int max_div, double d, double mphase, double vphase, int vi, double tdur) { e.reduce(); // if the note is too short to split, just play it straight // or if the note is longer, roll the dice and maybe play it straight // (1.0 - 2.0 * min_dur) / (11.0 * e.duration + 1.0 - 24.0 * min_dur) double local_min = min_dur; if (e.duration < 2 * local_min || rand.NextDouble() < Math.Exp(0.18 * (2.0 - e.duration / local_min))) { double zerop = tdur * (2.0 + Math.Cos(2.0 * Math.PI * (0.5 * mphase + e.offset / duration)) * Math.Cos(2.0 * Math.PI * (vphase + ((double)vi) / 4.0))); double restp = Math.Exp(-(e.duration - min_dur) / zerop); if (rand.NextDouble() < restp) { work.trace.Write(string.Format("R{0}/{1}", e.numer, e.denom)); return; } e.duration *= 0.92; path.Add(e); work.trace.Write(string.Format("{0}/{1}", e.numer, e.denom)); return; } // divide the note into a random number of parts, but not too many int mdiv = (int)(e.duration / min_dur); if (mdiv > max_div) { mdiv = max_div; } int div = 2 + rand.Next(mdiv - 1); double time = e.offset; double pulse = e.duration / (double)div; int denom = div * e.denom; int parts = 2 + rand.Next(div - 1); Rhythm_Element[] part = new Rhythm_Element[parts]; for (int i = 0; i < parts; i++) { Rhythm_Element ne = new Rhythm_Element(time, pulse, e.numer, denom); part[i] = ne; } for (int i = 0; i < div - parts; i++) { int pick = rand.Next(parts); part[pick].duration += pulse; part[pick].numer += e.numer; } for (int i = 0; i < parts; i++) { part[i].offset = time; time += part[i].duration; } work.trace.Write("("); bool first = true; for (int i = 0; i < parts; i++) { if (!first) { work.trace.Write(" "); } first = false; divide(part[i], min_dur, max_div, d, mphase, vphase, vi, tdur); } work.trace.Write(")"); }