EDIT: thanks @xmacex simple solution is below. I’d like to add that this whole approach should be easy to implement with any midi to cv converter as long as you can dedicate outputs to cc channels.
Hi all,
I’m scripting a trigger sequencer so I can use norns on some of my percussion modules and the bare bones are done.
The way I’m creating the triggers is by setting my cv outputs on my midi > cv modules to dedicated cc channels and scripting the cc amount to be 127 wait a fraction of a second and then be 0
trigger code
function trigon()
poly2:cc(1,127,1)
clock.run(trigoff)
end
end
function trigoff()
clock.sleep(0.05)
poly2:cc(1,0,1)
end
The code above is the simplest way I could send the cc high, wait, and then low again. To incorporate it into my sequence I simply insert a value into the function via function trigon(t) and if t = 1 (a step in the sequence is on) the function runs. This is all works smooth as butter when there is only one sequence track running but, the moment I change this function to include the cc channel it should be sending to the whole script crashes the moment I hit a trigger.
faulty trigger code
function trigon(ch,t)
if t == 1 then
poly2:cc(ch,127,1)
clock.run(trigoff(ch))
end
end
function trigoff(ch)
clock.sleep(0.05)
poly2:cc(ch,0,1)
end
The specific line I suspect to be the problem here is “clock.run(trigoff(ch))”.
Any advice as to why I’m encountering this problem, or if there is a different way I could handle the wait to turn my triggers off?
maiden
lua: /home/we/norns/lua/core/clock.lua:82: /home/we/norns/lua/core/clock.lua:19: bad argument #1 to ‘create’ (function expected, got nil)
stack traceback:
[C]: in function ‘error’
/home/we/norns/lua/core/clock.lua:82: in function ‘core/clock.resume’
Full code. only channel 1 working
include(‘midigrid/config/launchpadmini_config’)
include(‘midigrid/lib/midigrid’)
local grid = include(‘midigrid/lib/mg_128’)
g = grid.connect()
function go()
norns.script.load(norns.state.script)
end
– declare variables
steps = {}
–going to change stepcount into nested table so each track can have different sequence lengths
stepcount = 8
position = 1
channel = {1,2,3,4}
x_pos = 1
y_pos = 1
pressed = 1
pad = {
{1,5,9 ,13},
{2,6,10,14},
{3,7,11,15},
{4,8,12,16}
}
– for new clock system
function pulse()
while true do
clock.sync(1/4)
count()
end
end
function clock.transport.stop()
clock.cancel(clock_id)
end
function clock.transport.start()
clock_id = clock.run(pulse)
end
function init()
clock.transport.start()
poly2 = midi.connect(1)
g:all(0)
– default all trigger sequences to 0
for track=1,stepcount do
steps[track] = {}
for step=1,16 do
steps[track][step] = 0
end
end
grid_redraw()
position = 1
end
g.key = function(x,y,z)
– ignore as trigon has changed since implementing the sequencer to be fixed
if z == 1 and x <= 4 and y <= 4 then
x_pos = x
y_pos = y
pressed = pad[x_pos][y_pos]
print (pressed)
trigon()
– switches a steps state on or off // ofsets to use bottom four rows on grids
elseif z == 1 and y >= 5 then
if steps[channel[y-4]][x] == 0 or nil then
steps[channel[y-4]][x] = 1
else
steps[channel[y-4]][x] = steps[channel[y-4]][x] - steps[channel[y-4]][x]
end
print(“ch: " …y-4 …” step “…x…”: "… steps[channel[y-4]][x])
grid_redraw()
end
end
– uses midi cc to create a trigger // currently only triggering on channel 1 for testing
function trigon(t)
if t == 1 then
poly2:cc(1,127,1)
clock.run(trigoff)
end
end
function trigoff()
clock.sleep(0.05)
poly2:cc(1,0,1)
end
function draw_active()
for track = 1,4 do
for step = 1, stepcount do
g:led(step,track+4,steps[track][step])
g:refresh()
end
end
end
function draw_step()
for track = 1,4 do
g:led(position,track+4,15)
end
end
function grid_redraw()
g:all(0)
draw_active()
draw_step()
g:refresh()
end
function count()
g:refresh()
– itterates through steps and sends a trigger if steps =1 // currently only triggering on channel 1 for testing
position = (position % stepcount) + 1
trigon(steps[1][position])
grid_redraw()
end
function cleanup ()
clock.cancel(clock_id)
end
full code faulty
include(‘midigrid/config/launchpadmini_config’)
include(‘midigrid/lib/midigrid’)
local grid = include(‘midigrid/lib/mg_128’)
g = grid.connect()
function go()
norns.script.load(norns.state.script)
end
– declare variables
steps = {}
–going to change stepcount into nested table so each track can have different sequence lengths
stepcount = 8
position = 1
channel = {1,2,3,4}
x_pos = 1
y_pos = 1
pressed = 1
pad = {
{1,5,9 ,13},
{2,6,10,14},
{3,7,11,15},
{4,8,12,16}
}
– for new clock system
function pulse()
while true do
clock.sync(1/4)
count()
end
end
function clock.transport.stop()
clock.cancel(clock_id)
end
function clock.transport.start()
clock_id = clock.run(pulse)
end
function init()
clock.transport.start()
poly2 = midi.connect(1)
g:all(0)
– default all trigger sequences to 0
for track=1,stepcount do
steps[track] = {}
for step=1,16 do
steps[track][step] = 0
end
end
grid_redraw()
position = 1
end
g.key = function(x,y,z)
– ignore as trigon has changed since implementing the sequencer to be fixed
if z == 1 and x <= 4 and y <= 4 then
x_pos = x
y_pos = y
pressed = pad[x_pos][y_pos]
print (pressed)
trigon()
– switches a steps state on or off // ofsets to use bottom four rows on grids
elseif z == 1 and y >= 5 then
if steps[channel[y-4]][x] == 0 or nil then
steps[channel[y-4]][x] = 1
else
steps[channel[y-4]][x] = steps[channel[y-4]][x] - steps[channel[y-4]][x]
end
print(“ch: " …y-4 …” step “…x…”: "… steps[channel[y-4]][x])
grid_redraw()
end
end
– uses midi cc to create a trigger // currently only triggering on channel 1 for testing
function trigon(ch,t)
if t == 1 then
poly2:cc(ch,127,1)
clock.run(trigoff(ch))
end
end
function trigoff(ch)
clock.sleep(0.05)
poly2:cc(ch,0,1)
end
function draw_active()
for track = 1,4 do
for step = 1, stepcount do
g:led(step,track+4,steps[track][step])
g:refresh()
end
end
end
function draw_step()
for track = 1,4 do
g:led(position,track+4,15)
end
end
function grid_redraw()
g:all(0)
draw_active()
draw_step()
g:refresh()
end
function count()
g:refresh()
– itterates through steps and sends a trigger if steps =1 // currently only triggering on channel 1 for testing
position = (position % stepcount) + 1
for ch = 1,4 do
trigon(ch,steps[1][position])
end
grid_redraw()
end
function cleanup ()
clock.cancel(clock_id)
end