-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update for public lib. NEEDS TESTING
- Loading branch information
=
committed
May 4, 2021
1 parent
e251d4d
commit 913828a
Showing
18 changed files
with
856 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- boolean logic | ||
-- output logic transfer functions are dynamically selected per channel | ||
-- a state change on any input triggers update of all outputs | ||
|
||
-- enumeration of the fnlist. least to most density of transfer | ||
fenum = {'~|','>','<','&','~^','^','~&','<=','>=','|'} | ||
|
||
public.add('f1','&',fenum) | ||
public.add('f2','|',fenum) | ||
public.add('f3','^',fenum) | ||
public.add('f4','~^',fenum) | ||
|
||
-- all the dynamic transfer fns between 2 inputs (ordering doesn't matter) | ||
fnlist = | ||
{ '~|' = function(a,b) return not (a or b) end | ||
, '>' = function(a,b) return a>b end | ||
, '<' = function(a,b) return a<b end | ||
, '&' = function(a,b) return (a and b) end | ||
, '~^' = function(a,b) return a==b end | ||
, '^' = function(a,b) return a~=b end | ||
, '~&' = function(a,b) return not (a and b) end | ||
, '<=' = function(a,b) return a<=b end | ||
, '>=' = function(a,b) return a>=b end | ||
, '|' = function(a,b) return (a or b) end | ||
} | ||
|
||
function q(n) return input[n].volts > 1.0 end | ||
function apply() | ||
local a, b = q(1), q(2) | ||
output[1].volts = fnlist[public.f1](a, b) | ||
output[2].volts = fnlist[public.f2](a, b) | ||
output[3].volts = fnlist[public.f3](a, b) | ||
output[4].volts = fnlist[public.f4](a, b) | ||
end | ||
|
||
function init() | ||
for n=1,2 do | ||
input[n].mode('change') | ||
input[n].change = apply -- update all outs on any state change | ||
end | ||
apply() -- initialize to current state | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- clock divider | ||
-- in1: clock input | ||
-- in2: division selector (see divs) | ||
-- out1-4: divided outputs | ||
|
||
function newdiv(tab) | ||
for n=1,4 do | ||
output[n].clock_div = tab[n] | ||
end | ||
end | ||
|
||
-- choose your clock divisions | ||
public.add('win1', {5,7,11,13}, newdiv) | ||
public.add('win2', {3,5,7,11}, newdiv) | ||
public.add('win3', {2,3,5,7}, newdiv) | ||
public.add('win4', {2,4,8,16}, newdiv) | ||
public.add('win5', {4,8,16,32}, newdiv) | ||
|
||
WINDOWS = {public.win1, public.win2, public.win3, public.win4, public.win5} | ||
|
||
function init() | ||
input[1].mode('clock',1/4) | ||
input[2].mode('window', {-3,-1,1,3}) | ||
for n=1,4 do | ||
output[n]:clock(public.win3[n]) | ||
end | ||
end | ||
|
||
input[2].window = function(win, dir) | ||
newdiv(WINDOWS[win]) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
--- gingerbread man chaotic attractor | ||
-- input1: clock | ||
-- input2: offset | ||
-- output1: X1 | ||
-- output2: Y1 | ||
-- output3: X2 | ||
-- output4: Y2 | ||
|
||
-- TODO view in x-y mode | ||
function init() | ||
input[1]{ mode = 'change' | ||
, direction = 'rising' | ||
} | ||
end | ||
|
||
-- two instances | ||
gs = { {x=0,y=0} | ||
, {x=0,y=0} | ||
} | ||
|
||
function make_bread(g, xoff, yoff) | ||
local x1 = g.x | ||
g.x = 0.5 - g.y + math.abs(x1) + xoff | ||
g.y = x1 + yoff | ||
if g.x > 5 then g.x = 5.0 end | ||
if g.y > 5 then g.y = 5.0 end | ||
end | ||
|
||
input[1].change = function() | ||
make_bread(gs[1], input[2].volts, 0) | ||
make_bread(gs[2], 0, input[2].volts) | ||
for n=1,2 do | ||
output[n*2-1].volts = gs[n].x | ||
output[n*2].volts = gs[n].y | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
-- boids | ||
-- t gill 190925 | ||
-- inspired by http://www.vergenet.net/~conrad/boids/pseudocode.html | ||
|
||
-- params | ||
follow = 0.75 -- input=1, free=0 | ||
pull = 0.5 -- to centre | ||
avoid = 0.1 -- V threshold | ||
sync = 1/20 -- dir attraction | ||
limit = 0.05 -- max volts per timestep | ||
|
||
timing = 0.02 -- calc speed | ||
|
||
boids = {} | ||
count = 4 | ||
|
||
-- artificially provide a 'centre-of-mass' | ||
function centring(b,c) | ||
return (c - b.p) * pull | ||
end | ||
|
||
function avoidance(bs,b) | ||
v = 0 | ||
for n=1,count do | ||
if bs[n] ~= b then -- ignore self | ||
d = bs[n].p - b.p | ||
if math.abs(d) < avoid then | ||
v = v - d/2 | ||
end | ||
end | ||
end | ||
return v | ||
end | ||
|
||
function syncing(bs,b) | ||
v = 0 | ||
for n=1,count do | ||
if bs[n] ~= b then -- ignore self | ||
v = v + bs[n].v | ||
end | ||
end | ||
v = v / (count-1) | ||
return (v - b.v) * sync | ||
end | ||
|
||
function findcentre(bs,c) | ||
m = 0 | ||
for n=1,count do | ||
m = m + bs[n].p | ||
end | ||
m = m/count | ||
return m + follow*(c-m) | ||
end | ||
|
||
function move( bs, n, c, v ) | ||
mass = findcentre(bs,c) | ||
b = bs[n] | ||
v1 = centring(b,mass) | ||
v2 = avoidance(bs,b) | ||
v3 = syncing(bs,b) | ||
b.v = b.v + v1 + v2 + v3 | ||
if b.v > limit then b.v = limit | ||
elseif b.v < -limit then b.v = -limit end | ||
b.v = b.v * v | ||
b.p = b.p + b.v | ||
return b | ||
end | ||
|
||
function draw( b, n, v ) | ||
output[n].slew = v*1.1 | ||
output[n].volts = b.p | ||
end | ||
|
||
-- round-robin calculation | ||
function step(c) | ||
c = (c % count)+1 | ||
accel = input[2].volts | ||
draw( boids[c], c, timing ) | ||
boids[c] = move( boids, c, input[1].volts, (accel+5.0)/5.0 ) | ||
end | ||
|
||
function init_boids() | ||
local bs = {} | ||
for n=1,count do | ||
bs[n] = { p = math.random()*3.0 - 1.0 | ||
, v = 0 | ||
} | ||
end | ||
return bs | ||
end | ||
|
||
function init() | ||
boids = init_boids() | ||
mover = metro.init{ event = step | ||
, time = timing/count | ||
, count = -1 | ||
} | ||
mover:start() | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- boolean logic | ||
-- out1: 1 AND 2 | ||
-- out2: 1 OR 2 | ||
-- out3: 1 XOR 2 | ||
-- out4: true on 1rising, false on 2rising | ||
|
||
g = {false, false} -- state of the input gates | ||
flipflop = false -- state of the flipflop | ||
function init() | ||
for n=1,2 do | ||
input[n].mode('change') | ||
g[n] = input[n].volts > 1.0 | ||
end | ||
end | ||
|
||
function logic( chan, state ) | ||
g[chan] = state | ||
if state then flipflop = (chan == 1) and true or false end | ||
|
||
output[1].volts = (g[1] and g[2]) and 5 or 0 | ||
output[2].volts = (g[1] or g[2]) and 5 or 0 | ||
output[3].volts = (g[1] ~= g[2]) and 5 or 0 -- XOR is the same as not-equal | ||
output[4].volts = flipflop and 5 or 0 | ||
end | ||
|
||
input[1].change = function(s) | ||
logic(1,s) | ||
end | ||
input[2].change = function(s) | ||
logic(2,s) | ||
end |
Oops, something went wrong.