"Performers" can handle melodies
This commit is contained in:
		| @@ -2,8 +2,10 @@ pico-8 cartridge // http://www.pico-8.com | ||||
| version 42 | ||||
| __lua__ | ||||
| #include shared/_meta.lua | ||||
| #include shared/instrument.lua | ||||
| #include shared/nflags.lua | ||||
| #include shared/pattern.lua | ||||
| #include shared/performer.lua | ||||
| #include shared/pflags.lua | ||||
| #include shared/track.lua | ||||
| #include unique.lua | ||||
| @@ -15,10 +17,11 @@ __gfx__ | ||||
| 00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| __sfx__ | ||||
| 010f2000000500c05007055030421c03028030230351f022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 010f20000000007040130400e0450a032230302f0302a035260220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 010f20001e2241e2201e22525224252202522523224232222322521224202241e2241c2241c2251a2241a22519224192201922023224232202322022224222222222222225000001c2241e224202242122423224 | ||||
| 010f2000252242522523224232252a2242a2252c2242c2252d2242d2252f2242d2242c2242c2252a2242a22528224282252a22428224262242622528224262242522425220252202522500000000000000000000 | ||||
| 010f200000000000000e0401a04015045110322a03036030310352d02200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 010f200000000000000000015040210401c04518032310203d0203802534012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| __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() | ||||
| end | ||||
|  | ||||
| function nflags:clone() | ||||
|  return nflags:new(self) | ||||
| end | ||||
|  | ||||
| function nflags:validate() | ||||
|  local c,e,v,w,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] | ||||
| end | ||||
|  | ||||
| function track:plot(channel,offset,inst) | ||||
| function track:plot(channel,offset,ndata) | ||||
|  assert_range(channel,0,4,"channel") | ||||
|  assert_range(offset,0,self.next_frame_start,"offset") | ||||
|  local tup=self.ix_to_frame[offset] | ||||
|  assert(tup)  -- should be unable to fail | ||||
|  local frame,offset=unpack(tup) | ||||
|  self.frames[frame+1][channel+1]:plot(offset,inst) | ||||
|  self.frames[frame+1][channel+1]:plot(offset,ndata) | ||||
| end | ||||
|  | ||||
| function track:build( | ||||
| @@ -73,6 +73,6 @@ function track:build( | ||||
|   for i=0,3 do | ||||
|    poke(fmaddr+i,map_to_real_pattern(self.frames[frame][i+1])) | ||||
|   end | ||||
|   fmaddr+=1 | ||||
|   fmaddr+=4 | ||||
|  end | ||||
| end | ||||
							
								
								
									
										66
									
								
								unique.lua
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								unique.lua
									
									
									
									
									
								
							| @@ -18,20 +18,60 @@ end | ||||
| function build_bgm() | ||||
|  local bgm=track:new() | ||||
|  | ||||
|  bgm:add(32) | ||||
|  bgm:add(32) | ||||
|  | ||||
|  local root=0 | ||||
|  for chan=0,7 do | ||||
|   local p=root+chan*7 | ||||
|   local start=0+chan*1 | ||||
|   local v=5-chan/3 | ||||
|   local c=chan%4 | ||||
|   bgm:plot(c,start+0,{v=v,p=p}) | ||||
|   bgm:plot(c,start+1,{v=v,p=p+12}) | ||||
|   bgm:plot(c,start+2,{v=v,p=p+7,e=5}) | ||||
|   bgm:plot(c,start+3,{v=v-1,p=p+3,e=2}) | ||||
|   -- bgm:plot(c,start+4,{v=v-1,p=p}) | ||||
|  end | ||||
|  trumpet=instrument:new(play_trumpet) | ||||
|  local perf=performer:new(bgm,0,trumpet,0,{30}) | ||||
|  perf:play(3,0) | ||||
|  perf:play(3,7) | ||||
|  perf:play(3,5,"warb") | ||||
|  perf:play(1,3) | ||||
|  perf:play(1,2) | ||||
|  perf:play(1,0) | ||||
|  perf:play(2,-2) | ||||
|  perf:play(2,-4) | ||||
|  perf:play(3,-5,"hold") | ||||
|  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 | ||||
| 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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user