• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.musicvis;
18 
19 import static android.renderscript.Element.RGB_565;
20 import static android.renderscript.Sampler.Value.LINEAR;
21 import static android.renderscript.Sampler.Value.WRAP;
22 
23 import android.os.Handler;
24 import android.os.SystemClock;
25 import android.renderscript.Mesh.Primitive;
26 import android.renderscript.*;
27 import android.renderscript.Element.Builder;
28 import android.util.Log;
29 
30 import java.util.TimeZone;
31 
32 public class GenericWaveRS extends RenderScriptScene {
33 
34     private final Handler mHandler = new Handler();
35     private final Runnable mDrawCube = new Runnable() {
36         public void run() {
37             updateWave();
38         }
39     };
40     private boolean mVisible;
41     private int mTexId;
42 
43     protected static class WorldState {
44         public float yRotation;
45         public int idle;
46         public int waveCounter;
47         public int width;
48     }
49     protected WorldState mWorldState = new WorldState();
50 
51     ScriptC_waveform mScript;
52 
53     private ScriptField_Vertex mVertexBuffer;
54 
55     private Mesh mCubeMesh;
56 
57     protected Allocation mPointAlloc;
58     // 1024 lines, with 4 points per line (2 space, 2 texture) each consisting of x and y,
59     // so 8 floats per line.
60     protected float [] mPointData = new float[1024*8];
61 
62     private ProgramVertex mPVBackground;
63     private ProgramVertexFixedFunction.Constants mPVAlloc;
64 
65     protected AudioCapture mAudioCapture = null;
66     protected int [] mVizData = new int[1024];
67 
68     private ProgramFragment mPfBackground;
69     private Sampler mSampler;
70     private Allocation mTexture;
71 
72     private static final int RSID_STATE = 0;
73     private static final int RSID_POINTS = 1;
74     private static final int RSID_LINES = 2;
75     private static final int RSID_PROGRAMVERTEX = 3;
76 
GenericWaveRS(int width, int height, int texid)77     protected GenericWaveRS(int width, int height, int texid) {
78         super(width, height);
79         mTexId = texid;
80         mWidth = width;
81         mHeight = height;
82         // the x, s and t coordinates don't change, so set those now
83         int outlen = mPointData.length / 8;
84         int half = outlen / 2;
85         for(int i = 0; i < outlen; i++) {
86             mPointData[i*8]   = i - half;          // start point X (Y set later)
87             mPointData[i*8+2] = 0;                 // start point S
88             mPointData[i*8+3] = 0;                 // start point T
89             mPointData[i*8+4]   = i - half;        // end point X (Y set later)
90             mPointData[i*8+6] = 1.0f;                 // end point S
91             mPointData[i*8+7] = 0f;              // end point T
92         }
93     }
94 
95     @Override
resize(int width, int height)96     public void resize(int width, int height) {
97         super.resize(width, height);
98         mWorldState.width = width;
99         if (mPVAlloc != null) {
100             Matrix4f proj = new Matrix4f();
101             proj.loadProjectionNormalized(mWidth, mHeight);
102             mPVAlloc.setProjection(proj);
103         }
104     }
105 
106     @Override
createScript()107     protected ScriptC createScript() {
108 
109         mScript = new ScriptC_waveform(mRS, mResources, R.raw.waveform);
110 
111         // set our java object as the data for the renderscript allocation
112         mWorldState.yRotation = 0.0f;
113         mWorldState.width = mWidth;
114         updateWorldState();
115 
116         //  Now put our model in to a form that renderscript can work with:
117         //  - create a buffer of floats that are the coordinates for the points that define the cube
118         //  - create a buffer of integers that are the indices of the points that form lines
119         //  - combine the two in to a mesh
120 
121         // First set up the coordinate system and such
122         ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
123         mPVBackground = pvb.create();
124         mPVAlloc = new ProgramVertexFixedFunction.Constants(mRS);
125         ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVAlloc);
126         Matrix4f proj = new Matrix4f();
127         proj.loadProjectionNormalized(mWidth, mHeight);
128         mPVAlloc.setProjection(proj);
129 
130         mScript.set_gPVBackground(mPVBackground);
131 
132         mVertexBuffer = new ScriptField_Vertex(mRS, mPointData.length / 4);
133 
134         // Start creating the mesh
135         final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
136         meshBuilder.addVertexAllocation(mVertexBuffer.getAllocation());
137         // This will be a triangle strip mesh
138         meshBuilder.addIndexSetType(Primitive.TRIANGLE_STRIP);
139 
140         // Create the Allocation for the vertices
141         mCubeMesh = meshBuilder.create();
142 
143         mPointAlloc = mVertexBuffer.getAllocation();
144 
145         mScript.bind_gPoints(mVertexBuffer);
146         mScript.set_gPointBuffer(mPointAlloc);
147         mScript.set_gCubeMesh(mCubeMesh);
148 
149         //  upload the vertex data
150         mPointAlloc.copyFromUnchecked(mPointData);
151 
152         // load the texture
153         mTexture = Allocation.createFromBitmapResource(mRS, mResources, mTexId,
154                                            Allocation.MipmapControl.MIPMAP_NONE,
155                                            Allocation.USAGE_GRAPHICS_TEXTURE);
156 
157         mScript.set_gTlinetexture(mTexture);
158 
159         /*
160          * create a program fragment to use the texture
161          */
162         Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
163         samplerBuilder.setMinification(LINEAR);
164         samplerBuilder.setMagnification(LINEAR);
165         samplerBuilder.setWrapS(WRAP);
166         samplerBuilder.setWrapT(WRAP);
167         mSampler = samplerBuilder.create();
168 
169         ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
170         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
171                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
172         mPfBackground = builder.create();
173         mPfBackground.bindSampler(mSampler, 0);
174 
175         mScript.set_gPFBackground(mPfBackground);
176 
177         return mScript;
178     }
179 
180     @Override
setOffset(float xOffset, float yOffset, int xPixels, int yPixels)181     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
182         mWorldState.yRotation = (xOffset * 4) * 180;
183         updateWorldState();
184     }
185 
186     @Override
start()187     public void start() {
188         super.start();
189         mVisible = true;
190         if (mAudioCapture != null) {
191             mAudioCapture.start();
192         }
193         SystemClock.sleep(200);
194         updateWave();
195     }
196 
197     @Override
stop()198     public void stop() {
199         super.stop();
200         mVisible = false;
201         if (mAudioCapture != null) {
202             mAudioCapture.stop();
203         }
204         updateWave();
205     }
206 
update()207     public void update() {
208     }
209 
updateWave()210     void updateWave() {
211         mHandler.removeCallbacks(mDrawCube);
212         if (!mVisible) {
213             return;
214         }
215         mHandler.postDelayed(mDrawCube, 20);
216         update();
217         mWorldState.waveCounter++;
218         updateWorldState();
219     }
220 
updateWorldState()221     protected void updateWorldState() {
222         mScript.set_gYRotation(mWorldState.yRotation);
223         mScript.set_gIdle(mWorldState.idle);
224         mScript.set_gWaveCounter(mWorldState.waveCounter);
225         mScript.set_gWidth(mWorldState.width);
226     }
227 }
228