T-Mobile Galaxy S6 Battery Woes

I’ve been using a T-Mobile Galaxy S6 since the device launched with T-mobile’s … more

Earthquake Early Warning in Your Pocket

Probably all of us reading this have a smartphone in our pocket. For many of us, the … more

Sony: The OEM You Want To Save

In our recent Discuss article, we asked you readers on which OEM you would like to help. While the … more

How to Lock and Protect Your Apps – XDA Xposed Tuesday

The smartphone revolution has passed. Everybody has mobile apps. Some of … more

[LiveWallpaper DEV] DeadMau5 Audio Visualizer [v1.4]

419 posts
Thanks Meter: 130
By Metastable, Senior Member on 10th August 2011, 07:02 AM
Post Reply Subscribe to Thread Email Thread
I've been working on a new Live Wallpaper with a DeadMau5 theme to it. Decided to make a build thread because I don't see many around this forum and thought it would be interesting to do.

The goal is to recreate DeadMau5's current concert setup:

It is being coded in pure Java using OpenGL ES 1.0. As I am only starting to use OpenGL ES and I think 1.0 is slightly more beginner friendly due to not needing to create a custom pipeline, I choose 1.0 though may move to 2.0 later.

I initially started by creating an LED class which is basically a primitive cube:
public class Led{
	 public Led(float width, float height, float depth) {
	        width /= 2;
	        height /= 2;
	        depth /= 2;

	        float tempVertices[] = { -width, -height, -depth, // 0
	                        	  width, -height, -depth, // 1
	                        	  width,  height, -depth, // 2
	                        	 -width,  height, -depth, // 3
	                        	 -width, -height,  depth, // 4
	                        	  width, -height,  depth, // 5
	                        	  width,  height,  depth, // 6
	                        	 -width,  height,  depth, // 7

	        short tempIndices[] = { 0, 4, 5, 0, 5, 1, 
	        					1, 5, 6, 1, 6, 2, 
	        					2, 6, 7, 2, 7, 3, 
	        					3, 7, 4, 3, 4, 0, 
	        					4, 7, 6, 4, 6, 5, 
	        					3, 0, 1, 3, 1, 2,};
	        vertices = tempVertices;
	        indices = tempIndices;
	public void setColor(float red, float green, float blue, float alpha) {
		super.setColor(red, green, blue, alpha);

        private float red, green, blue, alpha = 0f;
        private float[] vertices;
        private short[] indices;

I then created a Panel class which creates a flat array of Leds 10x10 for a total of 100 leds per panel. Then finally with a Cube class that creates an array of Panels, translated and rotated to create the final Cube image, here:

Which I think is decent reproduction of the real thing:

I then set off on being able to display images onto my glorious cube of light. OpenGL allows you to change the color of the elements that you are drawing, in this case cubes.

I contemplated the best approach on doing this, ultimately settling on drawing onto a bitmap and then mapping out my Leds to individual pixels of said bitmap. I draw what I want onto a bitmap of dimensions 119x145. It only needs to be this small because the amount of data that I can display on the cube is limited to how many Leds I use. At the moment there is a total of 7500 Leds in my cube. If I ever decide to increase the amount of Leds per panel I would then need to increase the size of my bitmap.

The process of mapping the actual Leds to pixels took the longest time of the entire project so far. Having to manually map 7500 pixels is not very fun. Originally creating a byte[] containing all the coordinates I was able to start the mapping process, one... pixel... at a time. I eventually ran into a wall because apparently you can only have so many bytes in your constructor, damn. The next logical step was to move over all the mappings onto an external file and then read from it when needed.

So I created this:
public class PixelMapper {
	public static void main(String[] args) throws IOException {
		InputStream stream = new FileInputStream("C:/Users/Jano/Documents/DeadMau5 Audio Visualizer/cube_mapping.txt");
	    Scanner s = new Scanner(stream);
	    List<Byte> bytes = new ArrayList<Byte>();
	    while (s.hasNextByte()) {
	    byte[] byteArray = new byte[bytes.size()];
	    for(int i = 0; i < bytes.size(); i++)
	    	byteArray[i] = bytes.get(i);
	    FileOutputStream out = new FileOutputStream(new File("C:/Users/Jano/Documents/DeadMau5 Audio Visualizer/cube_mapping"));
This little piece of code does two things, reads a text file containing all of my coordinates and writes them onto a binary file. I had first read straight from the text file in my wallpaper but the process would take way too long, I'm talking 3 minutes plus long. It seems my phone was simply too slow for the task and much prefers reading from a binary file, which completes in under 5 secs.

After all of the grueling mapping that had to be done, I was rewarded with this:

And here it is with a gray background to better see what's going on:

It is not a static image displayed on the cube but a dynamic image that goes to the music being played. I used the Laser Visual that I had developed for my first Live Wallpaper, Epic Audio Visualizer, to provided the lovely images.

Initially the cube would refresh very slowly, perhaps 5-10 fps, as I each Led would draw itself, making OpenGL ES crawl. So I set out to find a way to speed up the process and thus learned about Batchers.

A Batcher takes all of your vertices, in this case 8 per led, and draws them in one OpenGL call. It increased performance greatly but I lost the ability to change the color of each Led, thus no more lovely pictures. That was until I figured I could use OpenGL once again to solve this issue.

OpenGL ES allows you to assign a color to each vertex and create smooth color transitions between vertices. I don't want smooth transitions between Leds, just solid colors for each one. To remedy the problem and created a float[] and when ever I grab a color from the bitmap I copy it to the array 8 times, once per vertex. I'm not entirely sure this is the most efficient process but I couldn't find another solution that said otherwise.

Surprisingly, it worked rather well and I now get ~30 fps, which is what I currently have it hard maxed at.

With that now complete and my cube running smoothly, dancing away to Pandora, I set out to reproduce the VersaTubes(that's what I discovered they are called) in the background. They look like narrow strips of Leds together, so that's what I called my next class, Strip ;].

Similar to my Panel class, it creates an array of Leds width x height. In my case I create 2 different strips, 2x40 and 2x40. From pictures that I have looked it, it looks like the smaller strips are exactly half the size of the larger ones. Getting all of the positioning and adjustments right, I now have a decent reproduction of the VersaTubes.

My next step is going to be mapping out the strips (exciting! /sarcasm), which should not be too bad. I have already figured out that I will be needing a bitmap of dimensions 54x40, which is great because the smaller the bitmap the less time it times to draw onto it and map the colors.

And that is where I am currently in the project. Congrats on reading that giant wall of text and pictures, I hope you found some enjoyment/motivation/ideas/what ever. As you have probably seen, the cube is not a solid object in itself, but I don't plan on allowing it to rotate that far, if at all, so it really isn't visible when it's actually running.

Look for my next update and I will gladly answer any questions. Feel free to comment and give suggestions. Thanks for reading.
Last edited by Metastable; 22nd October 2011 at 06:03 PM.
The Following 31 Users Say Thank You to Metastable For This Useful Post: [ View ]
10th August 2011, 07:49 AM |#2  
tyl3rdurden's Avatar
Senior Member
Flag Concord, MA / Seoul, Korea
Thanks Meter: 30
This is amazing and a great read. Thanks for this. Its great inspiration and help. Hope you keep up the good fight.
10th August 2011, 08:10 AM |#3  
Metastable's Avatar
OP Senior Member
Thanks Meter: 130
Thanks, I appreciate the kind words.
10th August 2011, 04:54 PM |#4  
drknezz's Avatar
Senior Member
Flag Western Australia
Thanks Meter: 24
Man this looks slick as! When do you think you'll have a fully operational version so I can run this beast on my Galaxy S? =D
10th August 2011, 07:37 PM |#5  
Metastable's Avatar
OP Senior Member
Thanks Meter: 130
Thanks! I'd say another week at least. After the VersaTubes are done I will be adding the DeadMau5 LED head and then finishing touches, such as spotlights to create a true concert feel.
10th August 2011, 10:38 PM |#6  
blazelazydays's Avatar
Senior Member
Thanks Meter: 9
this is probably the best live wallpaper concept I've seen. can't wait man!

Sent from my Nexus S 4G using XDA App
10th August 2011, 10:44 PM |#7  
Andy2.2's Avatar
Thanks Meter: 5
nice, looks really good
11th August 2011, 12:57 AM |#8  
Metastable's Avatar
OP Senior Member
Thanks Meter: 130
Originally Posted by blazelazydays

this is probably the best live wallpaper concept I've seen. can't wait man!

Sent from my Nexus S 4G using XDA App

Thanks, stay tuned for progress updates.

Originally Posted by Andy2.2

nice, looks really good

Thanks. Nice avatar picture =].
11th August 2011, 05:53 AM |#9  
Senior Member
Flag SLO
Thanks Meter: 53
i just started programming (4 months ago) again after 4 years and all the logic is still there but im a bit rusty on some of the syntax. what does the operator '/=' do?

                width /= 2;
	        height /= 2;
	        depth /= 2;
i cant remember and any search for '/=' returns nothing usefull. i gotta dig up my Kernighan & Ritchie 'The C Programming Language' book. its got most of the syntac for modern languages in it. (and yes i know you are using java, but java is C like in syntax..)



nvm, druggggeedd it up from the dregs of my mem

width = width / 2

Last edited by killersnowman; 11th August 2011 at 06:37 AM.
11th August 2011, 08:09 AM |#10  
exb0's Avatar
Senior Member
Flag 3.137136,101.594663
Thanks Meter: 419
Man can't wait for this!
Post Reply Subscribe to Thread
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes