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