Soundスクラッチ
ステージドラッグでスクラッチ。
/**
* Copyright _arikata ( http://wonderfl.net/user/_arikata )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ncpy
*/
package
{
import flash.display.Bitmap;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundLoaderContext;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import com.bit101.components.PushButton;
import com.bit101.components.Slider;
/**
* SoundTest
* @author Arikata Nobuaki
*/
public class SoundTest extends MovieClip
{
private static const BUFFER_LENGTH:uint = 2048;
private static const SWF_WIDTH:uint = 465;
private static const SWF_HEIGHT:uint = 465;
private static const MP3_FILE:String = "http://www.takasumi-nagai.com/soundfiles/sound001.mp3"; //お借りします。
private static const BAR_WIDTH:uint = 20;
private var _sound:Sound;
private var _sc:SoundChannel;
private var _wave:ByteArray;
private var _mp3:Sound;
private var soundPitch:Number = 1;
private var df_soundPitch:Number = 1;
private var _playingPosition:Number = 0;
private var _press:Boolean = false;
private var targetX:Number;
private var _view:Bitmap;
private var _bar:Shape;
private var slider:Slider;
public function SoundTest()
{
Wonderfl.capture_delay(10);
_view = new Bitmap();
_view.bitmapData = new WaveViewBitmapData(SWF_WIDTH, SWF_HEIGHT, true, 0);
addChild(_view);
_bar = new Shape();
var g:Graphics = _bar.graphics;
g.beginFill(0, .7);
g.drawRect( -BAR_WIDTH / 2, 0, BAR_WIDTH, SWF_HEIGHT);
addChild(_bar);
slider = new Slider(Slider.HORIZONTAL, this, 310, 5, onSlide);
slider.setSize(150, 13);
slider.value = 75;
slider.backClick = true;
var x1:PushButton = new PushButton(this, 275, 5, "x1");
x1.setSize(30, 13);
x1.addEventListener(MouseEvent.MOUSE_UP, x1Handler);
if (stage) init(null);
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.frameRate = 60;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
//mp3FileLoad
_mp3 = new Sound();
_mp3.addEventListener(Event.COMPLETE, mp3LoadComp);
_mp3.load(new URLRequest(MP3_FILE), new SoundLoaderContext(1, true));
}
private function mp3LoadComp(e:Event):void
{
_mp3.removeEventListener(Event.COMPLETE, mp3LoadComp);
//mp3Decode
_wave = new ByteArray();
do {
var len:Number = _mp3.extract(_wave, BUFFER_LENGTH);
} while (len >= BUFFER_LENGTH);
//drawWave
var drawer:DrawController = new DrawController(WaveViewBitmapData(_view.bitmapData), _wave, SWF_WIDTH, SWF_HEIGHT);
drawer.addEventListener(Event.COMPLETE, drawComp);
drawer.start();
}
private function drawComp(e:Event):void
{
//SoundPlayStart
_sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleDataHandler);
_sc = _sound.play(0, 0);
addEventListener(Event.ENTER_FRAME, tick);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function tick(e:Event):void
{
if (_press)
{
targetX = mouseX<8?8:(mouseX>SWF_WIDTH-8?SWF_WIDTH-8:mouseX);
var prex:Number = _bar.x;
_bar.x += (targetX - _bar.x) * .2;
soundPitch += ((_bar.x - prex) / 5 - soundPitch) * .1;
_playingPosition += (_wave.length * _bar.x / SWF_WIDTH - _playingPosition) * .2;
}
else
{
_bar.x += (SWF_WIDTH * _playingPosition / _wave.length - _bar.x) * .25;
soundPitch += (df_soundPitch - soundPitch) * .1;
}
}
private function onSampleDataHandler(e:SampleDataEvent):void
{
var left:Number,
right:Number,
length:int = _wave.length;
for (var i:int = 0; i < BUFFER_LENGTH; i++)
{
_playingPosition += soundPitch * 8;
loopHandler();
_wave.position = Math.floor(_playingPosition / 4) * 4;
try
{
left = _wave.readFloat();
right = _wave.readFloat();
e.data.writeFloat(left);
e.data.writeFloat(right);
}
catch (error:Error)
{
trace(error);
trace(_wave.position + " / " + length);
break;
}
}
}
private function loopHandler():void
{
var length:int = _wave.length;
if (_playingPosition + 8 >= length)
{
_playingPosition -= length - 8;
if(!_press) _bar.x = SWF_WIDTH * _playingPosition / length;
}
else if (_playingPosition < 0)
{
_playingPosition += length - 8;
if(!_press) _bar.x = SWF_WIDTH * _playingPosition / length;
}
}
private function mouseDownHandler(e:MouseEvent):void
{
if (e.target == stage)
{
_press = true;
targetX = mouseX;
}
}
private function mouseUpHandler(e:MouseEvent):void
{
_press = false;
}
private function x1Handler(e:MouseEvent):void
{
df_soundPitch = 1;
slider.value = 75;
}
private function onSlide(e:Event):void
{
df_soundPitch = e.target.value / 25 -2;
}
}
}
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.ByteArray;
import flash.utils.getTimer;
class DrawController extends Sprite
{
private static const lineColor:uint = 0xFF336699;
private var _g:WaveViewBitmapData;
private var _wave:ByteArray;
private var _width:int;
private var _height:int;
private var pastX:int;
private var pastYLeft:int;
private var pastYRight:int;
private var pos:int = 0;
private var time:int;
public function DrawController(_g:WaveViewBitmapData, _wave:ByteArray, _width:int, _height:int)
{
this._g = _g;
this._wave = _wave;
this._width = _width;
this._height = _height;
pastX = 0,
pastYLeft = _width / 4,
pastYRight = 3 * _height / 4,
_wave.position = 0;
}
public function start():void
{
time = getTimer();
var length:int = _wave.length,
left:Number,
right:Number,
x:int,
y:int,
yLeft:int = _height / 4,
yRight:int = 3 * _height / 4,
g:WaveViewBitmapData = _g;
_wave.position = pos;
//trace(_width * _wave.position / length);
while (_wave.position < length)
{
left = _wave.readFloat();
right = _wave.readFloat();
x = _width * _wave.position / length;
y = yLeft + left * 50;
g.drawLine(pastX, pastYLeft, x, y, lineColor, lineColor);
pastYLeft = y;
y = yRight + right * 50;
g.drawLine(pastX, pastYRight, x, y, lineColor, lineColor);
pastX = x;
pastYRight = y;
if (getTimer() - time > 1000 / 100)
{
pos = _wave.position;
addEventListener(Event.ENTER_FRAME, refresh);
break;
}
}
if (_wave.position >= length) dispatchEvent(new Event(Event.COMPLETE));
/**/
}
private function refresh(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, refresh);
start();
}
}
import flash.display.BitmapData;
class WaveViewBitmapData extends BitmapData
{
public function WaveViewBitmapData(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF)
{
super(width, height, transparent, fillColor);
}
public function drawLine(x0:int, y0:int, x1:int, y1:int, color0:uint = 0xFF000000, color1:uint = 0xFF000000):void
{
var bol:Boolean,
dx:int,
dy:int,
e:int,
x:int,
y:int,
ys:int,
oneColor:Boolean,
color:uint,
dotMethod:Function = setPixel32;
if (color0 == color1)
{
oneColor = true;
color = color0;
}
dx = x1 - x0;
dy = y1 - y0;
bol = (dy ^ (dy >> 31)) - (dy >> 31) > (dx ^ (dx >> 31)) - (dx >> 31);
if (bol)
{
x0 ^= y0;
y0 ^= x0;
x0 ^= y0;
x1 ^= y1;
y1 ^= x1;
x1 ^= y1;
dx = x1 - x0;
dy = y1 - y0;
}
if (x0 > x1)
{
x0 ^= x1;
x1 ^= x0;
x0 ^= x1;
y0 ^= y1;
y1 ^= y0;
y0 ^= y1;
dx = x1 - x0;
dy = y1 - y0;
color0 ^= color1;
color1 ^= color0;
color0 ^= color1;
}
dy = (dy ^ (dy >> 31)) - (dy >> 31);
e = dx * .5;
ys = (y0 < y1) ? 1 : -1;
y = y0;
for (x = x0; x <= x1; x++)
{
if (!oneColor) color = (color1 - color0) * (x - x0) / (x1 - x0) + color0;
if (bol)
{
setPixel32(y, x, color);
}
else
{
setPixel32(x, y, color);
}
e -= dy;
if (e < 0)
{
y += ys;
e += dx;
}
}
}
}