This was a response I made to a post about extracting sound bytes, found on ActionScript.org.

The code listed in the post works for me, though there are some bad coding practices in it.

What I found to be areas of concern:

  • This only works in FlashPlayer 10 and Air 1.0, so certain methods (e.g., sound.extract()) are not found in previous SDK’s.
  • The code is not optimized – that is, it takes a long time to load. A tiny test MP3 I made took over 7 seconds, which implies that there must be a better way to handle this. The code may actually be working, but that may be unknown to the programmer.
  • Put the MP3 is in the same directory as the SWF.
  • This Flash can only be run from a webpage (this is because of the way you are loading the MP3). An error #2032 indicates this (though it means other things, too).
  • The code should provide debugging feedback. I added a TextField to the object that inherits this class, and wrote content to that TextField (instead of using trace()).
  • Extend from MovieClip class instead of Sprite. I had to do this because I was using a Flash library object, and the linkage’s Base Class needed to extend a MovieClip.

    Good coding practices may help clear up difficulties, too.

  • The Sound and URLRequest objects should not be declared at the class level, but rather within methods.
  • The ByteArray is defined as a class variable, but then bashed by a local declaration in the completeHandler() method.
  • Add error checking to the code!

    My revision follows.

    Before using this class:
    You inherit this class within Flash by setting up a linkage to this class from a Flash library object. Further, you will have to add a dynamic TextField called text1 to the object that inherits this class within Flash (it must be a child object of the inheriting library object).
    This example only has one error check added, but you have to do a lot more to make sure the code works as you expect. Look into the try-catch syntax. Further, I made no attempt to optimize the code.

    package
    {
    	import flash.display.MovieClip;
    	import flash.events.Event;
    	import flash.events.IOErrorEvent;
    	import flash.events.ProgressEvent;
    	import flash.display.Graphics;
    	import flash.media.Sound;
    	import flash.net.URLRequest;
    	import flash.utils.ByteArray;
    	
    	// Change: from Sprite class
    	public class soundTest extends MovieClip 
    	{
    		const WAVE_HEIGHT:int = 200; 
    		var snd:Sound;
    		
    		// change: removed defs from this area.
    		var req:URLRequest;
    		var buffer:ByteArray;
    		
    		public function soundTest():void 
    		{
    			if (stage) init();
    			else addEventListener(Event.ADDED_TO_STAGE, init);
    		}
    		
    		private function init(e:Event = null):void 
    		{
    			removeEventListener(Event.ADDED_TO_STAGE, init);
    			
    			// entry point
    			// change: moved sound def to here:
    			req = new URLRequest("test.mp3");
    			snd = new Sound();
    			
    			snd.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    			snd.addEventListener(Event.COMPLETE, completeHandler);
    			// change: added error checking
    			snd.addEventListener(IOErrorEvent.IO_ERROR, ioerrorHandler, false, 0, true);
    			
    			snd.load(req);
    		}
    		
    		//change: added this function
    		private function ioerrorHandler(e:IOErrorEvent):void 
    		{
    			traceHTML("(caught error) soundTest.init: " + e.type + " :\n.\n" + e.toString());
    		}
    		
    		public function completeHandler(e:Event):void {
    			
    			traceHTML("soundTest.completeHandler");
    			
    			var g:Graphics = this.graphics; 
    			g.lineStyle(1, 0x6600CC); 
    			
    			// Change: removed: snd.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
    			// Change: added remove Complete handler
    			e.target.removeEventListener(e.type, completeHandler);
    			e.target.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
    			
    			// change: removed declaration from here (was not accessing class variable):
    			buffer = new ByteArray();
    			var buffercounter:int = 0;
    			
    			var lsample:Number
    			var rsample:Number
    			var lmin:Number;
    			var lmax:Number;
    			var rmin:Number;
    			var rmax:Number;
    	
    			//outerloop
    			
    			while (snd.extract(buffer, 8192)) {
    				buffer.position = 0;
    				lmin = 0.0;
    				lmax = 0.0;
    				rmin = 0.0;
    				rmax = 0.0;
    				//innerloop
    				
    				traceHTML("soundTest.completeHandler: buffer.bytesAvailable:" + buffer.bytesAvailable);
    				
    				while (buffer.bytesAvailable) {
    					lsample = buffer.readFloat();
    					rsample = buffer.readFloat();
    					
    					traceHTML("soundTest.completeHandler: lsample:" + lsample);
    					
    					if (lsample  lmax) lmax = lsample;
    					if (rsample  rmax) rmax = rsample;
    					
    					traceHTML("soundTest.completeHandler: lmin:" + lmin	);
    					
    					buffer.position += 1024;
    				}
    				//draw the wave
    				g.moveTo(buffercounter, ( -lmax + 1.0) * WAVE_HEIGHT);
    				g.lineTo(buffercounter, ( -lmin + 1.0) * WAVE_HEIGHT);
    				g.moveTo(buffercounter, ( -rmax + 2.0) * WAVE_HEIGHT);
    				g.lineTo(buffercounter, ( -rmin + 2.0) * WAVE_HEIGHT);
    				buffercounter++;
    			}
    			traceHTML("completed");
    		}
    
    		public function progressHandler(event:ProgressEvent):void {
    			//traceHTML("soundTest.progressHandler");
    			traceHTML(Number(event.bytesLoaded / event.bytesTotal * 100).toPrecision(3) + "% loaded.");
    		}
    
    		// change: added this function
    		public function traceHTML(str:String):void 
    		{
    			//if (text1) 
    			//{
    				text1.appendText(str + "\n");
    			//}
    		}
    	}
    }
    

    – 30 –

    Advertisements