"Performers" can handle melodies
This commit is contained in:
parent
6bcbb0524c
commit
fa282184a9
@ -2,8 +2,10 @@ pico-8 cartridge // http://www.pico-8.com
|
|||||||
version 42
|
version 42
|
||||||
__lua__
|
__lua__
|
||||||
#include shared/_meta.lua
|
#include shared/_meta.lua
|
||||||
|
#include shared/instrument.lua
|
||||||
#include shared/nflags.lua
|
#include shared/nflags.lua
|
||||||
#include shared/pattern.lua
|
#include shared/pattern.lua
|
||||||
|
#include shared/performer.lua
|
||||||
#include shared/pflags.lua
|
#include shared/pflags.lua
|
||||||
#include shared/track.lua
|
#include shared/track.lua
|
||||||
#include unique.lua
|
#include unique.lua
|
||||||
@ -15,10 +17,11 @@ __gfx__
|
|||||||
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
__sfx__
|
__sfx__
|
||||||
010f2000000500c05007055030421c03028030230351f022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
010f20001e2241e2201e22525224252202522523224232222322521224202241e2241c2241c2251a2241a22519224192201922023224232202322022224222222222222225000001c2241e224202242122423224
|
||||||
010f20000000007040130400e0450a032230302f0302a035260220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
010f2000252242522523224232252a2242a2252c2242c2252d2242d2252f2242d2242c2242c2252a2242a22528224282252a22428224262242622528224262242522425220252202522500000000000000000000
|
||||||
010f200000000000000e0401a04015045110322a03036030310352d02200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
010f200000000000000e0401a04015045110322a03036030310352d02200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
010f200000000000000000015040210401c04518032310203d0203802534012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
010f200000000000000000015040210401c04518032310203d0203802534012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
__music__
|
__music__
|
||||||
00 00010203
|
00 00404040
|
||||||
|
00 01404040
|
||||||
|
|
||||||
|
31
shared/instrument.lua
Normal file
31
shared/instrument.lua
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
instrument=klass()
|
||||||
|
function instrument:init(callback)
|
||||||
|
self.callback=callback
|
||||||
|
self.volume=1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
function instrument:spackle(track,channel,t0,t1,note,verbs)
|
||||||
|
-- a one-indexed table of note data
|
||||||
|
-- (one-indexed because Lua kind of sucks)
|
||||||
|
local nflagses,keep_silence=self.callback(t1-t0,note,instrument_split_verbs(verbs))
|
||||||
|
for i,nflags in pairs(nflagses) do
|
||||||
|
if nflags.v>0 or keep_silence then
|
||||||
|
nflags = nflags:clone() -- avoid breaking instrument
|
||||||
|
|
||||||
|
local min_v=0
|
||||||
|
if (nflags.v>0) min_v = 1
|
||||||
|
nflags.v = mid(flr(nflags.v * self.volume + 0.5),min_v,7)
|
||||||
|
|
||||||
|
track:plot(channel,t0+i-1,nflags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
instrument_split_verbs=function(x)
|
||||||
|
if (not x) return {}
|
||||||
|
local t={}
|
||||||
|
for i in all(split(x)) do
|
||||||
|
t[i]=true
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
@ -9,6 +9,10 @@ function nflags:init(o)
|
|||||||
self:validate()
|
self:validate()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function nflags:clone()
|
||||||
|
return nflags:new(self)
|
||||||
|
end
|
||||||
|
|
||||||
function nflags:validate()
|
function nflags:validate()
|
||||||
local c,e,v,w,p
|
local c,e,v,w,p
|
||||||
=self.c,self.e,self.v,self.w,self.p
|
=self.c,self.e,self.v,self.w,self.p
|
||||||
|
28
shared/performer.lua
Normal file
28
shared/performer.lua
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
performer=klass()
|
||||||
|
function performer:init(track,channel,instrument,time,roots)
|
||||||
|
assert_range(#roots,1,33,"#roots")
|
||||||
|
|
||||||
|
self.track=track
|
||||||
|
self.channel=channel
|
||||||
|
self.instrument=instrument
|
||||||
|
self.time=time
|
||||||
|
self.roots=roots
|
||||||
|
self.selected_root=1
|
||||||
|
end
|
||||||
|
|
||||||
|
function performer:root(root)
|
||||||
|
assert_range(root,1,#self.roots,"root")
|
||||||
|
self.selected_root=root
|
||||||
|
end
|
||||||
|
function performer:play(duration,note,verbs)
|
||||||
|
local base=self.roots[self.selected_root]
|
||||||
|
local note=base+note
|
||||||
|
local t0=self.time
|
||||||
|
local t1=t0+duration
|
||||||
|
self.time+=duration
|
||||||
|
self.instrument:spackle(self.track,self.channel,t0,t1,note,verbs)
|
||||||
|
end
|
||||||
|
function performer:rest(duration)
|
||||||
|
self.time+=duration
|
||||||
|
end
|
||||||
|
|
@ -31,13 +31,13 @@ function track:pattern(channel,offset)
|
|||||||
return self.frames[offset+1][channel+1]
|
return self.frames[offset+1][channel+1]
|
||||||
end
|
end
|
||||||
|
|
||||||
function track:plot(channel,offset,inst)
|
function track:plot(channel,offset,ndata)
|
||||||
assert_range(channel,0,4,"channel")
|
assert_range(channel,0,4,"channel")
|
||||||
assert_range(offset,0,self.next_frame_start,"offset")
|
assert_range(offset,0,self.next_frame_start,"offset")
|
||||||
local tup=self.ix_to_frame[offset]
|
local tup=self.ix_to_frame[offset]
|
||||||
assert(tup) -- should be unable to fail
|
assert(tup) -- should be unable to fail
|
||||||
local frame,offset=unpack(tup)
|
local frame,offset=unpack(tup)
|
||||||
self.frames[frame+1][channel+1]:plot(offset,inst)
|
self.frames[frame+1][channel+1]:plot(offset,ndata)
|
||||||
end
|
end
|
||||||
|
|
||||||
function track:build(
|
function track:build(
|
||||||
@ -73,6 +73,6 @@ function track:build(
|
|||||||
for i=0,3 do
|
for i=0,3 do
|
||||||
poke(fmaddr+i,map_to_real_pattern(self.frames[frame][i+1]))
|
poke(fmaddr+i,map_to_real_pattern(self.frames[frame][i+1]))
|
||||||
end
|
end
|
||||||
fmaddr+=1
|
fmaddr+=4
|
||||||
end
|
end
|
||||||
end
|
end
|
66
unique.lua
66
unique.lua
@ -18,20 +18,60 @@ end
|
|||||||
function build_bgm()
|
function build_bgm()
|
||||||
local bgm=track:new()
|
local bgm=track:new()
|
||||||
|
|
||||||
|
bgm:add(32)
|
||||||
bgm:add(32)
|
bgm:add(32)
|
||||||
|
|
||||||
local root=0
|
trumpet=instrument:new(play_trumpet)
|
||||||
for chan=0,7 do
|
local perf=performer:new(bgm,0,trumpet,0,{30})
|
||||||
local p=root+chan*7
|
perf:play(3,0)
|
||||||
local start=0+chan*1
|
perf:play(3,7)
|
||||||
local v=5-chan/3
|
perf:play(3,5,"warb")
|
||||||
local c=chan%4
|
perf:play(1,3)
|
||||||
bgm:plot(c,start+0,{v=v,p=p})
|
perf:play(1,2)
|
||||||
bgm:plot(c,start+1,{v=v,p=p+12})
|
perf:play(1,0)
|
||||||
bgm:plot(c,start+2,{v=v,p=p+7,e=5})
|
perf:play(2,-2)
|
||||||
bgm:plot(c,start+3,{v=v-1,p=p+3,e=2})
|
perf:play(2,-4)
|
||||||
-- bgm:plot(c,start+4,{v=v-1,p=p})
|
perf:play(3,-5,"hold")
|
||||||
end
|
perf:play(3,5,"hold")
|
||||||
|
perf:play(4,4,"warb")
|
||||||
|
perf:rest(1)
|
||||||
|
perf:play(1,-2)
|
||||||
|
perf:play(1,0)
|
||||||
|
perf:play(1,2)
|
||||||
|
perf:play(1,3)
|
||||||
|
perf:play(1,5)
|
||||||
|
|
||||||
|
perf:play(2,7)
|
||||||
|
perf:play(2,5)
|
||||||
|
perf:play(2,12)
|
||||||
|
perf:play(2,14)
|
||||||
|
perf:play(2,15)
|
||||||
|
perf:play(1,17)
|
||||||
|
perf:play(1,15)
|
||||||
|
perf:play(2,14)
|
||||||
|
perf:play(2,12)
|
||||||
|
perf:play(2,10)
|
||||||
|
perf:play(1,12)
|
||||||
|
perf:play(1,10)
|
||||||
|
perf:play(2,8)
|
||||||
|
perf:play(1,10)
|
||||||
|
perf:play(1,8)
|
||||||
|
perf:play(4,7)
|
||||||
|
perf:rest(4)
|
||||||
|
|
||||||
return bgm
|
return bgm
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function play_trumpet(duration,pitch,verbs)
|
||||||
|
local e=0
|
||||||
|
if (verbs.slide) e=1
|
||||||
|
if (verbs.warb) e=2
|
||||||
|
|
||||||
|
local out={}
|
||||||
|
for i=1,duration do
|
||||||
|
out[i]=nflags:new{p=pitch,v=2,w=2,e=e}
|
||||||
|
end
|
||||||
|
if (not verbs.slide) out[1].e=4
|
||||||
|
if (not verbs.hold and #out>1) out[#out].e=5
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user