Skip to content

Instantly share code, notes, and snippets.

@eggman
Last active August 25, 2017 12:27
Show Gist options
  • Save eggman/ca0b3771ecc1a4a771f6acc32b8666ee to your computer and use it in GitHub Desktop.
Save eggman/ca0b3771ecc1a4a771f6acc32b8666ee to your computer and use it in GitHub Desktop.
example draw spectrum and waterfall (fixed value).
package com.example.eggman.spectrum1;
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
private DrawTest myDraw;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myDraw = new DrawTest(this);
setContentView(myDraw);
}
@Override
protected void onPause() {
super.onPause();
myDraw.onPause();
}
@Override
protected void onResume() {
super.onResume();
myDraw.onResume();
}
static public class DrawTest extends View {
private int xx = 0;
private ScheduledExecutorService ses = null;
private Bitmap[] waterfallLines = null;
private int waterfallLinesTopIndex = 0;
private int[] waterfallColorMap = new int[256];
private final Runnable task = new Runnable(){
@Override
public void run() {
postInvalidate();
}
};
public DrawTest(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
byte[] spectrum = getData();
for (int i = 0; i < 256; i++) {
if (i < 20) waterfallColorMap[i] = Color.argb(0xff,0, 0, 0); // level 0: black background
else if ((i >= 20) && (i < 70)) waterfallColorMap[i] = Color.argb(0xff,0, 0, 140*(i-20)/50); // level 1: black -> blue
else if ((i >= 70) && (i < 100)) waterfallColorMap[i] = Color.argb(0xff,60*(i-70)/30, 125*(i-70)/30, 115*(i-70)/30 + 140); // level 2: blue -> light-blue / greenish
else if ((i >= 100) && (i < 150)) waterfallColorMap[i] = Color.argb(0xff,195*(i-100)/50 + 60, 130*(i-100)/50 + 125, 255-(255*(i-100)/50)); // level 3: light blue -> yellow
else if ((i >= 150) && (i < 250)) waterfallColorMap[i] = Color.argb(0xff,255, 255-255*(i-150)/100, 0); // level 4: yellow -> red
else if (i >= 250) waterfallColorMap[i] = Color.argb(0xff,255, 255*(i-250)/5, 255*(i-250)/5); // level 5: red -> white
}
if(this.waterfallLines == null)
createWaterfallLineBitmaps();
drawFft(canvas, spectrum);
drawWaterFall(canvas);
}
public void onResume(){
ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(task, 0L, 100L, TimeUnit.MILLISECONDS);
}
public void onPause(){
ses.shutdown();
ses = null;
}
private void createWaterfallLineBitmaps() {
// Recycle bitmaps if not null:
if(this.waterfallLines != null) {
for(Bitmap b: this.waterfallLines)
b.recycle();
}
// Create new array:
this.waterfallLines = new Bitmap[(getHeight() / 2)];
for (int i = 0; i < waterfallLines.length; i++)
waterfallLines[i] = Bitmap.createBitmap(getWidth(), 1, Bitmap.Config.ARGB_8888);
}
private byte[] getData() {
byte[] spectrum = new byte[]{-100, -104, -103, -104, -103, -103, -100, -106,
-103, -105, -101, -102, -100, -101, -103, -104, -105, -104, -104, -104,
-103, -102, -103, -101, -102, -103, -104, -103, -102, -104, -102, -103,
-103, -105, -103, -103, -105, -101, -104, -104, -102, -105, -103, -103,
-104, -101, -101, -101, -103, -105, -103, -103, -104, -102, -103, -103,
-105, -101, -106, -104, -101, -104, -105, -105, -104, -102, -103, -101,
-102, -103, -105, -103, -100, -104, -101, -103, -106, -102, -103, -104,
-105, -104, -105, -102, -12, -14, -15, -10, -15, -16, -14, -12,
-100, -102, -102, -102, -105, -102, -101, -104, -103, -104, -103, -100,
-104, -102, -103, -103, -105, -102, -104, -105, -104, -102, -103, -104,
-104, -102, -103, -105, -103, -106, -105, -105, -106, -102, -105, -100,
-106, -103, -102, -102, -103, -105, -105, -104, -102, -104, -103, -102,
-103, -96, -89, -103, -105, -102, -104, -103, -105, -104, -104, -102, -105,
-99, -106, -104, -104, -101, -101, -105, -103, -104, -107, -106, -103,
-104, -102, -105, -103, -102, -104, -102, -104, -103, -100, -103, -103,
-104, -104, -102, -104, -104, -102, -104, -105, -101, -103, -103, -101,
-101, -103, -104, -102, -102, -105, -102, -103, -103, -104, -102, -103,
-103, -99, -103, -104, -102, -106, -107, -102, -102, -106, -101, -102,
-104, -102, -104, -101, -105, -101, -99, -102, -102, -104, -104, -105,
-102, -104, -105, -103, -103, -104, -102, -100, -104, -103, -106, -105,
-106, -99, -105, -99, -105, -103, -101, -104, -104, -104, -104, -105, -105,
-103, -103, -103, -105, -100, -101, -103, -105, -104, -105, -106, -99,
-104, -104, -106, -105, -101, -103, -102, -101, -103, -104, -105, -105,
-104, -104, -103, -100, -102, -105, -103, -104, -105, -102, -104, -105,
-103, -103, -104, -102};
//randomize
for(int i = 0; i < spectrum.length; i++)
{
if(spectrum[i] < -80)
spectrum[i] = (byte) (- 110 + (double )(110 + spectrum[i]) *4 * Math.random());
else
spectrum[i] = (byte) (- 110 + (double )(110 + spectrum[i]) * Math.random());
}
return spectrum;
}
private void drawFft(Canvas canvas, byte[] spectrum) {
Paint paint = new Paint();
Paint waterfallLinePaint = new Paint();
int fftstarty = getHeight() / 2;
int fftheight = getHeight() / 2;
int fftpowerwitdh = fftheight / 110;
int fftfreqwidth = getWidth() / (spectrum.length);
int xpad = getWidth() - spectrum.length * fftfreqwidth;
paint.setColor(Color.BLUE);
paint.setStrokeWidth(fftfreqwidth);
paint.setStyle(Paint.Style.FILL);
Canvas newline = new Canvas(waterfallLines[waterfallLinesTopIndex]);
int x = 0;
for(int i=0; i < spectrum.length; i++) {
float[] pts2 = {xpad + x, fftstarty, xpad + x, fftstarty - (110 + spectrum[i])*fftpowerwitdh};
x = x + fftfreqwidth;
canvas.drawLines(pts2, paint);
waterfallLinePaint.setColor(waterfallColorMap[(int) 2*(10+110 + spectrum[i])]);
newline.drawLine(xpad + i*fftfreqwidth, 0, xpad + i*fftfreqwidth + fftfreqwidth, 0, waterfallLinePaint);
}
}
private void drawWaterFall(Canvas canvas) {
Paint defaultPaint = new Paint();
int yPos = getHeight() / 2;
int yDiff = 1;
// draw the bitmaps on the canvas:
for (int i = 0; i < waterfallLines.length; i++) {
int idx = (waterfallLinesTopIndex + i) % waterfallLines.length;
canvas.drawBitmap(waterfallLines[idx], 0, yPos, defaultPaint);
yPos += yDiff;
}
// move the array index (note that we have to decrement in order to do it correctly)
waterfallLinesTopIndex--;
if(waterfallLinesTopIndex < 0)
waterfallLinesTopIndex += waterfallLines.length;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment