지금까지 Sound, SoundChannel, SoundTransform을 이용하여 만들어 보았다. 그렇다면 좀더 시각적인 효과를 넣어 만들어 보자. 지금까지 만들어진 파일에 몇가지를 추가해보자.
사운드 스펙트럼을 추가하여 재생되고 있는 사운드 데이터 파형을 시각적으로 보여주고, 사운드의 진행상태를 파악하기 위해 progress bar를 추가하여 보겠다.
[code as3]
package
{
import fl.events.SliderEvent;
import fl.controls.Slider;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.net.URLRequest;
public class MyMusic extends Sprite
{
public function MyMusic()
{
super(); // Sprite 클래스(상속하는 상위클래스) 생성.
configureSound(); // 사운드 설정
}
/**
* @private
* 사운드 객체 : 객체 생성시 자동으로 사운드 파일 로드.
*/
private var music:Sound = new PowerUp(); //new Sound(new URLRequest("힘을내줘.mp3"));
/**
* @private
* 사운드 채널
*/
private var channel:SoundChannel;
/**
* @private
* 현재 재생 위치(ms)
*/
private var position:Number = 0;
/**
* @private
* 사운드 변환 : 볼륨 및 패닝 속성 포함.
*/
private var vol_tran:SoundTransform;
/**
* @private
* 사운드 스펙트럼.
*/
private var spectrum:Sprite;
/**
* @private
* 스펙트럼 그리기.
*/
private var gt:Graphics;
/**
* @private
* 사운드 ByteArray
*/
private var ba:ByteArray;
/**
* @private
* 사운드 초기화
*
* Slider(클래스) snapInterval(속성) : 패닝 slider 이동시 값이 증가하거나 감소하는 기준 간격 설정.
*/
private function configureSound():void
{
pan_slider.maximum = 1; // 패닝 Slider 최대값 설정.
pan_slider.minimum = -1; // 패닝 Slider 최소값 설정.
pan_slider.value = 0; // 기본값 0으로 설정.
pan_slider.snapInterval = 0.1; // 0.1만큼 증가 감소.
pause_btn.mouseEnabled = false; // 일시정지버튼 비활성화.
play_btn.mouseEnabled = true; // 재생 버튼 활성화.
pause_btn.addEventListener(MouseEvent.CLICK, pauseButtonClickHandler); //일시정지버튼 이벤트 등록.
play_btn.addEventListener(MouseEvent.CLICK, playButtonClickHandler); // 재생버튼 이벤트 등록.
sound_vol.addEventListener(SliderEvent.THUMB_DRAG, volumeSliderHandler); // 볼륨조절 이벤트 등록
pan_slider.addEventListener(SliderEvent.THUMB_DRAG, panSliderHandler); // 패닝조절 이벤트 등록
}
/**
* @private
* 재생시간 출력 : 단위시간을 00:00 형식으로 출력
*
* 분 : Math.floor(sec/60)
* 초 : Math.floor(sec%60)
* Math 클래스의 유용한 메서드 : Math.ceil() - 올림, Math.round() - 반올림, Math.floor() - 내림
*/
private function ConverTime(milli:Number):String
{
var n:Number = milli / 1000; // 입력값이 ms(밀리초)이므로 1000으로 나눠 초단위로 바꿈
var min:int = Math.floor(n/60); // 분 계산
var second:int = Math.floor(n%60); // 초 계산
var min_str:String; // 분 단위 형식 저장
var second_str:String; // 초 단위 형식 저장
if(min<10) // 계산된 분이 10보다 작으면
{
min_str = "0" + min; // "0" 와 계산된 분을 더해 분의 두자리 형식 만듬
}
else // 계산된 분이 10보다 크면
{
min_str = String(min); // 계산된 분을 String으로 캐스팅
}
if(second<10) // 계산된 초가 10보다 작으면
{
second_str = "0" +second; // "0" 와 계산된 초를 더해 초의 두자리 형식 만듬
}
else // 계산된 초가 10보다 크면
{
second_str = String(second); // 계산된 초를 String으로 캐스팅
}
return min_str + ":" + second_str; // 계산된 분과 초를 "00:00" 형식으로 만들어 반환
}
/**
* @private
* 사운드 진행상태( progress_mc 와 스펙트럼)
*
* percent(백분율) : 현재 재생 위치 / 사운드 시간
* ByteArray : 만들어진 ByteArray 객체의 크기는 512개의 부동 소수점 값으로 고정.
* 처음 256개의 값은 왼쪽 채널을, 다음 256개의 값은 오른쪽 채널.
* 진폭 범위 : -1 ~ 1 (부동 소수점 값)
*/
private function barEnterFrameHandler(event:Event):void
{
var percent:Number = (channel.position / music.length) * 100;
progress_mc.bar_mc.scaleX = percent; // percent값을 bar_mc에 적용
position_txt.text = (ConverTime(channel.position)); // 현재 재생 시간
length_txt.text = (ConverTime(music.length)); //전체 재생 시간
if(!spectrum)
{
spectrum = new Sprite(); // 사운드 스펙트럼을 그려 넣을 Sprite 객체 생성
gt = spectrum.graphics; // 스펙트럼 그리기위해 Graphics 클래스 생성
spectrum.y = 150; // 사운드 스펙트럼 위치 설정
addChild(spectrum); // 사운드 스펙트럼 화면에 표시(Sprite 객체 DisplayObject에 추가)
ba = new ByteArray(); // 512byte의 사운드 정보를 담음
}
gt.clear(); // 스팩트럼 그리기 전에 지움
gt.lineStyle(1, 0x0000FF, 1); // 선 스타일 지정 : 선의 두께, 색상값, 알파값
gt.beginFill(0x0000FF, 1); // 색 채우기 : 채울 색상값, 알파값
gt.moveTo(0, 0); // 현재 위치 이동 : pixel단위
SoundMixer.computeSpectrum(ba, false); // 사운드 정보 저장, 사운드 파형은 진폭.
for(var i:uint = 0; i < 512; i++)
{
var n:Number = ba.readFloat() * 100;
gt.lineTo(i, n);
}
}
/**
* @private
* 사운드 종료
*/
private function barSoundCompletehandler(event:Event):void
{
removeEventListener(Event.ENTER_FRAME, barEnterFrameHandler); // 사운드 종료 후 이벤트 제거
}
/**
* @private
* 사운드 볼륨
*
* 사운드 볼륨 범위 : 0 ~ 1
* SoundTransForm의 volume 속성 값 : 0 ~ 1
* Slider Component 값(정수값) : -1, 0, 1
* event.target : 마우스로 Slider를 클릭한 지점
* Slider(클래스) value(속성) : 현재 값을 가져오거나 설정.
* 이 값은 최소값과 최대값 사이에서 슬라이더 썸의 위치에 따라 결정.
* Slider : maximum = 10, minimum = 0
*/
private function volumeSliderHandler(event:SliderEvent):void
{
vol_tran = channel.soundTransform; // 현재 재생되고 있는 사운드의 볼륨 정보를 넘겨줌.
vol_tran.volume = event.target.value / 10; // 실제 보륨에 적용하기 위해 단위변환.
channel.soundTransform = vol_tran; // 변환된 사운드의 볼륨을 다시 적용.
}
/**
* @private
* 사운드 패닝
*
* 사운드 패닝 범위 : -1 ~ 1
* SoundTransForm의 volume 속성 값 : 0 ~ 1
* Slider Component 값(정수값) : -1, 0, 1
*/
private function panSliderHandler(event:SliderEvent):void
{
vol_tran = channel.soundTransform; // 현재 재생되고 있는 사운드의 패닝 정보를 넘겨줌.
vol_tran.pan = event.value;
channel.soundTransform = vol_tran; // 변환된 사운드의 패닝 다시 적용.
}
/**
* @private
* 일시정지 버튼
* channel : 사운드 정지시 등록한 이벤트 제거
* progress_mc : 사운드 정지시 진행상황 등록 이벤트 제거
*/
private function pauseButtonClickHandler(event:MouseEvent):void
{
pause_btn.mouseEnabled = false; // 일시정지버튼 비활성화
play_btn.mouseEnabled = true; // 재생 버튼 활성화
position = channel.position; // 현재 재생 위치 저장
channel.stop(); // 사운드 정지
channel.removeEventListener(Event.SOUND_COMPLETE, barSoundCompletehandler);
progress_mc.removeEventListener(Event.ENTER_FRAME, barEnterFrameHandler);
}
/**
* @private
* 재생 버튼
* channel : 재생이 끝나면 다시 재생시킬 수 있도록 이벤트 등록
* progress_mc : 지속적으로 현재 재생 위치를 알아오기 위해 이벤트 등록
*/
private function playButtonClickHandler(event:MouseEvent):void
{
pause_btn.mouseEnabled = true; // 일시정지버튼 활성화
play_btn.mouseEnabled = false; // 재생버튼 비활성화
channel = music.play(position); // 사운드 재생
vol_tran = channel.soundTransform; // 현재 재생되고 있는 사운드의 볼륨, 패닝 정보를 넘겨줌.
vol_tran.volume = sound_vol.value / 10;
channel.soundTransform = vol_tran; // 변환된 사운드의 볼륨, 패닝을 다시 적용.
channel.addEventListener(Event.SOUND_COMPLETE, barSoundCompletehandler);
progress_mc.addEventListener(Event.ENTER_FRAME, barEnterFrameHandler);
}
}
}
[/code]
댓글 없음:
댓글 쓰기