Home | History | Annotate | Download | only in vis5
      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.vis5)
     18 
     19 #include "rs_graphics.rsh"
     20 
     21 float gAngle;
     22 int   gPeak;
     23 float gRotate;
     24 float gTilt;
     25 int   gIdle;
     26 int   gWaveCounter;
     27 
     28 rs_program_vertex gPVBackground;
     29 rs_program_fragment gPFBackgroundMip;
     30 rs_program_fragment gPFBackgroundNoMip;
     31 rs_program_raster gPR;
     32 
     33 rs_allocation gTvumeter_background;
     34 rs_allocation gTvumeter_peak_on;
     35 rs_allocation gTvumeter_peak_off;
     36 rs_allocation gTvumeter_needle;
     37 rs_allocation gTvumeter_black;
     38 rs_allocation gTvumeter_frame;
     39 rs_allocation gTvumeter_album;
     40 
     41 rs_program_store gPFSBackground;
     42 
     43 typedef struct Vertex {
     44     float2 position;
     45     float2 texture0;
     46 } Vertex_t;
     47 Vertex_t *gPoints;
     48 
     49 
     50 rs_allocation gPointBuffer;
     51 rs_allocation gTlinetexture;
     52 rs_mesh gCubeMesh;
     53 
     54 #define RSID_POINTS 1
     55 
     56 static void drawVU(rs_matrix4x4 *ident) {
     57     rs_matrix4x4 mat1;
     58     float scale = 0.0041;
     59 
     60     rsMatrixLoad(&mat1,ident);
     61     rsMatrixRotate(&mat1, 0.f, 0.f, 0.f, 1.f);
     62     rsMatrixScale(&mat1, scale, scale, scale);
     63     rsgProgramVertexLoadModelMatrix(&mat1);
     64 
     65     rsgBindProgramFragment(gPFBackgroundMip);
     66     rsgBindProgramStore(gPFSBackground);
     67 
     68     // draw the background image (416x233)
     69     rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_background);
     70     rsgDrawQuadTexCoords(
     71             -208.0f, -33.0f, 600.0f,       // space
     72                 0.0f, 1.0f,               // texture
     73             208, -33.0f, 600.0f,           // space
     74                 1.0f, 1.0f,               // texture
     75             208, 200.0f, 600.0f,           // space
     76                 1.0f, 0.0f,               // texture
     77             -208.0f, 200.0f, 600.0f,       // space
     78                 0.0f, 0.0f);              // texture
     79 
     80     // draw the peak indicator light (56x58)
     81     if (gPeak > 0) {
     82         rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_peak_on);
     83     } else {
     84         rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_peak_off);
     85     }
     86     rsgDrawQuadTexCoords(
     87             140.0f, 70.0f, 600.0f,         // space
     88                 0.0f, 1.0f,               // texture
     89             196, 70.0f, 600.0f,            // space
     90                 1.0f, 1.0f,               // texture
     91             196, 128.0f, 600.0f,           // space
     92                 1.0f, 0.0f,               // texture
     93             140.0f, 128.0f, 600.0f,        // space
     94                 0.0f, 0.0f);              // texture
     95 
     96 
     97 
     98     // Draw the needle (88x262, center of rotation at 44,217 from top left)
     99 
    100     // set matrix so point of rotation becomes origin
    101     rsMatrixLoad(&mat1,ident);
    102     rsMatrixTranslate(&mat1, 0.f, -57.0f * scale, 0.f);
    103     rsMatrixRotate(&mat1, gAngle - 90.f, 0.f, 0.f, 1.f);
    104     rsMatrixScale(&mat1, scale, scale, scale);
    105     rsgProgramVertexLoadModelMatrix(&mat1);
    106     rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_needle);
    107     rsgDrawQuadTexCoords(
    108             -44.0f, -102.0f+57.f, 600.0f,         // space
    109                 0.0f, 1.0f,             // texture
    110             44.0f, -102.0f+57.f, 600.0f,             // space
    111                 1.0f, 1.0f,              // texture
    112             44.0f, 160.0f+57.f, 600.0f,             // space
    113                 1.0f, 0.0f,              // texture
    114             -44.0f, 160.0f+57.f, 600.0f,         // space
    115                 0.0f, 0.0f);             // texture
    116 
    117 
    118     // restore matrix
    119     rsMatrixLoad(&mat1,ident);
    120     rsMatrixRotate(&mat1, 0.f, 0.f, 0.f, 1.f);
    121     rsMatrixScale(&mat1, scale, scale, scale);
    122     rsgProgramVertexLoadModelMatrix(&mat1);
    123 
    124     // erase the part of the needle we don't want to show
    125     rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_black);
    126     rsgDrawQuad(-100.f, -55.f, 600.f,
    127              -100.f, -105.f, 600.f,
    128               100.f, -105.f, 600.f,
    129               100.f, -55.f, 600.f);
    130 
    131 
    132     // draw the frame (472x290)
    133     rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_frame);
    134     rsgDrawQuadTexCoords(
    135             -236.0f, -60.0f, 600.0f,           // space
    136                 0.0f, 1.0f,                  // texture
    137             236, -60.0f, 600.0f,               // space
    138                 1.0f, 1.0f,                  // texture
    139             236, 230.0f, 600.0f,               // space
    140                 1.0f, 0.0f,                  // texture
    141             -236.0f, 230.0f, 600.0f,           // space
    142                 0.0f, 0.0f);                 // texture
    143 
    144 
    145 }
    146 
    147 int fadeoutcounter = 0;
    148 int fadeincounter = 0;
    149 int wave1pos = 0;
    150 int wave1amp = 0;
    151 int wave2pos = 0;
    152 int wave2amp= 0;
    153 int wave3pos = 0;
    154 int wave3amp= 0;
    155 int wave4pos = 0;
    156 int wave4amp= 0;
    157 float idle[4096];
    158 int waveCounter = 0;
    159 int lastuptime = 0;
    160 float autorotation = 0;
    161 
    162 #define FADEOUT_LENGTH 100
    163 #define FADEOUT_FACTOR 0.95f
    164 #define FADEIN_LENGTH 15
    165 
    166 static void makeIdleWave(float *points) {
    167     int i;
    168     // show a number of superimposed moving sinewaves
    169     float amp1 = sin(0.007f * wave1amp) * 120 * 1024;
    170     float amp2 = sin(0.023f * wave2amp) * 80 * 1024;
    171     float amp3 = sin(0.011f * wave3amp) * 40 * 1024;
    172     float amp4 = sin(0.031f * wave4amp) * 20 * 1024;
    173     for (i = 0; i < 256; i++) {
    174         float val = sin(0.013f * (wave1pos + i * 4)) * amp1
    175                   + sin(0.029f * (wave2pos + i * 4)) * amp2;
    176         float off = sin(0.005f * (wave3pos + i * 4)) * amp3
    177                   + sin(0.017f * (wave4pos + i * 4)) * amp4;
    178         if (val < 2.f && val > -2.f) val = 2.f;
    179         points[i*8+1] = val + off;
    180         points[i*8+5] = -val + off;
    181     }
    182 }
    183 
    184 
    185 static void drawWave(rs_matrix4x4 *ident) {
    186     float scale = .008f;
    187     rs_matrix4x4 mat1;
    188     rsMatrixLoad(&mat1, ident);
    189     rsMatrixScale(&mat1, scale, scale / 2048.f, scale);
    190     rsMatrixTranslate(&mat1, 0.f, 81920.f, 350.f);
    191     rsgProgramVertexLoadModelMatrix(&mat1);
    192     int i;
    193 
    194     if (gIdle) {
    195 
    196         // idle state animation
    197         float *points = (float*)gPoints;
    198         if (fadeoutcounter > 0) {
    199             // fade waveform to 0
    200             for (i = 0; i < 256; i++) {
    201                 float val = fabs(points[i*8+1]);
    202                 val = val * FADEOUT_FACTOR;
    203                 if (val < 2.f) val = 2.f;
    204                 points[i*8+1] = val;
    205                 points[i*8+5] = -val;
    206             }
    207             fadeoutcounter--;
    208             if (fadeoutcounter == 0) {
    209                 wave1amp = 0;
    210                 wave2amp = 0;
    211                 wave3amp = 0;
    212                 wave4amp = 0;
    213             }
    214         } else {
    215             // idle animation
    216             makeIdleWave(points);
    217         }
    218         fadeincounter = FADEIN_LENGTH;
    219     } else {
    220         if (fadeincounter > 0 && fadeoutcounter == 0) {
    221             // morph from idle animation back to waveform
    222             makeIdleWave(idle);
    223             if (waveCounter != gWaveCounter) {
    224                 waveCounter = gWaveCounter;
    225                 float *points = (float*)gPoints;
    226                 for (i = 0; i < 256; i++) {
    227                     float val = fabs(points[i*8+1]);
    228                     points[i*8+1] = (val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+1] * fadeincounter) / FADEIN_LENGTH;
    229                     points[i*8+5] = (-val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+5] * fadeincounter) / FADEIN_LENGTH;
    230                 }
    231             }
    232             fadeincounter--;
    233             if (fadeincounter == 0) {
    234                 fadeoutcounter = FADEOUT_LENGTH;
    235             }
    236         } else {
    237             fadeoutcounter = FADEOUT_LENGTH;
    238         }
    239     }
    240 
    241     rsgBindProgramRaster(gPR);
    242     rsgBindProgramFragment(gPFBackgroundNoMip);
    243     rsgBindTexture(gPFBackgroundNoMip, 0, gTlinetexture);
    244     rsgDrawMesh(gCubeMesh);
    245 }
    246 
    247 
    248 static void drawVizLayer(rs_matrix4x4 *ident) {
    249     for (int i = 0; i < 6; i++) {
    250         if (i & 1) {
    251             drawVU(ident);
    252         } else {
    253             drawWave(ident);
    254         }
    255 
    256         rsMatrixRotate(ident, 60.f, 0.f, 1.f, 0.f);
    257     }
    258 }
    259 
    260 
    261 int root(void) {
    262     rsgClearColor(0.f, 0.f, 0.f, 1.f);
    263 
    264     rsgBindProgramVertex(gPVBackground);
    265 
    266     int i;
    267     rs_matrix4x4 ident;
    268     int now = (int)rsUptimeMillis();
    269     int delta = now - lastuptime;
    270     lastuptime = now;
    271     if (delta > 80) {
    272         // Limit the delta to avoid jumps when coming back from sleep.
    273         // A value of 80 will make the rotation keep the same speed
    274         // until the frame rate drops to 12.5 fps, at which point it
    275         // will start slowing down.
    276         delta = 80;
    277     }
    278     autorotation += .3 * delta / 35;
    279     while (autorotation > 360.f) autorotation -= 360.f;
    280 
    281     rsMatrixLoadIdentity(&ident);
    282     rsMatrixRotate(&ident, gTilt, 1.f, 0.f, 0.f);
    283     rsMatrixRotate(&ident, autorotation + gRotate, 0.f, 1.f, 0.f);
    284 
    285     // draw the reflections
    286     rsMatrixTranslate(&ident, 0.f, -1.f, 0.f);
    287     rsMatrixScale(&ident, 1.f, -1.f, 1.f);
    288     drawVizLayer(&ident);
    289 
    290     // draw the reflecting plane
    291     rsgBindProgramFragment(gPFBackgroundMip);
    292     rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_album);
    293     rsgDrawQuadTexCoords(
    294             -1500.0f, -60.0f, 1500.0f,           // space
    295                 0.f, 1.f,    // texture
    296             1500, -60.0f, 1500.0f,               // space
    297                 1.f, 1.f,    // texture
    298             1500, -60.0f, -1500.0f,               // space
    299                 1.f, 0.f,    // texture
    300             -1500.0f, -60.0f, -1500.0f,           // space
    301                 0.f, 0.f);   // texture
    302 
    303     // draw the visualizer
    304     rsMatrixScale(&ident, 1.f, -1.f, 1.f);
    305     rsMatrixTranslate(&ident, 0.f, 1.f, 0.f);
    306 
    307     drawVizLayer(&ident);
    308 
    309     wave1pos++;
    310     wave1amp++;
    311     wave2pos--;
    312     wave2amp++;
    313     wave3pos++;
    314     wave3amp++;
    315     wave4pos++;
    316     wave4amp++;
    317 
    318     return 1;
    319 }
    320