A VisualizerBox architecture

Music visualizers often look really cool, especially at first. But after a time they may seem too repetitive, even boring. Therefore, in our design, we'll build the ability to queue up a number of different visualizations, and then, after a period of time, transition from one to the next.

To begin our implementation, we'll define an architecture structure that will be expandable and let us develop new visualizations as we go along.

However, even before that, we must ensure that the app has permission to use the Android audio features we need. Add the following directives to AndroidManifest.xml:

    <!-- Visualizer permissions -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

Remember that the RenderBox library, first developed in Chapter 5, RenderBox Engine, allows MainActivity to delegate much of the graphics and Cardboard VR work to the RenderBox class and associated classes (Component, Material, and so on). We will follow a similar design pattern here, built on top of RenderBox. MainActivity can instantiate specific visualizations and then delegate the work to the VisualizerBox class.

The VisualizerBox class will provide the callback functions to the Android Visualizer class. Let's define a skeletal implementation of this first. Create a VisualizerBox Java class, as follows:

public class VisualizerBox {
    static final String TAG = "VisualizerBox";
    public VisualizerBox(final CardboardView cardboardView){
    }
    public void setup() {
    }
    public void preDraw() {
    }
    public void postDraw() {
    }
}

Integrate VisualizerBox into MainActivity, adding a visualizerBox variable at the top of the class. In MainActivity, add the following line:

    VisualizerBox visualizerBox;

Initialize it in onCreate:

        visualizerBox = new VisualizerBox(cardboardView);

Also, in MainActivity, call the corresponding version of each of the IRenderBox interface methods:

    @Override
    public void setup() {
        visualizerBox.setup();
    }
    @Override
    public void preDraw() {
        visualizerBox.preDraw();
    }
    @Override
    public void postDraw() {
        visualizerBox.postDraw();
    }

Good. Now we'll set up VisualizerBox to let you build and use one or more visualizations. So, first let's define the abstract Visualization class in the Visualization.java file, as follows:

public abstract class Visualization {
    VisualizerBox visualizerBox;            //owner

    public Visualization(VisualizerBox visualizerBox){
        this.visualizerBox = visualizerBox;
    }
    public abstract void setup();
    public abstract void preDraw();
    public abstract void postDraw();
}

Now we have a mechanism to create a variety of visualization implementations for the app. Before we go ahead and start writing one of those, let's also provide the integration with VisualizerBox. At the top of the VisualizerBox class, add a variable to the current activeViz object:

    public Visualization activeViz;

Then, call it from the interface methods:

    public void setup() {
        if(activeViz != null)
            activeViz.setup();
    }
    public void preDraw() {
        if(activeViz != null)
            activeViz.preDraw();
    }
    public void postDraw() {
        if(activeViz != null)
            activeViz.postDraw();
    }

Of course, we're not even using the Android Visualizer class yet and not rendering anything on the screen. That'll come next.

For now, let's create a placeholder for a visualization. Create a new folder in your project named visualizations. Right-click on your Java code folder (for example, java/com/cardbookvr/visualizevr/), go to New | Package, and name it visualizations. Then, right click on the new visualizations folder, go to New | Java Class, and name it BlankVisualization. Then, define it as extends Visualization as follows:

public class BlankVisualization extends Visualization {
    static final String TAG = "BlankVisualization";
    public BlankVisualization(VisualizerBox visualizerBox) {
        super(visualizerBox);
    }
    @Override
    public void setup() {
    }
    @Override
    public void preDraw() {
    }
    @Override
    public void postDraw() {
    }
}

We'll be able to use this as a template for specific visualizers. The purpose of each method is pretty self-explanatory:

  • setup: This initializes variables, transforms, and materials for the visualization
  • preDraw: This code is executed at the beginning of each frame; for example, using the current captured audio data
  • postDraw: This code is executed at the end of each frame

Now let's add some meat to this skeleton.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset