def PDur(n, k, start=0, dur=0.25): """ Returns the *actual* durations based on Euclidean rhythms (see PEuclid) where dur is the length of each step. e.g. `PDur(3, 8)` will return `P[0.75, 0.75, 0.5]` """ data = EuclidsAlgorithm(n, k) count, seq = 1, [] for item in data[1:]: if item == 1: seq.append(count) count = 1 else: count += 1 seq.append(count) pattern = Pattern(seq) if start != 0: pattern = pattern.rotate(int(start)) return pattern * dur
def __init__(self, s, dur=0.5): character = [] durations = [] if type(s) is str: s = Pattern().fromString(s) dur = s.dur(dur) self.data = [] for i, char in s.items(): # Recursively get rhythms if isinstance(char, PGroup): character += list(char) durations += list(self.__class__(char, dur)) else: character.append(char) durations.append(dur) # After recursive collection of durations, adjust for rests (spaces) self.chars = [] for i, dur in enumerate(durations): if character[i] == ' ' and i > 0: self.data[-1] += dur else: self.data.append(dur) self.chars.append(character[i])
def PSum(n, total, **kwargs): """ Returns a Pattern of length 'n' that sums to equal 'total' ``` e.g. PSum(3,8) -> P[3, 3, 2] PSum(5,4) -> P[1, 0.75, 0.75, 0.75, 0.75] ``` """ lim = kwargs.get("lim", 0.125) data = [total + 1] step = 1 while sum(data) > total: data = [step for x in range(n)] step *= 0.5 i = 0 while sum(data) < total and step >= lim: if sum(data) + step > total: step *= 0.5 else: data[i % n] += step i += 1 return Pattern(data)
def __init__(self, start, stop=None): GeneratorPattern.__init__(self) if hasattr(start, "__iter__"): self.data = Pattern(start) self.func = lambda index: random.choice(self.data) else: self.low = start if stop is not None else 0 self.high = stop if stop is not None else start
def PZip(pat1, pat2, *patN): ''' Creates a Pattern that 'zips' together multiple patterns. `PZip([0,1,2], [3,4])` will create the Pattern `P[(0, 3), (1, 4), (2, 3), (0, 4), (1, 3), (2, 4)]` ''' l, p = [], [] for pat in [pat1, pat2] + list(patN): p.append(P[pat]) l.append(len(p[-1])) length = LCM(*l) return Pattern([tuple(pat[i] for pat in p) for i in range(length)])
def PAlt(pat1, pat2, *patN): ''' Returns a Pattern generated by alternating the values in the given sequences ''' data = [] item = [asStream(p) for p in [pat1, pat2] + list(patN)] size = LCM(*[len(i) for i in item]) for n in range(size): for i in item: data.append(modi(i, n)) return Pattern(data)
def PZip2(pat1, pat2, rule=lambda a, b: True): ''' Like `PZip` but only uses two Patterns. Zips together values if they satisfy the rule. ''' length = LCM(len(pat1), len(pat2)) data = [] i = 0 while i < length: a, b = modi(pat1, i), modi(pat2, i) if rule(a, b): data.append((a, b)) i += 1 return Pattern(data)
def PPairs(seq, func=lambda n: 8 - n): """ Laces a sequence with a second sequence obtained by performing a function on the original. By default this is `lambda n: 8 - n`. """ i = 0 data = [] for item in seq: data.append(item) data.append(func(item)) i += 1 if i >= MAX_SIZE: break return Pattern(data)
def __getitem__(self, args): if hasattr(args, '__iter__'): data = [] for item in args: if type(item) is slice: data.extend(sliceToRange(item)) else: data.append(item) elif type(args) is slice: data = sliceToRange(args) else: data = args return Pattern(data)
def PSine(n=16): """ Returns values of one cycle of sine wave split into 'n' parts """ i = (2 * math.pi) / n return Pattern([math.sin(i * j) for j in range(int(n))])
def PStretch(seq, size): ''' Returns 'seq' as a Pattern and looped until its length is 'size' e.g. `PStretch([0,1,2], 5)` returns `P[0, 1, 2, 0, 1]` ''' return Pattern(seq).stretch(size)
def new_function(*args): pat = Pattern() for i in range( LCM(*[len(arg) for arg in args if hasattr(arg, '__len__')])): pat |= f(*[modi(arg, i) for arg in args]) return pat
def PShuf(seq): ''' PShuf(seq) -> Returns a shuffled version of seq''' return Pattern(seq).shuffle()
def PStutter(seq, n=2): """ PStutter(seq, n) -> Creates a pattern such that each item in the array is repeated n times (n can be a pattern) """ return Pattern(seq).stutter(n)
def PSq(a=1, b=2, c=3): ''' Returns a Pattern ''' return Pattern([x**b for x in range(a, a + c)])
def P10(n): ''' Returns an n-length Pattern of a randomly generated series of 1's and 0's ''' return Pattern([random.choice((0, 1)) for i in range(int(n))])
def PEuclid(n, k): ''' Returns the Euclidean rhythm which spreads 'n' pulses over 'k' steps as evenly as possible. e.g. `PEuclid(3, 8)` will return `P[1, 0, 0, 1, 0, 0, 1, 0]` ''' return Pattern(EuclidsAlgorithm(n, k))
def PStep(n, value, default=0): ''' Returns a Pattern that every n-term is 'value' otherwise 'default' ''' return Pattern([default] * (n - 1) + [value])
def PTri(start, stop=None, step=None): ''' Returns a Pattern equivalent to `Pattern(range(start, stop, step)) with its reversed form appended.''' rev_step = step if step is not None else 1 data = list(PRange(start, stop, step)) return Pattern(data + [item + rev_step for item in reversed(data)])
def PRange(start, stop=None, step=None): ''' Returns a Pattern equivalent to `Pattern(range(start, stop, step)) ''' return Pattern( range(*[val for val in (start, stop, step) if val is not None]))