[WavPlayer.as]
package {
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.media.SoundChannel;
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.media.Sound;
import flash.media.SoundTransform;
import flash.media.SoundChannel;
public class WavPlayer {
private var _myUrl:String;
private var _byteStream:URLStream;
private var _wavFormat:PCMFormat;
private var _sound:Sound;
private var _channel:SoundChannel;
public function WavPlayer(myUrl:String = null) {
super();
Init();
InitListeners();
Load(myUrl);
}
/* PUBLIC ********************************************************************************/
public function Load(myUrl:String = null):void {
if (myUrl != null) {
_myUrl = myUrl;
var myUrlRequest:URLRequest = new URLRequest(myUrl);
_byteStream.load(myUrlRequest);
}
}
public function CleanUp():void {
_byteStream.removeEventListener(ProgressEvent.PROGRESS, LoadProgress);
_byteStream.removeEventListener(Event.COMPLETE, LoadComplete);
_byteStream.removeEventListener(IOErrorEvent.IO_ERROR, LoadError);
}
/* INIT **********************************************************************************/
private function Init():void {
_myUrl = “”;
_byteStream = new URLStream();
}
private function InitListeners():void {
_byteStream.addEventListener(ProgressEvent.PROGRESS, LoadProgress);
_byteStream.addEventListener(Event.COMPLETE, LoadComplete);
_byteStream.addEventListener(IOErrorEvent.IO_ERROR, LoadError);
}
/* EVENT HANDLERS ************************************************************************/
private function LoadProgress(e:ProgressEvent):void {
trace(“bytesLoaded/bytesTotal: “+e.bytesLoaded.toString()+”/”+e.bytesTotal.toString());
}
private function LoadError(e:IOErrorEvent):void {
trace(“loadError”);
}
private function LoadComplete(e:Event):void {
trace(“loading complete… analyzing header…”);
var wavHeader:ByteArray = new ByteArray(); wavHeader.endian = Endian.LITTLE_ENDIAN;
var wavData:ByteArray = new ByteArray(); wavData.endian = Endian.LITTLE_ENDIAN;
_byteStream.readBytes(wavHeader, 0, PCMFormat.HEADER_SIZE);
_wavFormat = new PCMFormat();
try {
_wavFormat.AnalyzeHeader(wavHeader);
} catch (e:Error) {
trace(e);
return;
}
var bytesToRead:uint = _byteStream.bytesAvailable < _wavFormat._waveDataLength ? _byteStream.bytesAvailable : _wavFormat._waveDataLength;
_byteStream.readBytes(wavData, 0, bytesToRead);
var swf:SWFFormat = new SWFFormat(_wavFormat);
var compiledSWF:ByteArray = swf.CompileSWF(wavData);
var compiledSWFLoader:Loader = new Loader();
compiledSWFLoader.loadBytes(compiledSWF);
compiledSWFLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, generateCompleteHandler);
}
private function generateCompleteHandler(e:Event):void {
var soundClass:Class = LoaderInfo(e.target).applicationDomain.getDefinition(SWFFormat.CLASS_NAME) as Class;
_sound = new soundClass() as Sound;
_sound.play(0, 0, null);
}
}
}
[PCMFormat.as]
package {
import flash.utils.ByteArray;
public class PCMFormat {
/* CLASS PROPERTIES **********************************************************************/
public static const HEADER_SIZE:uint = 44;
public var _channels:uint;
public var _sampleRate:uint;
public var _byteRate:uint;
public var _blockAlign:uint;
public var _bitsPerSample:uint;
public var _waveDataLength:uint;
public var _fullDataLength:uint;
/* CONSTRUCTOR ***************************************************************************/
public function PCMFormat() {
}
/* PUBLIC METHODS ************************************************************************/
public function AnalyzeHeader(byteArray:ByteArray):void {
var typeArray:ByteArray = new ByteArray();
byteArray.readBytes(typeArray, 0, 4);
if (typeArray.toString() != “RIFF”) {
throw new Error(“Error: incorrect RIFF header”);
return;
}
_fullDataLength = byteArray.readUnsignedInt()+8;
byteArray.position = 0×10;
var chunkSize:Number = byteArray.readUnsignedInt();
if (chunkSize != 0×10) {
throw new Error(“Error: incorrect chunk size”);
return;
}
var isPCM:Boolean = Boolean(byteArray.readShort());
if (!isPCM) {
throw new Error(“Error: this file is not PCM wave file”);
return;
}
_channels = byteArray.readShort();
_sampleRate = byteArray.readUnsignedInt();
switch (_sampleRate) {
case 44100:
case 22050:
case 11025:
case 5512:
break;
default:
throw new Error(“Decode error: incorrect sample rate”);
return;
}
_byteRate = byteArray.readUnsignedInt();
_blockAlign = byteArray.readShort();
_bitsPerSample = byteArray.readShort();
byteArray.position += 0×04;
_waveDataLength = byteArray.readUnsignedInt();
if (!_blockAlign) {
_blockAlign = _channels*_bitsPerSample/8;
}
byteArray.position = 0;
}
}
}
[SWFFormat.as]
package {
import flash.utils.ByteArray;
import flash.utils.Endian;
import PCMFormat;
public class SWFFormat {
/* CLASS PROPERTIES **********************************************************************/
private static const SWF_PART0:String = “46575309″;
private static const SWF_PART1:String = “7800055F00000FA000000C01004411080000004302FFFFFFBF150B00000001005363656E6520310000BF14C7000000010000000010002E00000000080013574156506C61796572536F756E64436C6173730B666C6173682E6D6564696105536F756E64064F626A6563740C666C6173682E6576656E74730F4576656E744469737061746368657205160116031802160600050701020702040701050704070300000000000000000000000000010102080300010000000102010104010003000101050603D030470000010101060706D030D04900470000020201010517D0306500600330600430600230600258001D1D1D6801470000BF03″;
private static const SWF_PART2:String = “3F131800000001000100574156506C61796572536F756E64436C61737300440B0800000040000000″;
public static const CLASS_NAME:String = “WAVPlayerSoundClass”;
private var _pcmFormat:PCMFormat;
/* CONSTRUCTOR ***************************************************************************/
public function SWFFormat(format:PCMFormat) {
_pcmFormat = format;
}
/* PRIVATE METHODS ***********************************************************************/
private function WriteBytesFromString(byteArray:ByteArray, bytesHexString:String):void {
var length:uint = bytesHexString.length;
for (var i:uint = 0;i<length;i+=2) {
var hexByte:String = bytesHexString.substr(i, 2);
var byte:uint = Number(“0x”+hexByte);
byteArray.writeByte(byte);
}
}
private function TraceArray(array:ByteArray):String { // for debug
var out:String = “”;
var pos:uint = array.position;
array.position = 0;
while (array.bytesAvailable) {
var str:String = array.readUnsignedByte().toString(16).toUpperCase();
str = str.length < 2 ? “0″+str : str;
out += str+’ ‘;
}
array.position = pos;
return out;
}
private function GetFormatByte():uint {
var byte:uint = (_pcmFormat._bitsPerSample == 0×10) ? 0×32 : 0×00;
byte += (_pcmFormat._channels-1);
byte += 4*(Math.floor(_pcmFormat._sampleRate/5512.5).toString(2).length-1); // 
return byte;
}
/* PUBLIC METHODS ************************************************************************/
public function CompileSWF(audioData:ByteArray):ByteArray {
var dataLength:uint = audioData.length;
var swfSize:uint = dataLength+307;
var totalSamples:uint = dataLength/_pcmFormat._blockAlign;
var output:ByteArray = new ByteArray();
output.endian = Endian.LITTLE_ENDIAN;
WriteBytesFromString(output, SWFFormat.SWF_PART0);
output.writeUnsignedInt(swfSize);
WriteBytesFromString(output, SWFFormat.SWF_PART1);
output.writeUnsignedInt(dataLength+7);
output.writeByte(1);
output.writeByte(0);
output.writeByte(GetFormatByte());
output.writeUnsignedInt(totalSamples);
output.writeBytes(audioData);
WriteBytesFromString(output, SWFFormat.SWF_PART2);
return output;
}
}
}
Posted in Actionscript 3.0