Merge "ligbaaudio: Fix pause, flush and getXRunCount for input streams." into oc-dev
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
index b482e93..7c34252 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
@@ -24,7 +24,7 @@
#include <time.h>
#include <aaudio/AAudio.h>
-#define NUM_SECONDS 10
+#define NUM_SECONDS 5
#define NANOS_PER_MICROSECOND ((int64_t)1000)
#define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000)
#define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000)
@@ -33,13 +33,13 @@
#define SHARING_MODE AAUDIO_SHARING_MODE_SHARED
/**
- * Simple wrapper for AAudio that opens a default stream and then calls
- * a callback function to fill the output buffers.
+ * Simple wrapper for AAudio that opens an input stream and then calls
+ * a callback function to process the input data.
*/
-class SimpleAAudioPlayer {
+class SimpleAAudioRecorder {
public:
- SimpleAAudioPlayer() {}
- ~SimpleAAudioPlayer() {
+ SimpleAAudioRecorder() {}
+ ~SimpleAAudioRecorder() {
close();
};
@@ -71,6 +71,15 @@
}
return AAudioStream_getSamplesPerFrame(mStream);;
}
+ /**
+ * Only call this after open() has been called.
+ */
+ int64_t getFramesRead() {
+ if (mStream == nullptr) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return AAudioStream_getFramesRead(mStream);;
+ }
/**
* Open a stream
@@ -85,7 +94,7 @@
AAudioStreamBuilder_setDirection(mBuilder, AAUDIO_DIRECTION_INPUT);
AAudioStreamBuilder_setSharingMode(mBuilder, mRequestedSharingMode);
AAudioStreamBuilder_setDataCallback(mBuilder, proc, userContext);
- AAudioStreamBuilder_setFormat(mBuilder, AAUDIO_FORMAT_PCM_I16);
+ AAudioStreamBuilder_setFormat(mBuilder, AAUDIO_FORMAT_PCM_FLOAT);
// Open an AAudioStream using the Builder.
result = AAudioStreamBuilder_openStream(mBuilder, &mStream);
@@ -121,11 +130,10 @@
}
// Write zero data to fill up the buffer and prevent underruns.
- // Assume format is PCM_I16. TODO use floats.
aaudio_result_t prime() {
int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(mStream);
const int numFrames = 32; // arbitrary
- int16_t zeros[numFrames * samplesPerFrame];
+ float zeros[numFrames * samplesPerFrame];
memset(zeros, 0, sizeof(zeros));
aaudio_result_t result = numFrames;
while (result == numFrames) {
@@ -151,8 +159,16 @@
fprintf(stderr, "ERROR - AAudioStream_requestStop() returned %d %s\n",
result, AAudio_convertResultToText(result));
}
- int32_t xRunCount = AAudioStream_getXRunCount(mStream);
- printf("AAudioStream_getXRunCount %d\n", xRunCount);
+ return result;
+ }
+
+ // Pause the stream. AAudio will stop calling your callback function.
+ aaudio_result_t pause() {
+ aaudio_result_t result = AAudioStream_requestPause(mStream);
+ if (result != AAUDIO_OK) {
+ fprintf(stderr, "ERROR - AAudioStream_requestPause() returned %d %s\n",
+ result, AAudio_convertResultToText(result));
+ }
return result;
}
@@ -227,7 +243,7 @@
int main(int argc, char **argv)
{
(void)argc; // unused
- SimpleAAudioPlayer player;
+ SimpleAAudioRecorder recorder;
PeakTrackerData_t myData = {0.0};
aaudio_result_t result;
const int displayRateHz = 20; // arbitrary
@@ -238,37 +254,60 @@
setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
printf("%s - Display audio input using an AAudio callback\n", argv[0]);
- player.setSharingMode(SHARING_MODE);
+ recorder.setSharingMode(SHARING_MODE);
- result = player.open(MyDataCallbackProc, &myData);
+ result = recorder.open(MyDataCallbackProc, &myData);
if (result != AAUDIO_OK) {
- fprintf(stderr, "ERROR - player.open() returned %d\n", result);
+ fprintf(stderr, "ERROR - recorder.open() returned %d\n", result);
goto error;
}
- printf("player.getFramesPerSecond() = %d\n", player.getFramesPerSecond());
- printf("player.getSamplesPerFrame() = %d\n", player.getSamplesPerFrame());
+ printf("recorder.getFramesPerSecond() = %d\n", recorder.getFramesPerSecond());
+ printf("recorder.getSamplesPerFrame() = %d\n", recorder.getSamplesPerFrame());
- result = player.start();
+ result = recorder.start();
if (result != AAUDIO_OK) {
- fprintf(stderr, "ERROR - player.start() returned %d\n", result);
+ fprintf(stderr, "ERROR - recorder.start() returned %d\n", result);
goto error;
}
- printf("Sleep for %d seconds while audio plays in a callback thread.\n", NUM_SECONDS);
- for (int i = 0; i < loopsNeeded; i++)
+ printf("Sleep for %d seconds while audio record in a callback thread.\n", NUM_SECONDS);
+ for (int i = 0; i < loopsNeeded; i++)
{
const struct timespec request = { .tv_sec = 0,
.tv_nsec = NANOS_PER_SECOND / displayRateHz };
(void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/);
+ printf("%08d: ", (int)recorder.getFramesRead());
+ displayPeakLevel(myData.peakLevel);
+ }
+ printf("Woke up. Stop for a moment.\n");
+
+ result = recorder.stop();
+ if (result != AAUDIO_OK) {
+ goto error;
+ }
+ sleep(1);
+ result = recorder.start();
+ if (result != AAUDIO_OK) {
+ fprintf(stderr, "ERROR - recorder.start() returned %d\n", result);
+ goto error;
+ }
+
+ printf("Sleep for %d seconds while audio records in a callback thread.\n", NUM_SECONDS);
+ for (int i = 0; i < loopsNeeded; i++)
+ {
+ const struct timespec request = { .tv_sec = 0,
+ .tv_nsec = NANOS_PER_SECOND / displayRateHz };
+ (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/);
+ printf("%08d: ", (int)recorder.getFramesRead());
displayPeakLevel(myData.peakLevel);
}
printf("Woke up now.\n");
- result = player.stop();
+ result = recorder.stop();
if (result != AAUDIO_OK) {
goto error;
}
- result = player.close();
+ result = recorder.close();
if (result != AAUDIO_OK) {
goto error;
}
@@ -276,7 +315,7 @@
printf("SUCCESS\n");
return EXIT_SUCCESS;
error:
- player.close();
+ recorder.close();
printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result));
return EXIT_FAILURE;
}
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 8498950..c21caa4 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -507,6 +507,9 @@
* Use AAudioStream_Start() to resume playback after a pause.
* After this call the state will be in AAUDIO_STREAM_STATE_PAUSING or AAUDIO_STREAM_STATE_PAUSED.
*
+ * This will return AAUDIO_ERROR_UNIMPLEMENTED for input streams.
+ * For input streams use AAudioStream_requestStop().
+ *
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return AAUDIO_OK or a negative error.
*/
@@ -519,6 +522,8 @@
* Frame counters are not reset by a flush. They may be advanced.
* After this call the state will be in AAUDIO_STREAM_STATE_FLUSHING or AAUDIO_STREAM_STATE_FLUSHED.
*
+ * This will return AAUDIO_ERROR_UNIMPLEMENTED for input streams.
+ *
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return AAUDIO_OK or a negative error.
*/
@@ -704,6 +709,9 @@
*
* An underrun or overrun can cause an audible "pop" or "glitch".
*
+ * Note that some INPUT devices may not support this function.
+ * In that case a 0 will always be returned.
+ *
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return the underrun or overrun count
*/
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index f0a6ceb..918f5dd 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -177,10 +177,13 @@
aaudio_result_t AudioStreamRecord::requestPause()
{
+ // This does not make sense for an input stream.
+ // There is no real difference between pause() and stop().
return AAUDIO_ERROR_UNIMPLEMENTED;
}
aaudio_result_t AudioStreamRecord::requestFlush() {
+ // This does not make sense for an input stream.
return AAUDIO_ERROR_UNIMPLEMENTED;
}
@@ -259,7 +262,7 @@
int32_t AudioStreamRecord::getXRunCount() const
{
- return AAUDIO_ERROR_UNIMPLEMENTED; // TODO implement when AudioRecord supports it
+ return 0; // TODO implement when AudioRecord supports it
}
int32_t AudioStreamRecord::getFramesPerBurst() const