'Sound'에 해당되는 글 4건

  1. 2011.03.05 [AS3] Flash 로 오디오 플레이어 만들기 (4)
  2. 2010.10.10 ID3 관련 사이트 (1)
  3. 2008.12.11 [AS3.0] Sound Spectrum
  4. 2008.12.11 [AS3.0] flash.media.Sound 기본내용정리.
Actionscript3.02011.03.05 12:13

 Flash Player 는 다양한 멀티미디어를 불러오고 재생 할 수 있다. 그 중에서 오디오 관련 파일은 기본적으로 MP3 파일을 재생 할 수 있으며, popforge (http://code.google.com/p/popforge/) 와 같은 라이브러리를 사용하면 WAVE 파일도 재생 가능 하다. 하지만 이 문서에서는 Actionscript3 에서 제공하고 있는 기본 API 를 가지고 파일을 불러오고 재생 하기 위한 기본적인 이론에 대해 다룬다.


 Flash 에서 오디오 파일을 재생 하기 위해서는 Sound, SoundChannel 를 사용한다. 디테일한 플레이어를 구현하기 위해서는 다른 클래스도 알아야 하지만 기본 기능만 만든다면 위 두가지 클래스의 레퍼런스만 봐도 충분히 구현 할 수 있다. 


Sound Class


 Sound Class 를 MP3 파일을 로드 하고 재생 하는 기능을 담당한다. 파일을 로드 하기 위한 load, 재생하기 위한 play, 재생을 끈어버리기(재생의 멈춤이 아니다) 위한 close 메소드 등을 가지고 있다. MP3 파일을 재생 하기 위해서는 다음과 같은 절차를 따라야 한다.


1. Sound 객체 생성

2. Sound 객체에 Event.COMPLETE 이벤트 등록

3. load 메소드를 이용하여 파일 로드

4. 로드가 완료 되면 2 에서 등록했던 이벤트가 발생

5. 로드가 완료 된 후에 play 메소드를 이용해서 재생 


 오디오 파일을 로드 하는 방법은 URLLoader 나 Loader 에서 사용하는 방법과 동일하다. 다음은 위의 절차를 코드화 한 것이다.



package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.media.Sound;
	import flash.net.Socket;
	import flash.net.URLRequest;
	
	public class SoundPlayerTest extends Sprite
	{
		private var _player:Sound;
		public function SoundPlayerTest()
		{
			_player = new Sound();
			_player.addEventListener(Event.COMPLETE, playerReadyHandler);			
			_player.addEventListener(IOErrorEvent.IO_ERROR, playerIOErrorHandler);
			_player.addEventListener(SecurityErrorEvent.SECURITY_ERROR, playerSecurityErrorHandler);
			
			_player.load(new URLRequest("remote/file/10cm_01.mp3"));
		}
		private function playerReadyHandler(event:Event):void 
		{		
			_player.play();
		}		
		private function playerIOErrorHandler(event:IOErrorEvent):void 
		{
			trace("로드에러");
		}
		private function playerSecurityErrorHandler(event:SecurityErrorEvent):void 
		{
			trace("보안에러");
		}
		
	}
}


 위와 같은 방법으로 로드를 하면 해당 파일에 대한 length 로 음원의 길이를 알수 있고, MP3 파일은 곡의 정보를 담고 있는 id3 태그를 가질수 있기 때문에 해당 파일에 id3 태그가 있다면 접근 할 수 있다. 기본적으로 접근 할 수 있는 id3 는 다음과 같다.



_player.addEventListener(Event.ID3, id3TagLoadHandler);
private function id3TagLoadHandler(event:Event):void 
{
	trace("album : "+_player.id3.album);
	trace("artist : "+_player.id3.artist);
	trace("comment : "+_player.id3.comment);
	trace("genre : "+_player.id3.genre);
	trace("songName : "+_player.id3.songName);
	trace("track : "+_player.id3.track);
	trace("year : "+_player.id3.year);
}


id3 태그에 대한 더 자세한 내용은 뒷부분에서 다루고 있다.


주의 해야 할 점은 새로운 파일을 로드 할때마다 Sound 객체를 새로 생성해 줘야 한다. 재사용할시 에러가 발생한다.


SoundChannel Class 


