-
-
Save dndrks/257a85f36bfe66fdaf00d54025ea63b4 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
--- Lied. | |
local Lied = {} | |
local MusicUtil = require "musicutil" | |
local TabUtil = require "tabutil" | |
-- TODO operate by reference so the scale can change without recreating the sequin | |
local dim = {3,6,9,15,18,21,-6} | |
local bass = {-6,-12,-15} | |
local lyd = {12,14,16,18,19,9,11,24} | |
local text = "C l o u d" | |
--- TODO this is a new file called sequins.lua | |
local sequins = {} | |
-- arg1: value table eg{0,2,4,7,9} | |
-- arg2: behaviour enum:{'next','prev',rand','drunk'} -- n as next# | |
-- retv: function that generates the next note | |
function sequins.new( vals, behaviour ) | |
local ix = 1 | |
local function generate() | |
local newix = 0 | |
if behaviour == 'next' then | |
newix = ix + 1 | |
elseif behaviour == 'prev' then | |
newix = ix - 1 | |
elseif behaviour == 'rand' then | |
newix = math.random(#vals) | |
elseif behaviour == 'drunk' then | |
newix = ix + math.random(-1,1) | |
end | |
-- clamp to vals table length | |
while newix < 1 do newix = newix + #vals end | |
while newix > #vals do newix = newix - #vals end | |
local val = vals[newix] | |
-- currently we explictly step the index forward in some cases but not others | |
-- ideally this would be cleaned up & have a single return point | |
if type(val) == 'function' then | |
local v, action = val() -- allows nested tables | |
if action == 'skip' then | |
ix = newix -- nb: doesn't matter if it's before/after recursion | |
return generate( vals, behaviour ) | |
elseif action == 'again' then | |
-- ix stays the same! | |
else -- was a nested table, but just returned a value (no action) | |
ix = newix | |
end | |
return v | |
else -- assume a number | |
ix = newix | |
return val | |
end | |
end | |
return generate -- named function so we can use recursion inside | |
end | |
-- returns a value on everyth call. otherwise instructs the caller to skip it. | |
function sequins.every( everyth, sequin ) | |
local ev = everyth | |
return | |
function() | |
ev = e%everyth +1 | |
if ev == 1 then | |
return sequin() | |
else | |
return 0, 'skip' | |
end | |
end | |
end | |
-- returns count values in a row, stopping the calling sequin from moving forward until count is exhausted | |
function sequins.count( count, sequin ) | |
local cou = count | |
return | |
function() | |
cou = cou%count +1 | |
if cou == 1 then | |
print'match' | |
return sequin() | |
else | |
return sequin(), 'again' | |
end | |
end | |
end | |
function Lied.init() | |
anumbs = string.gsub(text, "a", 1) | |
bnumbs = string.gsub(anumbs, "b", 2) | |
cnumbs = string.gsub(bnumbs, "c", 3) | |
dnumbs = string.gsub(cnumbs, "d", 4) | |
enumbs = string.gsub(dnumbs, "e", 5) | |
fnumbs = string.gsub(enumbs, "f", 6) | |
gnumbs = string.gsub(fnumbs, "g", 7) | |
hnumbs = string.gsub(gnumbs, "h", 8) | |
inumbs = string.gsub(hnumbs, "i", 9) | |
jnumbs = string.gsub(inumbs, "j", 10) | |
knumbs = string.gsub(jnumbs, "k", 11) | |
lnumbs = string.gsub(knumbs, "l", 12) | |
mnumbs = string.gsub(lnumbs, "m", 13) | |
nnumbs = string.gsub(mnumbs, "n", 14) | |
onumbs = string.gsub(nnumbs, "o", 15) | |
pnumbs = string.gsub(onumbs, "p", 16) | |
qnumbs = string.gsub(pnumbs, "q", 17) | |
rnumbs = string.gsub(qnumbs, "r", 18) | |
snumbs = string.gsub(rnumbs, "s", 19) | |
tnumbs = string.gsub(snumbs, "t", 20) | |
unumbs = string.gsub(tnumbs, "u", 21) | |
vnumbs = string.gsub(unumbs, "v", 22) | |
wnumbs = string.gsub(vnumbs, "w", 23) | |
xnumbs = string.gsub(wnumbs, "x", 24) | |
ynumbs = string.gsub(xnumbs, "y", 25) | |
znumbs = string.gsub(ynumbs, "z", 26) | |
Anumbs = string.gsub(znumbs, "A", 27) | |
Bnumbs = string.gsub(Anumbs, "B", 28) | |
Cnumbs = string.gsub(Bnumbs, "C", 29) | |
Dnumbs = string.gsub(Cnumbs, "D", 30) | |
Enumbs = string.gsub(Dnumbs, "E", 31) | |
Fnumbs = string.gsub(Enumbs, "F", 32) | |
Gnumbs = string.gsub(Fnumbs, "G", 33) | |
Hnumbs = string.gsub(Gnumbs, "H", 34) | |
Inumbs = string.gsub(Hnumbs, "I", 35) | |
Jnumbs = string.gsub(Inumbs, "J", 36) | |
Knumbs = string.gsub(Jnumbs, "K", 37) | |
Lnumbs = string.gsub(Knumbs, "L", 38) | |
Mnumbs = string.gsub(Lnumbs, "M", 39) | |
Nnumbs = string.gsub(Mnumbs, "N", 40) | |
Onumbs = string.gsub(Nnumbs, "O", 41) | |
Pnumbs = string.gsub(Onumbs, "P", 42) | |
Qnumbs = string.gsub(Pnumbs, "Q", 43) | |
Rnumbs = string.gsub(Qnumbs, "R", 44) | |
Snumbs = string.gsub(Rnumbs, "S", 45) | |
Tnumbs = string.gsub(Snumbs, "T", 46) | |
Unumbs = string.gsub(Tnumbs, "U", 47) | |
Vnumbs = string.gsub(Unumbs, "V", 48) | |
Wnumbs = string.gsub(Vnumbs, "W", 49) | |
Xnumbs = string.gsub(Wnumbs, "X", 50) | |
Ynumbs = string.gsub(Xnumbs, "Y", 51) | |
Znumbs = string.gsub(Ynumbs, "Z", 52) | |
print(Znumbs) | |
crow.input[1].mode('clock') | |
crow.output[2].action = "{to(5,0),to(0,0.025)}" | |
crow.output[4].action = "{to(5,0),to(0,0.025)}" | |
function Lied.Split(s, delimiter) | |
local result = {}; | |
for match in (s..delimiter):gmatch("(.-)"..delimiter) do | |
table.insert(result, match); | |
end | |
return result; | |
end | |
local lied = Lied.Split(Znumbs, "%s") | |
print(lied) | |
-- create our sequin which interleaves the playback of two tables of notes (from above) | |
local mysequin = | |
sequins.new( { sequins.new( lied, 'prev' ) | |
, sequins.count( 5, sequins.new( lied, 'next' ) ) | |
} | |
, 'next' ) | |
-- iniates a timebase which will pull a note from the sequin on each step | |
local myarp = Lied.run_arp( Lied.play_note | |
, mysequin | |
, 11/5 | |
) | |
local myotherarp = Lied.run_arp( Lied.play_other_note | |
, mysequin | |
, 5/1) | |
local mythirdarp = Lied.run_arp( Lied.play_with | |
, mysequin | |
, 4/1) | |
print("LIED INITIALIZED") | |
end | |
function Lied.play_note(v) | |
--v = v + 48 -- shift up to good range | |
local freq = v/12 | |
print("playing note") | |
crow.output[1].volts = freq | |
crow.output[1].scale( {1,3,5,6,8,10,11,13}, 12, 1.0 ) | |
crow.output[2].execute() | |
end | |
function Lied.play_other_note(v) | |
--v = v + 48 -- shift up to good range | |
local freq = v/12 | |
print("playing other note") | |
crow.output[3].volts = freq | |
crow.output[3].scale( {1,3,5,6,8,10,11,13}, 12, 1.0 ) | |
crow.output[4].execute() | |
end | |
function Lied.play_with(v) | |
local freq = v/12 | |
crow.ii.wdel.clock_ratio( 1, v ) | |
end | |
function Lied.run_arp(fn,seq,sync) | |
return clock.run( | |
function() | |
while true do | |
clock.sync(sync) | |
fn( seq() ) | |
end | |
end) | |
end | |
return Lied |
Author
dndrks
commented
Mar 21, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment