• 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 Allocation mLineIdxAlloc;
63     // 2 indices per line
64     private short [] mIndexData = new short[1024*2];
65 
66     private ProgramVertex mPVBackground;
67     private ProgramVertexFixedFunction.Constants mPVAlloc;
68 
69     protected AudioCapture mAudioCapture = null;
70     protected int [] mVizData = new int[1024];
71 
72     private ProgramFragment mPfBackground;
73     private Sampler mSampler;
74     private Allocation mTexture;
75 
76     private static final int RSID_STATE = 0;
77     private static final int RSID_POINTS = 1;
78     private static final int RSID_LINES = 2;
79     private static final int RSID_PROGRAMVERTEX = 3;
80 
GenericWaveRS(int width, int height, int texid)81     protected GenericWaveRS(int width, int height, int texid) {
82         super(width, height);
83         mTexId = texid;
84         mWidth = width;
85         mHeight = height;
86         // the x, s and t coordinates don't change, so set those now
87         int outlen = mPointData.length / 8;
88         int half = outlen / 2;
89         for(int i = 0; i < outlen; i++) {
90             mPointData[i*8]   = i - half;          // start point X (Y set later)
91             mPointData[i*8+2] = 0;                 // start point S
92             mPointData[i*8+3] = 0;                 // start point T
93             mPointData[i*8+4]   = i - half;        // end point X (Y set later)
94             mPointData[i*8+6] = 1.0f;                 // end point S
95             mPointData[i*8+7] = 0f;              // end point T
96         }
97     }
98 
99     @Override
resize(int width, int height)100     public void resize(int width, int height) {
101         super.resize(width, height);
102         mWorldState.width = width;
103         if (mPVAlloc != null) {
104             Matrix4f proj = new Matrix4f();
105             proj.loadProjectionNormalized(mWidth, mHeight);
106             mPVAlloc.setProjection(proj);
107         }
108     }
109 
110     @Override
createScript()111     protected ScriptC createScript() {
112 
113         mScript = new ScriptC_waveform(mRS, mResources, R.raw.waveform);
114 
115         // set our java object as the data for the renderscript allocation
116         mWorldState.yRotation = 0.0f;
117         mWorldState.width = mWidth;
118         updateWorldState();
119 
120         //  Now put our model in to a form that renderscript can work with:
121         //  - create a buffer of floats that are the coordinates for the points that define the cube
122         //  - create a buffer of integers that are the indices of the points that form lines
123         //  - combine the two in to a mesh
124 
125         // First set up the coordinate system and such
126         ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
127         mPVBackground = pvb.create();
128         mPVAlloc = new ProgramVertexFixedFunction.Constants(mRS);
129         ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVAlloc);
130         Matrix4f proj = new Matrix4f();
131         proj.loadProjectionNormalized(mWidth, mHeight);
132         mPVAlloc.setProjection(proj);
133 
134         mScript.set_gPVBackground(mPVBackground);
135 
136         mVertexBuffer = new ScriptField_Vertex(mRS, mPointData.length / 4);
137 
138         // Start creating the mesh
139         final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
140         meshBuilder.addVertexAllocation(mVertexBuffer.getAllocation());
141         // Create the Allocation for the indices
142         mLineIdxAlloc = Allocation.createSized(mRS, Element.U16(mRS), mIndexData.length,
143                                                Allocation.USAGE_GRAPHICS_VERTEX |
144                                                Allocation.USAGE_SCRIPT);
145         // This will be a line mesh
146         meshBuilder.addIndexSetAllocation(mLineIdxAlloc, Primitive.LINE);
147 
148         // Create the Allocation for the vertices
149         mCubeMesh = meshBuilder.create();
150 
151         mPointAlloc = mVertexBuffer.getAllocation();
152 
153         mScript.bind_gPoints(mVertexBuffer);
154         mScript.set_gPointBuffer(mPointAlloc);
155         mScript.set_gCubeMesh(mCubeMesh);
156 
157         //  put the vertex and index data in their respective buffers
158         updateWave();
159         for(int i = 0; i < mIndexData.length; i ++) {
160             mIndexData[i] = (short) i;
161         }
162 
163         //  upload the vertex and index data
164         mPointAlloc.copyFromUnchecked(mPointData);
165         mLineIdxAlloc.copyFrom(mIndexData);
166         mLineIdxAlloc.syncAll(Allocation.USAGE_SCRIPT);
167 
168         // load the texture
169         mTexture = Allocation.createFromBitmapResource(mRS, mResources, mTexId);
170 
171         mScript.set_gTlinetexture(mTexture);
172 
173         /*
174          * create a program fragment to use the texture
175          */
176         Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
177         samplerBuilder.setMinification(LINEAR);
178         samplerBuilder.setMagnification(LINEAR);
179         samplerBuilder.setWrapS(WRAP);
180         samplerBuilder.setWrapT(WRAP);
181         mSampler = samplerBuilder.create();
182 
183         ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
184         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
185                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
186         mPfBackground = builder.create();
187         mPfBackground.bindSampler(mSampler, 0);
188 
189         mScript.set_gPFBackground(mPfBackground);
190 
191         return mScript;
192     }
193 
194     @Override
setOffset(float xOffset, float yOffset, int xPixels, int yPixels)195     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
196         mWorldState.yRotation = (xOffset * 4) * 180;
197         updateWorldState();
198     }
199 
200     @Override
start()201     public void start() {
202         super.start();
203         mVisible = true;
204         if (mAudioCapture != null) {
205             mAudioCapture.start();
206         }
207         SystemClock.sleep(200);
208         updateWave();
209     }
210 
211     @Override
stop()212     public void stop() {
213         super.stop();
214         mVisible = false;
215         if (mAudioCapture != null) {
216             mAudioCapture.stop();
217         }
218         updateWave();
219     }
220 
update()221     public void update() {
222     }
223 
updateWave()224     void updateWave() {
225         mHandler.removeCallbacks(mDrawCube);
226         if (!mVisible) {
227             return;
228         }
229         mHandler.postDelayed(mDrawCube, 20);
230         update();
231         mWorldState.waveCounter++;
232         updateWorldState();
233     }
234 
updateWorldState()235     protected void updateWorldState() {
236         mScript.set_gYRotation(mWorldState.yRotation);
237         mScript.set_gIdle(mWorldState.idle);
238         mScript.set_gWaveCounter(mWorldState.waveCounter);
239         mScript.set_gWidth(mWorldState.width);
240     }
241 }
242