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