/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2011 (C) Sindre Mehus
*/
package github.madmarty.madsonic.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.audiofx.Visualizer;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
import github.madmarty.madsonic.R;
import github.madmarty.madsonic.audiofx.VisualizerController;
import github.madmarty.madsonic.domain.PlayerState;
import github.madmarty.madsonic.service.DownloadService;
import github.madmarty.madsonic.service.DownloadServiceImpl;
/**
* A simple class that draws waveform data received from a
* {@link Visualizer.OnDataCaptureListener#onWaveFormDataCapture}
*
* @author Sindre Mehus
* @version $Id$
*/
public class VisualizerView extends View {
private static final int PREFERRED_CAPTURE_RATE_MILLIHERTZ = 20000;
private static final int COLOR_DARK = Color.rgb(255, 175, 0);
private static final int COLOR_HOLO = Color.rgb(0, 191, 255);
private static final int COLOR_RED = Color.rgb(235, 30, 30);
private static final int COLOR_PINK = Color.rgb(250, 88, 244);
private static final int COLOR_GREEN = Color.rgb(162, 255, 0);
private final Paint paint = new Paint();
private byte[] data;
private float[] points;
private boolean active;
public VisualizerView(Context context) {
super(context);
paint.setStrokeWidth(2f);
paint.setAntiAlias(true);
int VisualizerColor = COLOR_DARK;
DownloadService downloadService = DownloadServiceImpl.getInstance();
if (downloadService != null) {
switch (downloadService.getThemeCode()) {
case DARK: case LIGHT: case LIGHT_FULL:
VisualizerColor = COLOR_DARK;
break;
case HOLO: case HOLO_FULL:
VisualizerColor = COLOR_HOLO;
break;
case RED: case RED_FULL:
VisualizerColor = COLOR_RED;
break;
case PINK: case PINK_FULL:
VisualizerColor = COLOR_PINK;
break;
case GREEN: case GREEN_FULL:
VisualizerColor = COLOR_GREEN;
break;
}
}
paint.setColor(VisualizerColor);
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
Visualizer visualizer = getVizualiser();
if (visualizer == null) {
return;
}
int captureRate = Math.min(PREFERRED_CAPTURE_RATE_MILLIHERTZ, Visualizer.getMaxCaptureRate());
if (active) {
visualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
updateVisualizer(waveform);
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
}
}, captureRate, true, false);
} else {
visualizer.setDataCaptureListener(null, captureRate, false, false);
}
visualizer.setEnabled(active);
invalidate();
}
private Visualizer getVizualiser() {
DownloadService downloadService = DownloadServiceImpl.getInstance();
VisualizerController visualizerController = downloadService == null ? null : downloadService.getVisualizerController();
return visualizerController == null ? null : visualizerController.getVisualizer();
}
private void updateVisualizer(byte[] waveform) {
this.data = waveform;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!active) {
return;
}
DownloadService downloadService = DownloadServiceImpl.getInstance();
if (downloadService != null && downloadService.getPlayerState() != PlayerState.STARTED) {
return;
}
if (data == null) {
return;
}
if (points == null || points.length < data.length * 4) {
points = new float[data.length * 4];
}
int w = getWidth();
int h = getHeight();
for (int i = 0; i < data.length - 1; i++) {
points[i * 4] = w * i / (data.length - 1);
points[i * 4 + 1] = h / 2 + ((byte) (data[i] + 128)) * (h / 2) / 128;
points[i * 4 + 2] = w * (i + 1) / (data.length - 1);
points[i * 4 + 3] = h / 2 + ((byte) (data[i + 1] + 128)) * (h / 2) / 128;
}
canvas.drawLines(points, paint);
}
}