blob: 580f4c9a9ae50ef81e8077ad54e08d9c8ea7a66a [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source 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.google.sample.oboe.manualtest;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.google.sample.oboe.manualtest.R;
/**
* Display an audio waveform in a custom View.
*/
public class WaveformView extends View {
private Paint mWavePaint;
private int mCurrentWidth;
private int mCurrentHeight;
private Paint mBackgroundPaint;
private float[] mData;
private int mSampleCount;
private int mSampleOffset;
private float mOffsetY;
private float mScaleY;
private int[] mCursors;
private Paint mCursorPaint;
public WaveformView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.WaveformView, 0, 0);
init();
}
@SuppressWarnings("deprecation")
private void init() {
Resources res = getResources();
mWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mWavePaint.setColor(res.getColor(R.color.waveform_line));
float strokeWidth = res.getDimension(R.dimen.waveform_stroke_width);
mWavePaint.setStrokeWidth(strokeWidth);
mCursorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCursorPaint.setColor(Color.RED);
mCursorPaint.setStrokeWidth(3.0f);
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBackgroundPaint.setColor(res.getColor(R.color.waveform_background));
mBackgroundPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCurrentWidth = w;
mCurrentHeight = h;
mOffsetY = 0.5f * h;
mScaleY = 0.0f - mOffsetY;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float [] localData = mData;
canvas.drawRect(0.0f, 0.0f, mCurrentWidth,
mCurrentHeight, mBackgroundPaint);
if (localData == null || mSampleCount == 0) {
return;
}
float xScale = ((float) mCurrentWidth) / (mSampleCount - 1);
float x0 = 0.0f;
if (xScale < 1.0) {
// Draw a vertical bar for multiple samples.
float ymin = mOffsetY;
float ymax = mOffsetY;
for (int i = 0; i < mSampleCount; i++) {
float x1 = i * xScale;
if ((int) x0 != (int) x1) {
// draw old data
canvas.drawLine(x0, ymin, x0, ymax, mWavePaint);
x0 = x1;
ymin = mOffsetY;
ymax = mOffsetY;
}
float y1 = (localData[i] * mScaleY) + mOffsetY;
ymin = Math.min(ymin, y1);
ymax = Math.max(ymax, y1);
}
} else {
// Draw line between samples.
float y0 = (localData[0] * mScaleY) + mOffsetY;
for (int i = 1; i < mSampleCount; i++) {
float x1 = i * xScale;
float y1 = (localData[i] * mScaleY) + mOffsetY;
canvas.drawLine(x0, y0, x1, y1, mWavePaint);
x0 = x1;
y0 = y1;
}
}
if (mCursors != null) {
for (int i = 0; i < mCursors.length; i++) {
float x = mCursors[i] * xScale;
canvas.drawLine(x, 0, x, mCurrentHeight, mCursorPaint);
}
}
}
/**
* Copy data into internal buffer then repaint.
*/
public void setSampleData(float[] samples) {
setSampleData(samples, 0, samples.length);
}
public void setSampleData(float[] samples, int offset, int count) {
if ((offset+count) > samples.length) {
throw new IllegalArgumentException("Exceed array bounds. ("
+ offset + " + " + count + ") > " + samples.length);
}
if (mData == null || count > mData.length) {
mData = new float[count];
}
System.arraycopy(samples, offset, mData, 0, count);
mSampleCount = count;
mSampleOffset = offset;
}
public void clearSampleData() {
mData = null;
mSampleCount = 0;
mSampleOffset = 0;
}
/**
* Copy cursor positions into internal buffer then repaint.
*/
public void setCursorData(int[] cursors) {
if (cursors == null) {
mCursors = null;
} else {
if (mCursors == null || cursors.length != mCursors.length) {
mCursors = new int[cursors.length];
}
System.arraycopy(cursors, 0, mCursors, 0, mCursors.length);
}
}
}