「竹内関数で音楽生成 - aikeの日記」に影響されて、ActionScriptとSiONで作ってみました。アルペジオが違う等、原曲の完成度の高さをまったく再現できていません。(PLAYボタンをクリックすると音がなります。)
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import org.si.sion.SiONDriver;
import org.si.sion.SiONVoice;
import org.si.sion.utils.SiONPresetVoice;
import com.bit101.components.PushButton;
[SWF(width = "100", height = "20", frameRate = "30")]
public class tfmusic extends Sprite
{
private var driver:SiONDriver = new SiONDriver();
private var voice:SiONVoice = new SiONPresetVoice()["valsound.guitar1"];
private var note:Vector.<int> = Vector.<int>([
0, 2, 4, 5, 7, 9, 11
]);
private var arpeggio:Vector.<int> = Vector.<int>([
0, 2, 1, 2, 0, 1, 2, 1
]);
private var taraiBuffer:Vector.<int> = new Vector.<int>();
private var taraiBufferSize:int, taraiBufferPtr:int;
public function tfmusic()
{
tarai(10, 5, 0);
taraiBufferSize = taraiBuffer.length;
driver.bpm = 130;
driver.setTimerInterruption(16, onTimerInterruption);
new PushButton(this, 0, 0, "PLAY", notePlay);
}
private function notePlay(event:MouseEvent):void
{
taraiBufferPtr = 0;
driver.play();
}
private function onTimerInterruption():void
{
if (taraiBufferPtr < taraiBufferSize) {
var taraiXYZ:Vector.<int> = new Vector.<int>();
taraiXYZ[0] = taraiBuffer[taraiBufferPtr++];
taraiXYZ[1] = taraiBuffer[taraiBufferPtr++];
taraiXYZ[2] = taraiBuffer[taraiBufferPtr++];
taraiXYZ.sort(Array.NUMERIC);
for (var i:int = 0; i < 16; i++) {
driver.noteOn(noteNumber(taraiXYZ[arpeggio[i % 8]] + 2), voice, 1, i);
}
} else {
driver.stop();
}
}
private function noteNumber(x:int):int
{
return 60 + Math.floor(x / 7) * 12 + note[x % 7 + (x < 0 ? (x % 7 ? 7 : 0) : 0)];
}
private function tarai(x:int, y:int, z:int):int
{
taraiBuffer.push(x, y, z);
if (x > y) {
return tarai(tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y));
} else {
return y;
}
}
}
}