summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorninatai <ninatai@google.com>2015-05-15 18:20:31 -0700
committerninatai <ninatai@google.com>2015-05-15 18:20:31 -0700
commit9c39ed651cfee1193cc480ac95cda367ea9f1e2d (patch)
tree1183dc95e1261912801a5da69e4552e3d523f0a0
parent2590779e25bd9ccf5a72e077421cfb8b6a83c113 (diff)
downloaddrrickorang-9c39ed651cfee1193cc480ac95cda367ea9f1e2d.tar.gz
Histogram with log scale, x/y axis, and y label.
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java4
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java124
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java8
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java3
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java10
5 files changed, 122 insertions, 27 deletions
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
index aac3522..801e2bf 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
@@ -1,5 +1,6 @@
package org.drrickorang.loopback;
+import android.os.Trace;
import android.util.Log;
/**
@@ -78,6 +79,7 @@ public class Correlation {
int currentIndex = 0;
double nextGroup = groupSize;
+ Trace.beginSection("Processing Correlation");
for (int i = 0; i<N && currentIndex<mBlockSize; i++) {
if(i> nextGroup) { //advanced to next group.
@@ -90,6 +92,8 @@ public class Correlation {
}
dataDownsampled[currentIndex] += Math.abs(data[i]);
}
+ Trace.endSection();
+
status = true;
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java
index 2fce8f2..d20f404 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java
@@ -4,31 +4,44 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
-import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.View;
/**
* Created by ninatai on 5/14/15.
*/
public class HistogramView extends View {
- private Paint mPaint;
+ private Paint mHistPaint;
+ private Paint mTextPaint;
+ private Paint mLinePaint;
+
private static int[] mData;
private static int mMaxLatency = 0;
private static boolean mExceedRange = false;
+ private int mBase = 10; //base of logarithm
+ private int mNumberOfXLabel = 4;
+ private int mTextSize = 30;
+ private int mLineWidth = 3;
public HistogramView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
- // TODO when to call this? For optimization
+ // initiate once for optimization
private void init() {
- mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mPaint.setStyle(Paint.Style.FILL);
- mPaint.setColor(Color.BLUE);
+ mHistPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mHistPaint.setStyle(Paint.Style.FILL);
+ mHistPaint.setColor(Color.BLUE);
+
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint.setColor(Color.RED);
+ mTextPaint.setTextSize(mTextSize);
+
+ mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mLinePaint.setColor(Color.BLACK);
+ mLinePaint.setStrokeWidth(mLineWidth);
}
@Override
@@ -41,12 +54,10 @@ public class HistogramView extends View {
return;
}
- // coordinate starts at (0,0), up to (right, bottom)
- int right = this.getRight();
- int bottom = this.getBottom();
-
- // Rect rect1 = new Rect(0, 0, width, height);
if (mMaxLatency != 0) {
+
+
+ // the range of latencies that's going to be displayed on histogram
int range;
if (mMaxLatency > arrayLength - 1) {
range = arrayLength;
@@ -59,8 +70,13 @@ public class HistogramView extends View {
if (range == 0) {
return;
}
- float width = ((float)right / range);
+ // coordinate starts at (0,0), up to (right, bottom)
+ int right = this.getRight();
+ int bottom = this.getBottom();
+
+
+ // calculate the max frequency among all latencies
int maxLatencyFreq = 0;
for (int i = 1; i < arrayLength; i++) {
if (mData[i] > maxLatencyFreq) {
@@ -68,24 +84,86 @@ public class HistogramView extends View {
}
}
+
if (maxLatencyFreq == 0) {
return;
}
- float height =( (float)bottom / maxLatencyFreq);
- float currentLeft = 0;
- float currentTop = 0;
- float currentRight = 0;
- float currentBottom = bottom;
- for (int i = 0; i < arrayLength; i++) {
+ // find the closest order of 10 according to maxLatencyFreq
+ int order = 0;
+ while (Math.pow(mBase, order) < maxLatencyFreq) {
+ order += 1;
+ }
+ float height =( (float) (bottom - mTextSize) / (order + 1)); // height for one decade
+
+
+
+
+
+ // TODO add x labels
+ int totalXLabel = mNumberOfXLabel + 1; // last label is for the last beam
+
+ // y labels
+ String[] yLabels = new String[order+2]; // will store {"0", "1", "10", "100", ...} for base = 10
+ yLabels[0] = "0";
+ canvas.drawText(yLabels[0], 0, bottom - mTextSize - mLineWidth, mTextPaint);
+ int currentValue = 1;
+ for (int i = 1; i <= (order + 1); i++)
+ {
+ yLabels[i] = Integer.toString(currentValue);
+ // FIXME since no margin added, can't show the top y label (100) -> fixed. now it display lower by amount of textsize
+ canvas.drawText(yLabels[i], 0, bottom - (i * height), mTextPaint); // for the third argument, + mTextSize - mTextSize cancels out
+ currentValue *= 10;
+
+ }
+ // draw x axis
+ canvas.drawLine(0, bottom - mTextSize, right, bottom - mTextSize, mLinePaint);
+
+ // draw y axis
+ int yMargin = getTextWidth(yLabels[order+1], mTextPaint);
+ int extraYMargin = 5;
+ canvas.drawLine(yMargin + extraYMargin, bottom, yMargin + extraYMargin, 0, mLinePaint);
+
+
+ float width = ((float) (right - yMargin - extraYMargin - mLineWidth) / range); // width of each beam in the histogram
+
+ float currentLeft = yMargin + extraYMargin + mLineWidth; // FIXME there's an extra 1 pixel split, not sure why
+ float currentTop;
+ float currentRight;
+ // TODO separate each beam
+ // draw the histogram
+ mData[0] = 1;
+ mData[range-1] = 1;
+ int currentBottom = bottom - mTextSize - mLineWidth;
+ for (int i = 0; i < range; i++) {
currentRight = currentLeft + width;
- currentTop = bottom - (height * mData[i]);
- canvas.drawRect(currentLeft, currentTop , currentRight, currentBottom, mPaint);
+ // calculate the height of the beam
+ if (mData[i] == 0) {
+ currentTop = currentBottom;
+ } else {
+ float units = (float) ((Math.log10((double) mData[i])) + 1.0);
+ currentTop = currentBottom - (height * units);
+ }
+
+ canvas.drawRect(currentLeft, currentTop, currentRight, currentBottom, mHistPaint);
currentLeft = currentRight;
- //currentTop = currentBottom;
}
+
+
+
+
+
+
}
- int x = 1;
+
+ }
+
+ // get the width of a certain string, using a certain paint
+ public int getTextWidth(String text, Paint paint) {
+ Rect bounds = new Rect();
+ paint.getTextBounds(text, 0, text.length(), bounds);
+ int width = bounds.left + bounds.width();
+ return width;
}
void redraw() {
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java
index b4d4247..6182ccb 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java
@@ -15,7 +15,7 @@ import java.util.HashMap;
// TODO remember that after one record, set mPreviousTime back to zero -> done in onButtonTest
public class LatencyRecord {
private static long mPreviousTime = 0;
- private static long mCurrentTime;
+ private static long mCurrentTime = 0;
private static final int range = 102; //TODO adjust this value
private static int mMaxLatency = 0;
private static boolean exceedRange = false;
@@ -26,9 +26,10 @@ public class LatencyRecord {
public static void collectLatency() {
mCurrentTime = System.nanoTime();
// if = 0 it's the first time the thread runs, so don't record the interval
+ // FIXME discard the first few records
if (mPreviousTime != 0 && mCurrentTime != 0) {
long diffInNano = mCurrentTime - mPreviousTime;
- int diffInMilli = (int) Math.ceil(((double) (diffInNano / 1000000))); // round up
+ int diffInMilli = (int) Math.ceil(( ((double)diffInNano / 1000000))); // round up
if (diffInMilli > mMaxLatency) {
mMaxLatency = diffInMilli;
@@ -60,7 +61,10 @@ public class LatencyRecord {
public static void resetRecord() {
mPreviousTime = 0;
+ mCurrentTime = 0;
Arrays.fill(mJavaLatency, 0);
+ mMaxLatency = 0;
+
}
public static int[] getLatencyArray() {
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java
index 2f02f7b..e1e168d 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java
@@ -21,6 +21,7 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.database.Cursor;
+import android.os.Trace;
import android.provider.MediaStore;
import android.os.ParcelFileDescriptor;
@@ -302,6 +303,7 @@ public class LoopbackActivity extends Activity {
public void onButtonTest(View view) {
if( !isBusy()) {
+ Trace.beginSection("Processing TestButton");
restartAudioSystem();
resetLatencyRecord();
try {
@@ -318,6 +320,7 @@ public class LoopbackActivity extends Activity {
nativeAudioThread.runTest();
}
}
+ Trace.endSection();
} else {
//please wait, or restart application.
// Toast.makeText(getApplicationContext(), "Test in progress... please wait",
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java
index e0c46f3..960e472 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java
@@ -417,11 +417,17 @@ public class LoopbackAudioThread extends Thread {
}
}
+
+ private void resetLatencyRecord() {
+ LatencyRecord.resetRecord();
+ }
+
public void run() {
double phase = 0;
double maxval = Math.pow(2, 15);
+ resetLatencyRecord();
while (!Thread.interrupted()) {
boolean isRecording = false;
@@ -430,10 +436,10 @@ public class LoopbackAudioThread extends Thread {
}
//long mStartTime = System.nanoTime();
- //WaitTimeRecord.collectLatency(); //FIXME should it be here,
+ //LatencyRecord.collectLatency(); //FIXME should it be here,
if (isRecording && mRecorder != null) {
- LatencyRecord.collectLatency(); // or here?
+ LatencyRecord.collectLatency(); // or here?
int nSamplesRead = mRecorder.read(mAudioShortArray, 0, mMinRecordBuffSizeInSamples);
// int nbBytesRead = mRecorder.read(mAudioByteArray, 0,