summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorninatai <ninatai@google.com>2015-05-13 18:03:40 -0700
committerninatai <ninatai@google.com>2015-05-13 18:03:40 -0700
commit8962f3e75b483cf4e46a5c6ef1ab1677fc22f266 (patch)
tree6f56abc63fe148feb1d5e396ef645c3461170c98
parent8940c03baa51593af9388e7ba817939a3117a73f (diff)
downloaddrrickorang-8962f3e75b483cf4e46a5c6ef1ab1677fc22f266.tar.gz
Partial code for collecting latency data
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyActivity.java34
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java67
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java9
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java14
-rw-r--r--LoopbackApp/app/src/main/res/layout/main_activity.xml16
-rw-r--r--LoopbackApp/app/src/main/res/values/strings.xml1
6 files changed, 141 insertions, 0 deletions
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyActivity.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyActivity.java
new file mode 100644
index 0000000..81eb122
--- /dev/null
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyActivity.java
@@ -0,0 +1,34 @@
+package org.drrickorang.loopback;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.TextView;
+
+import java.lang.reflect.AccessibleObject;
+
+/**
+ * Created by ninatai on 5/13/15.
+ */
+public class LatencyActivity extends Activity {
+ public void onCreate(Bundle savedInstanceState) {
+
+ super.onCreate(savedInstanceState);
+
+ Intent intent = getIntent();
+ String message = "Audio latency testing app using the Dr. Rick O'Rang audio loopback dongle.\n\n" +
+ "Author: Ricardo Garcia\n\n" +
+ "Open source project on: https://github.com/gkasten/drrickorang\n\n" +
+ "References: https://source.android.com/devices/audio/loopback.html\n" +
+ "https://source.android.com/devices/audio/latency_measure.html#loopback";
+
+ // Create the text view
+ TextView textView = new TextView(this);
+ textView.setTextSize(20);
+ textView.setText(message);
+
+ // Set the text view as the activity layout
+ setContentView(textView);
+ }
+}
diff --git a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java
new file mode 100644
index 0000000..23a143c
--- /dev/null
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LatencyRecord.java
@@ -0,0 +1,67 @@
+package org.drrickorang.loopback;
+
+/**
+ * Created by ninatai on 5/12/15.
+ */
+
+import android.util.Log;
+
+import org.drrickorang.loopback.LoopbackAudioThread.RecorderRunnable;
+
+import java.util.HashMap;
+
+
+public class LatencyRecord {
+ private static long mPreviousTime = 0;
+ private static long mCurrentTime;
+ private static final int range = 1002;
+ private static int mMaxLatency = 0;
+
+ private static int[] mJavaLatency = new int[range];
+
+
+ public static void collectLatency() {
+ mCurrentTime = System.nanoTime();
+ // if = 0 it's the first time the thread runs, so don't record the interval
+ if (mPreviousTime != 0 && mCurrentTime != 0) {
+ long diffInNano = mCurrentTime - mPreviousTime;
+ int diffInMilli = (int) Math.ceil(((double) (diffInNano / 1000))); // round up
+
+ if (diffInMilli > mMaxLatency) {
+ mMaxLatency = diffInMilli;
+ }
+
+ // from 0 ms to 1000 ms, plus a sum of all instances > 1000ms
+ if (diffInMilli >= 0 && diffInMilli < (range - 1)) {
+ mJavaLatency[diffInMilli] += 1;
+ } else if (diffInMilli >= (range - 1)) {
+ mJavaLatency[range-1] += 1;
+ } else if (diffInMilli < 0) {
+ // throw new IllegalLatencyException("Latency must be >= 0");
+ errorLog("Having negative Latency.");
+ }
+
+ }
+
+ mPreviousTime = mCurrentTime;
+ }
+
+ private static void errorLog(String msg) {
+ Log.e("LatencyTracker", msg);
+ }
+
+ private static void log(String msg) {
+ Log.v("LatencyTracker", msg);
+ }
+
+ public static class IllegalLatencyException extends Exception {
+
+ public IllegalLatencyException(String message)
+ {
+ super(message);
+ }
+ }
+
+
+
+}
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 3a5acb0..02205ec 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackActivity.java
@@ -476,6 +476,15 @@ public class LoopbackActivity extends Activity {
showToast("Test in progress... please wait");
}
+
+ public void onButtonLatency(View view) {
+ if(!isBusy()) {
+ Intent aboutIntent = new Intent(this, LatencyActivity.class);
+ startActivity(aboutIntent);
+ } else
+ showToast("Test in progress... please wait");
+ }
+
/** Called when the user clicks the button */
public void onButtonSettings(View view) {
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 e7ed9c2..b17e483 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/LoopbackAudioThread.java
@@ -28,6 +28,7 @@ import android.util.Log;
import android.os.Handler;
import android.os.Message;
+import org.drrickorang.loopback.LatencyRecord;
/**
* A thread/audio track based audio synth.
@@ -65,6 +66,8 @@ public class LoopbackAudioThread extends Thread {
boolean isPlaying = false;
private Handler mMessageHandler;
+ // private static long mStartTime = 0; // the start time of the current loop in "run()"
+
static final int FUN_PLUG_AUDIO_THREAD_MESSAGE_REC_STARTED = 992;
static final int FUN_PLUG_AUDIO_THREAD_MESSAGE_REC_ERROR = 993;
static final int FUN_PLUG_AUDIO_THREAD_MESSAGE_REC_COMPLETE = 994;
@@ -304,6 +307,8 @@ public class LoopbackAudioThread extends Thread {
private short[] mAudioTone;
private int mAudioToneIndex;
+ // private static long mStartTime = 0;
+
double twoPi = 6.28318530718;
public double[] mvSamples; //captured samples
@@ -424,7 +429,12 @@ public class LoopbackAudioThread extends Thread {
isRecording = mIsRecording;
}
+ //long mStartTime = System.nanoTime();
+ //WaitTimeRecord.collectLatency();
+
if (isRecording && mRecorder != null) {
+ LatencyRecord.collectLatency();
+
int nSamplesRead = mRecorder.read(mAudioShortArray, 0, mMinRecordBuffSizeInSamples);
// int nbBytesRead = mRecorder.read(mAudioByteArray, 0,
// mMinRecordBuffSizeInBytes / 2);
@@ -472,6 +482,7 @@ public class LoopbackAudioThread extends Thread {
stopRecording();//close this
}
+
public boolean isStillRoomToRecord() {
boolean result = false;
if (mvSamples != null) {
@@ -511,5 +522,8 @@ public class LoopbackAudioThread extends Thread {
Log.v("Recorder", msg);
}
+ //public static long getStartTime()
+ // return mStartTime;
+
} //RecorderRunnable
}; //end thread.
diff --git a/LoopbackApp/app/src/main/res/layout/main_activity.xml b/LoopbackApp/app/src/main/res/layout/main_activity.xml
index 00ee4d0..ec71434 100644
--- a/LoopbackApp/app/src/main/res/layout/main_activity.xml
+++ b/LoopbackApp/app/src/main/res/layout/main_activity.xml
@@ -103,6 +103,22 @@
</LinearLayout>
<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/buttonLatency"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/buttonLatency"
+ android:onClick="onButtonLatency"/>
+ </LinearLayout>
+
+ <LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
diff --git a/LoopbackApp/app/src/main/res/values/strings.xml b/LoopbackApp/app/src/main/res/values/strings.xml
index a3a5173..652ff0b 100644
--- a/LoopbackApp/app/src/main/res/values/strings.xml
+++ b/LoopbackApp/app/src/main/res/values/strings.xml
@@ -27,6 +27,7 @@
<string name="buttonZoomOut">Zoom Out</string>
<string name="buttonZoomIn"> Zoom In</string>
<string name="buttonAbout">About</string>
+ <string name="buttonLatency">Latency Plot</string>
<!-- disabled -->
<string name="buttonZoomInFull">In Full</string>