Created
March 9, 2019 10:02
-
-
Save phonk/7fe45b5a6e8e6b63851011bf9c15929e to your computer and use it in GitHub Desktop.
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
-- kayan: probabalistic | |
-- melody discovery | |
-- | |
-- ENC2 = reveal melody | |
-- KEY2 = discover new melody | |
-- | |
-- support your local | |
-- rainforest | |
-- | |
-- created by @burn | |
engine.name = 'KarplusRings' | |
local cs = require 'controlspec' | |
local sequence = { | |
pos = 0, | |
note_data = {}, | |
prob_data = {} | |
} | |
local reveal_level = 35; | |
local octave_range = 2; | |
local transpose = 2; | |
local seq_length = 32; | |
local scale_data = {}; | |
local animation_counter = 0; | |
local animation_flipflop = true; | |
local pluck_distance = 0; | |
function init() | |
params:add_number("tempo", "tempo", 20, 240, 48) | |
params:set_action("tempo", function(n) | |
t.time = 15/n | |
end) | |
params:add_number("length", "length", 4, 64, 32) | |
params:set_action("length", function(n) | |
seq_length = n; | |
end) | |
params:add_number("transpose", "transpose", 0, 5, 2) | |
params:set_action("transpose", function(n) | |
transpose = n; | |
end) | |
params:add_number("octave_range", "octave_range", 1, 4, 2) | |
params:set_action("octave_range", function(n) | |
octave_range = n; | |
end) | |
params:add_separator() | |
cs.AMP = cs.new(0,1,'lin',0,0.5,'') | |
params:add_control("amp", "amp", cs.AMP) | |
params:set_action("amp", | |
function(x) engine.amp(x) end) | |
cs.DECAY = cs.new(0.1,15,'lin',0,3.6,'s') | |
params:add_control("damping", "damping", cs.DECAY) | |
params:set_action("damping", | |
function(x) engine.decay(x) end) | |
cs.COEF = cs.new(0,1,'lin',0,0.11,'') | |
params:add_control("brightness", "brightness", cs.COEF) | |
params:set_action("brightness", | |
function(x) engine.coef(x) end) | |
cs.LPF_FREQ = cs.new(100,10000,'lin',0,4500,'') | |
params:add_control("lpf_freq", "lpf_freq", cs.LPF_FREQ) | |
params:set_action("lpf_freq", | |
function(x) engine.lpf_freq(x) end) | |
cs.LPF_GAIN = cs.new(0,3.2,'lin',0,0.5,'') | |
params:add_control("lpf_gain", "lpf_gain", cs.LPF_GAIN) | |
params:set_action("lpf_gain", | |
function(x) engine.lpf_gain(x) end) | |
cs.BPF_FREQ = cs.new(100,10000,'lin',0,0.5,'') | |
params:add_control("bpf_freq", "bpf_freq", cs.BPF_FREQ) | |
params:set_action("bpf_freq", | |
function(x) engine.bpf_freq(x) end) | |
cs.BPF_RES = cs.new(0,4,'lin',0,0.5,'') | |
params:add_control("bpf_res", "bpf_res", cs.BPF_RES) | |
params:set_action("bpf_res", | |
function(x) engine.bpf_res(x) end) | |
create_scale_data(); | |
create_sequence_data(); | |
create_playloop_metro() | |
create_animation_metro() | |
params:bang() | |
end | |
function create_scale_data() | |
-- want a custom scale? define it here. | |
scale = {0,2,3,5,7,10} | |
scale_data = {} | |
-- copy the scale over 4 octaves | |
for octave=0,3 do | |
for scale_note = 1,#scale do | |
if scale[scale_note] > 11 then error("Note values must be between 0 and 11 inclusive") end | |
table.insert(scale_data, (scale[scale_note]+(octave*12))) | |
end | |
end | |
-- scale_data = {0,2,3,5,7,10,12,14,15,17,19,22,24,26,27,29,31,34,36,38,39,41,43,46} | |
end | |
-- create all of the note and probability data on init | |
function create_sequence_data() | |
for i=1, 64 do | |
sequence.note_data[i] = scale_data[math.random (1, #scale_data)]; | |
sequence.prob_data[i] = math.random (1, 100); | |
end | |
end | |
function create_playloop_metro() | |
t = metro.init() | |
t.count = -1 | |
t.time = 15/params:get("tempo") | |
t.event = function(stage) | |
sequence.pos = sequence.pos + 1 | |
if sequence.pos > seq_length then sequence.pos = 1 end | |
-- does the note playing | |
if sequence.prob_data[sequence.pos] <= reveal_level then | |
animation_counter = 30; | |
engine.hz((55*2^(((transpose * 12)+(sequence.note_data[sequence.pos] % (octave_range*12)))/12))) | |
end | |
end | |
t:start() | |
end | |
function create_animation_metro() | |
x = metro.init() | |
x.event = function(stage) | |
if norns.menu.status() == false then draw_screen() end | |
end | |
x:start(0.0224) | |
end | |
function key(n, z) | |
if n == 2 and z == 0 then | |
create_sequence_data(); | |
end | |
end | |
function enc(n, delta) | |
if n == 2 then | |
animation_counter = 0 | |
reveal_level = reveal_level + delta | |
if reveal_level > 100 then reveal_level = 100 end | |
if reveal_level < 0 then reveal_level = 0 end | |
draw_screen() | |
end | |
end | |
function draw_screen() | |
if animation_counter >= 0 then | |
screen.clear() | |
screen.level(15) | |
screen.aa(2) | |
screen.move(0,32) | |
if animation_flipflop == true then | |
pluck_distance = 30-(animation_counter/3) | |
animation_flipflop = false | |
else | |
pluck_distance = 30+(animation_counter/3) | |
screen.stroke() | |
animation_flipflop = true | |
end | |
screen.curve(-5,32,60,pluck_distance,130,32) | |
screen.stroke() | |
end | |
screen.font_face(0) | |
screen.font_size(8) | |
screen.level(15) | |
-- draw right aligned text | |
screen.move(127,63) | |
screen.text_right("reveal " .. reveal_level.."%") | |
screen.update() | |
animation_counter = animation_counter - 1 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment