Papervision3D Sound Spectrum
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); } } }
-
John Lindquist
-
Tunied
-
John Lindquist
-
Tunied
Search
Recommended Books
Speaking at FITC Toronto
Recent Posts
- Moving to johnlindquist.com
- AsyncCommand with Robotlegs, Signals, Flight, MinimalComps
- Search Widget – Robotlegs, Signals, Flight, Minimal Comps, Yahoo Astra
- FDT Super Awesome March Deal
- haXe Tutorial
- AS3 Signals Tutorial
- Preferred Video Tutorial Resolution?
- TweenMax – Tweening a timeline (Advanced Tweening)
- Robotlegs + Flight + Union Platform
- Back in the saddle
- Eclipse Theme Designer Preview
- RobotLegs Hello World Video Tutorial
- 10 Things Every Senior Flash Developer Should Know
- Efflex – 3D Effects for Flex
- MorphController – Mighty Morphing Papervision3D
Recent Comments
- Ocatarinabelachichix on about
- Rajiv on faq
- Rajiv on 3ds max texture baking for Papervision3D
- Anupam Biswas on Maya Texture Baking
- Anupam Biswas on Maya Texture Baking
- Arindam Mojumder on requests
- Arindam Mojumder on requests
- Arindam Mojumder on Full Screen Cube
- Arindam Mojumder on faq
- Mimosa123321 on requests
Categories
Archives
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

