page.layout: post
page.title: Sequins
page.date: 2021-07-17 00:00:00 +0000
page.url ⛓️: /2021/07/17/1-sequins/
page.content_id: 12
page.author: Tyler
page.type: Praxis
page.ascii: ^
page.x: 3
page.y: 11
page.class: black
page.attributes: crow, sequins

Both crow and norns use Lua. sequins is a new feature in crow 3.0 that I find very exciting. Today I’m going to port it over to norns.

First step is to review the existing code here: https://github.com/monome/crow/blob/main/lua/sequins.lua. At first glance it appears as though it can be straight up copy-pasta’d. Let’s try it…

Turns out the code works without any changes whatsoever.

Here’s a sequin(ce) you can use:

s{
  s{0,12,0,0},
  s{1,2,2,4,2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,2,10,2,6,6,4,6,6,2,10,2,4,2,12,12,4,2,4,6,2,10,6,6,6,2,6,4,2,10,14,4,2,4,14,6,10,2,4,6,8,6,6,4,6,8,4,8,10,2,10,2,6,4,6,8,4,2,4,12,8,4,8,4,6,12}:step(s{3,5,7}),
  s{0,0,12,0},
  s{0,0,1,0,2,1,3,0,4,2,5,1,6,3,7,0,8,4,9,2,10,5,11,1,12,6,13,3,14,7,15,0,16,8,17,4,18,9,19,2,20,10,21,5,22,11,23,1,24,12,25,6,26,13,27,3,28,14,29,7,30,15,31,0,32,16,33,8,34,17,35,4,36,18,37,9,38,19,39,2,40,20,41,10}:step(1,2,3),
  s{0,0,0,12},
  s{0,1,1,1,1,0,1,1,1,2,0,1,1,1,1,1,0,0,1,1,1,0,0,1,1,0,1,3,0,1,1,1,0,0,0,1,1,0,1,1,0,1,1,0,1,0,0,2,2,0,1,1,0,1,1,3,1,0,0,2,1,0,1,2,0,0,1,0,0,0,0,2,1,0,1,1,0,0,1,0,3,0,0,6,0,0,0,0,0,0,4,0,1,0,0,3,1,0,0,1,0,1,1,1,0,0,0,3,1,3,1,3,0,0,0,0,2,0,0,3,1,0,0,1,1,0,1,4,1,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,0,0,2,1,0,0,1}:step(13,15,16),
  s{12,0,0,0},
  0,
  3,
  7,
  0,
  3,
  s{7,5},
  0,
  3,
  s{5,7},
}

It is based on these data sets:


At some point in the future sequins may be merged into the norns core. Until then, you can copy and paste this file directly into a norns script and it will work just fine.

Then invoke like this:

-- copy and pasted sequins code from link above goes here

-- then something like this:

lattice = require "lattice"
MusicUtil = require "musicutil"

engine.name = "PolyPerc"

payload = s{
  s{0,12,0,0},
  s{1,2,2,4,2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,2,10,2,6,6,4,6,6,2,10,2,4,2,12,12,4,2,4,6,2,10,6,6,6,2,6,4,2,10,14,4,2,4,14,6,10,2,4,6,8,6,6,4,6,8,4,8,10,2,10,2,6,4,6,8,4,2,4,12,8,4,8,4,6,12}:step(s{3,5,7}),
  s{0,0,12,0},
  s{0,0,1,0,2,1,3,0,4,2,5,1,6,3,7,0,8,4,9,2,10,5,11,1,12,6,13,3,14,7,15,0,16,8,17,4,18,9,19,2,20,10,21,5,22,11,23,1,24,12,25,6,26,13,27,3,28,14,29,7,30,15,31,0,32,16,33,8,34,17,35,4,36,18,37,9,38,19,39,2,40,20,41,10}:step(1,2,3),
  s{0,0,0,12},
  s{0,1,1,1,1,0,1,1,1,2,0,1,1,1,1,1,0,0,1,1,1,0,0,1,1,0,1,3,0,1,1,1,0,0,0,1,1,0,1,1,0,1,1,0,1,0,0,2,2,0,1,1,0,1,1,3,1,0,0,2,1,0,1,2,0,0,1,0,0,0,0,2,1,0,1,1,0,0,1,0,3,0,0,6,0,0,0,0,0,0,4,0,1,0,0,3,1,0,0,1,0,1,1,1,0,0,0,3,1,3,1,3,0,0,0,0,2,0,0,3,1,0,0,1,1,0,1,4,1,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,0,0,2,1,0,0,1}:step(13,15,16),
  s{12,0,0,0},
  0,
  3,
  7,
  0,
  3,
  s{7,5},
  0,
  3,
  s{5,7},
}


function init()
  current = ""
  offset = 60
  is_screen_dirty = true
  ticks = 0
  draw_loop_id = clock.run(draw_loop)
  aaa_lattice = lattice:new()
  aaa_lattice:new_pattern{
    action = function(t) event(t) end,
    division = 1/4,
    enabled = true
  }
  aaa_lattice:start()
end

function event()
  ticks = ticks + 1
  current = payload()
  engine.hz(MusicUtil.note_num_to_freq(current + offset))
  is_screen_dirty = true
end

function redraw()
  screen.clear()
  screen.level(15)
  screen.font_size(8)
  screen.font_face(1)
  screen.move(10, 10)
  screen.text("T = " .. ticks)
  screen.move(10, 20)
  screen.text("SEQUINS = " .. current)
  screen.move(10, 30)
  screen.text("NOTE = " .. MusicUtil.note_num_to_freq(current + offset))
  screen.update()
end

function draw_loop()
  while true do
    check_screen()
    clock.sleep(1 / 15)
  end
end

function check_screen()
  if is_screen_dirty then
    redraw()
    is_screen_dirty = false
  end
end

function rerun()
  norns.script.load(norns.state.script)
end

function r()
  rerun()
end