Skip to content
Permalink
main
Go to file
@evanmcook
Latest commit 8465201 Dec 27, 2020 History
fixed order of lines to make sure the song stops playing first, and then the screen is marked as dirty
5 contributors

Users who have contributed to this file

@ryanlaws @tyleretters @schollz @Quixotic7 @evanmcook
executable file 250 lines (212 sloc) 6.92 KB
-- never tried this before... a table for organizing "composed" musical parts
-- verses, choruses, bridges, melodies, generative things...?
local parts = {}
function parts.xox(riddim)
-- return riddim detector
return function (beat)
beat = (beat % #riddim) + 1
return riddim:sub(beat, beat) ~= '-'
end
end
function parts.brownian(min, value, max, width)
math.randomseed(util.time())
-- return (naive) brownian motion generator
local delta = math.random(0 - width, width)
return function()
delta = (0.9 * delta) + (0.1 * math.random(0 - width, width))
value = value + delta
value = math.max(min, math.min(value, max))
-- U-turn
if (value == min) or (value == max) then
delta = (0 - delta)
end
return value
end
end
function parts.init(soundEngine)
parts.soundEngine = soundEngine
parts.quarter_beat = 0
parts.sixteenth_beat = 0
-- parts.endingMeas is the measure at which the song stops, as determined by an pseudo RNG with a range between
-- the first parameter of the random method and the second, both inclusive
parts.endingMeas = math.random(450,500)
-- <3 stepseq fam
parts.riddims = {
['and_a']=
parts.xox('--xx'),
['and_a_ting']=
parts.xox('--xx--xx--xx---x'),
['juke']=
parts.xox('x--x--x-'),
['grey']=
parts.xox('x--x--x--x--x---'),
['like_that']=
parts.xox('x----x----x----x'),
['boom']=
parts.xox('x--x------x--x--'),
['bap']=
parts.xox('----x---'),
['nervous']=
parts.xox('x-xx')
}
-- need to declare these here so they don't get recreated
parts.state = {
['pupil1'] = soundEngine:getSetParam(1, 'cutoff'),
['dilation1'] = parts.brownian(50, 800, 5000, 200),
['surface1'] = soundEngine:getSetParam(1, 'mod2'),
['shine1'] = parts.brownian(0, 100, 300, 20),
['is_nervous'] = false
}
-- chords
soundEngine:setSynthParams(3,{amp=0.2,cutoff=1500,attack=clock.get_beat_sec()*4,release=clock.get_beat_sec()*16})
parts.drumPat = 1
parts.drums = {}
for i = 1, 16 do
parts.drums[i] = {}
parts.drums[i].kick = {}
parts.drums[i].snare = {}
parts.drums[i].hh = {}
end
parts.drums[2].kick = {1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}
parts.drums[3].hh = {
0,0,1,0,
0,0,1,0,
0,0,1,0,
0,0,1,0}
parts.drums[4].kick = {
1,0,1,0,
0,0,0,0,
1,0,0,0,
0,0,1,0}
parts.drums[4].snare = {
0,0,0,0,
1,0,0,0,
0,0,0,0,
1,0,0,0}
parts.drums[4].hh = {
1,0,1,0,
1,0,1,0,
1,0,1,0,
1,0,1,0}
end
function parts:whole_notes(phase)
self.soundEngine:bang_note(69, 2, 0)
if song.measure == 8 then self.drumPat = 2
elseif song.measure == 16 then self.drumPat = 3
elseif song.measure == 24 then self.drumPat = 4
elseif song.measure >= parts.endingMeas then
song.is_playing = false
song.is_screen_dirty = true
end
-- trig condition
self.state.is_nervous = (math.random(5) == 2)
if song.measure == 100 then
self.soundEngine:bang_note(62, 1, 0)
elseif song.measure % 4 == 1 then
self.soundEngine:bang_note(62, 1, 0)
elseif song.measure % 15 == 1 then
self.soundEngine:bang_note(76, 1, 0)
end
end
function parts:quarter_notes(phase)
if math.random(1, 2) == 1 then
self.soundEngine:bang_note(81, 2, 0)
end
self.quarter_beat = self.quarter_beat+1
local beat = self.quarter_beat
if beat>32 then
-- rest
if parts.riddims.like_that(beat) then
parts.state.pupil1(parts.state.dilation1())
end
if parts.riddims.juke(beat) then
-- math.random() h8z floats
parts.state.surface1(parts.state.shine1() / 100)
else
parts.state.surface1(0)
end
else
if beat%31==0 then self.soundEngine:bang_note(59, 1, 0)
elseif beat%29==0 then self.soundEngine:bang_note(60, 1, 0)
elseif beat%27==0 then self.soundEngine:bang_note(55, 1, 0)
elseif beat%25==0 then self.soundEngine:bang_note(52, 1, 0)
elseif beat%23==0 then self.soundEngine:bang_note(52, 1, 0)
elseif beat%21==0 then self.soundEngine:bang_note(52, 1, 0)
elseif beat%17==0 then self.soundEngine:bang_note(48, 1, 0)
elseif beat%15==0 then self.soundEngine:bang_note(52, 1, 0)
elseif beat%11==0 then self.soundEngine:bang_note(52, 1, 0)
elseif beat%9==0 then self.soundEngine:bang_note(47, 1, 0)
elseif beat%7==0 then self.soundEngine:bang_note(52, 1, 0)
elseif beat%5==0 then self.soundEngine:bang_note(52, 1, 0)
elseif beat%1==0 then self.soundEngine:bang_note(45, 1, 0)
end
end
end
function parts:sixteenth_notes(phase)
self.sixteenth_beat = self.sixteenth_beat+1
local beat = self.sixteenth_beat
local shift_shape1 = self.soundEngine:getSetParam(1, 'algo')
if beat<64 then
-- nothing
else
if self.riddims.boom(beat) then
shift_shape1('sinfmlp')
elseif self.riddims.bap(beat) then
shift_shape1('sinfb')
elseif self.riddims.and_a(beat) then
shift_shape1('square_mod2')
end
if self.state.is_nervous and self.riddims.nervous(beat) then
self.soundEngine:bang_note(81, 1, 0)
end
if beat%31==0 then self.soundEngine:bang_note(71, 1, 0)
elseif beat%29==0 then self.soundEngine:bang_note(72, 1, 0)
elseif beat%27==0 then self.soundEngine:bang_note(67, 1, 0)
elseif beat%25==0 then self.soundEngine:bang_note(64, 1, 0)
elseif beat%23==0 then self.soundEngine:bang_note(64, 1, 0)
elseif beat%21==0 then self.soundEngine:bang_note(64, 1, 0)
elseif beat%17==0 then self.soundEngine:bang_note(60, 1, 0)
elseif beat%15==0 then self.soundEngine:bang_note(64, 1, 0)
elseif beat%11==0 then self.soundEngine:bang_note(64, 1, 0)
elseif beat%9==0 then self.soundEngine:bang_note(59, 1, 0)
elseif beat%7==0 then self.soundEngine:bang_note(64, 1, 0)
elseif beat%5==0 then self.soundEngine:bang_note(64, 1, 0)
elseif beat%1==0 then self.soundEngine:bang_note(57, 1, 0)
end
end
if song.measure<16 then
elseif beat%128==113 then
self.soundEngine:bang_note(67,3,0)
elseif beat%128==97 then
print("chord4")
self.soundEngine:bang_note(59,3,0)
self.soundEngine:bang_note(64,3,0)
self.soundEngine:bang_note(62,3,0)
self.soundEngine:bang_note(55,3,0)
elseif beat%128==65 then
self.soundEngine:bang_note(57,3,0)
self.soundEngine:bang_note(64,3,0)
self.soundEngine:bang_note(53,3,0)
self.soundEngine:bang_note(60,3,0)
elseif beat%128==33 then
self.soundEngine:bang_note(64,3,0)
self.soundEngine:bang_note(59,3,0)
self.soundEngine:bang_note(55,3,0)
elseif beat%128==1 then
self.soundEngine:bang_note(60,3,0)
self.soundEngine:bang_note(64,3,0)
self.soundEngine:bang_note(57,3,0)
end
local noteIndex = (self.sixteenth_beat % 16) + 1
local pat = self.drums[self.drumPat]
if pat.kick[noteIndex] == 1 then
self.soundEngine:bang_note(32, 4, 0)
end
if pat.snare[noteIndex] == 1 then
self.soundEngine:bang_note(38, 5, 0)
end
if pat.hh[noteIndex] == 1 then
self.soundEngine:bang_note(60, 6, 0)
end
end
return parts