Home | History | Annotate | Download | only in musicvis
      1 // Copyright (C) 2009 The Android Open Source Project
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #pragma version(1)
     16 
     17 #pragma rs java_package_name(com.android.musicvis)
     18 
     19 #include "rs_graphics.rsh"
     20 
     21 float gYRotation;
     22 int gIdle;
     23 int gWaveCounter;
     24 int gWidth;
     25 
     26 rs_program_vertex gPVBackground;
     27 rs_program_fragment gPFBackground;
     28 
     29 typedef struct Vertex {
     30     float2 position;
     31     float2 texture0;
     32 } Vertex_t;
     33 Vertex_t *gPoints;
     34 
     35 rs_allocation gPointBuffer;
     36 rs_allocation gTlinetexture;
     37 rs_mesh gCubeMesh;
     38 
     39 #define RSID_POINTS 1
     40 
     41 #define FADEOUT_LENGTH 100
     42 #define FADEOUT_FACTOR 0.95f
     43 #define FADEIN_LENGTH 15
     44 
     45 static int fadeoutcounter = 0;
     46 static int fadeincounter = 0;
     47 static int wave1pos = 0;
     48 static int wave1amp = 0;
     49 static int wave2pos = 0;
     50 static int wave2amp= 0;
     51 static int wave3pos = 0;
     52 static int wave3amp= 0;
     53 static int wave4pos = 0;
     54 static int wave4amp= 0;
     55 static float idle[8192];
     56 static int waveCounter = 0;
     57 
     58 static void makeIdleWave(float *points) {
     59     // show a number of superimposed moving sinewaves
     60     float amp1 = sin(0.007f * wave1amp) * 120;
     61     float amp2 = sin(0.023f * wave2amp) * 80;
     62     float amp3 = sin(0.011f * wave3amp) * 40;
     63     float amp4 = sin(0.031f * wave4amp) * 20;
     64     for (int i = 0; i < 1024; i++) {
     65         float val = fabs(sin(0.013f * (wave1pos + i)) * amp1
     66                   + sin(0.029f * (wave2pos + i)) * amp2);
     67         float off = sin(0.005f * (wave3pos + i)) * amp3
     68                   + sin(0.017f * (wave4pos + i)) * amp4;
     69         if (val < 2.f && val > -2.f) val = 2.f;
     70         points[i*8+1] = val + off;
     71         points[i*8+5] = -val + off;
     72     }
     73     wave1pos++;
     74     wave1amp++;
     75     wave2pos--;
     76     wave2amp++;
     77     wave3pos++;
     78     wave3amp++;
     79     wave4pos++;
     80     wave4amp++;
     81 }
     82 
     83 int root(void) {
     84     rsgClearColor(0.f, 0.f, 0.f, 1.f);
     85 
     86     int i;
     87 
     88     if (gIdle) {
     89 
     90         // idle state animation
     91         float *points = (float*)gPoints;
     92         if (fadeoutcounter > 0) {
     93             // fade waveform to 0
     94             for (i = 0; i < 1024; i++) {
     95                 float val = fabs(points[i*8+1]);
     96                 val = val * FADEOUT_FACTOR;
     97                 if (val < 2.f) val = 2.f;
     98                 points[i*8+1] = val;
     99                 points[i*8+5] = -val;
    100             }
    101             fadeoutcounter--;
    102             if (fadeoutcounter == 0) {
    103                 wave1amp = 0;
    104                 wave2amp = 0;
    105                 wave3amp = 0;
    106                 wave4amp = 0;
    107             }
    108         } else {
    109             // idle animation
    110             makeIdleWave(points);
    111         }
    112         fadeincounter = FADEIN_LENGTH;
    113     } else {
    114         if (fadeincounter > 0 && fadeoutcounter == 0) {
    115             // morph from idle animation back to waveform
    116             makeIdleWave(idle);
    117             if (waveCounter != gWaveCounter) {
    118                 waveCounter = gWaveCounter;
    119                 float *points = (float*)gPoints;
    120                 for (i = 0; i < 1024; i++) {
    121                     float val = fabs(points[i*8+1]);
    122                     points[i*8+1] = (val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+1] * fadeincounter) / FADEIN_LENGTH;
    123                     points[i*8+5] = (-val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+5] * fadeincounter) / FADEIN_LENGTH;
    124                 }
    125             }
    126             fadeincounter--;
    127             if (fadeincounter == 0) {
    128                 fadeoutcounter = FADEOUT_LENGTH;
    129             }
    130         } else {
    131             fadeoutcounter = FADEOUT_LENGTH;
    132         }
    133     }
    134 
    135     rs_matrix4x4 mat1;
    136     float yrot = gYRotation;
    137     float scale = 0.004165f * (1.0f + 2.f * fabs(sin(radians(yrot))));
    138 
    139     // Draw the visualizer.
    140     rsgBindProgramVertex(gPVBackground);
    141     rsgBindProgramFragment(gPFBackground);
    142     rsgBindTexture(gPFBackground, 0, gTlinetexture);
    143 
    144     // Change the model matrix to account for the large model
    145     // and to do the necessary rotations.
    146     rsMatrixLoadIdentity(&mat1);
    147     rsMatrixRotate(&mat1, yrot, 0.f, 0.f, 1.f);
    148     rsMatrixScale(&mat1, scale, scale, scale);
    149     rsgProgramVertexLoadModelMatrix(&mat1);
    150 
    151     rsgDrawMesh(gCubeMesh);
    152 
    153     return 1;
    154 }
    155 
    156