Gapless sound looping in ActionScript 3.0

보통 사운드 루핑을 만들 때 Event.SOUND_COMPLETE 이벤트나 Sound.play(0, 999);를 사용할텐데요. 이 경우에 음악이 재생되는 사이에 약간의 틈이 발생합니다. 다음 플래시 무비처럼 말이죠.

이 파일은 아래의 코드와 같이, Event.SOUND_COMPLETE를 사용하여 사운드를 루프시키고 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import flash.media.*;
import flash.events.*;
import flash.utils.Timer;
 
var snd:Sound = new loop();
var chn:SoundChannel;
 
function playSound():void
{
	if(chn){
		chn.removeEventListener(Event.SOUND_COMPLETE, sndListener);
	}
	chn = snd.play();
	chn.addEventListener(Event.SOUND_COMPLETE, sndListener);
}
 
function sndListener(e:Event):void
{
	playSound();
}
 
lbl.text = "Loop with Event.SOUND_COMPLETE";
btn2.enabled = false;
btn1.addEventListener(MouseEvent.CLICK, clickListener1);
btn2.addEventListener(MouseEvent.CLICK, clickListener2);
function clickListener1(e:MouseEvent):void
{
	playSound();
	btn1.enabled = false;
	btn2.enabled = true;
}
function clickListener2(e:MouseEvent):void
{
	btn1.enabled = true;
	btn2.enabled = false;
	chn.stop();
}

Continue reading »

 

XML에 차일드 노드를 추가하는 것은 XML.appendChild() 메소드를 사용하면 되는데, 공식적으로 속성(attribute)을 추가하는 메소드는 없습니다.

그래서 구글로 검색해 보니, 다음과 같은 방법으로 간단히 속성을 추가할 수가 있네요.

var xml:XML = new XML(<root />);
xml.@newAtrb = "value";
trace(xml.toXMLString());
// output: <root newAtrb="value"/>
 

배열(Array)을 벡터(Vector)로 변환하는 것을 테스트 해봤습니다. 인터넷에서 검색해보면 거의 for나 for in을 사용해서 변환을 시키더군요. 그래서 Function.apply()를 사용하면 어떨까 하고 시험해 봤는데, apply 가 압도적인 속도를 보여주고, 코드 또한 간결하네요.

아래 코드로 테스트 해보면 대충 for는 80ms, for in은 90ms, apply는 15ms 정도의 속도를 보여줍니다. Function.apply()를 가끔 사용하긴 하는데, 이렇게 빠른지는 오늘 처음 알았네요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import flash.utils.getTimer;
 
// original array
var arr:Array = new Array();
for(var i:uint=0; i<1000000; i++){
	arr.push(i);
}
 
// vector
var vec:Vector.<int> = new Vector.<int>();
 
var n:int = getTimer();
 
// for
/*var len:uint = arr.length;
for(i=0; i<len; i++){
	vec.push(arr[i]);
}*/
 
// for in
/*var num:uint;
for each(num in arr)
{
    vec.push(num); 
}*/
 
// Function.apply
vec.push.apply(null, arr);
 
trace(getTimer() - n);
trace(vec.length);
 

이전 프로젝트에서 데모로 만들었던 기능인데, 이번 프로젝트에서도 사용할 수 있을 것 같아서 개발하는 중인 샘플입니다. 우선 LayoutEditor 에서 격자로 배치된 셀들을 선택하여 병합/분할이 가능하고, 만들어진 레이아웃을 XML로 저장합니다.

저장된 XML을 ItemArranger 에서 로드하여, 필요한 컴퍼넌트를 배치하여 최종 상태를 다시 XML로 저장합니다.

이렇게 만들어진 XML을 다른 어플리케이션에서 불러와, 위에서 만들어진 레이아웃대로 화면을 구성하도록 할 수 있죠.

이거 만들면서 테스트 해봤는데, 조금 응용하면 드림위버 같은 HTML 에디터의 테이블 편집 기능도 충분히 구현할 수 있더군요. 물론, 반대로 HTML의 테이블 태그를 액션스크립트로 파싱하여 표시하는 것도 가능하고요.

 

어제 올렸던 대시라인 그리기에서 조금 더 기능을 추가해 봤습니다. 포토샵에서 선택영역을 지정하면 점선이 이동하는 효과가 나오는데, 그걸 적용했습니다. 행진하는 개미 ^^

beginBitmapFill(bitmap:BitmapData, matrix:Matrix=null, repeat:Boolean=true, smooth:Boolean=false):void
위와 같이 Graphics.beginBitmapFill() 메소드에 2번째 파라메터로 매트릭스를 지정하여 사용할 수 있습니다. 그래서 하나의 비트맵데이터를 가지고 매트릭스에 회전을 주어서 사용을 했더니, 비트맵데이터가 외곡되는 문제가 생기네요. 일단 귀찮아서 비트맵데이터 4개를 가지고 그렸는데, 최적화하는 방법은 좀 더 찾아 봐야할 듯 하네요.

click to view the source code

© 2011 Hangun's World - Blog Suffusion theme by Sayontan Sinha