Last active
August 25, 2017 12:27
-
-
Save eggman/ca0b3771ecc1a4a771f6acc32b8666ee to your computer and use it in GitHub Desktop.
example draw spectrum and waterfall (fixed value).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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