DAN ZEN EXPO - CODE EXHIBIT - WOODPECKER


package samples {
	
	import flash.display.*;
	import flash.net.URLRequest;	
	import flash.net.navigateToURL;		
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.filters.*;	
	import flash.events.*;	

	// SEE FEATHERS.AS FOR DETAILS OF SETTING UP MULTIPLE ANIMATED CLIPS

	// see the WoodPecker.as file located at the path below for instructions on installing classes
		
	import com.danzen.effects.woodpecker.*;	
	
	// WOODPECKER INTRODUCTION  
	// WoodPecker is a package of AS3 custom classes for animating MovieClips to sound
	// MP3 and FLV sounds work - they must be on the same drive or look into crossdomain policy
	// due to limitations in Flash, WoodPecker does not work with live sounds
	// use the Microphone Class and the activityLevel property for live sounds
	// WoodPecker works with all sounds currently playing - you cannot specify certain sounds
	// http://woodpeckerflash.wordpress.com - by inventor Dan Zen - http://www.danzen.com
	// if you are using WoodPecker for commercial purposes, you are welcome to donate to Dan Zen
	// donations can be made to agency@danzen.com at http://www.paypal.com
	
	// WOODPECKER FEATURES  
	// animate by frequency (bass, mid, treble for instance) or by wave form
	// animate one MovieClip or any number of clips
	// animate different clips in one WoodPecker object
	// You can have more than one WoodPecker object
	// animate width, height, and alpha (any combination of these)
	// animate other properties by not adding WoodPecker to the stage
	// and using the alpha of WoodPecker (Number 0-1) to animate rotation or filter values
	// set the x and y of the clips
	// set the maximum and minimum size of the clips
	// set the alpha and color of the clips
	// set the blendMode and filters of the clips
	// you can set these for each individual clip or to all the clips
	// indeed, set any property of the clips by accessing the created MovieClip
	// you can set whether people can drag the clips around
	// this is handy for you as you set up WoodPecker because you can record the location of clips
	
	// USING WOODPECKER  
	// please make sure that com/danzen/effects/woodpecker/ is in a folder in your class path
	// WoodPecker uses the com/danzen/utilities/DynamicObject.as file as well

	// note: you do not animate MovieClips that are on the state - here are the steps:
	// please see the example code below that shows these steps in operation

	// 1. make a MovieClip in the library and under properties/linkage name set the Class name
	// 2. pass that class name as well as other parameters to the new WoodPecker() (set dragable=true)
	// 3. run your Flash and you will see objects created by WoodPecker
	// 4. drag them around to the right places and then call the recordBeat() method
	// 5. see the examples for how to do this with a KeyPress event
	// 6. copy the traced setBeatObject() method call to the line after your WoodPecker object
	// 7. run your Flash again and you will see that your settings are saved
	// 8. from then on, you can make modifications to the individual beats
	// 9. for instance, using a different Class, setting unique sizes or filters, etc.
	//    (if you are animating the alpha, make sure you have different beatSize and startSize)

	// CONSTRUCTOR  
	// WoodPecker(theClip:Class, theType:Array, theNumBeats:Number=1, theSize:Number=100, theFrequency:Boolean=true, theDragable:Boolean=true):void
	//	constructor to start animating clips to sound
	//	PARAMETERS:
	//		theClip:Class
	//			a class such as a MovieClip in the library with its Class set under properties > linkage
	//		theType:Array
	//			an array of three Booleans for scale width, height, alpha based on beat amplitude i.e. [true, true, false]
	//		theNumBeats
	//			the number of instances that will be made from theClip Class
	//		theSize
	//			the size of theClip's largest animated width or height dimension
	//		theFrequency
	//			set to true if a frequency spectrum is tested - base, mid, treble
	//			set to false if a wave form is tested - provides more an even undulating effect
	//		theDragable:Boolean
	//			you can drag the clips around - this can be for interactivity or to record their positions
	
	// EVENTS  
	// no events
	
	// METHODS  
	// setBeat(what:String, which:Number, amount:Object):void
		// sets the specified property (what) for the specified beat (which) to the specified value
		// properties to choose from are:
		// "clip","x","y","alpha","color","blendMode","filters","beatSize","startSize"
	// setAllBeats(what:String, amount:Object):void
		// sets the specified property (what) of every beat to the specified value - see above for properties
	// getBeats():Array
		// gets an array of the beat clips
	// getBeatAt(w:Number):Object
		// gets a specific beat in the array
	// setBeatObject(o:Object):void
		// receives an object with all the properties above holding an Array each containing the values for the beats
		// example: {clip:[Class1, Class2], x:[12, 34], y:[29, 44], alpha:[1, 1], etc. }
	// getBeatObject():Object
		// returns the object that holds all the properties above as arrays of values per beat
	// recordBeat():void
		// traces the code for the BeatObject so that you can hard code your initialized object
	// dispose():void
		// stops tracking beats and removes listeners, etc.
	
	// PROPERTIES  
	// displayOn:Boolean
		// sets the alpha of each surregate clip to .5 so you can see them better during set up
	
	public class Beautiful extends Sprite {			
				
		private var myPicture:Loader;
		private var mySound:Sound;
		private var myChannel:SoundChannel;
		private var myBars:WoodPecker;
		private var myBalls:WoodPecker;
		private var myWoodPecker:WoodPecker;
		
		public function Beautiful() {
						
			mySound = new Sound();
			mySound.load(new URLRequest("beautiful.mp3"));
			myChannel = mySound.play();
			myChannel.addEventListener(Event.SOUND_COMPLETE, replay);

			var clip:Class = Bar; // this is the class for your movieClip
			var numBeats:Number = 40;
			var size:Number = 100;
			var type:Array = [false, true, false];  // scale width, height, alpha based on beat amplitude
			var frequency:Boolean = true; // true for frequency and false for wave
			var dragable:Boolean = false;
						
			myBars = new WoodPecker(clip, type, numBeats, size, frequency, dragable);			
			myBars.setAllBeats("startSize",1);
			addChild(myBars);
			myBars.x = 100;
			myBars.y = 170;
						
			clip = Ball; // this is the class for your movieClip
			numBeats = 4;
			size = 240;			
			type = [true, true, false];  // scale width, height, alpha based on beat amplitude
			frequency = false; // otherwise wave
			dragable = false;
						
			myBalls = new WoodPecker(clip, type, numBeats, size, frequency, dragable);						

			addChild(myBalls);			
			myBalls.setAllBeats("startSize",30);
			myBalls.setAllBeats("blendMode","difference");
			myBalls.setAllBeats("filters",[new BlurFilter(10,10,3)]);
			myBalls.setAllBeats("x",300);
			myBalls.setAllBeats("y",370);
			myBalls.alpha = .9
			
			
			clip = WoodPeckerIcon; // this is the class for your movieClip
			numBeats = 1;
			size = 200;
			type = [true, true, false];  // scale width, height, alpha based on beat amplitude
			frequency = true; // true for frequency and false for wave
			dragable = false;
						
			myWoodPecker = new WoodPecker(clip, type, numBeats, size, frequency, dragable);						
			myWoodPecker.x = 620;
			myWoodPecker.y = 250;
			myWoodPecker.buttonMode = true;	
			myWoodPecker.tabEnabled = false;
			
			addChild(myWoodPecker);			
			myWoodPecker.setBeat("startSize",0,100);
			myWoodPecker.setBeat("alpha",0,.7);			
						
			myWoodPecker.addEventListener(MouseEvent.CLICK, woodpeckerFlash);
			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyListener);

		}
		
		private function replay(e:Event) {
			myChannel.removeEventListener(Event.SOUND_COMPLETE, replay);
			myChannel = mySound.play();
			myChannel.addEventListener(Event.SOUND_COMPLETE, replay);
		}
		
		private function woodpeckerFlash(e:MouseEvent) {
			navigateToURL(new URLRequest("http://woodpeckerflash.wordpress.com"), "woodpecker");
		}
		
		private function keyListener(e:KeyboardEvent) {
			if (e.keyCode == 82 && (e.shiftKey || e.ctrlKey)) { // R - Record
				myWoodPecker.recordBeat();
			}
			if (e.keyCode == 68 && (e.shiftKey || e.ctrlKey)) { // D - Display
				myWoodPecker.displayOn = !myWoodPecker.displayOn;
			}
		}		
	}	
}

