pulsar/shared/conductor.lua

77 lines
1.9 KiB
Lua
Raw Permalink Normal View History

2024-03-17 04:09:11 +00:00
conductor=klass()
function conductor:init(track,time)
self.track=track
self.time=time
end
function conductor:perform(
performers,
pitchblocks,
notation
)
local n_performers=#performers
local n_pitchblocks=#pitchblocks.chunks
assert(#notation==n_performers,"need "..n_performers.." parts for "..n_performers.." performers")
for i=1,n_performers do
assert(#notation[i]==n_pitchblocks,"performers should have "..n_pitchblocks.." for "..n_pitchblocks.." pitchblocks")
local function resolve_pitch(t,ix)
local block = pitchblocks.chunks[t+1]
assert_range(ix,0,#block,"pitch ix")
return block[ix+1]
end
local running_note=nil
local function touch_running_note(
t,pitch,force_new,verbs
)
if force_new or (running_note and running_note.pitch != pitch) or (not running_note and pitch!=nil) then
if running_note then
performers[i].time=self.time+running_note.t
performers[i]:play(t-running_note.t,running_note.pitch,running_note.verbs)
running_note=nil
end
if pitch then
running_note={
t=t,
pitch=pitch,
verbs=verbs
}
end
end
end
for t=0,n_pitchblocks-1 do
local note_char=notation[i][t+1]
local pitch
local force_start_new
local verbs=""
if note_char >= "a" and note_char <= "z" then
ix = ord(note_char) - ord("a")
pitch=resolve_pitch(t,ix)
elseif note_char >= "A" and note_char <= "Z" then
ix = ord(note_char) - ord("A")
pitch=resolve_pitch(t,ix)
force_start_new = true
elseif note_char == "." then
pitch=nil
elseif note_char == "@" then
pitch,verbs=0,"kick"
elseif note_char == "!" then
pitch,verbs=0,"snare"
elseif note_char == "'" then
pitch,verbs=0,"hihat"
else
assert(false,"wtf? "..note_char)
end
touch_running_note(t,pitch,force_start_new,verbs)
end
touch_running_note(n_pitchblocks,nil)
performers[i].time=self.time
end
end