Skip to content

Instantly share code, notes, and snippets.

@jlmitch5
Created July 9, 2018 03:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlmitch5/e44284e285c183a801419660271f30ac to your computer and use it in GitHub Desktop.
Save jlmitch5/e44284e285c183a801419660271f30ac to your computer and use it in GitHub Desktop.
seaaaaa
-- seaaaaa with no screen
--
-- subtractive polysynth with 5 patterns
-- controlled by midi or grid
--
-- grid pattern player:
-- 1 1 record toggle
-- 1 2 play toggle
-- 1 3-7 pattern selectors
-- 1 8 transpose mode
local tab = require 'tabutil'
local pattern_time = require 'pattern_time'
local selectedPattern = 1
local mode_transpose = {0, 0, 0, 0, 0}
local root = {{ x=5, y=5 }, { x=5, y=5 }, { x=5, y=5 }, { x=5, y=5 }, { x=5, y=5 }}
local trans = {{ x=5, y=5 }, { x=5, y=5 }, { x=5, y=5 }, { x=5, y=5 }, { x=5, y=5 }}
local lit = {{}, {}, {}, {}, {}}
engine.name = 'PolySub'
-- pythagorean minor/major, kinda
local ratios = { 1, 9/8, 6/5, 5/4, 4/3, 3/2, 27/16, 16/9 }
local base = 27.5 -- low A
local function getHz(deg,oct)
return base * ratios[deg] * (2^oct)
end
local function getHzET(note)
return 55*2^(note/12)
end
-- current count of active voices
local nvoices = {0, 0, 0, 0, 0}
function init()
pat = {pattern_time.new(), pattern_time.new(), pattern_time.new(), pattern_time.new(), pattern_time.new()}
pat[1].process = grid_note_trans
pat[2].process = grid_note_trans
pat[3].process = grid_note_trans
pat[4].process = grid_note_trans
pat[5].process = grid_note_trans
params:add_control("shape", controlspec.new(0,1,"lin",0,0,""))
params:set_action("shape", function(x) engine.shape(x) end)
params:add_control("timbre", controlspec.new(0,1,"lin",0,0.5,""))
params:set_action("timbre", function(x) engine.timbre(x) end)
params:add_control("noise", controlspec.new(0,1,"lin",0,0,""))
params:set_action("noise", function(x) engine.noise(x) end)
params:add_control("cut", controlspec.new(0,32,"lin",0,8,""))
params:set_action("cut", function(x) engine.cut(x) end)
params:add_control("fgain", controlspec.new(0,6,"lin",0,0,""))
params:set_action("fgain", function(x) engine.fgain(x) end)
params:add_control("cutEnvAmt", controlspec.new(0,1,"lin",0,0,""))
params:set_action("cutEnvAmt", function(x) engine.cutEnvAmt(x) end)
params:add_control("detune", controlspec.new(0,1,"lin",0,0,""))
params:set_action("detune", function(x) engine.detune(x) end)
params:add_control("ampAtk", controlspec.new(0.01,10,"lin",0,0.05,""))
params:set_action("ampAtk", function(x) engine.ampAtk(x) end)
params:add_control("ampDec", controlspec.new(0,2,"lin",0,0.1,""))
params:set_action("ampDec", function(x) engine.ampDec(x) end)
params:add_control("ampSus", controlspec.new(0,1,"lin",0,1,""))
params:set_action("ampSus", function(x) engine.ampSus(x) end)
params:add_control("ampRel", controlspec.new(0.01,10,"lin",0,1,""))
params:set_action("ampRel", function(x) engine.ampRel(x) end)
params:add_control("cutAtk", controlspec.new(0.01,10,"lin",0,0.05,""))
params:set_action("cutAtk", function(x) engine.cutAtk(x) end)
params:add_control("cutDec", controlspec.new(0,2,"lin",0,0.1,""))
params:set_action("cutDec", function(x) engine.cutDec(x) end)
params:add_control("cutSus", controlspec.new(0,1,"lin",0,1,""))
params:set_action("cutSus", function(x) engine.cutSus(x) end)
params:add_control("cutRel", controlspec.new(0.01,10,"lin",0,1,""))
params:set_action("cutRel", function(x) engine.cutRel(x) end)
engine.level(0.05)
engine.stopAll()
params:read("tehn/earthsea.pset")
params:bang()
if g then gridredraw() end
end
function gridkey(x, y, z)
if x == 1 then
if z == 1 then
if y == 1 and pat[selectedPattern].rec == 0 then
mode_transpose[selectedPattern] = 0
trans[selectedPattern].x = 5
trans[selectedPattern].y = 5
pat[selectedPattern]:stop()
pat[selectedPattern]:clear()
pat[selectedPattern]:rec_start()
elseif y == 1 and pat[selectedPattern].rec == 1 then
pat[selectedPattern]:rec_stop()
if pat[selectedPattern].count > 0 then
root[selectedPattern].x = pat[selectedPattern].event[1].x
root[selectedPattern].y = pat[selectedPattern].event[1].y
trans[selectedPattern].x = root[selectedPattern].x
trans[selectedPattern].y = root[selectedPattern].y
pat[selectedPattern]:start()
end
elseif y == 2 and pat[selectedPattern].play == 0 and pat[selectedPattern].count > 0 then
if pat[selectedPattern].rec == 1 then
pat[selectedPattern]:rec_stop()
end
pat[selectedPattern]:start()
elseif y == 2 and pat[selectedPattern].play == 1 then
pat[selectedPattern]:stop()
nvoices[selectedPattern] = 0
lit[selectedPattern] = {}
elseif y >= 3 and y <= 7 then
selectedPattern = y - 2
elseif y == 8 then
mode_transpose[selectedPattern] = 1 - mode_transpose[selectedPattern]
end
end
else
if mode_transpose[selectedPattern] == 0 then
local e = {}
e.id = x*8 + y
e.x = x
e.y = y
e.state = z
e.selectedPattern = selectedPattern
pat[selectedPattern]:watch(e)
grid_note(e)
else
trans[selectedPattern].x = x
trans[selectedPattern].y = y
end
end
gridredraw()
end
function grid_note(e)
local note = ((7-e.y)*5) + e.x
if e.state > 0 then
if nvoices[selectedPattern] < 6 then
engine.start(e.id, getHzET(note))
lit[selectedPattern][e.id] = {}
lit[selectedPattern][e.id].x = e.x
lit[selectedPattern][e.id].y = e.y
nvoices[selectedPattern] = nvoices[selectedPattern] + 1
end
else
if lit[selectedPattern][e.id] ~= nil then
engine.stop(e.id)
lit[selectedPattern][e.id] = nil
nvoices[selectedPattern] = nvoices[selectedPattern] - 1
end
end
gridredraw()
end
function grid_note_trans(e)
local note = ((7-e.y+(root[e.selectedPattern].y-trans[e.selectedPattern].y))*5) + e.x + (trans[e.selectedPattern].x-root[e.selectedPattern].x)
if e.state > 0 then
if nvoices[e.selectedPattern] < 6 then
engine.start(e.id, getHzET(note))
lit[e.selectedPattern][e.id] = {}
lit[e.selectedPattern][e.id].x = e.x + trans[e.selectedPattern].x - root[e.selectedPattern].x
lit[e.selectedPattern][e.id].y = e.y + trans[e.selectedPattern].y - root[selectedPattern].y
nvoices[e.selectedPattern] = nvoices[e.selectedPattern] + 1
end
else
engine.stop(e.id)
lit[e.selectedPattern][e.id] = nil
nvoices[e.selectedPattern] = nvoices[e.selectedPattern] - 1
end
gridredraw()
end
function gridredraw()
g:all(0)
g:led(1,1,2 + pat[selectedPattern].rec * 10)
g:led(1,2,2 + pat[selectedPattern].play * 10)
for y=3,7 do
if selectedPattern + 2 == y then
g:led(1,y,12)
end
end
g:led(1,8,2 + mode_transpose[selectedPattern] * 10)
if mode_transpose[selectedPattern] == 1 then g:led(trans[selectedPattern].x, trans[selectedPattern].y, 4) end
for i,e in pairs(lit[selectedPattern]) do
g:led(e.x, e.y,15)
end
g:refresh()
end
function cleanup()
stop_all_screen_notes()
pat[1]:stop()
pat[2]:stop()
pat[3]:stop()
pat[4]:stop()
pat[5]:stop()
pat[1] = nil
pat[2] = nil
pat[3] = nil
pat[4] = nil
pat[5] = nil
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment