示例#1
0
        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);
        }
示例#2
0
        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(")");
        }