NekoX/TMessagesProj/src/main/java/org/telegram/ui/Components/AudioVisualizerDrawable.java

202 lines
6.1 KiB
Java

package org.telegram.ui.Components;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatMessageCell;
import java.util.Random;
public class AudioVisualizerDrawable {
private final CircleBezierDrawable[] drawables;
private final int[] tmpWaveform = new int[3];
private final float[] animateTo = new float[8];
private final float[] current = new float[8];
private final float[] dt = new float[8];
private float idleScale;
private boolean idleScaleInc;
private final Paint p1;
private View parentView;
private final Random random = new Random();
public float IDLE_RADIUS = AndroidUtilities.dp(6) * 0.33f;
public float WAVE_RADIUS = AndroidUtilities.dp(12) * 0.36f;
public float ANIMATION_DURATION = 120;
public int ALPHA = 61;
public AudioVisualizerDrawable() {
drawables = new CircleBezierDrawable[2];
for (int i = 0; i < 2; i++) {
CircleBezierDrawable drawable = drawables[i] = new CircleBezierDrawable(6);
drawable.idleStateDiff = 0;
drawable.radius = AndroidUtilities.dp(24);
drawable.radiusDiff = 0;
drawable.randomK = 1f;
}
p1 = new Paint(Paint.ANTI_ALIAS_FLAG);
}
final int MAX_SAMPLE_SUM = 6;
private float[] lastAmplitude = new float[MAX_SAMPLE_SUM];
private int lastAmplitudeCount;
private int lastAmplitudePointer;
public void setWaveform(boolean playing, boolean animate, float[] waveform) {
if (!playing && !animate) {
for (int i = 0; i < 8; i++) {
animateTo[i] = current[i] = 0;
}
return;
}
boolean idleState = waveform != null && waveform[6] == 0;
float amplitude = waveform == null ? 0 : waveform[6];
if (waveform != null && amplitude > 0.4) {
lastAmplitude[lastAmplitudePointer] = amplitude;
lastAmplitudePointer++;
if (lastAmplitudePointer > MAX_SAMPLE_SUM - 1) {
lastAmplitudePointer = 0;
}
lastAmplitudeCount++;
} else {
lastAmplitudeCount = 0;
}
if (idleState) {
for (int i = 0; i < 6; i++) {
waveform[i] = ((random.nextInt() % 500) / 1000f);
}
}
float duration = idleState ? ANIMATION_DURATION * 2 : ANIMATION_DURATION;
if (lastAmplitudeCount > MAX_SAMPLE_SUM) {
float a = 0;
for (int i = 0; i < MAX_SAMPLE_SUM; i++) {
a += lastAmplitude[i];
}
a /= (float) MAX_SAMPLE_SUM;
if (a > 0.52f) {
duration -= ANIMATION_DURATION * (a - 0.40f);
}
}
for (int i = 0; i < 7; i++) {
if (waveform == null) {
animateTo[i] = 0;
} else {
animateTo[i] = waveform[i];
}
if (parentView == null) {
current[i] = animateTo[i];
} else if (i == 6) {
dt[i] = (animateTo[i] - current[i]) / (ANIMATION_DURATION + 80);
} else {
dt[i] = (animateTo[i] - current[i]) / duration;
}
}
animateTo[7] = playing ? 1f : 0f;
dt[7] = (animateTo[7] - current[7]) / 120;
}
float rotation;
public void draw(Canvas canvas, float cx, float cy, boolean outOwner, Theme.ResourcesProvider resourcesProvider) {
if (outOwner) {
p1.setColor(Theme.getColor(Theme.key_chat_outLoader, resourcesProvider));
p1.setAlpha(ALPHA);
} else {
p1.setColor(Theme.getColor(Theme.key_chat_inLoader, resourcesProvider));
p1.setAlpha(ALPHA);
}
this.draw(canvas, cx, cy);
}
public void draw(Canvas canvas, float cx, float cy) {
for (int i = 0; i < 8; i++) {
if (animateTo[i] != current[i]) {
current[i] += dt[i] * 16;
if ((dt[i] > 0 && current[i] > animateTo[i]) || (dt[i] < 0 && current[i] < animateTo[i])) {
current[i] = animateTo[i];
}
parentView.invalidate();
}
}
if (idleScaleInc) {
idleScale += 0.02f;
if (idleScale > 1f) {
idleScaleInc = false;
idleScale = 1f;
}
} else {
idleScale -= 0.02f;
if (idleScale < 0) {
idleScaleInc = true;
idleScale = 0;
}
}
float enterProgress = current[7];
float radiusProgress = current[6] * current[0];
if (enterProgress == 0 && radiusProgress == 0) {
return;
}
for (int i = 0; i < 3; i++) {
tmpWaveform[i] = (int) (current[i] * WAVE_RADIUS);
}
drawables[0].setAdditionals(tmpWaveform);
for (int i = 0; i < 3; i++) {
tmpWaveform[i] = (int) (current[i + 3] * WAVE_RADIUS);
}
drawables[1].setAdditionals(tmpWaveform);
float radius = AndroidUtilities.dp(22) +
AndroidUtilities.dp(4) * radiusProgress +
IDLE_RADIUS * enterProgress;
if (radius > AndroidUtilities.dp(26)) {
radius = AndroidUtilities.dp(26);
}
drawables[0].radius = drawables[1].radius = radius;
canvas.save();
rotation += 0.6;
canvas.rotate(rotation, cx, cy);
canvas.save();
float s = 1f + 0.04f * idleScale;
canvas.scale(s, s, cx, cy);
drawables[0].draw(cx, cy, canvas, p1);
canvas.restore();
canvas.rotate(60, cx, cy);
s = 1f + 0.04f * (1f - idleScale);
canvas.scale(s, s, cx, cy);
drawables[1].draw(cx, cy, canvas, p1);
canvas.restore();
}
public void setParentView(View parentView) {
this.parentView = parentView;
}
public View getParentView() {
return parentView;
}
public void setColor(int color) {
p1.setColor(color);
}
}