diff options
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> |