aaudio_loopback: general cleanup, use dlsym
Cleanup printing.
Use dlsym so this can run on O.
Test: aaudio_loopback -tl -pl -n2
Change-Id: I77b931e59cced32b0cc23076f9b156d082e6bf0b
diff --git a/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h b/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
index b83851a..1e282d1 100644
--- a/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
+++ b/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
@@ -410,8 +410,7 @@
static void printAudioScope(float sample) {
- const int maxStars = 80
- ; // arbitrary, fits on one line
+ const int maxStars = 80; // arbitrary, fits on one line
char c = '*';
if (sample < -1.0) {
sample = -1.0;
@@ -555,7 +554,7 @@
break;
case STATE_WAITING_FOR_SILENCE:
- // Output silence.
+ // Output silence and wait for the echos to die down.
numSamples = numFrames * outputChannelCount;
for (int i = 0; i < numSamples; i++) {
outputData[i] = 0;
diff --git a/media/libaaudio/examples/loopback/src/loopback.cpp b/media/libaaudio/examples/loopback/src/loopback.cpp
index f2254ce..39d079e 100644
--- a/media/libaaudio/examples/loopback/src/loopback.cpp
+++ b/media/libaaudio/examples/loopback/src/loopback.cpp
@@ -128,7 +128,7 @@
myData->audioRecording.write(myData->inputData,
myData->actualInputChannelCount,
- numFrames);
+ framesRead);
int32_t numSamples = framesRead * myData->actualInputChannelCount;
convertPcm16ToFloat(myData->inputData, myData->conversionBuffer, numSamples);
@@ -161,17 +161,17 @@
static void usage() {
printf("Usage: aaudio_loopback [OPTION]...\n\n");
AAudioArgsParser::usage();
- printf(" -C{channels} number of input channels\n");
- printf(" -g{gain} recirculating loopback gain\n");
- printf(" -P{inPerf} set input AAUDIO_PERFORMANCE_MODE*\n");
- printf(" n for _NONE\n");
- printf(" l for _LATENCY\n");
- printf(" p for _POWER_SAVING\n");
- printf(" -t{test} select test mode\n");
- printf(" m for sine magnitude\n");
- printf(" e for echo latency (default)\n");
- printf(" f for file latency, analyzes %s\n\n", FILENAME_ECHOS);
- printf(" -X use EXCLUSIVE mode for input\n");
+ printf(" -C{channels} number of input channels\n");
+ printf(" -g{gain} recirculating loopback gain\n");
+ printf(" -P{inPerf} set input AAUDIO_PERFORMANCE_MODE*\n");
+ printf(" n for _NONE\n");
+ printf(" l for _LATENCY\n");
+ printf(" p for _POWER_SAVING\n");
+ printf(" -t{test} select test mode\n");
+ printf(" m for sine magnitude\n");
+ printf(" e for echo latency (default)\n");
+ printf(" f for file latency, analyzes %s\n\n", FILENAME_ECHOS);
+ printf(" -X use EXCLUSIVE mode for input\n");
printf("Example: aaudio_loopback -n2 -pl -Pl -x\n");
}
@@ -448,7 +448,7 @@
}
if (loopbackData.loopbackProcessor->getResult() < 0) {
- printf("Test failed!\n");
+ printf("ERROR: Could not get a good loopback signal. Probably because the volume was too low.\n");
} else {
printf("input error = %d = %s\n",
loopbackData.inputError, AAudio_convertResultToText(loopbackData.inputError));
@@ -467,11 +467,16 @@
}
int written = loopbackData.loopbackProcessor->save(FILENAME_ECHOS);
- printf("main() wrote %d mono samples to %s on Android device\n", written,
- FILENAME_ECHOS);
- printf("main() loopbackData.audioRecording.getSampleRate() = %d\n", loopbackData.audioRecording.getSampleRate());
+ if (written > 0) {
+ printf("main() wrote %8d mono samples to \"%s\" on Android device\n",
+ written, FILENAME_ECHOS);
+ }
+
written = loopbackData.audioRecording.save(FILENAME_ALL);
- printf("main() wrote %d mono samples to %s on Android device\n", written, FILENAME_ALL);
+ if (written > 0) {
+ printf("main() wrote %8d mono samples to \"%s\" on Android device\n",
+ written, FILENAME_ALL);
+ }
}
finish:
@@ -481,9 +486,8 @@
delete[] loopbackData.inputData;
delete[] outputData;
- printf(RESULT_TAG "error = %d = %s\n", result, AAudio_convertResultToText(result));
+ printf(RESULT_TAG "result = %s\n", AAudio_convertResultToText(result));
if ((result != AAUDIO_OK)) {
- printf("error %d = %s\n", result, AAudio_convertResultToText(result));
return EXIT_FAILURE;
} else {
printf("SUCCESS\n");
diff --git a/media/libaaudio/examples/utils/AAudioArgsParser.h b/media/libaaudio/examples/utils/AAudioArgsParser.h
index 4fc5b9f..eb6925a 100644
--- a/media/libaaudio/examples/utils/AAudioArgsParser.h
+++ b/media/libaaudio/examples/utils/AAudioArgsParser.h
@@ -19,7 +19,8 @@
#define MAX_CHANNELS 8
-#include <cctype>
+//#include <cctype>
+#include <dlfcn.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -29,6 +30,63 @@
#include "AAudioExampleUtils.h"
+
+static void (*s_setUsage)(AAudioStreamBuilder* builder, aaudio_usage_t usage) = nullptr;
+static void (*s_setContentType)(AAudioStreamBuilder* builder,
+ aaudio_content_type_t contentType) = nullptr;
+static void (*s_setInputPreset)(AAudioStreamBuilder* builder,
+ aaudio_input_preset_t inputPreset) = nullptr;
+
+static bool s_loadAttempted = false;
+static aaudio_usage_t (*s_getUsage)(AAudioStream *stream) = nullptr;
+static aaudio_content_type_t (*s_getContentType)(AAudioStream *stream) = nullptr;
+static aaudio_input_preset_t (*s_getInputPreset)(AAudioStream *stream) = nullptr;
+
+// Link to test functions in shared library.
+static void loadFutureFunctions() {
+ if (s_loadAttempted) return; // only try once
+ s_loadAttempted = true;
+
+ void *handle = dlopen("libaaudio.so", RTLD_NOW);
+ if (handle != nullptr) {
+ s_setUsage = (void (*)(AAudioStreamBuilder *, aaudio_usage_t))
+ dlsym(handle, "AAudioStreamBuilder_setUsage");
+ if (s_setUsage == nullptr) goto error;
+
+ s_setContentType = (void (*)(AAudioStreamBuilder *, aaudio_content_type_t))
+ dlsym(handle, "AAudioStreamBuilder_setContentType");
+ if (s_setContentType == nullptr) goto error;
+
+ s_setInputPreset = (void (*)(AAudioStreamBuilder *, aaudio_input_preset_t))
+ dlsym(handle, "AAudioStreamBuilder_setInputPreset");
+ if (s_setInputPreset == nullptr) goto error;
+
+ s_getUsage = (aaudio_usage_t (*)(AAudioStream *))
+ dlsym(handle, "AAudioStream_getUsage");
+ if (s_getUsage == nullptr) goto error;
+
+ s_getContentType = (aaudio_content_type_t (*)(AAudioStream *))
+ dlsym(handle, "AAudioStream_getContentType");
+ if (s_getContentType == nullptr) goto error;
+
+ s_getInputPreset = (aaudio_input_preset_t (*)(AAudioStream *))
+ dlsym(handle, "AAudioStream_getInputPreset");
+ if (s_getInputPreset == nullptr) goto error;
+ }
+ return;
+
+error:
+ // prevent any calls to these functions
+ s_setUsage = nullptr;
+ s_setContentType = nullptr;
+ s_setInputPreset = nullptr;
+ s_getUsage = nullptr;
+ s_getContentType = nullptr;
+ s_getInputPreset = nullptr;
+ dlclose(handle);
+ return;
+}
+
// TODO use this as a base class within AAudio
class AAudioParameters {
public:
@@ -140,9 +198,24 @@
AAudioStreamBuilder_setDeviceId(builder, mDeviceId);
AAudioStreamBuilder_setSharingMode(builder, mSharingMode);
AAudioStreamBuilder_setPerformanceMode(builder, mPerformanceMode);
- AAudioStreamBuilder_setUsage(builder, mUsage);
- AAudioStreamBuilder_setContentType(builder, mContentType);
- AAudioStreamBuilder_setInputPreset(builder, mInputPreset);
+
+ // Call P functions if supported.
+ loadFutureFunctions();
+ if (s_setUsage != nullptr) {
+ s_setUsage(builder, mUsage);
+ } else if (mUsage != AAUDIO_UNSPECIFIED){
+ printf("WARNING: setUsage not supported");
+ }
+ if (s_setContentType != nullptr) {
+ s_setContentType(builder, mContentType);
+ } else if (mUsage != AAUDIO_UNSPECIFIED){
+ printf("WARNING: setContentType not supported");
+ }
+ if (s_setInputPreset != nullptr) {
+ s_setInputPreset(builder, mInputPreset);
+ } else if (mUsage != AAUDIO_UNSPECIFIED){
+ printf("WARNING: setInputPreset not supported");
+ }
}
private:
@@ -332,14 +405,21 @@
printf(" PerformanceMode: requested = %d, actual = %d\n",
getPerformanceMode(), AAudioStream_getPerformanceMode(stream));
- printf(" Usage: requested = %d, actual = %d\n",
- getUsage(), AAudioStream_getUsage(stream));
- printf(" ContentType: requested = %d, actual = %d\n",
- getContentType(), AAudioStream_getContentType(stream));
+ loadFutureFunctions();
- if (AAudioStream_getDirection(stream) == AAUDIO_DIRECTION_INPUT) {
- printf(" InputPreset: requested = %d, actual = %d\n",
- getInputPreset(), AAudioStream_getInputPreset(stream));
+ if (s_setUsage != nullptr) {
+ printf(" Usage: requested = %d, actual = %d\n",
+ getUsage(), s_getUsage(stream));
+ }
+ if (s_getContentType != nullptr) {
+ printf(" ContentType: requested = %d, actual = %d\n",
+ getContentType(), s_getContentType(stream));
+ }
+
+ if (AAudioStream_getDirection(stream) == AAUDIO_DIRECTION_INPUT
+ && s_getInputPreset != nullptr) {
+ printf(" InputPreset: requested = %d, actual = %d\n",
+ getInputPreset(), s_getInputPreset(stream));
}
printf(" Is MMAP used? %s\n", AAudioStream_isMMapUsed(stream)