최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday

티스토리 뷰

   After Hanabi


After Hanabi Listen to my Beats. by Nujabes(2007 - Hydeout Productions 2nd Collection)




If you still hear faint memories of the old mind. Especially in the 90's sensibility...




   Listen to My Beats


뜬금없는 불금에 센치해져서 노래도 들을겸 만들어 보았다. 클래스 작업이 귀찮아서 그냥 fla에다가 코딩했는데


처음엔 그냥 노래만 흘러나오도록 라이브러에 박아넣고 play 할 생각 이었지만..


스펙트럼, 콘트롤러, 볼륨 등 기능이 붙어서 아예 한개의 플레이어 수준이 되어버렸다... ... 


source by Flash CS6 ) 


sound.vol1.egg


sound.vol2.egg






   Use


화면에 보이듯이 그냥 저렇게 라이브러리에 음악 파일을 넣어서 플레이.. 혹시나 하여 코드에 외부 로딩 코드도 넣어놓았다.





   Code



스펙트럼 : computeSpectrum 메서드와 ByteArray의 바이너리 빼고는 별다른게 없다.


//serpiko.tistroy.com by CCL

import flash.display.Graphics;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.utils.Timer;
import flash.events.TimerEvent;

var snd:Snd = new Snd();
/*var snd:Sound = new Sound();
var req:URLRequest = new URLRequest("StillDre.mp3");
snd.load(req);*/

var channel:SoundChannel;
channel = snd.play();

var myTimer:Timer = new Timer(1500);
var color:int;

myTimer.addEventListener(TimerEvent.TIMER, timerHandler);
myTimer.start();

this.addEventListener(Event.ENTER_FRAME, onLoop);

var byteInfo:ByteArray = new ByteArray();
var sp:Sprite = new Sprite();
sp.y = 150;
addChild(sp);

var gt:Graphics = sp.graphics;

function onLoop(evt:Event):void {
	gt.clear();
	gt.lineStyle(3, color ,1);
	gt.moveTo(0, 0);
	SoundMixer.computeSpectrum(byteInfo,true);
	for (var i:uint=0; i<512; i++) {
		var n:Number = -byteInfo.readFloat()*100;
		gt.lineTo(i, n);
	}
}

function timerHandler(e:TimerEvent):void{
	color = Math.random() * 0xFFFFFF;
}




플레이 콘트롤러 : 은근히 손댈게 많았다. 일차함수와 현재 듣고있는 사운드 포지션에 대한 계산, 마지막으로 enterFrame이 꼬이지 않게 


                         적재 적소에 배치하는 것이 관건..


// (CCL) http://serpiko.tistory.com/

import flash.events.Event;
import flash.display.MovieClip;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

//
var soundChannelPath:SoundChannel = (parent as MovieClip).soundSpectrum.channel;
var sndPath:Sound = MovieClip(parent).soundSpectrum.snd;
var channel:SoundChannel = soundChannelPath;
var snd = sndPath;
var pausePosition:int;
var isPlay:Boolean;
var dargFocus:Boolean;
var currentSnd:int;
var totalSnd:int;

//
rect.buttonMode = play_btn.buttonMode = stop_btn.buttonMode = true;
this.addEventListener(Event.ENTER_FRAME, loop);
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
play_btn.addEventListener(MouseEvent.CLICK, playHandler);
stop_btn.addEventListener(MouseEvent.CLICK, stopHandler);
rect.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);

function playHandler(e:MouseEvent):void
{
	if(!this.hasEventListener(Event.ENTER_FRAME))this.addEventListener(Event.ENTER_FRAME,loop);
	
	isPlay = !isPlay;
	if(isPlay){
		pausePosition = channel.position;
		channel.stop();
		(e.target as MovieClip).gotoAndStop(2);
	}else{
		channel = snd.play(pausePosition);
		(e.target as MovieClip).gotoAndStop(1);
	}
}

function stopHandler(e:MouseEvent):void
{
	removeEventListener(Event.ENTER_FRAME, loop);
	
	isPlay = true;
	play_btn.gotoAndStop(2);
	pausePosition = rect.x = activeBar.scaleX = 0;
	channel.stop();
}

function loop(e:Event):void
{
	currentSnd = Math.ceil(channel.position);
	totalSnd = Math.ceil(snd.length);
	
	//Y.x =  (D-C) / (B-A) * ( X.x - A) + C
	rect.x = (bar.width - rect.width) / (totalSnd - 0) * (currentSnd - 0) + 0;
	activeBar.scaleX = rect.x/ (bar.width - rect.width);
	
	if(currentSnd == totalSnd) {
		stop_btn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
		(parent as MovieClip).volumeControl.init();
	}
}

