Flashゲームプログラミング講座 for ActionScript3.0

 

サウンド関係のクラスについて

 


■ SoundMixer クラスとは?


静的に配置したすべてのサウンド」に対して一括で効果を付ける事ができます。
 
このクラスは静的に呼び出します。インスタンス化する必要はありません。
 
ストリームのバッファ秒を変更したり、ボリュームやパンといったスピーカーからの出力時のパラメータを設定することが出来ます。
 

■ Sound クラスとは?


サウンドを動的に再生する事ができます。
 
外部にあるサウンドファイルをストリーミングで読み込んだり、ライブラリにあるサウンドファイルを使って再生や停止を行うことが出来ます。
 

■ SoundChannel クラスとは?


動的に再生したサウンドに対して効果を付ける事ができます。
 
Sound クラスの play() メソッドの戻り値から取得できます。 ボリュームやパンといったスピーカーからの出力時のパラメータを設定することが出来ます。
 

■ SoundTransform クラスとは?


ボリュームやパンといった出力時のパラメータを格納する事ができます。
 
SoundMixer クラスや SoundChannel クラス、Sprite クラス等には、 soundTransform プロパティがあり、ここに SoundTransform オブジェクトを渡すと適用できます。
 

■チャンネルについて


FlashPlayer 9 以降がサポートしているサウンドのチャンネル数は 32 個です。
 
 



外部にあるサウンドファイルを再生する

 

サンプルをダウンロード
 


■読み込み可能なサウンドファイルを用意する


まず、サウンドファイルを用意します。
 
外部から読み込む事が可能なファイルは mp3 形式のみです。フォーマットも下記の制限があります。
 

■読み込み可能なフォーマット

 
■ビットレート方式

方式 利用の可否
CBR(固定ビットレート)
ABR(平均ビットレート) ×
VBR(可変ビットレート) ×
FFS(フリーフォーマットストリーム) ×
 
■サンプリングレート

44,100HZ
22,050HZ
11,025HZ
 
■ビットレート

160kbps
128kbps
112kbps
80kbps
64kbps
56kbps
48kbps
32kbps
24kbps
20kbps
16kbps
8kbps
 



■サウンドクラスをインスタンス化する


まずサウンドクラスをインスタンス化します。第01引数にサウンドファイルが置いてある相対パスかURLを指定すると、ストリーム読み込みを開始します。
 
第01引数を省略した場合は何も起こりません。
 
new Sound ( URL , SoundLoaderContext );
第01引数(略可)サウンドファイルまでの相対パスかURLをURLRequest型で指定します。
第02引数(略可)SoundLoaderContext オブジェクトを指定します。
戻り値 なし
 
サウンドクラスをインスタンス化しストリーム読み込みを開始する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトを作成してストリーム読み込みを開始
var sound_obj : Sound = new Sound(url);

swfファイルからの相対パスを使う事もできる

// サウンドファイルのURL
var url : URLRequest = new URLRequest("../sound/test.mp3");

// サウンドオブジェクトを作成してストリーム読み込みを開始
var sound_obj : Sound = new Sound(url);
 

■ストリーム読み込みを開始する


Sound クラスをインスタンス化するときに引数を省略した場合、 load() メソッドを使用して後からストリーム読み込みを開始することが出来ます。
 
すでにストリーム読み込み中にもかかわらずこのメソッドを呼び出すとエラーとなります。
 
Sound.load ( URL , SoundLoaderContext );
第01引数 サウンドファイルまでの相対パスかURLをURLRequest型で指定します。
第02引数(略可)SoundLoaderContext オブジェクトを指定します。
戻り値 なし
 
サウンドクラスをインスタンス化し、後でストリーム読み込みを開始する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトの作成
var sound_obj : Sound = new Sound();

// ストリーム読み込みを開始
sound_obj.load(url);
 
一度ストリーム読み込みを開始したら、サウンドオブジェクトを再利用して別のファイルを読み込むことはできません。
 
別のファイルを読み込みたい場合は、現在のサウンオブジェクトを破棄して、新しくサウンドオブジェクトを作り直します。
 

■ストリーム読み込みを停止する


ストリーム読み込みを停止したい場合は、close() メソッドを呼び出します。閉じた後は、サウンドファイルにアクセスすることはできません。
 
読み込みが最後まで完了した場合、このメソッドを呼び出すとエラーとなります。
 
ストリーム読み込みを閉じる

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound();

// サウンドのストリーム読み込みを開始
sound_obj.load(url);

try{
	// ストリーム読み込みを閉じる
	sound_obj.close();

}catch(e:Error){
	trace("エラー");
}
 



■サウンドを再生する


play() メソッドを呼び出すと再生を開始します。
 
Sound.play ( 再生開始時間 , ループ回数 , SoundTransform );
第01引数(略可)再生を開始する時間を単位:ミリ秒で指定します。
第02引数(略可)ループ再生する回数を指定します。第01引数で指定した場所から開始されます。
第03引数(略可)サウンドの詳細をSoundTransform型で指定します。
戻り値 SoundChannel オブジェクトを返します。
 
■第03引数 SoundTransform オブジェクト

再生前に、ボリュームやパン等の効果を付けたい場合はここでパラメータを指定します。
 
■戻り値 SoundChannel オブジェクト

再生中に、ボリュームやパン等の効果を付けたい場合はここでパラメータを指定します。
 
使用例です。
 
3回繰り返して再生する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound(url);

// サウンドを再生
sound_obj.play(0,3);
 
再生開始前にボリュームを設定する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound(url);

// サウンドトランスフォームオブジェクトを作成
var trans : SoundTransform = new SoundTransform();
trans.volume = 0.1;	// ボリューム
trans.pan = -1;		// パン

// サウンドを再生
sound_obj.play(0,0,trans);
 

■サウンドを停止する


サウンドを停止するには、play() メソッドの戻り値で得られた SoundChannel オブジェクトを使用します。
 
このクラスの stop() メソッドを呼び出します。
 
サウンドを停止する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound(url);

// サウンドを再生
var channel : SoundChannel = sound_obj.play(0,3);

// サウンドを停止
channel.stop();
 

■ストリーム読み込みのローティング状況を知る


どれだけ読み込まれたかのローディング状況を知りたい場合は、

Event.OPEN、
ProgressEvent.PROGRESS、
Event.COMPLETE、
IOErrorEvent.IO_ERROR


イベントを使用します。
 
読み込み状況を知る

var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");
var sound_obj : Sound = new Sound(url);


sound_obj.addEventListener (Event.OPEN,SoundOpenFunc);
function SoundOpenFunc (event : Event):void {
	trace ("ストリーム読み込みを開始した");
}

sound_obj.addEventListener (ProgressEvent.PROGRESS,SoundProgressFunc);
function SoundProgressFunc (event : ProgressEvent):void {
	trace ("読込:" + event.bytesLoaded);
	trace ("全体:" + event.bytesTotal);
	trace ("パーセント:" + Math.floor(event.bytesLoaded/event.bytesTotal*100));
}

sound_obj.addEventListener (Event.COMPLETE,SoundCompleteFunc);
function SoundCompleteFunc (event : Event):void {
	trace ("読み込みを完了");
}

sound_obj.addEventListener (IOErrorEvent.IO_ERROR,SoundIOErrorFunc);
function SoundIOErrorFunc (event : IOErrorEvent):void {
	trace ("ファイル入出力のエラー");
}
 



■SoundLoaderContext クラスについて


SoundLoaderContext クラスは、外部からサウンドファイルを読み込むためのパラメータを設定することができます。
 
SoundLoaderContext クラスをインスタンス化します。
 
new SoundLoaderContext ( バッファ時間 , クロスドメインポリシーファイルを使用する? );
第01引数(略可)ストリーム再生のバッファ時間(単位:ミリ秒)を指定します。このバッファがすべて満たされるまで読み込み待ちとなり、再生が中断されます。デフォルトは 1000
第02引数(略可)クロスドメインポリシーファイルを使用する場合 true を指定します。不必要に設定するとパフォーマンスが落ちます。デフォルトは false
戻り値 SoundLoaderContext オブジェクトを返します。
 
プロパティからも設定する事ができます。
 
プロパティ名 説明
bufferTime Number ストリーム再生のバッファ時間(単位:ミリ秒)を指定します。このバッファがすべて満たされるまで読み込み待ちとなり、再生が中断されます。デフォルトは 1000
checkPolicyFile Boolean クロスドメインポリシーファイルを使用する場合 true を指定します。不必要に設定するとパフォーマンスが落ちます。デフォルトは false
 
設定例です。
 
ストリームのバッファ時間を 5000 に設定する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound();

// サウンドローダーコンテキストを作成
var sound_loader_context : SoundLoaderContext = new SoundLoaderContext(5000);

// サウンドのストリーム読み込みを開始
sound_obj.load(url,sound_loader_context);
 
クロスドメインポリシーファイルを読み込む事によるサンドボックスの制限解除を試みる

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound();

// サウンドローダーコンテキストを作成
var sound_loader_context : SoundLoaderContext = new SoundLoaderContext(1000,true);

// サウンドのストリーム読み込みを開始
sound_obj.load(url,sound_loader_context);
 

■サンドボックスについて


swf ファイルから別ドメインにある mp3 ファイルを読み込む場合、サンドボックスによる制限があります。
 
サウンドファイルを読み込んで再生することはできますが、ID3 タグを取得することができません。
 
サンドボックスによる制限の解除するには、
こちらで解説しているクロスドメインポリシーファイルを設置する必要があります。

さらに、SoundLoaderContext クラスを使用して「クロスドメインポリシーファイルを使用する」という設定を行う必要があります。
 
 



ライブラリにあるサウンドファイルを再生する

 

サンプルをダウンロード
 


1.ライブラリにサウンドファイルを追加する


Flash のライブラリウィンドウに WAV か mp3 ファイルを読み込んでおきます。
 
サウンドファイルを選択して右クリックメニューからリンケージプロパティを開きます。
 
 
「クラス」に好きなクラス名を付けます。(ここでは MySound クラスという名前)

「基本クラス」に flash.media.Sound と記述します。

『ActionScript に書き出し』と『最初のフレームに書き出し』にチェックを付けます。
 
この状態で書き出せば swf ファイルにサウンドデータが埋め込まれるようになります。後はアクションスクリプトを使って動的に呼び出して使用します。
 

2.クラスをインスタンス化してサウンドオブジェクトを作成する


先ほど名前を付けたクラス名でインスタンス化するとサウンドオブジェクトを作成することができます。
 
設定した MySound クラスをインスタンス化してサウンドオブジェクトを作成する

// リンケージプロパティで設定したサウンドクラスを使ってサウンドオブジェクトを作成
var sound_obj : Sound = new MySound( );
 



■サウンドを再生する


play() メソッドを呼び出すと再生を開始します。
 
Sound.play ( 再生開始時間 , ループ回数 , SoundTransform );
第01引数(略可)再生を開始する時間を単位:ミリ秒で指定します。
第02引数(略可)ループ再生する回数を指定します。第01引数で指定した場所から開始されます。
第03引数(略可)サウンドの詳細をSoundTransform型で指定します。
戻り値 SoundChannel オブジェクトを返します。
 
■第03引数 SoundTransform オブジェクト

再生前に、ボリュームやパン等の効果を付けたい場合はここでパラメータを指定します。
 
■戻り値 SoundChannel オブジェクト

再生中に、ボリュームやパン等の効果を付けたい場合はここでパラメータを指定します。
 
使用例です。
 
3回繰り返して再生する

// リンケージプロパティで設定したサウンドクラスを使ってサウンドオブジェクトを作成
var sound_obj : Sound = new MySound();

// サウンドを再生
sound_obj.play(0,3);
 
再生開始前にボリュームを設定する

// リンケージプロパティで設定したサウンドクラスを使ってサウンドオブジェクトを作成
var sound_obj : Sound = new MySound();

// サウンドトランスフォームオブジェクトを作成
var trans : SoundTransform = new SoundTransform();
trans.volume = 0.1;	// ボリューム
trans.pan = -1;		// パン

// サウンドを再生
sound_obj.play(0,0,trans);
 

■サウンドを停止する


サウンドを停止したい場合は、play() メソッドの戻り値で得られた SoundChannel オブジェクトを使用します。このクラスが保持している stop() メソッドを呼び出します。
 
サウンドを停止する

// リンケージプロパティで設定したサウンドクラスを使ってサウンドオブジェクトを作成
var sound_obj : Sound = new MySound();

// サウンドを再生
var channel : SoundChannel = sound_obj.play(0,3);

// サウンドを停止
channel.stop();
 
 



静的に配置したサウンドを制御する

 

サンプルをダウンロード
 


■再生を開始するまで溜めるバッファ時間を設定する


SoundMixer.bufferTime を使用すると、バッファ時間(単位:秒)を変更できます。
デフォルトは 0.1 秒です。
 
サウンドのバッファ時間を0.5秒に変更する

SoundMixer.bufferTime = 0.5;
 

■全体のボリューム&パンを変更する


Adobe Flash を使ってタイムラインに静的に配置したすべてのサウンドのボリューム&パンを一括で変更するには SoundMixer クラスを使用します。
 
SoundTransform オブジェクトを作りパラメータを設定して、SoundMixer.soundTransform に代入します。
 
全体のボリューム&パンを変更する

// サウンドトランスフォームオブジェクトを作成
var trans : SoundTransform = new SoundTransform();
trans.volume = 0.1;	// ボリューム
trans.pan = -1;		// パン

// サウンドトランスフォームオブジェクトをセットして反映
SoundMixer.soundTransform = trans;

全体のサウンドのボリューム&パンを取得する

// サウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = SoundMixer.soundTransform;

trace(trans.volume);	// ボリューム
trace(trans.pan);	// パン
 

■インスタンスのボリューム&パンを変更する


SoundTransform クラスを使用すると各インスタンスごとにボリュームやパンを設定できます。
 
Sprite クラス等には、 soundTransform プロパティがあり、ここに SoundTransform オブジェクトが 格納されています。
 
SoundTransform オブジェクトを soundTransform プロパティに保持しているクラス

Microphone、NetStream、SoundChannel、SoundMixer、Sprite , MovieClip , MainTimeline
 
SoundTransform オブジェクトは、 soundTransform プロパティから取得することもできますし、新規に作成することもできます。
 
SoundTransform オブジェクトを作成する

// サウンドトランスフォームオブジェクトを作成する
var trans : SoundTransform = new SoundTransform();

trans.volume = 0.1;	// ボリューム
trans.pan = -1;		// パン

ムービークリップ mc に配置されているサウンドのボリューム&パンを取得する

// サウンドトランスフォームオブジェクトを取得する
var trans : SoundTransform = mc.soundTransform;

trace(trans.volume);	// ボリューム
trace(trans.pan);	// パン
 
設定した SoundTransform オブジェクトを soundTransform プロパティに代入すると、そのインスタンス中に配置されているサウンドのボリュームやパンを設定することができます。
 
表示リストに登録されている子のインスタンスにも反映されます。
 
ムービークリップ mc に配置されているサウンドのボリューム&パンを変更する

// サウンドトランスフォームオブジェクトを取得する
var trans : SoundTransform = mc.soundTransform;
trans.volume = 0.1;	// ボリューム
trans.pan = -1;		// パン

// サウンドオブジェクトをセットして反映
mc.soundTransform = trans;
 
soundTransform プロパティから直接プロパティにアクセスしても変更されません。必ず soundTransform プロパティにSoundTransform オブジェクトを渡す必要があります。
 
 



動的に再生したサウンドを制御する

 

サンプルをダウンロード
 
 

■動的に再生したサウンドを制御するには?


Sound クラスの play() メソッドを呼び出すと、 SoundChannel オブジェクトが得られます。
 
このオブジェクトを使用してサウンドを制御します。
 
サウンドクラスから動的に再生して SoundChannel オブジェクトを作成する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトの作成
var sound_obj : Sound = new Sound(url);

// サウンドの再生
var channel : SoundChannel = sound_obj.play();
 

■動的に再生したサウンドのボリュームやパンを設定する


SoundChannel クラスが保持している soundTransformプロパティから 現在の SoundTransform オブジェクトが得られます。
 
この SoundTransform オブジェクトにアクセスして volumepan などのパラメータを変更してから soundTransformプロパティに戻すと、再生したサウンドのボリュームやパンを変更することができます。
 
動的に再生したサウンドのボリュームやパンを設定する

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトの作成
var sound_obj : Sound = new Sound(url);

// サウンドの再生
var channel : SoundChannel = sound_obj.play();

// サウンドトランスフォームオブジェクトの取得
var trans : SoundTransform = channel.soundTransform;
trans.volume = 0.1;	// ボリューム
trans.pan = -1;		// パン

// サウンドトランスフォームオブジェクトをセットして反映
channel.soundTransform = trans;
 

■最後まで再生されたかを知る


動的に再生したサウンドが最後まで再生されたか知るには、soundComplete イベントを使用します。
 
サウンドの終了を知る

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトの作成
var sound_obj : Sound = new Sound(url);

// サウンドの再生
var channel : SoundChannel = sound_obj.play();

// サウンドの再生が終了したときに呼び出されるイベント
channel.addEventListener(Event.SOUND_COMPLETE,SoundCompFunc);
function SoundCompFunc(event:Event):void{
	trace("最後まで再生された");
}
 

■再生ヘッダの位置を知る


現在再生中の時間(単位:ミリ秒)を調べるには、 position プロパティを使用します。このプロパティは読み取り専用です。
 
サウンドの現在再生している時間を調べる

// サウンドファイルのURL
var url : URLRequest = new URLRequest("http://hakuhin.jp/test.mp3");

// サウンドオブジェクトの作成
var sound_obj : Sound = new Sound(url);

// サウンドの再生
var channel : SoundChannel = sound_obj.play();

// 毎フレーム呼び出されるイベント
stage.addEventListener(Event.ENTER_FRAME,EnterFrameFunc);
function EnterFrameFunc(event:Event){

	trace("再生位置 : " + channel.position / 1000);

}
 
 



左右から出力される音を詳細に設定する

 

サンプルをダウンロード
 


■SoundTransform クラスについて


サウンドの出力を詳細に設定するには、SoundTransform クラスを使用します。
 
SoundMixer クラスや SoundChannel クラス、Sprite クラス、Microphone クラスなどには、 soundTransform というプロパティがあり その中に SoundTransform オブジェクトが格納されています。
 
SoundMixer オブジェクトからSoundTransformオブジェクトを取り出す

// サウンドミキサーからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = SoundMixer.soundTransform;
 
SoundChannel オブジェクトからSoundTransformオブジェクトを取り出す

// サウンドファイルのURL
var url = new URLRequest("test.mp3");

// サウンドオブジェクトの作成
var sound_obj : Sound = new Sound(url);

