sound

Papervision3D Sound Spectrum

Saturday, December 6th, 2008 | examples, requests | Comments

This example is a remake of something Andy Zupko did about a year and a half ago. I just updated it to work with the latest version of Papervision3D and organized some of the code.

The song is by an indie group called Wolf Parade.

The .swf is about 4 megs (it has an embedded .mp3), so be patient while it downloads.

Click to change the layout.

source

You won’t be able to just copy and paste this. You will need the layout classes included in the source download.

package
{
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.media.Sound;
	import flash.media.SoundMixer;
	import flash.utils.ByteArray;
 
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.view.BitmapViewport3D;
 
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
	public class Papervision3DSoundSpectrum extends BasicView
	{
		[Embed(source="assets/WolfParade-CallItARitual.mp3")]
		private var soundAsset:Class;	
 
		private const HEIGHT:int = 800;
		private const blur:BlurFilter = new BlurFilter(3, 3, 2);
		private const alphaTrans:ColorTransform = new ColorTransform(1, 1, 1, 1, 4, 5, 3, -10);
 
		private var point:Point = new Point();
		private var bytes:ByteArray = new ByteArray();
		private var sound:Sound;
		private var gradient:Array;
 
		private var bitmapViewport:BitmapViewport3D;
 
		public var layout:ILayout;
		public var circleLayout:CircleLayout;
		public var lineLayout:LineLayout;
		public var squareLayout:SquareLayout;
 
		public var cubes:Array = [];
		public static const CHANNELS:int = 40;
 
		public function Papervision3DSoundSpectrum()
		{
			sound = new soundAsset() as Sound;
			sound.play();
 
			//we'll need a bitmapViewport to access bitmapData
			bitmapViewport = new BitmapViewport3D();
			//allow the blurring
			bitmapViewport.fillBeforeRender = false;
			addChild(bitmapViewport);
 
			camera.extra = {goPosition: DisplayObject3D.ZERO, goTarget: DisplayObject3D.ZERO};
			camera.x = 0, camera.y = 300, camera.z = 500; 
			camera.zoom = 10;
 
			gradient = createColors();
			createCubes();
 
			startRendering();
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onClick);
 
			circleLayout = new CircleLayout(this);
			lineLayout = new LineLayout(this);
			squareLayout = new SquareLayout(this);
 
			layout = circleLayout;
			layout.setAndAssignNext();
		}
 
		private function createColors(): Array
		{
			var gradient: Array = new Array();
 
			var shape:Shape = new Shape();
			var bitmapData:BitmapData = new BitmapData( 256, 1, true, 0 );
 
			var colors:Array = [0xff0000, 0xff0000, 0xffff00, 0x00ff00, 0x00ffff];
			var alphas:Array = [100, 100, 100, 100, 100];
			var ratios:Array = [0, 16, 128, 192, 255];
 
			var matrix:Matrix = new Matrix();
 
			matrix.createGradientBox(CHANNELS, 1, 0, 0, 0 );
 
			shape.graphics.beginGradientFill('linear', colors, alphas, ratios, matrix);
			shape.graphics.drawRect(0, 0, CHANNELS, 1);
			shape.graphics.endFill();
 
			bitmapData.draw(shape);
 
			for(var i:int = 0; i < CHANNELS; i++)
			{
				gradient[i] = bitmapData.getPixel32(i, 0);
			}
 
			return gradient;
		}
 
		private function createCubes():void
		{
			var cubeMaterial:ColorMaterial;
 
			var angleOffset:Number = Math.PI*2/CHANNELS;
			var radius:Number = 400;
			var angle:Number = 180;
 
			var cubeX:Number, cubeZ:Number;
			var cube:Cube;
 
			for(var i:int =0;i<CHANNELS;i++)
			{
				cubeMaterial = new ColorMaterial(gradient[i]);
				cubeMaterial.lineColor = 0x222222;
				cubeMaterial.lineAlpha = 1;
				cubeX = Math.cos(angle)*radius;
				cubeZ = Math.sin(angle)*radius;
 
				var materialsList:MaterialsList = new MaterialsList();
				materialsList.addMaterial(cubeMaterial, "all");
 
				cube = new Cube(materialsList, 50, 50, HEIGHT);
 
				cubes[i] = cube;		
				cubes[i].rotationY = 90;
				scene.addChild(cube);
			}
		}
 
		private function onClick(e:MouseEvent):void
		{
			layout.setAndAssignNext();
		}
 
		override protected function onRenderTick(event:Event = null):void
		{
			SoundMixer.computeSpectrum(bytes, true, 2);
			var channelModulo:int = int(256/CHANNELS);
 
			var average:Number = 0;
			var temp:Number = 0;
			var currentChannel:Number = 0;
 
			for(var i:int =1;i<=256;i++)
			{
				temp = bytes.readFloat();
				average += temp;
 
				if(i%channelModulo == 0)
				{
					//set the cur channel to this!
					if(currentChannel < cubes.length)
					{
						average /=channelModulo;
						if(average > cubes[currentChannel].scaleY)
						{
							cubes[currentChannel].scaleY = average;
						}
						else
						{
							cubes[currentChannel].scaleY -= 0.04;
							if(cubes[currentChannel].scaleY <= 0)
							{
								cubes[currentChannel].scaleY = 0;
							}
						}
						cubes[currentChannel].x += (cubes[currentChannel].extra.goX - cubes[currentChannel].x)/32;
						cubes[currentChannel].y = cubes[currentChannel].scaleY*HEIGHT/2;
						cubes[currentChannel].z += (cubes[currentChannel].extra.goZ - cubes[currentChannel].z)/32;
					}
 
					currentChannel++;
					average = 0;
				}
			}
 
			camera.orbit(bitmapViewport.containerSprite.mouseY, bitmapViewport.containerSprite.mouseX);
 
			renderer.renderScene(scene, camera, bitmapViewport);
			bitmapViewport.bitmapData.applyFilter(bitmapViewport.bitmapData, bitmapViewport.bitmapData.rect, point, blur);
			bitmapViewport.bitmapData.colorTransform(bitmapViewport.bitmapData.rect, alphaTrans);
		}
	}
}

Tags: , ,

Search

Recommended Books

Speaking at FITC Toronto

Recent Comments

 

July 2010
M T W T F S S
« May    
 1234
567891011
12131415161718
19202122232425
262728293031  

Preferred Video Tutorial Resolution

  • 1024x768 (53%, 85 Votes)
  • 1280x1024 (15%, 24 Votes)
  • 1920x1080 (15%, 24 Votes)
  • 800x600 (13%, 20 Votes)
  • 480x320 (4%, 6 Votes)
  • 640x480 (0%, 2 Votes)

Total Voters: 160

Loading ... Loading ...