Sound Class 가 중요한 기능을 하고 있지만 모든 기능을 제공 하지는 않는다. SoundChannel Class 를 이용하여 사운드를 재생 하면서 디테일한 조작을 할 수 있다. SoundChannel Class 를 보면 다음과 같은 메소드와 속성이 정의 되어 있다.


속성


leftPeak, rightPeak : 왼쪽 오른쪽의 현재 진폭(볼륨)을 나타내는 0(묵음)부터 1(최대 진폭)까지의 값

position : 사운드가 재생 중일 때 position 속성은 사운드 파일에서 재생 중인 현재 위치를 밀리초 단위 나타냄

soundTransform : SoundChannel 이 가지고 있는 사운드를 조작하기 위한 SoundTransform 객체



메소드

stop : 사운드 재생을 중단


위의 Sound 객체에 stop 메소드가 없고, SoundChannel 에 stop 메소드가 정의 되어 있다. 그 이유는 Sound 객체는 play 메소드를 이용하여 로드한 파일을 열어 주는 역할을 하고 SoundChannel 은 열린 파일 스트림에 대해 조작 역할을 한다.

load 메소드를 이용해 파일을 로드 하고 play 를 할때 play 메소드의 반환값으로 SoundChannel 객체가 넘어오므로 사운드를 조작 하기위해서는 이 반환객체를 조작 하여 사운드를 컨트롤 할 수 있다.



var channel:SoundChannel = new SoundChannel();

channel = _player.play();


일시 정지 및 재생 위치 변경


Sound Class 나 SoundChannel Class 나 모두 일시정지하는 메소드가 없다. 일시정지 기능은 SoundChannel 의 position 값과 Sound Class 의 play 메소드를 사용하여 구현 할 수 있다. 먼저 사운드를 일시 정지 할때 SoundChannel 의 position 값을 저장하고, 다시 재생 하면 Sound 의 play 메소드의 파라미터로 해당 position 값을 넘겨 줘서 사운드를 재생 하면 된다. 코드는 다음과 같다.

 
private function play(position:Number = 0):void 

{	
		
	_channel = _player.play(position);

}


private function pause():void 

{

	_channel.stop();

}

// 재생 버튼 클릭

private function playButtonClicked(event:MouseEvent):void

{

	play(_channel.position);

}

// 일시 정지 버튼 클릭		

private function pauseButtonClicked(event:MouseEvent):void

{

	pause();

}


재생 위치를 변경하는것도 위와 같은 방식으로 하면 된다. 단 play 할때 position 의 위치가 로드된 파일 길이보다 길면 재생이 안된다. 그러므로 Sound 객체의 length 보다 긴지 확인이 필요하다.


private function play(position:Number = 0):void 

{		

       if(position > _player.length)	
       { 
                 position  = _player.length; 
       }

       _channel = _player.play(position);

}


볼륨 변경


볼륨은 SoundChannel 의 soundTransform 을 이용한다. soundTransform 속성은 SoundTransform 객체 이다. 이 객체는 사운드 볼륨을 조작 하기 위한 여러 속성을 가지고 있다. 이 속성 중 volume 값을 변경 하면 된다. 값은 0 ~ 1 사이 이다.



var soundTransform:SoundTransform = new SoundTransform();

soundTransform.volume = 변경할 값;

_channel.soundTransform = soundTransform;


주의할 점은 SoundChannel 객체의 soundTransform 값을 직접 변경 하는것이 아니라, 새로운 SoundTransform 을 생성하여 값을 변경한 후에 적용해 주는 방식이다.


