Home | History | Annotate | Download | only in vis3
      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 
     45     Visualization3RS(int width, int height) {
     46         super(width, height, R.drawable.ice);
     47         lastOffset = 0;
     48     }
     49 
     50     @Override
     51     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
     52         mWorldState.yRotation = (xOffset * 4) * 360;
     53         updateWorldState();
     54     }
     55 
     56     @Override
     57     public void start() {
     58         if (mAudioCapture == null) {
     59             mAudioCapture = new AudioCapture(AudioCapture.TYPE_FFT, 512);
     60         }
     61         super.start();
     62     }
     63 
     64     @Override
     65     public void stop() {
     66         super.stop();
     67         if (mAudioCapture != null) {
     68             mAudioCapture.release();
     69             mAudioCapture = null;
     70         }
     71     }
     72 
     73     @Override
     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