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