summaryrefslogtreecommitdiff
path: root/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
diff options
context:
space:
mode:
Diffstat (limited to 'LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java')
-rw-r--r--LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java78
1 files changed, 46 insertions, 32 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 062341c..8cb8479 100644
--- a/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
+++ b/LoopbackApp/app/src/main/java/org/drrickorang/loopback/Correlation.java
@@ -16,22 +16,24 @@
package org.drrickorang.loopback;
-import android.os.Trace;
import android.util.Log;
+
/**
- * Created by rago on 5/8/15.
+ * This class is used to automatically estimate latency and its confidence.
*/
+
public class Correlation {
+ private static final String TAG = "Correlation";
- private int mBlockSize = 4096;
- private int mSamplingRate = 44100;
+ private int mBlockSize = 4096;
+ private int mSamplingRate;
private double [] mDataDownsampled = new double [mBlockSize];
private double [] mDataAutocorrelated = new double[mBlockSize];
public double mEstimatedLatencySamples = 0;
public double mEstimatedLatencyMs = 0;
-
+ public double mEstimatedLatencyConfidence = 0.0;
public void init(int blockSize, int samplingRate) {
@@ -39,8 +41,9 @@ public class Correlation {
mSamplingRate = samplingRate;
}
+
public boolean computeCorrelation(double [] data, int samplingRate) {
- boolean status = false;
+ boolean status;
log("Started Auto Correlation for data with " + data.length + " points");
mSamplingRate = samplingRate;
@@ -57,36 +60,51 @@ public class Correlation {
int maxIndex = -1;
double minLatencyMs = 8; //min latency expected. This algorithm should be improved.
- int minIndex = (int)(0.5 + minLatencyMs * mSamplingRate / (groupSize*1000));
+ int minIndex = (int) (0.5 + minLatencyMs * mSamplingRate / (groupSize * 1000));
+
+ double average = 0;
+ double rms = 0;
//find max
- for(int i=minIndex; i<mDataAutocorrelated.length; i++) {
- if(mDataAutocorrelated[i] > maxValue) {
+ for (int i = minIndex; i < mDataAutocorrelated.length; i++) {
+ average += mDataAutocorrelated[i];
+ rms += mDataAutocorrelated[i] * mDataAutocorrelated[i];
+ if (mDataAutocorrelated[i] > maxValue) {
maxValue = mDataAutocorrelated[i];
maxIndex = i;
}
}
- log(String.format(" Maxvalue %f, max Index : %d/%d (%d) minIndex=%d",maxValue, maxIndex, mDataAutocorrelated.length, data.length, minIndex));
-
+ rms = Math.sqrt(rms / mDataAutocorrelated.length);
+ average = average / mDataAutocorrelated.length;
+ log(String.format(" Maxvalue %f, max Index : %d/%d (%d) minIndex = %d", maxValue, maxIndex,
+ mDataAutocorrelated.length, data.length, minIndex));
+ log(String.format(" average : %.3f rms: %.3f", average, rms));
+ mEstimatedLatencyConfidence = 0.0;
+ if (average > 0) {
+ double factor = 3.0;
- mEstimatedLatencySamples = maxIndex*groupSize;
-
- mEstimatedLatencyMs = mEstimatedLatencySamples *1000/mSamplingRate;
+ double raw = (rms - average) / (factor * average);
+ log(String.format("Raw: %.3f", raw));
+ mEstimatedLatencyConfidence = Math.max(Math.min(raw, 1.0), 0.0);
+ }
+ log(String.format(" ****Confidence: %.2f", mEstimatedLatencyConfidence));
- log(String.format(" latencySamples: %.2f %.2f ms", mEstimatedLatencySamples, mEstimatedLatencyMs));
+ mEstimatedLatencySamples = maxIndex * groupSize;
+ mEstimatedLatencyMs = mEstimatedLatencySamples * 1000 / mSamplingRate;
+ log(String.format(" latencySamples: %.2f %.2f ms", mEstimatedLatencySamples,
+ mEstimatedLatencyMs));
status = true;
-
return status;
}
+
private boolean downsampleData(double [] data, double [] dataDownsampled) {
- boolean status = false;
- // mDataDownsampled = new double[mBlockSize];
- for (int i=0; i<mBlockSize; i++) {
+ boolean status;
+ for (int i = 0; i < mBlockSize; i++) {
dataDownsampled[i] = 0;
}
@@ -95,40 +113,35 @@ public class Correlation {
int currentIndex = 0;
double nextGroup = groupSize;
- //Trace.beginSection("Processing Correlation");
- for (int i = 0; i<N && currentIndex<mBlockSize; i++) {
+ for (int i = 0; i < N && currentIndex < mBlockSize; i++) {
- if(i> nextGroup) { //advanced to next group.
+ if (i > nextGroup) { //advanced to next group.
currentIndex++;
nextGroup += groupSize;
}
- if (currentIndex>=mBlockSize) {
+ if (currentIndex >= mBlockSize) {
break;
}
dataDownsampled[currentIndex] += Math.abs(data[i]);
}
- //Trace.endSection();
-
status = true;
-
return status;
}
+
private boolean autocorrelation(double [] data, double [] dataOut) {
boolean status = false;
double sumsquared = 0;
int N = data.length;
- for(int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
double value = data[i];
- sumsquared += value*value;
+ sumsquared += value * value;
}
- //dataOut = new double[N];
-
- if(sumsquared>0) {
+ if (sumsquared > 0) {
//correlate (not circular correlation)
for (int i = 0; i < N; i++) {
dataOut[i] = 0;
@@ -144,7 +157,8 @@ public class Correlation {
return status;
}
+
private static void log(String msg) {
- Log.v("Recorder", msg);
+ Log.v(TAG, msg);
}
}