id3 태그



 MP3 파일에는 id3 태그가 파일안에 정의 되어 있다. 그 형식들은 여러가지가 있으며, Flash Player 9 이후 버전 및 AIR 에서는 ID3 2.0 태그, 특히 2.3 및 2.4 태그를 지원 한다. 위의 예제에서 Event.ID3 이벤트를 통해 접근한 속성들은 Actionscript3 ID3Info (http://help.adobe.com/ko_KR/Flash/CS5/AS3LR/flash/media/ID3Info.html객체에서 정의하고 있는 값들이고 이외에도 Flash IDE 나 Flash Builder 의 자동완성에는 나오지 않지만 아래의 속성들이 접근 가능하다. 하지만 모든 값들은 해당 파일에 해당 속성이 정의 되어 있을 경우에만 접근 가능하고 정의 되어 있지 않다면 null 을 반환 한다.


Posted by Flash 동강
Programming2010.10.10 20:38

개인적으로 만들어 보고 싶은게 있어서 찾아본 id3 사이트들.



ID3 레퍼런스


http://www.id3.org/



ID3 Parser ( 가사 못불러옴 )



http://blog.ashier.com/2007/11/08/id3-parser/#comments



ID3 분석



http://clansim.tistory.com/99


http://blueskybox.tistory.com/31


http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm


http://www.gigamonkeys.com/book/practical-an-id3-parser.html


http://blog.naver.com/ttakiya?Redirect=Log&logNo=120001348951




ID3 가사 Write



http://mudchobo.tomeii.com/tt/443




ID3 태그 쓰기 (id3v1)



http://help.adobe.com/ko_KR/AIR/1.5/devappsflash/WS5b3ccc516d4fbf351e63e3d118666ade46-7dc4.html






'Programming' 카테고리의 다른 글

Facebook actionscript API  (0) 2011.11.27
ID3 관련 사이트  (1) 2010.10.10
Code Naming  (3) 2009.11.11
Strategy Pattern (AS3)  (4) 2009.08.26
Posted by Flash 동강
TAG ID3, MP3, Sound
Actionscript3.02008.12.11 11:46

SoundMixer.computeSpectrum() 
SoundMixer.computeSpectrum() 를 이용하면 현재 재생하고 있는 사운드에 대한 원시 데이터를 불러올수 있습니다. 

다음 그림에서는 FFTMode 매개 변수가 true로 설정되었을 때와 false로 설정되었을 때 computeSpectrum() 메서드로부터 반환된 데이터를 비교합니다. 이 그림에 사용된 사운드 데이터는 왼쪽 채널은 큰 베이스 사운드, 오른쪽 채널은 드럼 사운드에 대한 것입니다.

 

 // 드로잉 API 를 이용한 간단한 사운드 스트리밍
  1. import flash.display.Graphics;
  2. import flash.events.Event;
  3. import flash.media.Sound;
  4. import flash.media.SoundChannel;
  5. import flash.media.SoundMixer;
  6. import flash.net.URLRequest;
  7.  
  8. const PLOT_HEIGHT:int = 200;
  9. const CHANNEL_LENGTH:int = 256;
  10.  
  11. var snd:Sound = new Sound();
  12. var req:URLRequest = new URLRequest("mystory.mp3");
  13. snd.load(req);
  14.  
  15. var channel:SoundChannel;
  16. channel = snd.play();
  17. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  18. snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
  19.  
  20. var bytes:ByteArray = new ByteArray();
  21.  
  22. function onEnterFrame(event:Event):void
  23. {
  24.     SoundMixer.computeSpectrum(bytes, false, 0);
  25.    
  26.     var g:Graphics = this.graphics;
  27.    
  28.     g.clear();
  29.     g.lineStyle(0, 0x6600CC);
  30.     g.beginFill(0x6600CC);
  31.     g.moveTo(0, PLOT_HEIGHT);
  32.    
  33.     var n:Number = 0;
  34.        
  35.     // 왼쪽 채널
  36.     for (var i:int = 0; i < CHANNEL_LENGTH; i++)
  37.     {
  38.         n = (bytes.readFloat() * PLOT_HEIGHT);
  39.         g.lineTo(i * 2, PLOT_HEIGHT - n);
  40.     }
  41.     g.lineTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
  42.     g.endFill();
  43.    
  44.     // 오른쪽 채널
  45.     g.lineStyle(0, 0xCC0066);
  46.     g.beginFill(0xCC0066, 0.5);
  47.     g.moveTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
  48.    
  49.     for (i = CHANNEL_LENGTH; i > 0; i--)
  50.     {
  51.         n = (bytes.readFloat() * PLOT_HEIGHT);
  52.         g.lineTo(i * 2, PLOT_HEIGHT - n);
  53.     }
  54.     g.lineTo(0, PLOT_HEIGHT);
  55.     g.endFill();
  56. }
  57.  
  58. function onPlaybackComplete(event:Event)
  59. {
  60.     removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  61. }

 사운드 데이터는 512바이트의 데이터가 포함된 ByteArray 객체로 반환되며 각 개체는 -1과 1 사이의 부동 소수점 값을 포함합니다. 이러한 값은 재생 중인 사운드 파형의 위치 진폭을 나타냅니다. 값은 두 개의 256바이트 그룹으로 제공됩니다. 첫 번째 그룹은 왼쪽 스테레오 채널용이고 두 번째 그룹은 오른쪽 스테레오 채널용입니다.
FFTMode 매개 변수가 true로 설정된 경우, SoundMixer.computeSpectrum() 메서드는 파형 데이터가 아니라 주파수 스펙트럼 데이터를 반환합니다. 주파수 스펙트럼은 가장 낮은 주파수에서 가장 높은 주파수까지 사운드 주파수에 따라 배열된 진폭을 표시합니다. FFT(Fast Fourier Transform)는 파형 데이터를 주파수 스펙트럼 데이터로 변환하는 데 사용됩니다. 결과 주파수 스펙트럼 값은 0에서 약 1.414(2의 제곱근)까지입니다.

Posted by Flash 동강
Actionscript3.02008.12.11 11:44

Actionscript 3.0 에서의 사운드 작업 

ActionScript 3.0을 사용하여 사운드를 재생할 경우 다음 작업을 수행할 수 있습니다.

  • 특정 시작 위치에서 사운드 재생
  • 사운드를 일시 정지하고 나중에 같은 위치에서 다시 재생 시작
  • 사운드 재생이 끝나는 정확한 시간 알아보기
  • 사운드의 재생 진행률 추적
  • 사운드 재생 중에 볼륨 변경 및 패닝

위의 기능은 Sound 클래스로만 이룰 수 있는게 아니라 SoundChannel 이나 SoundMixer SoundTransform 클래스를 이용해야 가능합니다.  

기본적으로 Sound 클래스의 재생과 정지는 다음과 같습니다.

 

// 재생

var snd:Sound = new Sound(new URLRequest("bigSound.mp3"));
var channel:SoundChannel = snd.play();

//정지

var pausePosition:int = channel.position;
channel.stop();

 

//특정 위치에서의 사운드 시작

channel = snd.play(pausePosition);

 

// mp3 파일의 로드 처리시 기본 사용.

//재생 진행률을 표시하는 데 Event.ENTER_FRAME 이벤트를 시간 메커니즘으로 사용합니다. 그리고 현재 위치 값을 사운드 데이터의 전체 길이로 나누어 계산되는 재생 백분율을 정기적으로 보고합니다.

 

import flash.events.Event;
import flash.media.Sound;
import flash.net.URLRequest;

var snd:Sound = new Sound();
var req:URLRequest = new
    URLRequest("http://av.adobe.com/podcast/csbu_dev_podcast_epi_2.mp3");
snd.load(req);

var channel:SoundChannel;
channel = snd.play();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);

