Last active
September 20, 2018 05:50
-
-
Save okyeron/3a854b13c3a699daa02eb75f2861cebe to your computer and use it in GitHub Desktop.
adaptation of norns mlr to 64 grid
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
-- MLR | |
-- | |
-- http://monome.org/ | |
-- docs/norns/dust/tehn/mlr | |
-- | |
-- new/180828 | |
-- | |
-- - 6 channels | |
-- - improved sound engine | |
-- - alt+REC clears buffer | |
-- - panning | |
-- | |
-- ///////// | |
-- //// | |
-- //////////// | |
-- ////////// | |
-- /////// | |
-- / | |
-- //// | |
-- // | |
-- ///////// | |
-- /// | |
-- / | |
-- | |
-- //// | |
-- / | |
-- | |
-- / | |
-- | |
-- | |
engine.name = "SoftCut" | |
local g = grid.connect() | |
local pattern_time = require 'pattern_time' | |
local TRACKS = 6 | |
local FADE = 0.01 | |
local vREC = 1 | |
local vCUT = 2 | |
local vCLIP = 3 | |
local vTIME = 15 | |
-- events | |
local eCUT = 1 | |
local eSTOP = 2 | |
local eSTART = 3 | |
local eLOOP = 4 | |
local eSPEED = 5 | |
local eREV = 6 | |
local quantize = 0 | |
local midi_device = midi.connect() | |
local midiclocktimer | |
local function update_tempo() | |
local t = params:get("tempo") | |
local d = params:get("quant_div") | |
local interval = (60/t) / d | |
print("q > "..interval) | |
quantizer.time = interval | |
for i=1,TRACKS do | |
if track[i].tempo_map == 1 then | |
update_rate(i) | |
end | |
end | |
midiclocktimer.time = 60/24/t | |
end | |
function event(e) | |
if quantize == 1 then | |
event_q(e) | |
else | |
for i=1,4 do | |
pattern[i]:watch(e) | |
end | |
event_exec(e) | |
end | |
end | |
local quantize_events = {} | |
function event_q(e) | |
table.insert(quantize_events,e) | |
end | |
function event_q_clock() | |
if #quantize_events > 0 then | |
for k,e in pairs(quantize_events) do | |
for i=1,4 do | |
pattern[i]:watch(e) | |
end | |
event_exec(e) | |
end | |
quantize_events = {} | |
end | |
end | |
function event_exec(e) | |
if e.t==eCUT then | |
if track[e.i].loop == 1 then | |
track[e.i].loop = 0 | |
engine.loop_start(e.i,clip[track[e.i].clip].s) | |
engine.loop_end(e.i,clip[track[e.i].clip].e) | |
end | |
local cut = (e.pos/16)*clip[track[e.i].clip].l + clip[track[e.i].clip].s | |
engine.pos(e.i,cut) | |
engine.reset(e.i) | |
if track[e.i].play == 0 then | |
track[e.i].play = 1 | |
engine.start(e.i) | |
end | |
elseif e.t==eSTOP then | |
track[e.i].play = 0 | |
track[e.i].pos_grid = -1 | |
engine.stop(e.i) | |
dirtygrid=true | |
elseif e.t==eSTART then | |
track[e.i].play = 1 | |
engine.start(e.i) | |
dirtygrid=true | |
elseif e.t==eLOOP then | |
track[e.i].loop = 1 | |
track[e.i].loop_start = e.loop_start | |
track[e.i].loop_end = e.loop_end | |
--print("LOOP "..track[e.i].loop_start.." "..track[e.i].loop_end) | |
local lstart = clip[track[e.i].clip].s + (track[e.i].loop_start-1)/16*clip[track[e.i].clip].l | |
local lend = clip[track[e.i].clip].s + (track[e.i].loop_end)/16*clip[track[e.i].clip].l | |
--print(">>>> "..lstart.." "..lend) | |
engine.loop_start(e.i,lstart) | |
engine.loop_end(e.i,lend) | |
if view == vCUT then dirtygrid=true end | |
elseif e.t==eSPEED then | |
track[e.i].speed = e.speed | |
update_rate(e.i) | |
--n = math.pow(2,track[e.i].speed + params:get("speed_mod"..e.i)) | |
--if track[e.i].rev == 1 then n = -n end | |
--engine.rate(e.i,n) | |
if view == vREC then dirtygrid=true end | |
elseif e.t==eREV then | |
track[e.i].rev = e.rev | |
update_rate(e.i) | |
--n = math.pow(2,track[e.i].speed + params:get("speed_mod"..e.i)) | |
--if track[e.i].rev == 1 then n = -n end | |
--engine.rate(e.i,n) | |
if view == vREC then dirtygrid=true end | |
end | |
end | |
------ patterns | |
pattern = {} | |
for i=1,TRACKS do | |
pattern[i] = pattern_time.new() | |
pattern[i].process = event_exec | |
end | |
view = vREC | |
view_prev = view | |
v = {} | |
v.key = {} | |
v.enc = {} | |
v.redraw = {} | |
v.gridkey = {} | |
v.gridredraw = {} | |
viewinfo = {} | |
viewinfo[vREC] = 1 | |
viewinfo[vCUT] = 0 | |
viewinfo[vTIME] = 0 | |
focus = 1 | |
alt = 0 | |
track = {} | |
for i=1,TRACKS do | |
track[i] = {} | |
track[i].head = (i-1)%4+1 | |
track[i].play = 0 | |
track[i].rec = 0 | |
track[i].rec_level = 1 | |
track[i].pre_level = 0 | |
track[i].loop = 0 | |
track[i].loop_start = 0 | |
track[i].loop_end = 8 | |
track[i].clip = i | |
track[i].pos = 0 | |
track[i].pos_grid = -1 | |
track[i].speed = 0 | |
track[i].rev = 0 | |
track[i].tempo_map = 0 | |
end | |
set_clip_length = function(i, len) | |
clip[i].l = len | |
clip[i].e = clip[i].s + len | |
local bpm = 60 / len | |
while bpm < 60 do | |
bpm = bpm * 2 | |
print("bpm > "..bpm) | |
end | |
clip[i].bpm = bpm | |
end | |
clip_reset = function(i, length) | |
set_clip_length(i, length) | |
clip[i].name = "-" | |
end | |
clip = {} | |
for i=1,8 do | |
clip[i] = {} | |
clip[i].s = 2 + (i-1)*30 | |
clip[i].name = "-" | |
set_clip_length(i,4) | |
end | |
calc_quant = function(i) | |
local q = (clip[track[i].clip].l/16) | |
print("q > "..q) | |
return q | |
end | |
calc_quant_off = function(i, q) | |
local off = q | |
while off < clip[track[i].clip].s do | |
off = off + q | |
end | |
off = off - clip[track[i].clip].s | |
print("off > "..off) | |
return off | |
end | |
set_clip = function(i, x) | |
track[i].play = 0 | |
engine.stop(i) | |
track[i].clip = x | |
engine.loop_start(i,clip[track[i].clip].s) | |
engine.loop_end(i,clip[track[i].clip].e) | |
local q = calc_quant(i) | |
local off = calc_quant_off(i, q) | |
engine.quant(i,q) | |
engine.quant_offset(i,off) | |
track[i].loop = 0 | |
end | |
set_rec = function(n) | |
if track[n].rec == 1 then | |
engine.pre(n,track[n].pre_level) | |
engine.rec(n,track[n].rec_level) | |
else | |
engine.pre(n,1) | |
engine.rec(n,0) | |
end | |
end | |
held = {} | |
heldmax = {} | |
done = {} | |
first = {} | |
second = {} | |
for i = 1,8 do | |
held[i] = 0 | |
heldmax[i] = 0 | |
done[i] = 0 | |
first[i] = 0 | |
second[i] = 0 | |
end | |
key = function(n,z) _key(n,z) end | |
enc = function(n,d) | |
if n==1 then mix:delta("output",d) | |
else _enc(n,d) end | |
end | |
redraw = function() _redraw() end | |
g.event = function(x,y,z) _gridkey(x,y,z) end | |
set_view = function(x) | |
print("set view: "..x) | |
if x == -1 then x = view_prev end | |
view_prev = view | |
view = x | |
_key = v.key[x] | |
_enc = v.enc[x] | |
_redraw = v.redraw[x] | |
_gridkey = v.gridkey[x] | |
_gridredraw = v.gridredraw[x] | |
redraw() | |
dirtygrid=true | |
end | |
gridredraw = function() | |
if not g then return end | |
if dirtygrid == true then | |
_gridredraw() | |
dirtygrid = false | |
end | |
end | |
UP1 = controlspec.new(0, 1, 'lin', 0, 1, "") | |
BI1 = controlspec.new(-1, 1, 'lin', 0, 0, "") | |
-------------------- init | |
init = function() | |
params:add_option("midi_sync",{"off","on"}) | |
params:add_number("tempo",40,240,92) | |
params:set_action("tempo", function() update_tempo() end) | |
params:add_number("quant_div",1,32,4) | |
params:set_action("quant_div",function() update_tempo() end) | |
p = {} | |
for i=1,TRACKS do | |
engine.rec_on(i,1) -- always on!! | |
engine.pre(i,1) | |
engine.pre_lag(i,0.05) | |
engine.fade_pre(i,FADE) | |
engine.amp(i,1) | |
engine.rec(i,0) | |
engine.rec_lag(i,0.05) | |
engine.fade_rec(i,FADE) | |
engine.adc_rec(1,i,0.8) | |
engine.adc_rec(2,i,0.8) | |
engine.play_dac(i,1,1) | |
engine.play_dac(i,2,1) | |
engine.loop_start(i,clip[track[i].clip].s) | |
engine.loop_end(i,clip[track[i].clip].e) | |
engine.loop_on(i,1) | |
engine.quant(i,calc_quant(i)) | |
engine.fade_rec(i,0.1) | |
engine.fade(i,FADE) | |
engine.env_time(i,0.1) | |
engine.rate_lag(i,0) | |
--engine.reset(i) | |
p[i] = poll.set("phase_quant_"..i, function(x) phase(i,x) end) | |
p[i]:start() | |
params:add_control(i.."vol",UP1) | |
params:set_action(i.."vol", function(x) engine.amp(i,x) end) | |
--params:add_control(i.."pan",BI1) | |
--params:set_action(i.."pan", | |
--function(x) | |
--engine.play_dac(i,1,math.min(1,1+x)) | |
--engine.play_dac(i,2,math.min(1,1-x)) | |
--end) | |
params:add_control(i.."rec",UP1) | |
params:set_action(i.."rec", | |
function(x) | |
track[i].rec_level = x | |
set_rec(i) | |
end) | |
params:add_control(i.."pre",controlspec.UNIPOLAR) | |
params:set_action(i.."pre", | |
function(x) | |
track[i].pre_level = x | |
set_rec(i) | |
end) | |
params:add_control(i.."speed_mod", controlspec.BIPOLAR) | |
params:set_action(i.."speed_mod", function() update_rate(i) end) | |
end | |
quantizer = metro.alloc() | |
quantizer.time = 0.125 | |
quantizer.count = -1 | |
quantizer.callback = event_q_clock | |
quantizer:start() | |
--pattern_init() | |
set_view(vREC) | |
midiclocktimer = metro.alloc() | |
midiclocktimer.count = -1 | |
midiclocktimer.callback = function() | |
if midi_device and params:get("midi_sync")==2 then midi_device.send({248}) end | |
end | |
update_tempo() | |
midiclocktimer:start() | |
gridredrawtimer = metro.alloc(function() gridredraw() end, 0.02, -1) | |
gridredrawtimer:start() | |
dirtygrid = true | |
end | |
-- poll callback | |
phase = function(n, x) | |
--if n == 1 then print(x) end | |
local pp = ((x - clip[track[n].clip].s) / clip[track[n].clip].l)-- * 16 --TODO 16=div | |
--x = math.floor(track[n].pos*16) | |
--if n==1 then print("> "..x.." "..pp) end | |
x = math.floor(pp * 8) | |
if x ~= track[n].pos_grid then | |
track[n].pos_grid = x | |
if view == vCUT then dirtygrid=true end | |
end | |
end | |
update_rate = function(i) | |
local n = math.pow(2,track[i].speed + params:get(i.."speed_mod")) | |
if track[i].rev == 1 then n = -n end | |
if track[i].tempo_map == 1 then | |
local bpmmod = params:get("tempo") / clip[track[i].clip].bpm | |
--print("bpmmod: "..bpmmod) | |
n = n * bpmmod | |
end | |
engine.rate(i,n) | |
if view == vREC then redraw() end | |
end | |
gridkey_nav = function(x,z) | |
if z==1 then -- NAV ROW | |
if x==1 then | |
if alt == 1 then engine.clear() end | |
set_view(vREC) | |
elseif x==2 then set_view(vCUT) | |
elseif x==3 then set_view(vCLIP) | |
elseif x>4 and x <6 then -- PATTERNS | |
i = x - 3 | |
if alt == 1 then -- WITH ALT | |
pattern[i]:rec_stop() | |
pattern[i]:stop() | |
pattern[i]:clear() | |
elseif pattern[i].rec == 1 then -- WITH RECORD | |
pattern[i]:rec_stop() | |
pattern[i]:start() | |
elseif pattern[i].count == 0 then | |
pattern[i]:rec_start() | |
elseif pattern[i].play == 1 then -- WITH PLAY | |
pattern[i]:stop() | |
else pattern[i]:start() | |
end | |
elseif x==7 and alt == 0 then -- QUANT - NO ALT | |
quantize = 1 - quantize | |
if quantize == 0 then quantizer:stop() | |
else quantizer:start() | |
end | |
elseif x==7 and alt == 1 then -- QUANT - ALT | |
set_view(vTIME) | |
elseif x==16 then alt = 1 | |
end | |
elseif z==0 then | |
if x==8 then alt = 0 end -- PLAY | |
if x==7 and view == vTIME then set_view(-1) end -- SPEED? | |
end | |
dirtygrid=true | |
end | |
gridredraw_nav = function() | |
-- indicate view | |
g.led(view,1,15) | |
if alt==1 then g.led(8,1,9) end | |
if quantize==1 then g.led(7,1,9) end | |
for i=1,3 do | |
if pattern[i].rec == 1 then g.led(i+4,1,15) | |
elseif pattern[i].play == 1 then g.led(i+4,1,9) | |
elseif pattern[i].count > 0 then g.led(i+4,1,5) | |
else g.led(i+4,1,3) end | |
end | |
end | |
-------------------- REC | |
v.key[vREC] = function(n,z) | |
if n==2 and z==1 then | |
viewinfo[vREC] = 1 - viewinfo[vREC] | |
redraw() | |
end | |
end | |
v.enc[vREC] = function(n,d) | |
if viewinfo[vREC] == 0 then | |
if n==2 then | |
params:delta(focus.."vol",d) | |
elseif n==3 then | |
params:delta(focus.."speed_mod",d) | |
end | |
else | |
if n==2 then | |
params:delta(focus.."rec",d) | |
elseif n==3 then | |
params:delta(focus.."pre",d) | |
end | |
end | |
redraw() | |
end | |
v.redraw[vREC] = function() | |
screen.clear() | |
screen.level(15) | |
screen.move(10,16) | |
screen.text("REC > "..focus) | |
local sel = viewinfo[vREC] == 0 | |
screen.level(sel and 15 or 4) | |
screen.move(10,32) | |
screen.text(params:string(focus.."vol")) | |
screen.move(70,32) | |
screen.text(params:string(focus.."speed_mod")) | |
screen.level(3) | |
screen.move(10,40) | |
screen.text("volume") | |
screen.move(70,40) | |
screen.text("speed mod") | |
screen.level(not sel and 15 or 4) | |
screen.move(10,52) | |
screen.text(params:string(focus.."rec")) | |
screen.move(70,52) | |
screen.text(params:string(focus.."pre")) | |
screen.level(3) | |
screen.move(10,60) | |
screen.text("rec level") | |
screen.move(70,60) | |
screen.text("overdub") | |
screen.update() | |
end | |
v.gridkey[vREC] = function(x, y, z) | |
if y == 1 then gridkey_nav(x,z) | |
else | |
if z == 1 then | |
i = y-1 | |
if x>1 and x<4 then -- FOCUS | |
if alt == 1 then | |
track[i].tempo_map = 1 - track[i].tempo_map | |
update_rate(i) | |
elseif focus ~= i then | |
focus = i | |
redraw() | |
end | |
elseif x==1 and y<TRACKS+2 then | |
track[i].rec = 1 - track[i].rec | |
print("REC "..track[i].rec) | |
set_rec(i) | |
elseif x==8 and y<TRACKS+2 then | |
if track[i].play == 1 then | |
e = {} | |
e.t = eSTOP | |
e.i = i | |
event(e) | |
else | |
e = {} | |
e.t = eSTART | |
e.i = i | |
event(e) | |
end | |
elseif x>4 and x<8 and y<TRACKS+2 then -- SPEED? | |
local n = x-6 | |
e = {} e.t = eSPEED e.i = i e.speed = n | |
event(e) | |
elseif x==4 and y<TRACKS+2 then -- REV | |
local n = 1 - track[i].rev | |
e = {} e.t = eREV e.i = i e.rev = n | |
event(e) | |
end | |
dirtygrid=true | |
end | |
end | |
end | |
v.gridredraw[vREC] = function() | |
g.all(0) | |
g.led(2,focus+1,7) | |
g.led(3,focus+1,7) | |
for i=1,TRACKS do | |
local y = i+1 | |
g.led(1,y,3)--rec | |
if track[i].rec == 1 then g.led(1,y,9) end | |
if track[i].tempo_map == 1 then g.led(5,y,7) end -- tempo.map | |
g.led(4,y,3)--rev | |
g.led(8,y,3)--stop | |
g.led(6,y,3)--speed=1 | |
g.led(6+track[i].speed,y,9) | |
if track[i].rev == 1 then g.led(4,y,7) end | |
if track[i].play == 1 then g.led(8,y,15) end | |
end | |
gridredraw_nav() | |
g.refresh(); | |
end | |
--------------------CUT | |
v.key[vCUT] = function(n,z) | |
print("CUT key") | |
end | |
v.enc[vCUT] = function(n,d) | |
if n==2 then | |
params:delta(focus.."vol",d) | |
end | |
redraw() | |
end | |
v.redraw[vCUT] = function() | |
screen.clear() | |
screen.level(15) | |
screen.move(10,16) | |
screen.text("CUT > "..focus) | |
if viewinfo[vCUT] == 0 then | |
screen.move(10,32) | |
screen.text(params:string(focus.."vol")) | |
--screen.move(70,50) | |
--screen.text(params:get("loop_mod"..focus)) | |
screen.level(3) | |
screen.move(10,40) | |
screen.text("volume") | |
--screen.move(70,60) | |
--screen.text("speed mod") | |
else | |
screen.move(10,50) | |
screen.text(params:get(focus.."rec")) | |
screen.move(70,50) | |
screen.text(params:get(focus.."pre")) | |
screen.level(3) | |
screen.move(10,60) | |
screen.text("rec level") | |
screen.move(70,60) | |
screen.text("overdub") | |
end | |
screen.update() | |
end | |
v.gridkey[vCUT] = function(x, y, z) | |
if z==1 and held[y] then heldmax[y] = 0 end | |
held[y] = held[y] + (z*2-1) | |
if held[y] > heldmax[y] then heldmax[y] = held[y] end | |
--print(held[y]) | |
if y == 1 then gridkey_nav(x,z) | |
else | |
i = y-1 | |
if z == 1 then | |
if focus ~= i then | |
focus = i | |
redraw() | |
end | |
if alt == 1 and y<TRACKS+2 then | |
if track[i].play == 1 then | |
e = {} e.t = eSTOP e.i = i | |
else | |
e = {} e.t = eSTART e.i = i | |
end | |
event(e) | |
elseif y<TRACKS+2 and held[y]==1 then | |
first[y] = x | |
local cut = x-1 | |
--print("pos > "..cut) | |
e = {} e.t = eCUT e.i = i e.pos = cut | |
event(e) | |
elseif y<TRACKS+2 and held[y]==2 then | |
second[y] = x | |
end | |
elseif z==0 then | |
if y<TRACKS+2 and held[y] == 1 and heldmax[y]==2 then | |
e = {} | |
e.t = eLOOP | |
e.i = i | |
e.loop = 1 | |
e.loop_start = math.min(first[y],second[y]) | |
e.loop_end = math.max(first[y],second[y]) | |
event(e) | |
end | |
end | |
end | |
end | |
v.gridredraw[vCUT] = function() | |
g.all(0) | |
gridredraw_nav() | |
for i=1,TRACKS do | |
if track[i].loop == 1 then | |
for x=track[i].loop_start,track[i].loop_end do | |
g.led(x,i+1,4) | |
end | |
end | |
if track[i].play == 1 then | |
g.led((track[i].pos_grid+1)%8+1, i+1, 15) | |
--print ((track[i].pos_grid+1)%8+1) | |
end | |
end | |
g:refresh(); | |
end | |
--------------------CLIP | |
clip_sel = 1 | |
clip_clear_mult = 3 | |
function fileselect_callback(path) | |
if path ~= "cancel" then | |
if path:find(".aif") or path:find(".wav") then | |
print("file > "..path.." "..clip[track[clip_sel].clip].s) | |
engine.read(path, clip[track[clip_sel].clip].s, 16) -- FIXME 16 seconds to load | |
local ch, len = sound_file_inspect(path) | |
print("file length > "..len) | |
set_clip_length(track[clip_sel].clip, len/48000) | |
clip[track[clip_sel].clip].name = path:match("[^/]*$") | |
set_clip(clip_sel,track[clip_sel].clip) | |
update_rate(clip_sel) | |
else | |
print("not a sound file") | |
end | |
-- TODO re-set_clip any tracks with this clip loaded | |
redraw() | |
end | |
end | |
v.key[vCLIP] = function(n,z) | |
if n==2 and z==0 then | |
fileselect.enter(os.getenv("HOME").."/dust/audio", fileselect_callback) | |
elseif n==3 and z==1 then | |
clip_reset(clip_sel,60/params:get("tempo")*(2^(clip_clear_mult-2))) | |
set_clip(clip_sel,track[clip_sel].clip) | |
update_rate(clip_sel) | |
end | |
end | |
v.enc[vCLIP] = function(n,d) | |
if n==2 then | |
clip_sel = util.clamp(clip_sel-d,1,TRACKS) | |
elseif n==3 then | |
clip_clear_mult = util.clamp(clip_clear_mult+d,1,6) | |
end | |
redraw() | |
dirtygrid=true | |
end | |
local function truncateMiddle (str, maxLength, separator) | |
maxLength = maxLength or 30 | |
separator = separator or "..." | |
if (maxLength < 1) then return str end | |
if (string.len(str) <= maxLength) then return str end | |
if (maxLength == 1) then return string.sub(str, 1, 1) .. separator end | |
midpoint = math.ceil(string.len(str) / 2) | |
toremove = string.len(str) - maxLength | |
lstrip = math.ceil(toremove / 2) | |
rstrip = toremove - lstrip | |
return string.sub(str, 1, midpoint - lstrip) .. separator .. string.sub(str, 1 + midpoint + rstrip) | |
end | |
v.redraw[vCLIP] = function() | |
screen.clear() | |
screen.level(15) | |
screen.move(10,30) | |
screen.text("CLIP > "..clip_sel) | |
screen.move(10,50) | |
screen.text(truncateMiddle(clip[track[clip_sel].clip].name, 18)) | |
screen.level(3) | |
screen.move(10,60) | |
screen.text("name "..track[clip_sel].clip) | |
screen.move(100,50) | |
screen.text(2^(clip_clear_mult-2)) | |
screen.level(3) | |
screen.move(100,60) | |
screen.text("resize") | |
screen.update() | |
end | |
v.gridkey[vCLIP] = function(x, y, z) | |
if y == 1 then gridkey_nav(x,z) | |
elseif z == 1 and y < TRACKS+2 then | |
clip_sel = y-1 | |
set_clip(clip_sel,x) | |
redraw() | |
dirtygrid=true | |
end | |
end | |
v.gridredraw[vCLIP] = function() | |
g.all(0) | |
gridredraw_nav() | |
for i=1,8 do g.led(i,clip_sel+1,4) end | |
for i=1,TRACKS do g.led(track[i].clip,i+1,10) end | |
g:refresh(); | |
end | |
--------------------TIME | |
v.key[vTIME] = function(n,z) | |
print("TIME key") | |
end | |
v.enc[vTIME] = function(n,d) | |
if n==2 then | |
params:delta("tempo",d) | |
elseif n==3 then | |
params:delta("quant_div",d) | |
end | |
redraw() | |
end | |
v.redraw[vTIME] = function() | |
screen.clear() | |
screen.level(15) | |
screen.move(10,30) | |
screen.text("TIME") | |
if viewinfo[vTIME] == 0 then | |
screen.move(10,50) | |
screen.text(params:get("tempo")) | |
screen.move(70,50) | |
screen.text(params:get("quant_div")) | |
screen.level(3) | |
screen.move(10,60) | |
screen.text("tempo") | |
screen.move(70,60) | |
screen.text("quant div") | |
end | |
screen.update() | |
end | |
v.gridkey[vTIME] = function(x, y, z) | |
if y == 1 then gridkey_nav(x,z) end | |
end | |
v.gridredraw[vTIME] = function() | |
g.all(0) | |
gridredraw_nav() | |
g:refresh(); | |
end | |
function cleanup() | |
for i=1,4 do | |
pattern[i]:stop() | |
pattern[i] = nil | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment