AS3でwavファイルを再生

Filed under AS3

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

  1. Posted 2010/08/19 at 10:26 | Permalink

    Good brief and this mail helped me alot in my college assignement. Thanks you for your information.

Post a Comment

Your email is never published nor shared.