function onEnterFrame(event:Event):void
{
    var estimatedLength:int =
        Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal));
    var playbackPercent:uint =
        Math.round(100 * (channel.position / estimatedLength));
    trace("Sound playback is " + playbackPercent + "% complete.");
}

function onPlaybackComplete(event:Event)
{
    trace("The sound has finished playing.");
    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}

 사운드를 스트리밍 중 중단했을시 발생하는 문제

스트리밍되는 사운드 즉, 재생하는 동안 계속 로드되는 사운드의 경우 재생 프로세스에 이상 현상이 발생하기도 합니다. 스트리밍 사운드를 재생 중인 SoundChannel 인스턴스에서 응용 프로그램이 SoundChannel.stop() 메서드를 호출하면 한 프레임에 대한 사운드 재생이 중지되고 다음 프레임에서 사운드를 처음부터 다시 재생합니다. 이러한 현상이 나타나는 이유는 사운드 로드 프로세스가 아직 진행 중이기 때문입니다. 스트리밍 사운드의 로드와 재생을 모두 중단하려면 Sound.close() 메서드를 호출합니다. 

역시 고려 되야 하는 사운드 로드시 보안문제

사운드 파일의 원본 도메인은 내용 샌드박스의 보안 제한 사항을 정의합니다. 일반적으로 사운드 파일을 로드하는 응용 프로그램 또는 객체의 SWF 파일과 동일한 도메인 또는 폴더에 사운드 파일이 있으면 응용 프로그램 또는 객체는 해당 사운드 파일에 액세스할 수 있습니다. 응용 프로그램과는 다른 도메인에서 사운드가 제공되는 경우에도 크로스 도메인 정책 파일을 사용하여 내용 샌드박스에서 사운드를 가져올 수 있습니다.

응용 프로그램은 checkPolicyFile 속성을 사용하여 SoundLoaderContext 객체를 Sound.load() 메서드에 매개 변수로 전달할 수 있습니다. checkPolicyFile 속성을 true로 설정하면 Flash Player는 사운드가 로드된 서버에서 크로스 도메인 정책 파일을 찾습니다. 크로스 도메인 정책 파일이 존재하고 로드하는 SWF 파일의 도메인에 액세스 권한이 부여되면 SWF 파일은 사운드 파일을 로드하고 Sound 객체의 id3 속성에 액세스한 다음 로드된 사운드에 대한 SoundMixer.computeSpectrum() 메서드를 호출합니다.

소유자 샌드박스는 사운드의 로컬 재생을 제어합니다. 사운드 재생을 시작하는 응용 프로그램 또는 객체가 소유자 샌드박스를 정의합니다.

다음 조건에 맞는 경우 SoundMixer.stopAll() 메서드는 현재 재생 중인 모든 SoundChannel 객체의 사운드를 중지합니다.

  • 동일한 소유자 샌드박스 내의 객체에 의해 시작된 사운드
  • SoundMixer.stopAll() 메서드를 호출하는 응용 프로그램 또는 객체의 도메인에 대한 액세스를 허용하는 크로스 도메인 정책 파일을 가진 소스에서 제공되는 사운드

SoundMixer.stopAll() 메서드가 모든 재생 사운드를 실제로 중지하는지 알아보기 위해 응용 프로그램이 SoundMixer.areSoundsInaccessible() 메서드를 호출할 수 있습니다. 해당 메서드가 true 값을 반환하면 재생 중인 일부 사운드는 현재 소유자 샌드박스의 제어 범위를 벗어나므로 SoundMixer.stopAll() 메서드에 의해 중지되지 않습니다.

또한 SoundMixer.stopAll() 메서드는 외부 파일로부터 로드된 모든 사운드에 대해 재생 헤드가 계속 진행되지 않도록 중지합니다. 하지만 Flash 제작 도구를 사용하여 FLA 파일에 포함된 사운드 및 타임라인 내 프레임에 연결된 사운드는애니메이션이 새 프레임으로 이동하면 다시 재생되기 시작합니다.  

스피커 마다의 패닝 제어 

SoundChannel 객체의 팬 속성은 재생 중에 왼쪽 및 오른쪽 채널 각각에 다른 볼륨 수준을 지정하는 데 사용될 수 있습니다. 팬 속성은 -1 ~ 1 범위의 값을 가질 수 있습니다. 여기서 -1은 오른쪽 채널 음을 소거한 상태에서 왼쪽 채널을 최고 볼륨으로 재생한다는 의미이며, 1은 왼쪽 채널 음을 소거한 상태에서 오른쪽 채널을 최고 볼륨으로 재생한다는 의미입니다. -1과 1 사이의 숫자 값은 왼쪽과 오른쪽 채널 값에 대한 비례 값을 설정하며, 0은 양쪽 채널이 균형 있는 중간 볼륨 수준으로 재생된다는 의미입니다. 

 // Enterframe 을 이용하여 스피커의 양쪽 볼륨을 왔다 갔다 하는 코드 입니다.
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;

var snd:Sound = new Sound();         
var req:URLRequest = new URLRequest("bigSound.mp3");
snd.load(req);

var panCounter:Number = 0;

var trans:SoundTransform;
trans = new SoundTransform(1, 0);
var channel:SoundChannel = snd.play(0, 1, trans);
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);

addEventListener(Event.ENTER_FRAME, onEnterFrame);

function onEnterFrame(event:Event):void
{
    trans.pan = Math.sin(panCounter);
    channel.soundTransform = trans; // 또는 SoundMixer.soundTransform = trans;
    panCounter += 0.05;
}

function onPlaybackComplete(event:Event):void
{
    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
 본 내용은 Flash CS3 설명서를 정리한 내용 입니다.

Posted by Flash 동강