forked from monome/bowery
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheuclidean.lua
77 lines (64 loc) · 1.77 KB
/
euclidean.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
--- 4 euclidean rhythm generators
-- sam wolk 2019.10.21
-- in1: clock
-- in2: reset
-- outs: euclidean rhythms
-- ER parameters for each channel.
public.add('lengths', {16,16,16,16})
public.add('fills', {4,5,9,12})
public.add('offsets', {0,0,0,0})
-- private state
locations = {-1,-1,-1,-1}
-- ER function adapted from https://gist.github.com/vrld/b1e6f4cce7a8d15e00e4
function er(fill, length, ix)
local r = {}
-- place all filled slots at the start of the rhythm
for i=1,length do
r[i] = {i <= fill}
end
-- each element is now a table with either true or false
local function cat(t, dst, src)
-- copy all elements of t[src] to the end of t[dst] and remove t[src]
for _,v in ipairs(t[src]) do
table.insert(t[dst], v)
end
t[src] = nil
end
-- interleave the empty slots until they are spread out evenly
while #r > fill do
for i=1,math.min(fill, #r-fill) do
cat(r, i, #r)
end
end
-- fold all lists down to a single one
while #r > 1 do
cat(r, #r-1, #r)
end
-- return boolean (and discard table)
return r[1][ix]
end
-- Use a trigger to advance ER counters and activate ASLs on hits
input[1].change = function(state)
for i=1,4 do
--- increment counters
locations[i] = (locations[i] + 1) % lengths[i]
-- get current location
local index = (locations[i] + offsets[i]) % lengths[i]
-- create pulse if there is an event
if er(fills[i], lengths[i], index+1) then
output[i]()
end
end
end
input[2].change = function(state)
for i=1,4 do
locations[i] = -1 -- reset locations
end
end
function init()
input[1].mode('change',1,0.1,'rising')
input[2].mode('change',1,0.1,'rising')
for i=1,4 do
output[i].action = pulse(0.02,8)
end
end