wavファイルをByteArrayとして読み込んで再生させます。
以下のサイトを参考にさせてもらいました。
・ついにWAVLoaderが完成!ただしフォーマットは限定(Player10) « きんくまデザイン
FP10の動的サウンド生成機能を使って再生しています。
再生するwavファイルは、リニアPCMで16bitのものだけ。
ステレオでもモノラルでもOKです。
FP10の動的生成音は44.1kHzなので、wavファイルも44.1kHzか、それの半分、または1/4の22kHzや11kHzならちゃんと再生されます。
16kHzなどの場合は、再生スピードがはやくなります。
wavファイルの周波数データを動的サウンド生成で利用する場合、32767で割ってから利用しています。
これは、wavファイルの周波数は16bitの場合-32768 ~ +32767で表されているからです。
FP10の動的サウンド生成で扱うデータは-1~1なので、丸めこんでやる必要があるわけです。
以下、ソースです。
package
{
import flash.display.FrameLabel;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class read_wav02 extends Sprite
{
private var waveData:ByteArray;
private var channel:uint;
private var rate:int;
private var samplingRate:uint;
private var sound:Sound;
public function read_wav02()
{
stage.scaleMode=StageScaleMode.NO_SCALE;
stage.align=StageAlign.TOP_LEFT;
// ファイルの読み込み
var loader:URLLoader=new URLLoader;
loader.dataFormat=URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest("data.wav"));
}
private function onComplete(e:Event):void
{
var loader:URLLoader=e.target as URLLoader;
loader.removeEventListener(Event.COMPLETE, onComplete);
// wavファイルをByteArrayとして保存
var data:ByteArray=ByteArray(loader.data);
data.endian=Endian.LITTLE_ENDIAN;
data.position=0;
// 周波数データを保存するByteArray
waveData=new ByteArray;
waveData.endian=Endian.LITTLE_ENDIAN;
waveData.position=0;
// wavファイルを読み込んでいく
var format:uint;
var qRate:uint;
var isLoop:Boolean=true;
while(isLoop)
{
var chunk_type:String=data.readUTFBytes(4);
switch(chunk_type)
{
case "RIFF":
data.position+=8;
break;
case "fmt ":
var pos:uint=data.position;
var size:uint=data.readUnsignedInt();
format=data.readUnsignedShort();
channel=data.readUnsignedShort();
samplingRate=data.readUnsignedInt();
data.position+=6;
qRate=data.readUnsignedShort();
data.position=pos + size;
break;
case "data":
var dataLength:uint=data.readUnsignedInt();
data.readBytes(waveData, 0, dataLength);
isLoop=false;
break;
}
}
trace("Format ID is " + format + " (1 is Linear PCM).");
trace("Channel is " + channel + " (1:mono 2:stereo).");
trace("Sampling rate is " + samplingRate + " Hz.");
trace("Quantization bitrate is " + qRate + " .");
// リニアPCMで16ビットかつ、サンプリングレートが44.1kHz以下の場合再生します。
rate=int(44100 / samplingRate);
if (format == 1 && qRate == 16 && rate >= 1)
{
sound=new Sound;
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
sound.play();
}
}
private function onSampleData(e:SampleDataEvent):void
{
var data:ByteArray=e.data;
for(var i:int=0; i < 2048; i++)
{
// モノラルの場合の処理
if (channel == 1)
{
var wave:Number=waveData.readShort() / 32767;
if (wave > 1 || wave < -1) wave=0;
for(var j:int=0; j < rate; j++)
{
data.writeFloat(wave);
data.writeFloat(wave);
}
}
// ステレオの場合の処理
else if (channel == 2)
{
var left:Number=waveData.readShort() / 32767;
var right:Number=waveData.readShort() / 32767;
if (left > 1 || left < -1) left=0;
if (right > 1 || right < -1) right=0;
for(var j:int=0; j < rate; j++)
{
data.writeFloat(left);
data.writeFloat(right);
}
}
if (waveData.bytesAvailable <= 0) waveData.position=0;
}
}
}
}
One Comment
Good brief and this mail helped me alot in my college assignement. Thanks you for your information.