libaaudio: implement getTimestamp for legacy path
Fix: 36659408
Test: CTS test_aaudio.cpp
Signed-off-by: Phil Burk <philburk@google.com>
Change-Id: Ic73e69a3747b2daa1df5757650f897a58511e571
diff --git a/media/libaaudio/examples/write_sine/src/write_sine.cpp b/media/libaaudio/examples/write_sine/src/write_sine.cpp
index 511fe94..80b6252 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine.cpp
@@ -27,6 +27,7 @@
#define NUM_SECONDS 10
#define NANOS_PER_MICROSECOND ((int64_t)1000)
#define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000)
+#define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000)
static const char *getSharingModeText(aaudio_sharing_mode_t mode) {
const char *modeText = "unknown";
@@ -43,6 +44,15 @@
return modeText;
}
+static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) {
+ struct timespec time;
+ int result = clock_gettime(clockId, &time);
+ if (result < 0) {
+ return -errno;
+ }
+ return (time.tv_sec * NANOS_PER_SECOND) + time.tv_nsec;
+}
+
int main(int argc, char **argv)
{
(void)argc; // unused
@@ -56,7 +66,8 @@
const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM_I16;
aaudio_audio_format_t actualDataFormat = AAUDIO_FORMAT_PCM_I16;
- const aaudio_sharing_mode_t requestedSharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE;
+ //const aaudio_sharing_mode_t requestedSharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE;
+ const aaudio_sharing_mode_t requestedSharingMode = AAUDIO_SHARING_MODE_SHARED;
aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
AAudioStreamBuilder *aaudioBuilder = nullptr;
@@ -172,6 +183,26 @@
goto finish;
}
framesLeft -= actual;
+
+ // Use timestamp to estimate latency.
+ {
+ int64_t presentationFrame;
+ int64_t presentationTime;
+ result = AAudioStream_getTimestamp(aaudioStream,
+ CLOCK_MONOTONIC,
+ &presentationFrame,
+ &presentationTime
+ );
+ if (result == AAUDIO_OK) {
+ int64_t elapsedNanos = getNanoseconds() - presentationTime;
+ int64_t elapsedFrames = actualSampleRate * elapsedNanos / NANOS_PER_SECOND;
+ int64_t currentFrame = presentationFrame + elapsedFrames;
+ int64_t framesWritten = AAudioStream_getFramesWritten(aaudioStream);
+ int64_t estimatedLatencyFrames = framesWritten - currentFrame;
+ int64_t estimatedLatencyMillis = estimatedLatencyFrames * 1000 / actualSampleRate;
+ printf("estimatedLatencyMillis %d\n", (int)estimatedLatencyMillis);
+ }
+ }
}
xRunCount = AAudioStream_getXRunCount(aaudioStream);
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index af0593d..6ac8554 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -50,7 +50,6 @@
virtual aaudio_result_t requestFlush() = 0;
virtual aaudio_result_t requestStop() = 0;
- // TODO use aaudio_clockid_t all the way down to AudioClock
virtual aaudio_result_t getTimestamp(clockid_t clockId,
int64_t *framePosition,
int64_t *timeNanoseconds) = 0;
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index dd040a0..d380eb8 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -25,6 +25,7 @@
#include "AudioClock.h"
#include "AudioStreamRecord.h"
+#include "utility/AAudioUtilities.h"
using namespace android;
using namespace aaudio;
@@ -224,5 +225,28 @@
return 192; // TODO add query to AudioRecord.cpp
}
-// TODO implement getTimestamp
-
+aaudio_result_t AudioStreamRecord::getTimestamp(clockid_t clockId,
+ int64_t *framePosition,
+ int64_t *timeNanoseconds) {
+ ExtendedTimestamp extendedTimestamp;
+ status_t status = mAudioRecord->getTimestamp(&extendedTimestamp);
+ if (status != NO_ERROR) {
+ return AAudioConvert_androidToAAudioResult(status);
+ }
+ // TODO Merge common code into AudioStreamLegacy after rebasing.
+ int timebase;
+ switch(clockId) {
+ case CLOCK_BOOTTIME:
+ timebase = ExtendedTimestamp::TIMEBASE_BOOTTIME;
+ break;
+ case CLOCK_MONOTONIC:
+ timebase = ExtendedTimestamp::TIMEBASE_MONOTONIC;
+ break;
+ default:
+ ALOGE("getTimestamp() - Unrecognized clock type %d", (int) clockId);
+ return AAUDIO_ERROR_UNEXPECTED_VALUE;
+ break;
+ }
+ status = extendedTimestamp.getBestTimestamp(framePosition, timeNanoseconds, timebase);
+ return AAudioConvert_androidToAAudioResult(status);
+}
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.h b/media/libaaudio/src/legacy/AudioStreamRecord.h
index c8d389b..4667f05 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.h
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.h
@@ -44,10 +44,8 @@
virtual aaudio_result_t requestStop() override;
virtual aaudio_result_t getTimestamp(clockid_t clockId,
- int64_t *framePosition,
- int64_t *timeNanoseconds) override {
- return AAUDIO_ERROR_UNIMPLEMENTED; // TODO
- }
+ int64_t *framePosition,
+ int64_t *timeNanoseconds) override;
virtual aaudio_result_t read(void *buffer,
int32_t numFrames,
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index e0a04c3..8bb6aee 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -20,11 +20,11 @@
#include <stdint.h>
#include <media/AudioTrack.h>
-
#include <aaudio/AAudio.h>
-#include "AudioClock.h"
-#include "AudioStreamTrack.h"
+#include "utility/AudioClock.h"
+#include "AudioStreamTrack.h"
+#include "utility/AAudioUtilities.h"
using namespace android;
using namespace aaudio;
@@ -292,3 +292,29 @@
}
return AudioStream::getFramesRead();
}
+
+aaudio_result_t AudioStreamTrack::getTimestamp(clockid_t clockId,
+ int64_t *framePosition,
+ int64_t *timeNanoseconds) {
+ ExtendedTimestamp extendedTimestamp;
+ status_t status = mAudioTrack->getTimestamp(&extendedTimestamp);
+ if (status != NO_ERROR) {
+ return AAudioConvert_androidToAAudioResult(status);
+ }
+ // TODO Merge common code into AudioStreamLegacy after rebasing.
+ int timebase;
+ switch(clockId) {
+ case CLOCK_BOOTTIME:
+ timebase = ExtendedTimestamp::TIMEBASE_BOOTTIME;
+ break;
+ case CLOCK_MONOTONIC:
+ timebase = ExtendedTimestamp::TIMEBASE_MONOTONIC;
+ break;
+ default:
+ ALOGE("getTimestamp() - Unrecognized clock type %d", (int) clockId);
+ return AAUDIO_ERROR_UNEXPECTED_VALUE;
+ break;
+ }
+ status = extendedTimestamp.getBestTimestamp(framePosition, timeNanoseconds, timebase);
+ return AAudioConvert_androidToAAudioResult(status);
+}
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.h b/media/libaaudio/src/legacy/AudioStreamTrack.h
index 1de07ce..7a53022 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.h
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.h
@@ -47,9 +47,7 @@
virtual aaudio_result_t getTimestamp(clockid_t clockId,
int64_t *framePosition,
- int64_t *timeNanoseconds) override {
- return AAUDIO_ERROR_UNIMPLEMENTED; // TODO call getTimestamp(ExtendedTimestamp *timestamp);
- }
+ int64_t *timeNanoseconds) override;
virtual aaudio_result_t write(const void *buffer,
int32_t numFrames,