• 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.vis3;
18 
19 import com.android.musicvis.GenericWaveRS;
20 import com.android.musicvis.R;
21 import com.android.musicvis.RenderScriptScene;
22 import com.android.musicvis.AudioCapture;
23 
24 import android.graphics.Canvas;
25 import android.graphics.Rect;
26 import android.os.Handler;
27 import android.renderscript.Allocation;
28 import android.renderscript.Element;
29 import android.renderscript.Primitive;
30 import android.renderscript.ProgramVertex;
31 import android.renderscript.ScriptC;
32 import android.renderscript.SimpleMesh;
33 import android.renderscript.Type;
34 import android.renderscript.Element.Builder;
35 import android.util.Log;
36 import android.view.SurfaceHolder;
37 
38 import java.util.TimeZone;
39 
40 class Visualization3RS extends GenericWaveRS {
41 
42     private short [] mAnalyzer = new short[512];
43 
Visualization3RS(int width, int height)44     Visualization3RS(int width, int height) {
45         super(width, height, R.drawable.ice);
46     }
47 
48     @Override
setOffset(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels)49     public void setOffset(float xOffset, float yOffset,
50             float xStep, float yStep, int xPixels, int yPixels) {
51         // update our state, then push it to the renderscript
52         if (xStep <= 0.0f) {
53             xStep = xOffset / 2; // originator didn't set step size, assume we're halfway
54         }
55         // rotate 360 degrees per screen
56         mWorldState.yRotation = xStep == 0.f ? 0.f : (xOffset / xStep) * 360;
57         mState.data(mWorldState);
58     }
59 
60     @Override
start()61     public void start() {
62         if (mAudioCapture == null) {
63             mAudioCapture = new AudioCapture(AudioCapture.TYPE_FFT, 512);
64         }
65         super.start();
66     }
67 
68     @Override
stop()69     public void stop() {
70         super.stop();
71         if (mAudioCapture != null) {
72             mAudioCapture.release();
73             mAudioCapture = null;
74         }
75     }
76 
77     @Override
update()78     public void update() {
79 
80         int len = 0;
81         if (mAudioCapture != null) {
82             mVizData = mAudioCapture.getFormattedData(1, 1);
83             // the really high frequencies aren't that interesting for music,
84             // so just chop those off and use only the lower half of the spectrum
85             len = mVizData.length / 2;
86         }
87         if (len == 0) {
88             if (mWorldState.idle == 0) {
89                 mWorldState.idle = 1;
90                 mState.data(mWorldState);
91             }
92             return;
93         }
94 
95         len /= 2; // the bins are comprised of 2 values each
96 
97         if (len > mAnalyzer.length) len = mAnalyzer.length;
98 
99         if (mWorldState.idle != 0) {
100             mWorldState.idle = 0;
101             mState.data(mWorldState);
102         }
103 
104         for (int i = 1; i < len - 1; i++) {
105             int val1 = mVizData[i * 2];
106             int val2 = mVizData[i * 2 + 1];
107             int val = val1 * val1 + val2 * val2;
108             short newval = (short)(val * (i/16+1));
109             short oldval = mAnalyzer[i];
110             if (newval >= oldval - 800) {
111                 // use new high value
112             } else {
113                 newval = (short)(oldval - 800);
114             }
115             mAnalyzer[i] = newval;
116         }
117 
118         // distribute the data over mWidth samples in the middle of the mPointData array
119         final int outlen = mPointData.length / 8;
120         final int width = mWidth;
121         final int skip = (outlen - mWidth) / 2;
122 
123         int srcidx = 0;
124         int cnt = 0;
125         for (int i = 0; i < width; i++) {
126             float val = mAnalyzer[srcidx] / 8;
127             if (val < 1f && val > -1f) val = 1;
128             mPointData[(i + skip) * 8 + 1] = val;
129             mPointData[(i + skip) * 8 + 5] = -val;
130             cnt += len;
131             if (cnt > width) {
132                 srcidx++;
133                 cnt -= width;
134             }
135         }
136         mPointAlloc.data(mPointData);
137     }
138 
139 }
140