以前作ったMML再生用のスクリプトをFiberで書き直してみました。
def track(c, mml)
return Fiber.new {
ch = c
dat = mml
curev = -1
loop do
if curev == -1 || curev[1] == 0 then
curev = dat.getnext()
if curev == -1 then
Fiber.yield(-1)
end
if curev[0] != -1 then
tone($t, ch, curev[0])
end
elsif curev[0] != -1 && curev[1] == curev[2] then
$t.write(0x50,0x08+ch,0x00)
curev[1] -= 1
else
curev[1] -= 1
end
Fiber.yield(1)
end
}
end
# main
$t = BsdIic.new(0)
$t.write(0x50,0x07,0xf8)
if ch0.length != 0 then
tr0 = track(0, MML.new(ch0))
else
tr0 = nil
end
if ch1.length != 0 then
tr1 = track(1, MML.new(ch1))
else
tr1 = nil
end
if ch2.length != 0 then
tr2 = track(2, MML.new(ch2))
else
tr2 = nil
end
while (tr0 || tr1 || tr2)
if tr0 && tr0.resume == -1 then
tr0 = nil
end
if tr1 && tr1.resume == -1 then
tr1 = nil
end
if tr2 && tr2.resume == -1 then
tr2 = nil
end
tick = (60*1000*1000/(MML::gettempo*120)).to_i
Sleep::usleep(tick)
end
各トラックをFiberにしてtick毎に処理を動かしています。