OboeTester: add fader to control delay time
in "Echo Input to Output" test.
diff --git a/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.cpp b/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.cpp
index 1b34692..6ab28c2 100644
--- a/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.cpp
+++ b/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.cpp
@@ -18,9 +18,8 @@
#include "FullDuplexEcho.h"
oboe::Result FullDuplexEcho::start() {
- int32_t delaySize = 3 * getOutputStream()->getSampleRate();
- mDelayFrames = delaySize - 2;
- mDelayLine = std::make_unique<InterpolatingDelayLine>(delaySize);
+ int32_t delayFrames = (int32_t) (mDelayTimeSeconds * getOutputStream()->getSampleRate());
+ mDelayLine = std::make_unique<InterpolatingDelayLine>(delayFrames);
return FullDuplexStream::start();
}
@@ -38,14 +37,15 @@
float *outputFloat = (float *)outputData;
int32_t inputStride = getInputStream()->getChannelCount();
int32_t outputStride = getOutputStream()->getChannelCount();
+ float delayFrames = mDelayTimeSeconds * getOutputStream()->getSampleRate();
if (outputStride == 1) {
while (framesToEcho-- > 0) {
- *outputFloat++ = mDelayLine->process(mDelayFrames, *inputFloat); // mono delay
+ *outputFloat++ = mDelayLine->process(delayFrames, *inputFloat); // mono delay
inputFloat += inputStride;
}
} else if (outputStride == 2) {
while (framesToEcho-- > 0) {
- *outputFloat++ = mDelayLine->process(mDelayFrames, *inputFloat); // mono delay
+ *outputFloat++ = mDelayLine->process(delayFrames, *inputFloat); // mono delay
*outputFloat++ = 0.0f; // FIXME *inputFloat; // mono
inputFloat += inputStride;
}
diff --git a/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.h b/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.h
index 7a755ec..bdd00ff 100644
--- a/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.h
+++ b/apps/OboeTester/app/src/main/cpp/FullDuplexEcho.h
@@ -41,9 +41,14 @@
oboe::Result start() override;
+ void setDelayTime(double delayTimeSeconds) {
+ mDelayTimeSeconds = delayTimeSeconds;
+ }
+
private:
std::unique_ptr<InterpolatingDelayLine> mDelayLine;
- float mDelayFrames = 0.0f;
+ static constexpr double kMaxDelayTimeSeconds = 4.0;
+ double mDelayTimeSeconds = kMaxDelayTimeSeconds;
};
diff --git a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h
index e0a273e..09441d1 100644
--- a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h
+++ b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h
@@ -338,6 +338,12 @@
void configureBuilder(bool isInput, oboe::AudioStreamBuilder &builder) override;
+ void setDelayTime(double delayTimeSeconds) {
+ if (mFullDuplexEcho) {
+ mFullDuplexEcho->setDelayTime(delayTimeSeconds);
+ }
+ }
+
protected:
void finishOpen(bool isInput, oboe::AudioStream *oboeStream) override;
@@ -379,6 +385,10 @@
}
}
+ void setDelayTime(double delayTimeMillis) {
+ mActivityEcho.setDelayTime(delayTimeMillis);
+ }
+
private:
// WARNING - must match definitions in TestAudioActivity.java
diff --git a/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp b/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp
index 2779c6b..6b43d26 100644
--- a/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp
+++ b/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp
@@ -417,4 +417,11 @@
engine.setActivityType(activityType);
}
+JNIEXPORT void JNICALL
+Java_com_google_sample_oboe_manualtest_EchoActivity_setDelayTime(JNIEnv *env,
+ jobject instance,
+ jdouble delayTimeSeconds) {
+ engine.setDelayTime(delayTimeSeconds);
+}
+
}
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java
index 9e6df8a..63a6ed9 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java
@@ -65,4 +65,5 @@
public void setChannelEnabled(int channelIndex, boolean enabled) {
mOboeAudioOutputStream.setChannelEnabled(channelIndex, enabled);
}
+
}
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java
index 5ad1c94..e4ab24f 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java
@@ -18,14 +18,41 @@
import android.os.Bundle;
import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
/**
- * Activity to record and play back audio.
+ * Activity to capture audio and then send a delayed copy to output.
+ * There is a fader for setting delay time
*/
public class EchoActivity extends TestInputActivity {
AudioOutputTester mAudioOutTester;
+ protected TextView mTextDelayTime;
+ protected SeekBar mFaderDelayTime;
+ protected ExponentialTaper mTaperDelayTime;
+ private static final double MIN_DELAY_TIME_SECONDS = 0.004;
+ private static final double MAX_DELAY_TIME_SECONDS = 0.400;
+ private double mDelayTime;
+
+ protected static final int MAX_DELAY_TIME_PROGRESS = 1000;
+
+ private SeekBar.OnSeekBarChangeListener mDelayListener = new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ setDelayTimeByPosition(progress);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+ };
+
@Override
protected void inflateActivity() {
setContentView(R.layout.activity_echo);
@@ -38,8 +65,23 @@
updateEnabledWidgets();
mAudioOutTester = addAudioOutputTester();
+
+ mTextDelayTime = (TextView) findViewById(R.id.text_delay_time);
+ mFaderDelayTime = (SeekBar) findViewById(R.id.fader_delay_time);
+ mFaderDelayTime.setOnSeekBarChangeListener(mDelayListener);
+ mTaperDelayTime = new ExponentialTaper(MAX_DELAY_TIME_PROGRESS,
+ MIN_DELAY_TIME_SECONDS, MAX_DELAY_TIME_SECONDS);
+ mFaderDelayTime.setProgress(MAX_DELAY_TIME_PROGRESS / 2);
}
+ private void setDelayTimeByPosition(int progress) {
+ mDelayTime = mTaperDelayTime.linearToExponential(progress);
+ setDelayTime(mDelayTime);
+ mTextDelayTime.setText("DelayLine: " + (int)(mDelayTime * 1000) + " (msec)");
+ }
+
+ private native void setDelayTime(double delayTimeSeconds);
+
@Override
protected void onStart() {
super.onStart();
@@ -49,6 +91,7 @@
public void onStartEcho(View view) {
openAudio();
startAudio();
+ setDelayTime(mDelayTime);
}
public void onStopEcho(View view) {
diff --git a/apps/OboeTester/app/src/main/res/layout/activity_echo.xml b/apps/OboeTester/app/src/main/res/layout/activity_echo.xml
index 33e603c..9d77b7d 100644
--- a/apps/OboeTester/app/src/main/res/layout/activity_echo.xml
+++ b/apps/OboeTester/app/src/main/res/layout/activity_echo.xml
@@ -44,8 +44,25 @@
android:layout_height="wrap_content"
android:onClick="onStopEcho"
android:text="@string/stopAudio" />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/text_delay_time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Delay (msec)" />
+
+ <SeekBar
+ android:id="@+id/fader_delay_time"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:max="1000"
+ android:progress="1000" />
</LinearLayout>
</LinearLayout>
diff --git a/apps/OboeTester/app/src/main/res/layout/merge_audio_common.xml b/apps/OboeTester/app/src/main/res/layout/merge_audio_common.xml
index 15812ea..31e90fb 100644
--- a/apps/OboeTester/app/src/main/res/layout/merge_audio_common.xml
+++ b/apps/OboeTester/app/src/main/res/layout/merge_audio_common.xml
@@ -18,7 +18,7 @@
android:id="@+id/textThreshold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Threshold" />
+ android:text="BufferSize" />
<SeekBar
android:id="@+id/faderThreshold"