/* * Copyright suweller * based on Tenorion by keim_at_Si ( http://wonderfl.net/user/keim_at_Si ) */ package { import flash.display.*; import flash.events.*; import flash.geom.*; import org.si.sion.SiONDriver; import org.si.sion.events.*; import org.si.sion.utils.SiONPresetVoice; public class student_musicpad_MatrixPad extends Bitmap { public var driver:SiONDriver; public var presetVoice:SiONPresetVoice = new SiONPresetVoice(); private const NOTE_LENGTH:Number = 0.01; private const LOWEST_NOTE:int = 36; // music variables public var sequences:Vector.; public var lowest_note:int = LOWEST_NOTE; private var _notes:int; private var _steps:int; // graphic dimensions private var _note_body:int = 7; private var _note_border:int = 1; private var _note_spacing:int = 1; private var _total_height:int; private var _total_width:int; // graphic variables private var canvas:Shape = new Shape(); private var buffer:BitmapData; private var pad_on:BitmapData; private var pad_off:BitmapData; private var pt:Point = new Point(); // color transform settings highlighting the current step private var colt:ColorTransform = new ColorTransform(1,1,1,0.2); // beat counter public var beatCounter:int; function student_musicpad_MatrixPad(stage:Stage, d:SiONDriver, notes:int, steps:int) { // set global variables _notes = notes; _steps = steps; beatCounter = 0; driver = d; // calculate global variables _total_height = _notes * note_side(); _total_width = _steps * note_side(); sequences = new Vector.(_steps); for (var i:int = 0; i < _notes; i++) sequences[i] = 0; // setup the drawing areas super(new BitmapData(_total_width, _total_height, false, 0)); buffer = new BitmapData(_total_width, _total_height, true, 0); initializestudent_musicpad_MatrixPad(); addEventListener("enterFrame", _onEnterFrame); stage.addEventListener("click", _onClick); with(driver) { setBeatCallbackInterval(1); addEventListener(SiONTrackEvent.BEAT, _onBeat); setTimerInterruption(1, _onTimerInterruption); } } private function initializestudent_musicpad_MatrixPad() : void { pad_on = _pad(0x336600, 0x669933); pad_off = _pad(0x666600, 0x333300); for (var __x:int = 0; __x < _steps; __x++) { for (var __y:int = 0; __y < _notes; __y++) { pt.x = __x * note_side(); pt.y = __y * note_side(); buffer.copyPixels(pad_off, pad_off.rect, pt); bitmapData.copyPixels(pad_off, pad_off.rect, pt); } } } private function note_side() : int { return _note_body + (_note_border * 2) + _note_spacing; } private function _pad(border:int, face:int) : BitmapData { var pix:BitmapData = new BitmapData(note_side(), note_side(), false, 0); with(canvas.graphics) { clear(); lineStyle(_note_border, border); beginFill(face); drawRect(1, 1, note_side(), note_side()); endFill(); } pix.draw(canvas); return pix; } private function _onClick(e:Event) : void { if (mouseX >= 0 && mouseX < _total_width && mouseY >= 0 && mouseY < _total_height ) { var clicked_note:int = (_notes - 1) - int(_notes * mouseY / _total_height); var clicked_step:int = int(_steps * mouseX / _total_width); sequences[clicked_note] ^= 1 << clicked_step; pt.x = clicked_step * note_side(); pt.y = ( (_notes - 1) - clicked_note) * note_side(); if (sequences[clicked_note] & (1 << clicked_step)) { buffer.copyPixels(pad_on, pad_on.rect, pt); } else { buffer.copyPixels(pad_off, pad_off.rect, pt); } } } private function _onEnterFrame(e:Event) : void { bitmapData.draw(buffer, null, colt); } // _onBeat (SiONTrackEvent.BEAT) is called back in each beat at the sound timing. private function _onBeat(e:SiONTrackEvent) : void { var beat16th:int = e.eventTriggerID & (_steps - 1); for (pt.x = beat16th * note_side(), pt.y = 0; pt.y < _total_height; pt.y += note_side()) { bitmapData.copyPixels(pad_on, pad_on.rect, pt); } } // _onTimerInterruption (SiONDriver.setTimerInterruption) is called back in each beat at the buffering timing. public function _onTimerInterruption() : void { var beatIndex:int = beatCounter & (_steps - 1); for (var i:int = 0; i < _notes; i++) { if (sequences[i] & (1 << beatIndex)) { driver.noteOn(lowest_note + i, presetVoice["default.saw"], NOTE_LENGTH); } } beatCounter++; } } }