// サウンドの再生
var channel : SoundChannel = sound_obj.play();

// サウンドチャンネルからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = channel.soundTransform;
 
Sprite インスタンスからSoundTransformオブジェクトを取り出す

// スプライトオブジェクトを作成
var sprite : Sprite = new Sprite();

// スプライトからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = sprite.soundTransform;
 
Microphone オブジェクトからSoundTransformオブジェクトを取り出す

// Microphone オブジェクトを取得
var mic_obj:Microphone = Microphone.getMicrophone();

// Microphone オブジェクトからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = mic_obj.soundTransform;
 

■ボリュームを変更する


ボリュームを変更するには、 volume プロパティを変更します。0(無音) ~ 1(常音) までの値を指定します。
 
1 より大きい値も指定できますが、音量が大きすぎて「音割れ」を引き起こす可能性があります。
 
ボリュームを変更する

// サウンドミキサーからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = SoundMixer.soundTransform;

// ボリュームを設定
trans.volume = 0.5;

// サウンドトランスフォームオブジェクトをサウンドミキサーにセット
SoundMixer.soundTransform = trans;
 

■パンを変更する


パンを変更するには、 pan プロパティを変更します。-1(左)~ 0(中央) ~ 1(右) までの値を指定します。
 
パンを変更する

// サウンドミキサーからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = SoundMixer.soundTransform;

// パンを設定
trans.pan = 1;

// サウンドトランスフォームオブジェクトをサウンドミキサーにセット
SoundMixer.soundTransform = trans;
 

■左右から出力される音を詳細に設定する


4つのパラメータを使って左右から出力される音を詳細に設定することができます。
 
プロパティ 説明
leftToLeft 元は左から出力されていた音を左から出力します。0(無音) ~ 1(常音)
leftToRight 元は左から出力されていた音を右から出力します。0(無音) ~ 1(常音)
rightToLeft 元は右から出力されていた音を左から出力します。0(無音) ~ 1(常音)
rightToRight 元は右から出力されていた音を右から出力します。0(無音) ~ 1(常音)
 
モノラル出力する

// サウンドミキサーからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = SoundMixer.soundTransform;

// 詳細な出力を設定
trans.leftToLeft   = 0.5;	// 元は左から出力されていた音を左から出力
trans.leftToRight  = 0.5;	// 元は左から出力されていた音を右から出力
trans.rightToLeft  = 0.5;	// 元は右から出力されていた音を左から出力
trans.rightToRight = 0.5;	// 元は右から出力されていた音を右から出力

// サウンドトランスフォームオブジェクトをサウンドミキサーにセット
SoundMixer.soundTransform = trans;
 
リバースステレオ出力する

// サウンドミキサーからサウンドトランスフォームオブジェクトを取得
var trans : SoundTransform = SoundMixer.soundTransform;

// 詳細な出力を設定
trans.leftToLeft   = 0.0;	// 元は左から出力されていた音を左から出力
trans.leftToRight  = 1.0;	// 元は左から出力されていた音を右から出力
trans.rightToLeft  = 1.0;	// 元は右から出力されていた音を左から出力
trans.rightToRight = 0.0;	// 元は右から出力されていた音を右から出力

// サウンドトランスフォームオブジェクトをサウンドミキサーにセット
SoundMixer.soundTransform = trans;
 
 



ID3タグを取得する

 


■ID3Info クラスについて


ID3Info クラスは、ID3タグの情報をまとめたものです。
 
Sound オブジェクトの id3 プロパティに ID3Info オブジェクトが格納されています。
 
外部から読みこんだサウンドファイルに ID3タグが埋め込まれている場合、ID3Info オブジェクトに情報が格納されています。
 
Sound オブジェクトからID3Info オブジェクトを取得

// サウンドオブジェクト作成
var sound_obj:Sound = new Sound();

var url : URLRequest = new URLRequest("../sound/test.png");
loader_obj.load(url);

// ID3Info オブジェクトを取得
var id3info:ID3Info = sound_obj.id3;
 
ID3Info クラスのプロパティの一覧です。
 
プロパティ名説明タグ
albumアルバム名TALB (ID3 2.0)
artistアーティスト名TPE1 (ID3 2.0)
commentコメントCOMM (ID3 2.0)
genre曲のジャンルTCON (ID3 2.0)
songName曲名TIT2 (ID3 2.0)
trackトラック番号TRCK (ID3 2.0)
year録音された年TYER (ID3 2.0)
 
 
取得例です。
 
Sound オブジェクトからID3Info オブジェクトを取得

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound();

// // ストリーム読み込みを開始
var url : URLRequest = new URLRequest("../sound/test.mo3");
sound_obj.load(url);

// ID3タグの情報が含まれていれば呼び出されるイベント
sound_obj.addEventListener(Event.ID3,function (e:Event):void {

	// ID3Info オブジェクトを取得
	var id3info:ID3Info = sound_obj.id3;

	trace("アルバム名:" + id3info.album);
	trace("アーティスト名:" + id3info.artist);
	trace("コメント:" + id3info.comment);
	trace("曲のジャンル:" + id3info.genre);
	trace("曲名:" + id3info.songName);
	trace("トラック番号:" + id3info.track);
	trace("録音された年:" + id3info.year);

});
 

■ID3タグを取得できるか調べる


外部からサウンドファイルを読み込んだときに、ID3タグが含まれるかを調べるには、ID3 イベントを使用します。
 
Sound オブジェクトからID3Info オブジェクトを取得

// サウンドオブジェクトを作成
var sound_obj : Sound = new Sound();

// // ストリーム読み込みを開始
var url : URLRequest = new URLRequest("../sound/test.mo3");
sound_obj.load(url);

// ID3タグの情報が含まれていれば呼び出されるイベント
sound_obj.addEventListener(Event.ID3,function (e:Event):void {

	// ID3Info オブジェクトを取得
	var id3info:ID3Info = sound_obj.id3;

});
 
 



サウンドデータ(PCM)を取得する(Flash 10以降)

 

サンプルをダウンロード
 


■サウンドのPCMデータを取得する


サウンドのPCMデータを取得するには、Sound クラスの extract() メソッドを使用します。
 
Sound.extract ( ByteArray , 取得量 , 開始位置 );
第01引数 取得したデータを格納するための ArrayByte オブジェクトを指定します。
第02引数 取得したい量(サンプリング数)を設定します。
第03引数(略可)サウンドデータの取得を開始する位置(サンプリング数)を設定します。
戻り値 実際に取得できた量(サンプリング数)が返ります。サウンドの終端の場合は、第02引数で指定した数値と一致せず取得が途中で中断します。
 
MovieClip インスタンスからSoundTransformオブジェクトを取り出す

var url : URLRequest = new URLRequest("test.mp3");
var sound_obj : Sound = new Sound(url);	// サウンドオブジェクト

// 読み込みが終了した
sound_obj.addEventListener (Event.COMPLETE,SoundCompleteFunc);
function SoundCompleteFunc (event : Event) {

	var buffer:ByteArray = new ByteArray();

	// サウンドデータを取得
	var sampling = sound_obj.extract(buffer,8192);
}
 
このメソッドを使用するときは Sound オブジェクトが再生可能な状態になっている必要があります。

第03引数を指定せずにこのメソッドを何度も呼び出すと、以前取得を終了した所から再開して取得できます。
 

■取得できるサウンドデータの中身について


32bit浮動小数点数(-1.0 ~ 1.0)の連続したデータとなっています。
 
左右左右の繰り返しで、1サンプリングずつデータが格納されています。
 
通常であれば、1 秒間 44100 サンプリング数ステレオ形式として取得できます。
 
 
 
1 つのデータ(電圧を-1.0 ~ 1.0 に変換した値)が 4Byte で表され、さらに左右 2 チャンネルあるので 1 サンプリングにつき 8Byte 使用する事になります。
 
 
 



サウンドデータ(PCM)を使って再生する(Flash 10以降)

 


■サウンドデータ(PCM)を使って音を鳴らす


サウンドデータを使って、直接サウンドバッファに書き込んで音を鳴らすには、SampleDataEvent.SAMPLE_DATA イベントを使用します。
 
このイベントを使用すると、サウンドが再生される直前に登録した関数が呼び出され、サウンドデータを要求するようになります。
 
SampleDataEventクラスに data プロパティ(ByteArray 型)があるので、イベントが呼び出されるたびに少しずつ data プロパティにサウンドデータを書き込みます。
 

■data プロパティについて


■1回に書き込める量について

data プロパティに1度に書き込む量は、2048 ~ 8192 のサンプリング数である必要があります。
 
■書き込む量を多くする

サウンドバッファが長いので、多少の処理落ちが発生しても安定して再生できます。
 
1回の書き込み処理の量が多いので定期的に負荷が発生します。
 
次回のサウンドバッファに書き込めるタイミングが長いため、動的にエフェクトを掛けたい場合などの実際に反映できるまでの遅延(レイテンシー)が大きくなります。
 
■書き込む量を少なくする

サウンドバッファが短いので、少しの処理落ちで再生が不安定になります。 音が途切れたり、前回サウンドバッファに書き込んだ部分が繰り返し再生される事があります。
 
再生する PC のスペックが低いとサウンド再生が不安定になる恐れがあります。
 
1回の書き込み処理の量が少ないので負荷が分散されます。
 
次回のサウンドバッファに書き込めるタイミングが短いため、動的にエフェクトを掛けたい場合などの実際に反映できるまでの遅延(レイテンシー)が小さくなります。
 

■書き込むサウンドデータの中身について


32bit浮動小数点数(-1.0 ~ 1.0)の連続したデータとなっています。
 
左右左右の繰り返しで、1サンプリングずつデータを格納します。
 
通常であれば、1 秒間 44100 サンプリング数ステレオ形式となります。
 
 
 
サンプリング 44100 回でちょうど 1 秒となります。 1 つのデータ(電圧を-1.0 ~ 1.0 に変換した値)が 4Byte で表され、左右 2 チャンネルあるので 1 サンプリングにつき 8Byte 使用します。
 
 
 
データ取得用の「サウンドオブジェクト」と、データ再生用の「サウンドオブジェクト」を使用して再生する例です。
 
SampleDataEvent.SAMPLE_DATA イベントを使用する

// パラメータ
var sampling = 2048;		// 1度に転送するサンプリング数

// ソース用サウンドオブジェクト作成
var url : URLRequest = new URLRequest("test.mp3");
var src_obj : Sound = new Sound(url);

// 出力用サウンドオブジェクト
var out_obj = null;
var channel = null;

// ソース用サウンドオブジェクトの読み込みが完了
src_obj.addEventListener (Event.COMPLETE,SoundCompleteFunc);
function SoundCompleteFunc (event : Event) {

	// 出力用サウンドオブジェクト作成
	out_obj = new Sound();

	// 新しいオーディオデータ要求時に呼び出されるイベント
	out_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

	// 再生開始
	channel = out_obj.play();
}


// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{

	var i;

	// ソース用と出力用のバッファ
	var src_buffer:ByteArray = new ByteArray();
	var out_buffer:ByteArray = event.data;
	
	// サウンドデータを取得
	var get_sampling = src_obj.extract(src_buffer,sampling);

	// サウンドバッファが足りない場合は空白を埋める
	for(i=get_sampling;i < sampling;i++){
		src_buffer.writeFloat(0.0);
		src_buffer.writeFloat(0.0);
	}


	// サウンドデータを出力バッファにコピー
	var data;
	src_buffer.position = 0;
	for(i=0;i < sampling;i++){
		// 左チャンネル
		data = src_buffer.readFloat();
		out_buffer.writeFloat(data);
	
		// 右チャンネル
		data = src_buffer.readFloat();
		out_buffer.writeFloat(data);
	}

}
 



■波形をプログラムで作成して音を鳴らす



サンプルをダウンロード
 
波形をプログラムで作り出して音を鳴らしてみたいと思います。
 

■基本的な波形


波形の基本的なパターンに以下の種類があります。
 
■矩形波

一定の間隔で -1 と 1 を交互に切り替えます。

 
 
■ノコギリ波

-1 から 1 まで線形で変化させて瞬時に -1 に戻します。

 
 
■三角波

-1 から 1 まで線形で変化させて 1 から -1 まで線形で変化させます。

 
 
■正弦波

サインカーブです。

 
 
■ノイズ

ランダムな値を並べたものです。
 

■音程について


ドレミファソラシドといった音程を変化させい場合、周波数を変更します。

周波数は、1 秒間に波の周期が何回繰り返されるかという値です。

また、周波数が 220Hz でちょうど「ラ」の音となります。

 
とりあえず波を 1 秒間に 220 回繰り返すようにバッファに格納できれば「ラ」の音が出せます。
 
Flash のサンプリング数は1秒間に 44100 回です。
サンプリング数 44100 の中に 220 個の波を収めればいいので1つの波に使えるサンプリング数は、約 200 となります。
 
また、現在の波の状態から、

周波数を 2.0 倍にすると音程がちょうど1オクターブ上がります。
周波数を 0.5 倍にすると音程がちょうど1オクターブ下がります。
 
周波数 説明
27.5Hz 3オクターブ低い「ラ」
55.0Hz 2オクターブ低い「ラ」
110.0Hz 1オクターブ低い「ラ」
220.0Hz 基準とする「ラ」
440.0Hz 1オクターブ大きい「ラ」
880.0Hz 2オクターブ大きい「ラ」
1760.0Hz 3オクターブ大きい「ラ」
 
という事は、 1オクダーブを12段階(ド、ド#、レ、レ#、ミ、ファ、ファ#、ソ、ソ#、ラ、ラ#、シ)の音程に分けるとすると、

現在の周波数に、

「2 の (1 / 12) 乗」乗算すると音程を1段階上げる事ができます。
「2 の (1 / 12) 乗」除算すると音程を1段階下げる事ができます。
 
音程 周波数
65.4063913251Hz
ド# 69.2956577442Hz
73.4161919793Hz
レ# 77.7817459305Hz
82.4068892282Hz
ファ 87.3070578582Hz
ファ# 92.4986056779Hz
97.9988589954Hz
ソ# 103.826174394Hz
110.000000000Hz
ラ# 116.540940379Hz
123.470825314Hz
130.812782650Hz
ド# 138.591315488Hz
146.832383958Hz
レ# 155.563491861Hz
164.813778456Hz
ファ 174.614115716Hz
ファ# 184.997211355Hz
195.997717990Hz
ソ# 207.652348789Hz
220.000000000Hz
ラ# 233.081880759Hz
246.941650628Hz
261.625565300Hz
ド# 277.182630976Hz
293.664767917Hz
レ# 311.126983722Hz
329.627556912Hz
ファ 349.228231433Hz
ファ# 369.994422711Hz
391.995435981Hz
ソ# 415.304697579Hz
440.000000000Hz
ラ# 466.163761518Hz
493.883301256Hz
523.251130601Hz
ド# 554.365261953Hz
587.329535834Hz
レ# 622.253967444Hz
659.255113825Hz
ファ 698.456462866Hz
ファ# 739.988845423Hz
783.990871963Hz
ソ# 830.609395159Hz
880.000000000Hz
ラ# 932.327523036Hz
987.766602512Hz
1046.50226120Hz
ド# 1108.73052390Hz
1174.65907166Hz
レ# 1244.50793488Hz
1318.51022765Hz
ファ 1396.91292573Hz
ファ# 1479.97769084Hz
1567.98174392Hz
ソ# 1661.21879031Hz
1760.00000000Hz
ラ# 1864.65504607Hz
1975.53320502Hz
2093.00452240Hz
 
各波形の再生例です。
 
矩形波を出力する

// パラメータ
var frequency = 25;	// 周波数
var sampling = 2048;	// 1 度に転送するサンプリング数

// 周波数を徐々に上げるテスト
addEventListener(Event.ENTER_FRAME,function (e){
	frequency += 10;
	if(frequency > 2000)	frequency = 25;
});


// 波形用ワーク
var wave = {
	count : 0,	// カウント
	cycle : 0	// 周期
};

// サウンドオブジェクト
var sound_obj = new Sound();

// サンプルデータイベント登録
sound_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

// 再生開始
sound_obj.play();

// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{
	
	var i;

	// サウンドバッファ
	var buffer = event.data;

	// 開始直後のノイズ対策
	if(event.position == 0){
		for(i=0;i < 4096;i++){
			// 左チャンネル
			buffer.writeFloat(0.0);
			// 右チャンネル
			buffer.writeFloat(0.0);
		}
		return;
	}

	for(i=0;i < sampling;i++){
		wave.count --;
		if(wave.count < 0){
			// 周期更新
			wave.cycle = wave.count = 44100 / frequency;
		}

		// 位相(0.0~1.0)
		var d = 1.0 - wave.count / wave.cycle;
		
		// 矩形波
		if(d < 0.5)	d = -1.0;
		else		d =  1.0;

		// 左チャンネル
		buffer.writeFloat(d);
		// 右チャンネル
		buffer.writeFloat(d);
	}
}
 
ノコギリ波を出力する

// パラメータ
var frequency = 25;	// 周波数
var sampling = 2048;	// 1 度に転送するサンプリング数

// 周波数を徐々に上げるテスト
addEventListener(Event.ENTER_FRAME,function (e){
	frequency += 10;
	if(frequency > 2000)	frequency = 25;
});


// 波形用ワーク
var wave = {
	count : 0,	// カウント
	cycle : 0	// 周期
};

// サウンドオブジェクト
var sound_obj = new Sound();

// サンプルデータイベント登録
sound_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

// 再生開始
sound_obj.play();

// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{
	
	var i;

	// サウンドバッファ
	var buffer = event.data;

	// 開始直後のノイズ対策
	if(event.position == 0){
		for(i=0;i < 4096;i++){
			// 左チャンネル
			buffer.writeFloat(0.0);
			// 右チャンネル
			buffer.writeFloat(0.0);
		}
		return;
	}

	for(i=0;i < sampling;i++){
		wave.count --;
		if(wave.count < 0){
			// 周期更新
			wave.cycle = wave.count = 44100 / frequency;
		}

		// 位相(0.0~1.0)
		var d = 1.0 - wave.count / wave.cycle;
		
		// ノコギリ波
		d = d * 2 - 1;

		// 左チャンネル
		buffer.writeFloat(d);
		// 右チャンネル
		buffer.writeFloat(d);
	}
}
 
三角波を出力する

// パラメータ
var frequency = 25;	// 周波数
var sampling = 2048;	// 1 度に転送するサンプリング数

// 周波数を徐々に上げるテスト
addEventListener(Event.ENTER_FRAME,function (e){
	frequency += 10;
	if(frequency > 2000)	frequency = 25;
});


// 波形用ワーク
var wave = {
	count : 0,	// カウント
	cycle : 0	// 周期
};

// サウンドオブジェクト
var sound_obj = new Sound();

// サンプルデータイベント登録
sound_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

// 再生開始
sound_obj.play();

// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{
	
	var i;

	// サウンドバッファ
	var buffer = event.data;

	// 開始直後のノイズ対策
	if(event.position == 0){
		for(i=0;i < 4096;i++){
			// 左チャンネル
			buffer.writeFloat(0.0);
			// 右チャンネル
			buffer.writeFloat(0.0);
		}
		return;
	}

	for(i=0;i < sampling;i++){
		wave.count --;
		if(wave.count < 0){
			// 周期更新
			wave.cycle = wave.count = 44100 / frequency;
		}

		// 位相(0.0~1.0)
		var d = 1.0 - wave.count / wave.cycle;
		
		// 三角波
		if(d < 0.25)	d = d / 0.25;
		else if(d < 0.75)	d = (0.75 - d) * 4 - 1;
		else		d = (d - 0.75) / 0.25 - 1;

		// 左チャンネル
		buffer.writeFloat(d);
		// 右チャンネル
		buffer.writeFloat(d);
	}
}
 
正弦波を出力する

// パラメータ
var frequency = 25;	// 周波数
var sampling = 2048;	// 1 度に転送するサンプリング数

// 周波数を徐々に上げるテスト
addEventListener(Event.ENTER_FRAME,function (e){
	frequency += 10;
	if(frequency > 2000)	frequency = 25;
});


// 波形用ワーク
var wave = {
	count : 0,	// カウント
	cycle : 0	// 周期
};

// サウンドオブジェクト
var sound_obj = new Sound();

// サンプルデータイベント登録
sound_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

// 再生開始
sound_obj.play();

// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{
	
	var i;

	// サウンドバッファ
	var buffer = event.data;

	// 開始直後のノイズ対策
	if(event.position == 0){
		for(i=0;i < 4096;i++){
			// 左チャンネル
			buffer.writeFloat(0.0);
			// 右チャンネル
			buffer.writeFloat(0.0);
		}
		return;
	}

	for(i=0;i < sampling;i++){
		wave.count --;
		if(wave.count < 0){
			// 周期更新
			wave.cycle = wave.count = 44100 / frequency;
		}

		// 位相(0.0~1.0)
		var d = 1.0 - wave.count / wave.cycle;
		
		// 正弦波
		d = Math.sin(d * 2 * Math.PI);

		// 左チャンネル
		buffer.writeFloat(d);
		// 右チャンネル
		buffer.writeFloat(d);
	}
}
 
ノイズを出力する

// パラメータ
var sampling = 2048;	// 1 度に転送するサンプリング数

// サウンドオブジェクト
var sound_obj = new Sound();

// サンプルデータイベント登録
sound_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

// 再生開始
sound_obj.play();

// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{
	
	var i;

	// サウンドバッファ
	var buffer = event.data;

	// 開始直後のノイズ対策
	if(event.position == 0){
		for(i=0;i < 4096;i++){
			// 左チャンネル
			buffer.writeFloat(0.0);
			// 右チャンネル
			buffer.writeFloat(0.0);
		}
		return;
	}

	for(i=0;i < sampling;i++){
		// ランダム
		var d = Math.random() * 2 - 1;

		// 左チャンネル
		buffer.writeFloat(d);
		// 右チャンネル
		buffer.writeFloat(d);
	}
}
 



■音の再生速度を変更する



サンプルをダウンロード
 
サウンドデータを書き換えて、音の再生速度を変更してみます。
 
波の長さを変化させる事により再生速度を変化させてみます。 波の長さを変化させるという事は、周波数(1 秒間に波の周期が何回繰り返されるか)も変化します。
 
周波数を変更すると、音程が変化します。
波形を 2.0 倍の長さにすると音程がちょうど1オクターブ下がります。
波形を 0.5 倍の長さにすると音程がちょうど1オクターブ上がります。
 
補完例です。ここでは簡単に計算できる方法を紹介します。

波形を長くする場合は、小数部分を切り捨てて得られるサンプリング位置と同じサウンドデータを埋めます。
 
例えば波形を 1.4倍に長くした例です。
 
望ましいサンプリング位置 実際に参照するサンプリング位置
0.00000000 0
0.71428571 0
1.42857142 1
2.14285714 2
2.85714285 2
3.57142857 3
4.28571428 4
5.00000000 5
5.71428571 5
6.42857142 6
7.14285714 7
 
波形を短くする場合は、単純にデータを間引きます。
 
例えば波形を 0.7倍に短くした場合です。
 
望ましいサンプリング位置 実際に参照するサンプリング位置
0.00000000 0
1.42857142 1
2.85714285 2
4.28571428 4
5.71428571 5
7.14285714 7
8.57142857 8
10.00000000 10
11.42857142 11
12.85714285 12
14.28571428 14
 
使用例です。
 
"test.mp3"を読み込んで再生速度を変更する

// パラメータ
var sampling = 2048;		// 1度に転送するサンプリング数
var sound_speed = 1.5;	// 再生速度(1.0で等速)
var loop = true;		// ループあり
var loop_begin = 0;		// ループ開始地点

// ソース用サウンドオブジェクト作成
var url : URLRequest = new URLRequest("test.mp3");
var src_obj : Sound = new Sound(url);

// 出力用サウンドオブジェクト
var out_obj = null;
var channel = null;

// ソース用サウンドオブジェクトの読み込みが完了
src_obj.addEventListener (Event.COMPLETE,SoundCompleteFunc);
function SoundCompleteFunc (event : Event) {

	// 出力用サウンドオブジェクト作成
	out_obj = new Sound();

	// 新しいオーディオデータ要求時に呼び出されるイベント
	out_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

	// 再生開始
	channel = out_obj.play();
}


// 波形用ワーク
var wave = {
	pos : 0	// 再生位置
};


// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{

	var i;
	
	// サウンドバッファの開始位置
	var pos = wave.pos - Math.floor(wave.pos);
	
	// ソース用と出力用のバッファ
	var src_buffer:ByteArray = new ByteArray();
	var out_buffer:ByteArray = event.data;
	
	// 開始直後のノイズ対策
	if(event.position == 0){
		for(i=0;i < 4096;i++){
			// 左チャンネル
			out_buffer.writeFloat(0.0);
			// 右チャンネル
			out_buffer.writeFloat(0.0);
		}
		return;
	}
	
	// ソースから取得するサンプリング数
	var copy_sampling = Math.ceil(sampling * sound_speed);
	if(!copy_sampling)	copy_sampling = 1;
	
	// サウンドデータを取得
	var get_sampling = src_obj.extract(src_buffer,copy_sampling,wave.pos);

	// サウンドバッファが埋まるまでループを繰り返す
	while(true){
		wave.pos += get_sampling;
		copy_sampling -= get_sampling;
		if(copy_sampling <= 0)	break;

		if(!loop){
			// ループしないなら空白で埋める
			for(i=0;i < copy_sampling;i++){
				src_buffer.writeFloat(0);
				src_buffer.writeFloat(0);
			}
			break;
		}

		// ループ開始位置をセット
		wave.pos = loop_begin;

		// サウンドデータを再取得
		get_sampling = src_obj.extract(src_buffer,copy_sampling,wave.pos);
		
		// エラー
		if(!get_sampling)	return;
	}

	// 再生速度に合わせてサウンドデータをコピー
	var data;
	for(i=0;i < sampling;i++){
		src_buffer.position = Math.floor(pos) * 4 * 2;
		pos += sound_speed;
	
		// 左チャンネル
		data = src_buffer.readFloat();
		out_buffer.writeFloat(data);
	
		// 右チャンネル
		data = src_buffer.readFloat();
		out_buffer.writeFloat(data);
	}

}
 



■ディレイエフェクト



サンプルをダウンロード
 
再生時に使用したサウンドデータをディレイ用のバッファにも書き込んで残しておきます。
 
ディレイ用のバッファが一杯になったら一番古いデータから取り出します。 次に音を再生するタイミングで、「再生したいサウンドデータ」と「一番古いディレイ用のバッファのデータ」とをブレンドします。
 
計算結果で得られたデータを使って再生します。 ディレイ用のバッファで使用した部分は空いたとみなし、新しいデータを書き込んで残しておきます。
 
これを繰り返します。
 
ブレンドした計算結果によって前回よりも波が大きくなると、増幅され続けてものすごい大音量になってしまうのでなるべく減衰するように注意します。
 
使用例です。
 
ディレイエフェクト

// パラメータ
var sampling = 2048;		// 1度に転送するサンプリング数
var loop = true;		// ループあり
var loop_begin = 0;		// ループ開始地点
var delay_sampling = 1000;	// ディレイの時間(サンプリング数)
var delay_decrease_buf = 0.85;	// ディレイの減衰率 (ディレイバッファに乗算)
var delay_decrease_src = 0.5;	// ディレイの減衰率(再生ソースに乗算)


// ソース用サウンドオブジェクト作成
var url : URLRequest = new URLRequest("test.mp3");
var src_obj : Sound = new Sound(url);

// 出力用サウンドオブジェクト
var out_obj = null;
var channel = null;

// ソース用サウンドオブジェクトの読み込みが完了
src_obj.addEventListener (Event.COMPLETE,SoundCompleteFunc);
function SoundCompleteFunc (event : Event) {

	// 出力用サウンドオブジェクト作成
	out_obj = new Sound();

	// 新しいオーディオデータ要求時に呼び出されるイベント
	out_obj.addEventListener(SampleDataEvent.SAMPLE_DATA, SampleDataFunc);

	// 再生開始
	channel = out_obj.play();
}


// 波形用ワーク
var wave = {
	pos : 0	// 再生位置
};

// ディレイ用ワーク
var delay = {
	pos : 0,			// バッファ位置
	buffer : new ByteArray()	// ディレイ用バッファ
};
var i;
for(i=0;i < delay_sampling;i++){
	delay.buffer.writeFloat(0.0);
	delay.buffer.writeFloat(0.0);

}


// サウンドデータ要求時に呼び出されるイベント
function SampleDataFunc(event:SampleDataEvent):void{

	var i;

	// ソース用と出力用のバッファ
	var src_buffer:ByteArray = new ByteArray();
	var out_buffer:ByteArray = event.data;
	
	// 開始直後のノイズ対策
	if(event.position == 0){
		for(i=0;i < 4096;i++){
			// 左チャンネル
			out_buffer.writeFloat(0.0);
			// 右チャンネル
			out_buffer.writeFloat(0.0);
		}
		return;
	}
	
	// ソースから取得するサンプリング数
	var copy_sampling = sampling;
	
	// サウンドデータを取得
	var get_sampling = src_obj.extract(src_buffer,copy_sampling,wave.pos);

	// サウンドバッファが埋まるまでループを繰り返す
	while(true){
		wave.pos += get_sampling;
		copy_sampling -= get_sampling;
		if(copy_sampling <= 0)	break;

		if(!loop){
			// ループしないなら空白で埋める
			for(i=0;i < copy_sampling;i++){
				src_buffer.writeFloat(0);
				src_buffer.writeFloat(0);
			}
			break;
		}

		// ループ開始位置をセット
		wave.pos = loop_begin;

		// サウンドデータを再取得
		get_sampling = src_obj.extract(src_buffer,copy_sampling,wave.pos);
		
		// エラー
		if(!get_sampling)	return;
	}

	// 再生速度に合わせてサウンドデータをコピー
	var data;
	src_buffer.position = 0;
	for(i=0;i < sampling;i++){

		// ディレイバッファからソースを取得
		delay.buffer.position = delay.pos * 4 * 2;
		var src_l = delay.buffer.readFloat();
		var src_r = delay.buffer.readFloat();

		// 左チャンネル
		data = src_buffer.readFloat();
		data = src_l * delay_decrease_buf + data * delay_decrease_src;	// ディレイソースと再生ソースをブレンド
		out_buffer.writeFloat(data);
		var out_l = data;

		// 右チャンネル
		data = src_buffer.readFloat();
		data = src_r * delay_decrease_buf + data * delay_decrease_src;	// ディレイソースと再生ソースをブレンド
		out_buffer.writeFloat(data);
		var out_r = data;
		
		// 再生したサウンドデータをディレイバッファに格納
		var pos = delay.pos - 1;
		if(pos < 0)	pos += delay_sampling;
		delay.buffer.position = pos * 4 * 2;
		delay.buffer.writeFloat(out_l);
		delay.buffer.writeFloat(out_r);

		// ディレイバッファを進める
		delay.pos ++;
		if(delay_sampling <= delay.pos)	delay.pos = 0;
	}

}