summaryrefslogtreecommitdiff
path: root/LoopbackApp/app/src/main/java/org
diff options
context:
space:
mode:
authorninatai <ninatai@google.com>2015-05-18 13:39:22 -0700
committerninatai <ninatai@google.com>2015-05-18 13:39:22 -0700
commite344f24655d62061eb61e910fa1a1b47a5fde3ab (patch)
treee3a0025d554b3407fbbfa001dcd92544e40af573 /LoopbackApp/app/src/main/java/org
parent9c39ed651cfee1193cc480ac95cda367ea9f1e2d (diff)
downloaddrrickorang-e344f24655d62061eb61e910fa1a1b47a5fde3ab.tar.gz
This version contains the completed histogram. Fix the naming so everything now correctly refers to "Buffer Period" instead of "Latency".
Diffstat (limited to 'LoopbackApp/app/src/main/java/org')
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/BufferPeriod.java (renamed from LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java)55
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/BufferPeriodActivity.java (renamed from LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyActivity.java)8
-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.java108
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java20
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java7
6 files changed, 109 insertions, 93 deletions
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/BufferPeriod.java
index 6182ccb..71e82ff 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/BufferPeriod.java
@@ -11,38 +11,40 @@ import org.drrickorang.loopback.LoopbackAudioThread.RecorderRunnable;
import java.util.Arrays;
import java.util.HashMap;
-
-// TODO remember that after one record, set mPreviousTime back to zero -> done in onButtonTest
-public class LatencyRecord {
+// TODO add record for native audio thread
+public class BufferPeriod {
private static long mPreviousTime = 0;
private static long mCurrentTime = 0;
private static final int range = 102; //TODO adjust this value
- private static int mMaxLatency = 0;
+ private static int mMaxBufferPeriod = 0;
private static boolean exceedRange = false;
+ private static int mCount = 0;
+ private static int mDiscard = 5; // discard the first few buffer period values
- private static int[] mJavaLatency = new int[range];
+ private static int[] mJavaBufferPeriod = new int[range];
- public static void collectLatency() {
+ public static void collectBufferPeriod() {
mCurrentTime = System.nanoTime();
+ mCount += 1;
+
// 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) {
+ if (mPreviousTime != 0 && mCurrentTime != 0 && mCount > mDiscard) {
long diffInNano = mCurrentTime - mPreviousTime;
int diffInMilli = (int) Math.ceil(( ((double)diffInNano / 1000000))); // round up
- if (diffInMilli > mMaxLatency) {
- mMaxLatency = diffInMilli;
+ if (diffInMilli > mMaxBufferPeriod) {
+ mMaxBufferPeriod = diffInMilli;
}
// from 0 ms to 1000 ms, plus a sum of all instances > 1000ms
if (diffInMilli >= 0 && diffInMilli < (range - 1)) {
- mJavaLatency[diffInMilli] += 1;
+ mJavaBufferPeriod[diffInMilli] += 1;
} else if (diffInMilli >= (range - 1)) {
- mJavaLatency[range-1] += 1;
+ mJavaBufferPeriod[range-1] += 1;
} else if (diffInMilli < 0) {
- // throw new IllegalLatencyException("Latency must be >= 0");
- errorLog("Having negative Latency.");
+ // throw new IllegalBufferPeriodException("BufferPeriod must be >= 0");
+ errorLog("Having negative BufferPeriod.");
}
}
@@ -50,9 +52,9 @@ public class LatencyRecord {
mPreviousTime = mCurrentTime;
}
- // Check if max latency exceeds the range of latencies that are going to be displayed on histogram
+ // Check if max BufferPeriod exceeds the range of latencies that are going to be displayed on histogram
public static void setExceedRange() {
- if (mMaxLatency > (range - 2)) {
+ if (mMaxBufferPeriod > (range - 2)) {
exceedRange = true;
} else {
exceedRange = false;
@@ -62,34 +64,35 @@ public class LatencyRecord {
public static void resetRecord() {
mPreviousTime = 0;
mCurrentTime = 0;
- Arrays.fill(mJavaLatency, 0);
- mMaxLatency = 0;
+ Arrays.fill(mJavaBufferPeriod, 0);
+ mMaxBufferPeriod = 0;
+ mCount = 0;
}
- public static int[] getLatencyArray() {
- return mJavaLatency;
+ public static int[] getBufferPeriodArray() {
+ return mJavaBufferPeriod;
}
- public static int getMaxLatency() {
- return mMaxLatency;
+ public static int getMaxBufferPeriod() {
+ return mMaxBufferPeriod;
}
private static void errorLog(String msg) {
- Log.e("LatencyTracker", msg);
+ Log.e("BufferPeriodTracker", msg);
}
private static void log(String msg) {
- Log.v("LatencyTracker", msg);
+ Log.v("BufferPeriodTracker", msg);
}
- public static class IllegalLatencyException extends Exception {
+ public static class IllegalBufferPeriodException extends Exception {
- public IllegalLatencyException(String message)
+ public IllegalBufferPeriodException(String message)
{
super(message);
}
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyActivity.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/BufferPeriodActivity.java
index caf9d35..1eba069 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyActivity.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/BufferPeriodActivity.java
@@ -1,18 +1,14 @@
package org.drrickorang.loopback;
import android.app.Activity;
-import android.app.Notification;
-import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
-import java.lang.reflect.AccessibleObject;
-
/**
* Created by ninatai on 5/13/15.
*/
-public class LatencyActivity extends Activity {
+public class BufferPeriodActivity extends Activity {
private HistogramView mHistogramView;
private TextView mTextView;
@@ -21,7 +17,7 @@ public class LatencyActivity extends Activity {
super.onCreate(savedInstanceState);
- View view = getLayoutInflater().inflate(R.layout.latency_activity, null);
+ View view = getLayoutInflater().inflate(R.layout.buffer_period_activity, null);
setContentView(view);
mTextView = (TextView) findViewById(R.id.histogramInfo);
mHistogramView = (HistogramView) findViewById(R.id.viewHistogram);
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 801e2bf..ab2bbff 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
@@ -79,7 +79,7 @@ public class Correlation {
int currentIndex = 0;
double nextGroup = groupSize;
- Trace.beginSection("Processing Correlation");
+ //Trace.beginSection("Processing Correlation");
for (int i = 0; i<N && currentIndex<mBlockSize; i++) {
if(i> nextGroup) { //advanced to next group.
@@ -92,7 +92,7 @@ public class Correlation {
}
dataDownsampled[currentIndex] += Math.abs(data[i]);
}
- Trace.endSection();
+ //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 d20f404..96490a8 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java
@@ -15,14 +15,18 @@ public class HistogramView extends View {
private Paint mHistPaint;
private Paint mTextPaint;
private Paint mLinePaint;
+ private Paint mXLabelPaint;
private static int[] mData;
- private static int mMaxLatency = 0;
+ private static int mMaxBufferPeriod = 0;
private static boolean mExceedRange = false;
private int mBase = 10; //base of logarithm
private int mNumberOfXLabel = 4;
- private int mTextSize = 30;
+ private int mYLabelSize = 30;
+ private int mXLabelSize = 22;
private int mLineWidth = 3;
+ private int mHistogramInterval = 2; // separate each beam in the histogram by such amount
+ int mExtraYMargin = 5; // the extra margin between y labels and y-axis
public HistogramView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -37,7 +41,11 @@ public class HistogramView extends View {
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.RED);
- mTextPaint.setTextSize(mTextSize);
+ mTextPaint.setTextSize(mYLabelSize);
+
+ mXLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mXLabelPaint.setColor(Color.BLACK);
+ mXLabelPaint.setTextSize(mXLabelSize);
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinePaint.setColor(Color.BLACK);
@@ -54,16 +62,15 @@ public class HistogramView extends View {
return;
}
- if (mMaxLatency != 0) {
-
+ if (mMaxBufferPeriod != 0) {
// the range of latencies that's going to be displayed on histogram
int range;
- if (mMaxLatency > arrayLength - 1) {
+ if (mMaxBufferPeriod > arrayLength - 1) {
range = arrayLength;
mExceedRange = true;
} else {
- range = mMaxLatency + 1;
+ range = mMaxBufferPeriod + 1;
mExceedRange = false;
}
@@ -75,68 +82,82 @@ public class HistogramView extends View {
int right = this.getRight();
int bottom = this.getBottom();
-
// calculate the max frequency among all latencies
- int maxLatencyFreq = 0;
+ int maxBufferPeriodFreq = 0;
for (int i = 1; i < arrayLength; i++) {
- if (mData[i] > maxLatencyFreq) {
- maxLatencyFreq = mData[i];
+ if (mData[i] > maxBufferPeriodFreq) {
+ maxBufferPeriodFreq = mData[i];
}
}
-
- if (maxLatencyFreq == 0) {
+ if (maxBufferPeriodFreq == 0) {
return;
}
- // find the closest order of 10 according to maxLatencyFreq
+ // find the closest order of "mBase" according to maxBufferPeriodFreq
int order = 0;
- while (Math.pow(mBase, order) < maxLatencyFreq) {
+ while (Math.pow(mBase, order) < maxBufferPeriodFreq) {
order += 1;
}
- float height =( (float) (bottom - mTextSize) / (order + 1)); // height for one decade
-
-
-
+ float height =( (float) (bottom - mXLabelSize - mLineWidth) / (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 yStartPoint = bottom - mXLabelSize - mLineWidth;
+ canvas.drawText(yLabels[0], 0, yStartPoint, 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;
+ // Label is displayed at a height that's lower than it should be by the amount of "mYLabelSize"
+ canvas.drawText(yLabels[i], 0, yStartPoint - (i * height) + mYLabelSize, mTextPaint);
+ currentValue *= mBase;
}
+
+
// draw x axis
- canvas.drawLine(0, bottom - mTextSize, right, bottom - mTextSize, mLinePaint);
+ canvas.drawLine(0, bottom - mXLabelSize, right, bottom - mXLabelSize, mLinePaint);
// draw y axis
int yMargin = getTextWidth(yLabels[order+1], mTextPaint);
- int extraYMargin = 5;
- canvas.drawLine(yMargin + extraYMargin, bottom, yMargin + extraYMargin, 0, mLinePaint);
+ canvas.drawLine(yMargin + mExtraYMargin, bottom, yMargin + mExtraYMargin, 0, mLinePaint);
+
+ // width of each beam in the histogram
+ float width = ((float) (right - yMargin - mExtraYMargin - mLineWidth - range * mHistogramInterval) / range);
+
+ // draw x labels
+ String[] xLabels = new String[mNumberOfXLabel];
+ int xLabelInterval = (range - 2) / mNumberOfXLabel;
+ xLabels[0] = "0"; // first label is for 0
+ canvas.drawText(xLabels[0], yMargin - getTextWidth(xLabels[0], mXLabelPaint), bottom, mXLabelPaint);
+
+ int xStartPoint = yMargin + mExtraYMargin + mLineWidth; // position where first beam is placed on x-axis
+ for (int i = 1; i < mNumberOfXLabel; i++) {
+ xLabels[i] = Integer.toString(i * xLabelInterval);
+ canvas.drawText(xLabels[i], xStartPoint + (xLabelInterval * i * (width + mHistogramInterval)), bottom, mXLabelPaint);
+ }
+ String lastXLabel; // last label is for the last beam
+ if (mExceedRange) {
+ lastXLabel = Integer.toString(range - 1) + "+";
+ } else {
+ lastXLabel = Integer.toString(range - 1);
+ }
+ canvas.drawText(lastXLabel, right - getTextWidth(lastXLabel, mXLabelPaint) - 1, bottom, mXLabelPaint);
- 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
+ // draw the histogram
+ float currentLeft = yMargin + mExtraYMargin + 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;
+ int currentBottom = bottom - mXLabelSize - mLineWidth;
+
for (int i = 0; i < range; i++) {
currentRight = currentLeft + width;
+
// calculate the height of the beam
if (mData[i] == 0) {
currentTop = currentBottom;
@@ -146,18 +167,14 @@ public class HistogramView extends View {
}
canvas.drawRect(currentLeft, currentTop, currentRight, currentBottom, mHistPaint);
- currentLeft = currentRight;
+ currentLeft = currentRight + mHistogramInterval;
}
-
-
-
-
-
}
}
+
// get the width of a certain string, using a certain paint
public int getTextWidth(String text, Paint paint) {
Rect bounds = new Rect();
@@ -170,8 +187,9 @@ public class HistogramView extends View {
invalidate();
}
+
// Copy data into internal buffer
- public static void setLatencyArray(int[] pData) {
+ public static void setBufferPeriodArray(int[] pData) {
if (mData == null || pData.length != mData.length) {
mData = new int[pData.length];
}
@@ -179,8 +197,8 @@ public class HistogramView extends View {
// postInvalidate();
}
- public static void setMaxLatency(int latency) {
- mMaxLatency = latency;
+ public static void setMaxBufferPeriod(int BufferPeriod) {
+ mMaxBufferPeriod = BufferPeriod;
}
}
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 e1e168d..1dfc419 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java
@@ -50,7 +50,7 @@ import java.io.File;
import android.os.Build;
-import org.drrickorang.loopback.LatencyRecord;
+import org.drrickorang.loopback.BufferPeriod;
public class LoopbackActivity extends Activity {
/**
@@ -295,17 +295,17 @@ public class LoopbackActivity extends Activity {
//first refresh
refreshState();
}
- private void resetLatencyRecord() {
- LatencyRecord.resetRecord();
+ private void resetBufferPeriodRecord() {
+ BufferPeriod.resetRecord();
}
/** Called when the user clicks the button */
public void onButtonTest(View view) {
if( !isBusy()) {
- Trace.beginSection("Processing TestButton");
+ //Trace.beginSection("Processing TestButton");
restartAudioSystem();
- resetLatencyRecord();
+ resetBufferPeriodRecord();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
@@ -320,7 +320,7 @@ public class LoopbackActivity extends Activity {
nativeAudioThread.runTest();
}
}
- Trace.endSection();
+ //Trace.endSection();
} else {
//please wait, or restart application.
// Toast.makeText(getApplicationContext(), "Test in progress... please wait",
@@ -486,12 +486,12 @@ public class LoopbackActivity extends Activity {
}
- public void onButtonLatency(View view) {
+ public void onButtonBufferPeriod(View view) {
if(!isBusy()) {
- HistogramView.setLatencyArray(LatencyRecord.getLatencyArray());
- HistogramView.setMaxLatency(LatencyRecord.getMaxLatency());
+ HistogramView.setBufferPeriodArray(BufferPeriod.getBufferPeriodArray());
+ HistogramView.setMaxBufferPeriod(BufferPeriod.getMaxBufferPeriod());
- Intent aboutIntent = new Intent(this, LatencyActivity.class);
+ Intent aboutIntent = new Intent(this, BufferPeriodActivity.class);
startActivity(aboutIntent);
} else
showToast("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 960e472..e2eeec6 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java
@@ -28,7 +28,7 @@ import android.util.Log;
import android.os.Handler;
import android.os.Message;
-import org.drrickorang.loopback.LatencyRecord;
+import org.drrickorang.loopback.BufferPeriod;
/**
* A thread/audio track based audio synth.
@@ -419,7 +419,7 @@ public class LoopbackAudioThread extends Thread {
}
private void resetLatencyRecord() {
- LatencyRecord.resetRecord();
+ BufferPeriod.resetRecord();
}
public void run() {
@@ -436,10 +436,9 @@ public class LoopbackAudioThread extends Thread {
}
//long mStartTime = System.nanoTime();
- //LatencyRecord.collectLatency(); //FIXME should it be here,
if (isRecording && mRecorder != null) {
- LatencyRecord.collectLatency(); // or here?
+ BufferPeriod.collectBufferPeriod();
int nSamplesRead = mRecorder.read(mAudioShortArray, 0, mMinRecordBuffSizeInSamples);
// int nbBytesRead = mRecorder.read(mAudioByteArray, 0,