diff options
author | ninatai <ninatai@google.com> | 2015-05-18 13:39:22 -0700 |
---|---|---|
committer | ninatai <ninatai@google.com> | 2015-05-18 13:39:22 -0700 |
commit | e344f24655d62061eb61e910fa1a1b47a5fde3ab (patch) | |
tree | e3a0025d554b3407fbbfa001dcd92544e40af573 /LoopbackApp/app/src/main/java/org | |
parent | 9c39ed651cfee1193cc480ac95cda367ea9f1e2d (diff) | |
download | drrickorang-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.java | 4 | ||||
-rw-r--r-- | LoopbackApp/app/src/main/java/org/drrickorang/loopback/HistogramView.java | 108 | ||||
-rw-r--r-- | LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java | 20 | ||||
-rw-r--r-- | LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java | 7 |
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, |