package com.danzen.effects.woodpecker {

	// WOODPECKER INTRODUCTION  
	// WoodPecker lets you animate MovieClips in your Library to sound frequency
	// http://woodpeckerflash.wordpress.com - by inventor Dan Zen - http://www.danzen.com
	// if you are using WoodPecker for commercial purposes, you are welcome to donate to Dan Zen
	// donations can be made to agency@danzen.com at http://www.paypal.com
	
	// INSTALLING CLASSES
	// suggested installation:
	// create a "classes" folder on your hard drive - for example c:\classes
	// add the classes folder to your Flash class path:
	// Flash menu choose Edit > Preferences > ActionScript - ActionScript 3 Settings 
	// then use the + sign for the source path box to add the path to your classes folder	
	// put the provided com/danzen/ directory with its folders and files in the classes folder
	// the readme has more information if you need it

	// USING WOODPECKER
	// please make sure that com/danzen/effects/woodpecker/ is in a folder in your class path
	// WoodPecker uses the com/danzen/utilities/DynamicObject.as file as well - so put that there too

	// 1. make a MovieClip in the library and under properties/linkage name set the Class name
	// 2. pass that class name as well as other parameters to the new WoodPecker() (set dragable=true)
	// 3. run your Flash and you will see objects created by WoodPecker
	// 4. drag them around to the right places and then call the recordBeat() method
	// 5. see the examples for how to do this with a KeyPress event
	// 6. copy the traced setBeatObject() method call to the line after your WoodPecker object
	// 7. run your Flash again and you will see that your settings are saved
	// 8. from then on, you can make modifications to the individual beats
	// 9. for instance, using a different Class, setting unique sizes or filters, etc.
	//    (if you are animating the alpha, make sure you have different beatSize and startSize)
	
	// there is a list of methods, events and properties below for reference	
	// see the example files that come with WoodPecker to see how to do the steps above		


	import flash.display.*	
	import flash.events.*
	import flash.utils.Timer;
	import flash.filters.*;
	import flash.geom.ColorTransform;
	import flash.geom.Transform;
	import flash.geom.Matrix;
	import fl.motion.Color;
	
	import com.danzen.utilities.DynamicObject;
	
	public class WoodPecker extends Sprite {
		
		// CONSTRUCTOR
		// WoodPecker(theClip:Class, theType:Array, theNumBeats:Number=1, theSize:Number=100, theFrequency:Boolean=true, theDragable:Boolean=true):void
		//	constructor to start animating clips to sound
		//	PARAMETERS:
		//		theClip:Class
		//			a class such as a MovieClip in the library with its Class set under properties > linkage
		//		theType:Array
		//			an array of three Booleans for scale width, height, alpha based on beat amplitude i.e. [true, true, false]
		//		theNumBeats
		//			the number of instances that will be made from theClip Class
		//		theSize
		//			the size of theClip's largest animated width or height dimension
		//		theFrequency
		//			set to true if a frequency spectrum is tested - base, mid, treble
		//			set to false if a wave form is tested - provides more an even undulating effect
		//		theDragable:Boolean
		//			you can drag the clips around - this can be for interactivity or to record their positions
		//		theMic:Boolean
		//			do you want to process sound from the mic - you need to make a microphone object in your code

		// EVENTS
		// no events
		
		// METHODS
		// setBeat(what:String, which:Number, amount:Object):void
			// sets the specified property (what) for the specified beat (which) to the specified value
			// properties to choose from are:
			// "clip","x","y","alpha","color","blendMode","filters","beatSize","startSize"
		// setAllBeats(what:String, amount:Object):void
			// sets the specified property (what) of every beat to the specified value - see above for properties
		// getBeats():Array
			// gets an array of the beat clips
		// getBeatValues():Array
			// gets an array of beat values before scaled - right from the divided compute spectrum
		// getBeatAt(w:Number):Object
			// gets a specific beat in the array
		// setBeatObject(o:Object):void
			// receives an object with all the properties above holding an Array each containing the values for the beats
			// example: {clip:[Class1, Class2], x:[12, 34], y:[29, 44], alpha:[1, 1], etc. }
		// getBeatObject():Object
			// returns the object that holds all the properties above as arrays of values per beat
		// recordBeat():void
			// traces the code for the BeatObject so that you can hard code your initialized object
		// dispose():void
			// stops tracking beats and removes listeners, etc.
		
		// PROPERTIES 	
		// displayOn:Boolean
			// sets the alpha of each surregate clip to .5 so you can see them better during set up
			
		// PRIVATE VARIABLES			
		private var myClip:Class;
		private var myNumBeats:Number;
		private var mySize:Number;
		private var myType:Array;
		private var myFrequency:Boolean;
		private var myDragable:Boolean;
		private var myBeat:SoundBeat;
		private var myHolder:Sprite;
		private var myBeats:Sprite;
		private var myMenus:Sprite;		
		private var menuArray:Array = [];
		private var myTimer;Timer;		
		private var beatArray:Array = [];
		private var beatObject:Object;
		private var myValues:Array = [];
		private var bList:Array = ["clip","x","y","alpha","color","blendMode","filters","beatSize","startSize"];		
		private var currentDrag:Object;
		private var myDisplayOn:Boolean = false;
		private var myMic:Boolean = false;
		private var mySlow:Number;
		private var myGain:Number;
		private var myDamp:Number;
		private var myCount:Number=0;				

		public function WoodPecker (
					theClip:Class,
					theType:Array,
					theNumBeats:Number=1,
					theSize:Number=100,					
					theFrequency:Boolean=true,
					theDragable:Boolean=true,
					theMic:Boolean=false,
					theGain:Number=50,
					theSlow:Number=1,
					theDamp:Number=0) {			
			
			trace ("hi from WoodPecker");
			
			myClip = theClip;
			myNumBeats = theNumBeats;
			mySize = theSize;
			myType = theType;
			myFrequency = theFrequency;
			myDragable = theDragable;	
			myMic = theMic;	
			myGain = theGain;
			mySlow = theSlow;
			myDamp = theDamp;
	
			tabChildren = false;
			tabEnabled = false;
			
			myHolder = new Sprite();			
			myBeats = new Sprite();
			myMenus = new Sprite();
			myHolder.addChild(myBeats);
			myHolder.addChild(myMenus);
						
			var space = 10;
			for (var i:uint=0; i 0) {
				addEventListener(Event.ENTER_FRAME, animate);
			}

		}		
		
		private function animate(e:Event):void {		
			var thisBeat:MovieClip;
			var diff:Number;			
			for (var i:uint=0; i 0) {
					if (myType[0] && myType[1]) { // keep proportion
						if (menuArray[i].width > menuArray[i].height) {
							oldW = menuArray[i].width;
							beatArray[i].desiredW = startFactor + myValues[i] * scaleFactor / mySize;
							beatArray[i].desiredH = menuArray[i].height * beatArray[i].desiredW / oldW;						
						} else {
							oldH = menuArray[i].height;
							beatArray[i].desiredH = startFactor + myValues[i] * scaleFactor / mySize;
							beatArray[i].desiredW = menuArray[i].width * beatArray[i].desiredH / oldH;							
						}
					} else {
						if (myType[0]) {
							beatArray[i].desiredW = startFactor + myValues[i] * scaleFactor / mySize;
						}
						if (myType[1]) {
							beatArray[i].desiredW = beatArray[i].width;
							beatArray[i].desiredH = startFactor + myValues[i] * scaleFactor / mySize;
						}
						if (myType[3]) {
							beatArray[i].desiredR = startFactor + myValues[i] * scaleFactor / mySize;
						}
					}
				} else {
					if (myType[0] && myType[1]) { // keep proportion
						if (menuArray[i].width > menuArray[i].height) {
							oldW = menuArray[i].width;
							beatArray[i].width = startFactor + myValues[i] * scaleFactor / mySize;
							beatArray[i].height = menuArray[i].height * beatArray[i].width / oldW;						
						} else {
							oldH = menuArray[i].height;
							beatArray[i].height = startFactor + myValues[i] * scaleFactor / mySize;
							beatArray[i].width = menuArray[i].width * beatArray[i].height / oldH;							
						}
					} else {
						if (myType[0]) {
							beatArray[i].width = startFactor + myValues[i] * scaleFactor / mySize;
						}
						if (myType[1]) {
							beatArray[i].height = startFactor + myValues[i] * scaleFactor / mySize;
						}
						if (myType[3]) {
							beatArray[i].rotation = startFactor + myValues[i] * scaleFactor / mySize;
						}
					}
				}
				
				
				if (myType[2]) {
					beatArray[i].alpha = (startFactor + myValues[i] * scaleFactor) / beatObject["beatSize"][i] / mySize;
				}				
			}			
		}					

		private function setClip(w:Number, a:Object) {
			if (!a) {return;}
			var tempTransform;		
			var clip;
			var clip2;
			tempTransform = beatArray[w].transform.matrix;					
			clip = new a();
			clip2 = new a();					
			if (myDragable) {
				menuArray[w].removeEventListener(MouseEvent.MOUSE_DOWN, drag);
				menuArray[w].removeEventListener(MouseEvent.MOUSE_UP, drop);
			}						
			myBeats.removeChild(beatArray[w]);
			myMenus.removeChild(menuArray[w]);					
			beatArray[w] = clip;
			menuArray[w] = clip2;								
			clip.transform.matrix = tempTransform;
			clip2.transform.matrix = tempTransform;						
			clip2.alpha = 0;						
			myBeats.addChild(clip);	
			myMenus.addChild(clip2);						
			if (myDragable) {				
				clip2.mouseChildren = false;
				clip2.addEventListener(MouseEvent.MOUSE_DOWN, drag);
				clip2.addEventListener(MouseEvent.MOUSE_UP, drop);
				clip2.buttonMode = true; 
				clip2.mate = clip;							
			}									
			clip.num = w;
			clip2.num = w								
		}		
		
		private function setBeatProperties() {
			
			var b = {};
			for (var i:uint=0; i 1) {
					temp = temp[1].substr(0,-1);
				} else {
					temp = "";
				}
				beatConverted["clip"][i] = temp;
				if ( beatObject["filters"][i]) {					
					temp = beatObject["filters"][i].toString().split(" ");
					if (temp.length > 1) {
						temp = "[new "+temp[1].substr(0,-1)+"()]";
					} else {
						temp = "";
					} 
				} else {
					temp = "";
				}
				beatConverted["filters"][i] = temp;	
			}
			for (i=0; i 0) {
				addEventListener(Event.ENTER_FRAME, animate);
			}
		}
	
		public function dispose():void {				
			trace ("bye from WoodPecker");
			myTimer.removeEventListener(TimerEvent.TIMER, follow);
			myBeat.removeEventListener(SoundBeatEvent.PROCESS_SOUND, processBeat);	
			myBeat.dispose()
		}		

	}	
}