Improve APIs further
This commit is contained in:
@ -11,5 +11,5 @@ function klass()
|
||||
end
|
||||
|
||||
function assert_range(i,mn,mx,name)
|
||||
assert(i >= mn and i < mx, name.." must be ["..mn..","..mx..")")
|
||||
assert(i >= mn and i < mx, name.." must be ["..mn..","..mx..") and not "..i)
|
||||
end
|
77
shared/conductor.lua
Normal file
77
shared/conductor.lua
Normal file
@ -0,0 +1,77 @@
|
||||
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
|
14
shared/pitchblocks.lua
Normal file
14
shared/pitchblocks.lua
Normal file
@ -0,0 +1,14 @@
|
||||
pitchblocks=klass()
|
||||
function pitchblocks:init(width)
|
||||
assert_range(width,0,8,"width")
|
||||
self.width=width
|
||||
self.chunks={}
|
||||
end
|
||||
|
||||
function pitchblocks:add(n,notes)
|
||||
assert(#notes==self.width)
|
||||
for i=1,n do
|
||||
add(self.chunks,notes)
|
||||
end
|
||||
return self
|
||||
end
|
Reference in New Issue
Block a user