summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUtkarsh Gupta <utkarsh.eminem@gmail.com>2015-07-21 16:34:10 +0530
committerUtkarsh Gupta <utkarsh.eminem@gmail.com>2015-07-21 16:42:23 +0530
commit643192402417cd2402b897e2c319e9d5fef3cf3d (patch)
tree86635b707bef1655750ece12b6f695e6583cefcb
parent1cd8c8dd846d8c7df7f007266fedf98567d9230b (diff)
downloadandroid_packages_apps_Eleven-643192402417cd2402b897e2c319e9d5fef3cf3d.tar.gz
android_packages_apps_Eleven-643192402417cd2402b897e2c319e9d5fef3cf3d.tar.bz2
android_packages_apps_Eleven-643192402417cd2402b897e2c319e9d5fef3cf3d.zip
Upgrade visualizer
* A different visualizer: http://imgur.com/npV2zyO * Much smoother than the current one, Always stays above 60fps (even in powersave mode). * Abandon android-visualizer library. * Set visualizer color alpha to 75% Change-Id: I08ad5815893735f4427e84d460c4f7a06bf4b019 Signed-off-by: Utkarsh Gupta <utkarsh.eminem@gmail.com>
-rw-r--r--Android.mk1
-rw-r--r--res/layout/main_album_flow.xml4
-rw-r--r--res/values-xhdpi/equalizer_config.xml32
-rw-r--r--res/values-xxhdpi/equalizer_config.xml32
-rw-r--r--res/values/colors.xml3
-rw-r--r--res/values/equalizer_config.xml35
-rw-r--r--src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java15
-rw-r--r--src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java30
-rw-r--r--src/com/cyanogenmod/eleven/widgets/EqualizerView.java189
-rw-r--r--src/com/cyanogenmod/eleven/widgets/VisualizerView.java208
10 files changed, 237 insertions, 312 deletions
diff --git a/Android.mk b/Android.mk
index 17708a5..206db89 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,7 +14,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-v7-palette \
android-support-v7-cardview \
android-common \
- android-visualizer \
eleven_support_v4 \
eleven_recyclerview \
guava
diff --git a/res/layout/main_album_flow.xml b/res/layout/main_album_flow.xml
index 49b0afb..aa14181 100644
--- a/res/layout/main_album_flow.xml
+++ b/res/layout/main_album_flow.xml
@@ -32,8 +32,8 @@
android:background="@drawable/equalizer_background"
android:layout_gravity="bottom"/>
- <com.cyanogenmod.eleven.widgets.EqualizerView
- android:id="@+id/equalizerView"
+ <com.cyanogenmod.eleven.widgets.VisualizerView
+ android:id="@+id/visualizerView"
android:gravity="bottom"
android:layout_gravity="bottom"
android:layout_width="match_parent"
diff --git a/res/values-xhdpi/equalizer_config.xml b/res/values-xhdpi/equalizer_config.xml
deleted file mode 100644
index 0208508..0000000
--- a/res/values-xhdpi/equalizer_config.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2012-2014 The CyanogenMod Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <!-- Height of each filled in block in each eq bar -->
- <dimen name="eqalizer_path_effect_1">8dp</dimen>
- <!-- Height of each empty block in each eq bar -->
- <dimen name="eqalizer_path_effect_2">1dp</dimen>
- <!-- Width of each eq bar -->
- <dimen name="eqalizer_path_stroke_width">22dp</dimen>
-
- <!-- The amount of divisions to make for eq bars -->
- <integer name="equalizer_divisions">12</integer>
-
- <!-- fudge factors to tweak display for various configs
- ends up being dB = ((dB * fuzz_factor) + db_fuzz) -->
- <integer name="equalizer_db_fuzz_factor">15</integer>
- <integer name="equalizer_db_fuzz">0</integer>
-</resources> \ No newline at end of file
diff --git a/res/values-xxhdpi/equalizer_config.xml b/res/values-xxhdpi/equalizer_config.xml
deleted file mode 100644
index 59aca03..0000000
--- a/res/values-xxhdpi/equalizer_config.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2012-2014 The CyanogenMod Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <!-- Height of each filled in block in each eq bar -->
- <dimen name="eqalizer_path_effect_1">8dp</dimen>
- <!-- Height of each empty block in each eq bar -->
- <dimen name="eqalizer_path_effect_2">1dp</dimen>
- <!-- Width of each eq bar -->
- <dimen name="eqalizer_path_stroke_width">20dp</dimen>
-
- <!-- The amount of divisions to make for eq bars -->
- <integer name="equalizer_divisions">16</integer>
-
- <!-- fudge factors to tweak display for various configs
- ends up being dB = ((dB * fuzz_factor) + db_fuzz) -->
- <integer name="equalizer_db_fuzz_factor">35</integer>
- <integer name="equalizer_db_fuzz">0</integer>
-</resources> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 07de9d9..a12a6f5 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -145,4 +145,7 @@
<item>@color/letter_tile_deep_orange_color_dark</item>
<item>@color/letter_tile_brown_color_dark</item>
</array>
+
+ <!-- Color for the visualizer bars -->
+ <color name="visualizer_fill_color">#bfffffff</color>
</resources>
diff --git a/res/values/equalizer_config.xml b/res/values/equalizer_config.xml
deleted file mode 100644
index baf5945..0000000
--- a/res/values/equalizer_config.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2012-2014 The CyanogenMod Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <!-- Height of each filled in block in each eq bar -->
- <dimen name="eqalizer_path_effect_1">8dp</dimen>
- <!-- Height of each empty block in each eq bar -->
- <dimen name="eqalizer_path_effect_2">1dp</dimen>
- <!-- Width of each eq bar -->
- <dimen name="eqalizer_path_stroke_width">20dp</dimen>
-
- <!-- Color for the Equalizer tile -->
- <color name="equalizer_fill_color">#32ffffff</color>
-
- <!-- The amount of divisions to make for eq bars -->
- <integer name="equalizer_divisions">16</integer>
-
- <!-- fudge factors to tweak display for various configs
- ends up being dB = (dB * fuzz_factor + db_fuzz) -->
- <integer name="equalizer_db_fuzz_factor">0</integer>
- <integer name="equalizer_db_fuzz">0</integer>
-</resources> \ No newline at end of file
diff --git a/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java b/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java
index 775fe55..68819b1 100644
--- a/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java
+++ b/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java
@@ -182,10 +182,10 @@ public class HomeActivity extends SlidingPanelActivity implements
@Override
public void onWindowFocusChanged(boolean hasFocus) {
- getAudioPlayerFragment().onWindowFocusChanged(hasFocus
- && (getCurrentPanel() == Panel.MusicPlayer));
-
super.onWindowFocusChanged(hasFocus);
+
+ getAudioPlayerFragment().setVisualizerVisible(hasFocus
+ && getCurrentPanel() == Panel.MusicPlayer);
}
private void updateStatusBarColor() {
@@ -203,7 +203,7 @@ public class HomeActivity extends SlidingPanelActivity implements
}
@Override
protected void onPostExecute(BitmapWithColors bmc) {
- updateEqualizerColor(bmc != null
+ updateVisualizerColor(bmc != null
? bmc.getVibrantColor() : Color.TRANSPARENT);
updateStatusBarColor(bmc != null
? bmc.getVibrantDarkColor() : Color.TRANSPARENT);
@@ -212,11 +212,12 @@ public class HomeActivity extends SlidingPanelActivity implements
}
}
- private void updateEqualizerColor(int color) {
+ private void updateVisualizerColor(int color) {
if (color == Color.TRANSPARENT) {
- color = getResources().getColor(R.color.equalizer_fill_color);
+ color = getResources().getColor(R.color.visualizer_fill_color);
}
- getAudioPlayerFragment().updateVisualizerColor(color);
+
+ getAudioPlayerFragment().setVisualizerColor(color);
}
private void updateStatusBarColor(int color) {
diff --git a/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java b/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java
index 3b87698..4ecce67 100644
--- a/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java
+++ b/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java
@@ -61,7 +61,6 @@ import com.cyanogenmod.eleven.utils.MusicUtils;
import com.cyanogenmod.eleven.utils.NavUtils;
import com.cyanogenmod.eleven.utils.PreferenceUtils;
import com.cyanogenmod.eleven.widgets.BrowseButton;
-import com.cyanogenmod.eleven.widgets.EqualizerView;
import com.cyanogenmod.eleven.widgets.LoadingEmptyContainer;
import com.cyanogenmod.eleven.widgets.NoResultsContainer;
import com.cyanogenmod.eleven.widgets.PlayPauseProgressButton;
@@ -69,6 +68,7 @@ import com.cyanogenmod.eleven.widgets.QueueButton;
import com.cyanogenmod.eleven.widgets.RepeatButton;
import com.cyanogenmod.eleven.widgets.RepeatingImageButton;
import com.cyanogenmod.eleven.widgets.ShuffleButton;
+import com.cyanogenmod.eleven.widgets.VisualizerView;
import java.lang.ref.WeakReference;
@@ -132,8 +132,8 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
// Total time
private TextView mTotalTime;
- // Equalizer View
- private EqualizerView mEqualizerView;
+ // Visualizer View
+ private VisualizerView mVisualizerView;
// Equalizer Gradient
private View mEqualizerGradient;
@@ -196,8 +196,8 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
initPlaybackControls();
- mEqualizerView = (EqualizerView) mRootView.findViewById(R.id.equalizerView);
- mEqualizerView.initialize(getActivity());
+ mVisualizerView = (VisualizerView) mRootView.findViewById(R.id.visualizerView);
+ mVisualizerView.initialize(getActivity());
mEqualizerGradient = mRootView.findViewById(R.id.equalizerGradient);
mLyricsText = (TextView) mRootView.findViewById(R.id.audio_player_lyrics);
@@ -482,10 +482,8 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
mQueueEmpty.hideAll();
if (PreferenceUtils.getInstance(getActivity()).getShowVisualizer()) {
mEqualizerGradient.setVisibility(View.VISIBLE);
- mEqualizerView.setEnabled(true);
} else {
mEqualizerGradient.setVisibility(View.GONE);
- mEqualizerView.setEnabled(false);
}
mAddToPlaylistButton.setVisibility(View.VISIBLE);
}
@@ -737,20 +735,24 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
@Override
public void onBeginSlide() {
- mEqualizerView.setVisible(false);
+ mVisualizerView.setVisible(false);
}
@Override
public void onFinishSlide(SlidingPanelActivity.Panel visiblePanel) {
- mEqualizerView.setVisible(visiblePanel == SlidingPanelActivity.Panel.MusicPlayer);
+ setVisualizerVisible(visiblePanel == SlidingPanelActivity.Panel.MusicPlayer);
}
- public void onWindowFocusChanged(boolean hasFocus) {
- mEqualizerView.setVisible(hasFocus);
+ public void setVisualizerVisible(boolean visible) {
+ if (visible && PreferenceUtils.getInstance(getActivity()).getShowVisualizer()) {
+ mVisualizerView.setVisible(true);
+ } else {
+ mVisualizerView.setVisible(false);
+ }
}
- public void updateVisualizerColor(int color) {
- mEqualizerView.setColor(color);
+ public void setVisualizerColor(int color) {
+ mVisualizerView.setColor(color);
}
/**
@@ -811,7 +813,7 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
audioPlayerFragment.updateNowPlayingInfo();
audioPlayerFragment.dismissPopupMenu();
} else if (action.equals(MusicPlaybackService.PLAYSTATE_CHANGED)) {
- audioPlayerFragment.mEqualizerView.setPlaying(MusicUtils.isPlaying());
+ audioPlayerFragment.mVisualizerView.setPlaying(MusicUtils.isPlaying());
// Set the play and pause image
audioPlayerFragment.mPlayPauseProgressButton.getPlayPauseButton().updateState();
} else if (action.equals(MusicPlaybackService.REPEATMODE_CHANGED)
diff --git a/src/com/cyanogenmod/eleven/widgets/EqualizerView.java b/src/com/cyanogenmod/eleven/widgets/EqualizerView.java
deleted file mode 100644
index 58a178e..0000000
--- a/src/com/cyanogenmod/eleven/widgets/EqualizerView.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
-* Copyright (C) 2014 The CyanogenMod Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package com.cyanogenmod.eleven.widgets;
-
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.DashPathEffect;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-
-import com.cyanogenmod.eleven.R;
-import com.pheelicks.visualizer.AudioData;
-import com.pheelicks.visualizer.FFTData;
-import com.pheelicks.visualizer.VisualizerView;
-import com.pheelicks.visualizer.renderer.Renderer;
-
-public class EqualizerView extends VisualizerView {
- private boolean mLinked = false;
- private boolean mVisible = false;
- private boolean mPlaying = false;
- private boolean mEnabled = false;
- private int mColor;
-
- private TileBarGraphRenderer mBarRenderer;
- private ObjectAnimator mVisualizerColorAnimator;
-
- private final Runnable mLinkVisualizer = new Runnable() {
- @Override
- public void run() {
- if (!mLinked) {
- link(0);
- animate().alpha(1f).setDuration(300);
- mLinked = true;
- }
- }
- };
-
- private final Runnable mUnlinkVisualizer = new Runnable() {
- @Override
- public void run() {
- if (mLinked) {
- animate().alpha(0f).setDuration(300);
- unlink();
- mLinked = false;
- }
- }
- };
-
- private static class TileBarGraphRenderer extends Renderer {
- private int mDivisions;
- private Paint mPaint;
- private int mDbFuzz;
- private int mDbFuzzFactor;
-
- /**
- * Renders the FFT data as a series of lines, in histogram form
- *
- * @param divisions - must be a power of 2. Controls how many lines to draw
- * @param paint - Paint to draw lines with
- * @param dbfuzz - final dB display adjustment
- * @param dbFactor - dbfuzz is multiplied by dbFactor.
- */
- public TileBarGraphRenderer(int divisions, Paint paint, int dbfuzz, int dbFactor) {
- super();
- mDivisions = divisions;
- mPaint = paint;
- mDbFuzz = dbfuzz;
- mDbFuzzFactor = dbFactor;
- }
-
- @Override
- public void onRender(Canvas canvas, AudioData data, Rect rect) {
- // Do nothing, we only display FFT data
- }
-
- @Override
- public void onRender(Canvas canvas, FFTData data, Rect rect) {
- for (int i = 0; i < data.bytes.length / mDivisions; i++) {
- mFFTPoints[i * 4] = i * 4 * mDivisions;
- mFFTPoints[i * 4 + 2] = i * 4 * mDivisions;
- byte rfk = data.bytes[mDivisions * i];
- byte ifk = data.bytes[mDivisions * i + 1];
- float magnitude = (rfk * rfk + ifk * ifk);
- int dbValue = magnitude > 0 ? (int) (10 * Math.log10(magnitude)) : 0;
-
- mFFTPoints[i * 4 + 1] = rect.height();
- mFFTPoints[i * 4 + 3] = rect.height() - (dbValue * mDbFuzzFactor + mDbFuzz);
- }
-
- canvas.drawLines(mFFTPoints, mPaint);
- }
- }
-
- public EqualizerView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public EqualizerView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public EqualizerView(Context context) {
- this(context, null, 0);
- }
-
- public void initialize(Context context) {
- setEnabled(false);
-
- Resources res = mContext.getResources();
- mColor = res.getColor(R.color.equalizer_fill_color);
- Paint paint = new Paint();
- paint.setStrokeWidth(res.getDimensionPixelSize(R.dimen.eqalizer_path_stroke_width));
- paint.setAntiAlias(true);
- paint.setColor(mColor);
- paint.setPathEffect(new DashPathEffect(new float[]{
- res.getDimensionPixelSize(R.dimen.eqalizer_path_effect_1),
- res.getDimensionPixelSize(R.dimen.eqalizer_path_effect_2)
- }, 0));
-
- int bars = res.getInteger(R.integer.equalizer_divisions);
- mBarRenderer = new TileBarGraphRenderer(bars, paint,
- res.getInteger(R.integer.equalizer_db_fuzz),
- res.getInteger(R.integer.equalizer_db_fuzz_factor));
- addRenderer(mBarRenderer);
- }
-
- public void setVisible(boolean visible) {
- if (mVisible != visible) {
- mVisible = visible;
- checkStateChanged();
- }
- }
-
- public void setPlaying(boolean playing) {
- if (mPlaying != playing) {
- mPlaying = playing;
- checkStateChanged();
- }
- }
-
- public void setEnabled(boolean enabled) {
- if (mEnabled != enabled) {
- mEnabled = enabled;
- checkStateChanged();
- }
- }
-
- public void setColor(int color) {
- if (mColor != color) {
- mColor = color;
- if (mLinked) {
- if (mVisualizerColorAnimator != null) {
- mVisualizerColorAnimator.cancel();
- }
- mVisualizerColorAnimator = ObjectAnimator.ofArgb(mBarRenderer.mPaint, "color",
- mBarRenderer.mPaint.getColor(), mColor);
- mVisualizerColorAnimator.setStartDelay(900);
- mVisualizerColorAnimator.setDuration(1200);
- mVisualizerColorAnimator.start();
- } else {
- mBarRenderer.mPaint.setColor(mColor);
- }
- }
- }
-
- private void checkStateChanged() {
- if (mVisible && mPlaying && mEnabled) {
- mLinkVisualizer.run();
- } else {
- mUnlinkVisualizer.run();
- }
- }
-}
diff --git a/src/com/cyanogenmod/eleven/widgets/VisualizerView.java b/src/com/cyanogenmod/eleven/widgets/VisualizerView.java
new file mode 100644
index 0000000..a176bda
--- /dev/null
+++ b/src/com/cyanogenmod/eleven/widgets/VisualizerView.java
@@ -0,0 +1,208 @@
+/*
+* Copyright (C) 2014 The CyanogenMod Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.cyanogenmod.eleven.widgets;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.media.audiofx.Visualizer;
+import android.os.AsyncTask;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.cyanogenmod.eleven.R;
+
+public class VisualizerView extends View {
+ private Paint mPaint;
+ private Visualizer mVisualizer;
+ private ObjectAnimator mVisualizerColorAnimator;
+
+ private ValueAnimator[] mValueAnimators = new ValueAnimator[32];
+ private float[] mFFTPoints = new float[128];
+
+ private boolean mVisible = false;
+ private boolean mPlaying = false;
+ private int mColor;
+
+ private Visualizer.OnDataCaptureListener mVisualizerListener =
+ new Visualizer.OnDataCaptureListener() {
+ byte rfk, ifk;
+ int dbValue;
+ float magnitude;
+
+ @Override
+ public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {
+ }
+
+ @Override
+ public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
+ for (int i = 0; i < 32; i++) {
+ mValueAnimators[i].cancel();
+
+ rfk = fft[i * 2];
+ ifk = fft[i * 2 + 1];
+ magnitude = rfk * rfk + ifk * ifk;
+ dbValue = magnitude > 0 ? (int) (10 * Math.log10(magnitude)) : 0;
+
+ mValueAnimators[i].setFloatValues(mFFTPoints[i * 4 + 1],
+ mFFTPoints[i * 4 + 3] - (dbValue * 16f));
+ mValueAnimators[i].start();
+ }
+ }
+ };
+
+ private final Runnable mLinkVisualizer = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mVisualizer = new Visualizer(0);
+ } catch (Exception e) {
+ return;
+ }
+
+ mVisualizer.setEnabled(false);
+ mVisualizer.setCaptureSize(64);
+ mVisualizer.setDataCaptureListener(mVisualizerListener, Visualizer.getMaxCaptureRate(),
+ false, true);
+ mVisualizer.setEnabled(true);
+ }
+ };
+
+ private final Runnable mUnlinkVisualizer = new Runnable() {
+ @Override
+ public void run() {
+ mVisualizer.setEnabled(false);
+ mVisualizer.release();
+ mVisualizer = null;
+ }
+ };
+
+ public VisualizerView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public VisualizerView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public VisualizerView(Context context) {
+ this(context, null, 0);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+
+ float barUnit = w / 32f;
+ float barWidth = barUnit * 8f / 9f;
+ barUnit = barWidth + (barUnit - barWidth) * 32f / 31f;
+ mPaint.setStrokeWidth(barWidth);
+
+ for (int i = 0; i < 32; i++) {
+ mFFTPoints[i * 4] = mFFTPoints[i * 4 + 2] = i * barUnit + (barWidth / 2);
+ mFFTPoints[i * 4 + 3] = h;
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ if (mVisualizer != null) {
+ canvas.drawLines(mFFTPoints, mPaint);
+ }
+ }
+
+ public void initialize(Context context) {
+ mColor = context.getResources().getColor(R.color.visualizer_fill_color);
+
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(mColor);
+
+ for (int i = 0; i < 32; i++) {
+ final int j = i * 4 + 1;
+ mValueAnimators[i] = new ValueAnimator();
+ mValueAnimators[i].setDuration(128);
+ mValueAnimators[i].addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mFFTPoints[j] = (float) animation.getAnimatedValue();
+ }
+ });
+ }
+
+ mValueAnimators[31].addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ postInvalidate();
+ }
+ });
+ }
+
+ public void setVisible(boolean visible) {
+ if (mVisible != visible) {
+ mVisible = visible;
+ checkStateChanged();
+ }
+ }
+
+ public void setPlaying(boolean playing) {
+ if (mPlaying != playing) {
+ mPlaying = playing;
+ checkStateChanged();
+ }
+ }
+
+ public void setColor(int color) {
+ color = Color.argb(191, Color.red(color), Color.green(color), Color.blue(color));
+
+ if (mColor != color) {
+ mColor = color;
+
+ if (mVisualizer != null) {
+ if (mVisualizerColorAnimator != null) {
+ mVisualizerColorAnimator.cancel();
+ }
+
+ mVisualizerColorAnimator = ObjectAnimator.ofArgb(mPaint, "color",
+ mPaint.getColor(), mColor);
+ mVisualizerColorAnimator.setStartDelay(900);
+ mVisualizerColorAnimator.setDuration(1200);
+ mVisualizerColorAnimator.start();
+ } else {
+ mPaint.setColor(mColor);
+ }
+ }
+ }
+
+ private void checkStateChanged() {
+ if (mVisible && mPlaying) {
+ if (mVisualizer == null) {
+ AsyncTask.execute(mLinkVisualizer);
+ animate().alpha(1f).setDuration(300);
+ }
+ } else {
+ if (mVisualizer != null) {
+ animate().alpha(0f).setDuration(0);
+ AsyncTask.execute(mUnlinkVisualizer);
+ }
+ }
+ }
+}