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 44 Visualization3RS(int width, int height) { 45 super(width, height, R.drawable.ice); 46 } 47 48 @Override 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 61 public void start() { 62 if (mAudioCapture == null) { 63 mAudioCapture = new AudioCapture(AudioCapture.TYPE_FFT, 512); 64 } 65 super.start(); 66 } 67 68 @Override 69 public void stop() { 70 super.stop(); 71 if (mAudioCapture != null) { 72 mAudioCapture.release(); 73 mAudioCapture = null; 74 } 75 } 76 77 @Override 78 public void update() { 79 80 int len = 0; 81 if (mAudioCapture != null) { 82 mVizData = mAudioCapture.getFormattedData(64, 1); 83 len = mVizData.length; 84 } 85 if (len == 0) { 86 if (mWorldState.idle == 0) { 87 mWorldState.idle = 1; 88 mState.data(mWorldState); 89 } 90 return; 91 } 92 93 if (len > mAnalyzer.length) len = mAnalyzer.length; 94 95 if (mWorldState.idle != 0) { 96 mWorldState.idle = 0; 97 mState.data(mWorldState); 98 } 99 100 for (int i = 0; i < len; i++) { 101 short newval = (short)(mVizData[i] * (i/16+2)); 102 short oldval = mAnalyzer[i]; 103 if (newval >= oldval - 800) { 104 // use new high value 105 } else { 106 newval = (short)(oldval - 800); 107 } 108 mAnalyzer[i] = newval; 109 } 110 111 // distribute the data over mWidth samples in the middle of the mPointData array 112 final int outlen = mPointData.length / 8; 113 final int width = mWidth; 114 final int skip = (outlen - mWidth) / 2; 115 116 int srcidx = 0; 117 int cnt = 0; 118 for (int i = 0; i < width; i++) { 119 float val = mAnalyzer[srcidx] / 50; 120 if (val < 1f && val > -1f) val = 1; 121 mPointData[(i + skip) * 8 + 1] = val; 122 mPointData[(i + skip) * 8 + 5] = -val; 123 cnt += mAnalyzer.length; 124 if (cnt > width) { 125 srcidx++; 126 cnt -= width; 127 } 128 } 129 mPointAlloc.data(mPointData); 130 } 131 132 } 133