Last active
May 31, 2020 16:22
-
-
Save jmsole/6572916b58f79bb75392cd589b5e25da to your computer and use it in GitHub Desktop.
A basic cv-controlled clock with swing and clock multiplier for crow
This file contains hidden or 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
-- a basic cv-controlled clock with swing and clock division | |
-- input 1: 0 - 5v cv to control tempo | |
-- input 2: -5 - 5v cv to control swing on even notes | |
-- 0v is no swing, -5v is 25% swing and 5v is 75% swing | |
-- output 1: clock without swing | |
-- output 2: clock with swing and clock division | |
-- output 3: half-tempo clock with odd beats and clock division | |
-- output 4: half-tempo swinged clock with even beats and clock division | |
-- clock divider factor. 1 is no division, probably better to use even numbers | |
swingclockdivider = 2 | |
-- initial values and constants | |
pulsetime = 0.0025 | |
pulselevel = 5 | |
pulsepolarity = 1 | |
bpmmin = 50 | |
bpmmax = 200 | |
swingmin = 25 | |
swingmax = 75 | |
bpm = 120 | |
click = 60 / bpm | |
swing = 50 | |
-- a few functions that help later | |
function trunc_float(n) | |
trunc = string.format("%.4f", n) | |
return trunc | |
end | |
function map_range(a1, a2, b1, b2, s) | |
return b1 + (s-a1)*(b2-b1)/(a2-a1) | |
end | |
function volt2clock(v) | |
bpm = map_range(0, 5, bpmmin, bpmmax, v) | |
bpm = math.floor(bpm) | |
click = 60/bpm | |
click = trunc_float(click) * 2 -- need to multiply clock to make it slower | |
return click | |
end | |
function swing_delay(t, s) | |
swingdel = t * s / 50 | |
swingdel = trunc_float(swingdel) | |
return swingdel | |
end | |
function volt2swing(v) | |
swing = map_range(-5 , 5, swingmin, swingmax, v) | |
swing = math.floor(swing) | |
return swing | |
end | |
-- main clock function | |
function clock() | |
newclick = volt2clock(input[1].volts) | |
clock_metro.time = newclick | |
newswing = volt2swing(input[2].volts) | |
swingdel = swing_delay(newclick, newswing) / 2 | |
div = swingdel / swingclockdivider | |
-- print(bpm, newclick, newswing, swingdel, div, swingdel / swingclockdivider) | |
-- To get clock at normal speed on output 1 I am using delay to get clock divisions | |
-- because of the clock multiply in volt2clock | |
output[1]() | |
delay(function() output[1]() end, newclick / 2, 0) | |
if swingclockdivider == 1 then | |
output[2]() | |
output[3]() | |
delay(function() output[2]() output[4]() end, swingdel, 0) | |
elseif swingclockdivider >= 2 then | |
delay(function() output[2]() output[3]() end, newclick / swingclockdivider, swingclockdivider - 1) | |
delay(function() | |
delay(function() | |
output[2]() output[4]() | |
end | |
, newclick / swingclockdivider | |
, swingclockdivider - 1) | |
end | |
, div | |
, 0) | |
end | |
end | |
-- report function to print swing and bpm to druid | |
function report() | |
print(newswing, bpm) | |
end | |
-- initialization function | |
function init() | |
for n = 1,4 do | |
output[n].action = pulse( pulsetime, pulselevel, pulsepolarity ) | |
end | |
clock_metro = metro.init{ event = clock | |
, time = click | |
, count = -1 | |
} | |
clock_metro:start() | |
reporter = metro.init{ event = report | |
, time = 0.25 | |
, count = -1 | |
} | |
-- reporter:start() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment