前回のエントリーで、WAVファイルをバイナリ解析して再生しましたが
今回は、波形データ(-1~1の配列)からWAVファイルを生成してみたいと思います。

WAVファイルフォーマットに合わせて、バイナリを書いていく作業になります。

package
{
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	
	public class WavUtil
	{
		private static var SAMPLING_RATE:int = 44100;
		
		public static const MONAURAL:int = 1;
		public static const STEREO:int = 2;
		
		public static const BIT8:int = 8;
		public static const BIT16:int = 16;
		
		public function WavUtil() 
		
		/**
		 * PCM データ配列をWAV形式にエンコードします
		 * 
		 * @param	data	PCMデータ
		 * @param	channel	チャンネル数
		 * @param	bit		ビット数
		 * @return	WAVバイナリデータ
		 */
		public static function encode(data:Vector.< Number >, channel:int = 1, bit:int = 8):ByteArray
		{
			var byte:ByteArray = new ByteArray();
			byte.endian = Endian.LITTLE_ENDIAN;
			
			var filesize:int = data.length * channel + 44;
			var blocksize:int = channel * (bit / 8);
			
			//RIFFヘッダ
			byte.writeUTFBytes("RIFF");
			//これ以降のファイルサイズ
			byte.writeInt(filesize - 8);
			//WAVEヘッダ
			byte.writeUTFBytes("WAVE");
			//fmtチャンク
			byte.writeUTFBytes("fmt ");
			//fmt チャンクのバイト数
			byte.writeInt(16);
			//フォーマットID
			byte.writeShort(1);
			//チャンネル数
			byte.writeShort(channel);
			//サンプリングレート
			byte.writeInt(SAMPLING_RATE);
			//データ速度 (Byte/sec)
			byte.writeInt(SAMPLING_RATE * blocksize);
			//ブロックサイズ
			byte.writeShort(blocksize);
			//サンプルあたりのビット数 (bit/sample)
			byte.writeShort(bit);
			//dataチャンク
			byte.writeUTFBytes("data");
			//波形データのバイト数
			byte.writeInt(data.length * blocksize);
			//波形データ
			byte.writeBytes(getWaveData(data, channel, bit));
			
			return byte;
		}
		
		
		static private function getWaveData(data:Vector.< Number >, channel:int, bit:int):ByteArray
		{
			var byte:ByteArray = new ByteArray();
			byte.endian = Endian.LITTLE_ENDIAN;
			
			var cnt:int;
			
			switch(bit)
			{
				case BIT8:
					if (channel == MONAURAL)
					{
						for (cnt = 0; cnt < data.length; cnt++) byte.writeByte(int(data[cnt] * 127 + 128));
					}
					else if (channel == STEREO)
					{
						for (cnt = 0; cnt < data.length; cnt++) { byte.writeByte(int(data[cnt] * 127 + 128)); byte.writeByte(int(data[cnt] * 127 + 128)); };
					}
				break;
				
				case BIT16:
					if (channel == MONAURAL)
					{
						for (cnt = 0; cnt < data.length; cnt++) byte.writeShort(int(data[cnt] * 32768));
					}
					else if (channel == STEREO)
					{
						for (cnt = 0; cnt < data.length; cnt++) { byte.writeShort(int(data[cnt] * 32768)); byte.writeShort(int(data[cnt] * 32768)); };
					}
				break;
			}
			
			return byte;
		}
	}
}


上記エンコードクラスを使って作った簡易効果音ジェネレータ
 

SEMaker_capture.png

作成した効果音をSAVEボタンでローカルにWAVファイルとして保存できます。

今回は生成した波形をWAV書き出ししていますが、
マイクからの入力音声をWAVファイルとして保存したりも出来るかと思います。

それでは、よりよいバイナリ解析ライフを!
 

 

HTML5飯