function onPlaybackComplete(e:Event):void
{
	removeEventListener(Event.ENTER_FRAME, loop);
	trace("remove")
}

function downHandler(e:MouseEvent) {
	
	removeEventListener(Event.ENTER_FRAME, loop);
	
	//
	var bounds:Rectangle = new Rectangle(0,0,bar.width - rect.width,0);
	rect.startDrag(dargFocus,bounds);
	
	activeBar.addEventListener(Event.ENTER_FRAME, scaleLoop);
	if(!stage.hasEventListener(MouseEvent.MOUSE_UP))stage.addEventListener(MouseEvent.MOUSE_UP,upHandler);
}

function upHandler(e:MouseEvent) {
	
	rect.stopDrag();
	activeBar.removeEventListener(Event.ENTER_FRAME, scaleLoop);
	stage.removeEventListener(MouseEvent.MOUSE_UP,upHandler);
	if(!this.hasEventListener(Event.ENTER_FRAME))this.addEventListener(Event.ENTER_FRAME,loop);
	
	//Y.x =  (D-C) / (B-A) * ( X.x - A) + C
	currentSnd = (totalSnd - 0) / (bar.width - rect.width) * (rect.x - 0) + 0;
	channel.stop();
	channel = snd.play(currentSnd);
}

function scaleLoop(e:Event):void
{
	activeBar.scaleX = rect.x/ (bar.width - rect.width);
}



볼륨 콘트롤러 : 볼륨조절은 channel과 soundMixer 로 나누어서 선택할 수 있다. 


                      channel은 단일 지역 객체이고 soundmix는 응용 프로그램의 전역 사운드 컨트롤을 의미한다.


// (CCL) http://serpiko.tistory.com/

import flash.events.Event;
import flash.display.MovieClip;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

var barWidth:Number = bar.width - rect.width;
var percent:int = 50;
var soundChannelPath:SoundChannel = (parent as MovieClip).soundSpectrum.channel;

//-----------------------------------------------------------
var volMax:int = 100;
var volMin:int = 0;
var volum:int;
var vol_tran:SoundTransform;
var channel:SoundChannel;
this.channel = soundChannelPath;
vol_tran = channel.soundTransform;
var dargFocus:Boolean = false;

rect.buttonMode = true;
rect.addEventListener(MouseEvent.MOUSE_DOWN,down);

function down(e:MouseEvent) {
	rect.addEventListener(Event.ENTER_FRAME,volCalc);
	//
	var bounds:Rectangle = new Rectangle(0,0,barWidth,0);
	rect.startDrag(dargFocus,bounds);
	//
	if(!stage.hasEventListener(MouseEvent.MOUSE_UP))stage.addEventListener(MouseEvent.MOUSE_UP,up);
}

function up(e:MouseEvent) {
	rect.removeEventListener(Event.ENTER_FRAME,volCalc);
	rect.stopDrag();
	stage.removeEventListener(MouseEvent.MOUSE_UP,up);
}

function volCalc(e:Event) {
	//
	volum = Math.floor(rect.x * (volMax - volMin))/barWidth + volMin;
	//
	vol_tran.volume = volum/100;
	
	//channel.soundTransform = vol_tran; //only channel
	SoundMixer.soundTransform = vol_tran; //global soundMixer
	
	activeBar.scaleX = rect.x/barWidth;
}

function init() {
	//
	rect.x = barWidth*percent/100;
	//
	volum = Math.floor(rect.x * (volMax - volMin))/barWidth + volMin;
	//
	vol_tran.volume = volum/100;
	channel.soundTransform=vol_tran;
	//
	activeBar.scaleX = rect.x/barWidth;
}

init();



링크 이동 탭 : 상단의 링크 이동 탭, 별다른 기능이 없으므로 버튼에 축약형으로 표현.


import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.navigateToURL;

area_mc.buttonMode = true;
area_mc.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
						 var siteURL:String = "http://serpiko.tistory.com/";
						 navigateToURL(new URLRequest(siteURL));
						 });



'■ 플래시 ■ > Adobe ActionScript3.0' 카테고리의 다른 글

다수의 타겟을 가지는 드래그드랍  (0) 2014.08.22
particle  (0) 2014.06.11
이름이 없는 오브젝트에 대한 접근  (0) 2013.11.28
ByteArray를 사용한 문자열 인코딩  (0) 2013.11.28
Array Sort  (0) 2013.11.25
댓글