summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-07-21 20:17:55 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-07-21 20:17:55 +0000
commitc43f00402151642661c29968c40843a242765194 (patch)
treecd2e595133402ce536bbaf5c3522975bcad17b83
parent2832e3fff0df6a6692aa19954e808d10243cabe5 (diff)
parent449875fdd48ca7fc5d01faeb932d0b8a5f775701 (diff)
downloadgoldfish-android13-mainline-go-wifi-release.tar.gz
Snap for 8857176 from 449875fdd48ca7fc5d01faeb932d0b8a5f775701 to mainline-go-wifi-releaseaml_go_wif_330911000android13-mainline-go-wifi-release
Change-Id: I563fb9c021c99b639f6964f0dab20725991174a9
-rw-r--r--audio/device_port_sink.cpp39
-rw-r--r--audio/device_port_sink.h1
-rw-r--r--audio/device_port_source.cpp10
-rw-r--r--audio/stream_out.cpp17
-rw-r--r--audio/talsa.cpp12
-rw-r--r--audio/talsa.h4
-rw-r--r--emulator-info.txt2
7 files changed, 72 insertions, 13 deletions
diff --git a/audio/device_port_sink.cpp b/audio/device_port_sink.cpp
index 3936805d..a42f6926 100644
--- a/audio/device_port_sink.cpp
+++ b/audio/device_port_sink.cpp
@@ -46,6 +46,13 @@ namespace {
constexpr int kMaxJitterUs = 3000; // Enforced by CTS, should be <= 6ms
struct TinyalsaSink : public DevicePortSink {
+ // Mostly magic numbers.
+ // In pcm, the hardware works with `period_size` granularity.
+ // The `period_count` is the number of `period_size` units in the pcm
+ // buffer.
+ static constexpr size_t kPcmPeriodCount = 8;
+ static constexpr size_t kPcmPeriodSizeMultiplier = 2;
+
TinyalsaSink(unsigned pcmCard, unsigned pcmDevice,
const AudioConfig &cfg,
uint64_t &frames)
@@ -60,7 +67,8 @@ struct TinyalsaSink : public DevicePortSink {
, mPcm(talsa::pcmOpen(pcmCard, pcmDevice,
util::countChannels(cfg.base.channelMask),
cfg.base.sampleRateHz,
- cfg.frameCount,
+ kPcmPeriodCount,
+ kPcmPeriodSizeMultiplier * cfg.frameCount / kPcmPeriodCount,
true /* isOut */)) {
if (mPcm) {
LOG_ALWAYS_FATAL_IF(!talsa::pcmPrepare(mPcm.get()));
@@ -75,6 +83,15 @@ struct TinyalsaSink : public DevicePortSink {
mConsumeThread.join();
}
+ static int getLatencyMs(const AudioConfig &cfg) {
+ constexpr size_t inMs = 1000;
+ const size_t numerator = kPcmPeriodSizeMultiplier * cfg.frameCount;
+ const size_t denominator = kPcmPeriodCount * cfg.base.sampleRateHz / inMs;
+
+ // integer division with rounding
+ return (numerator + (denominator >> 1)) / denominator;
+ }
+
Result getPresentationPosition(uint64_t &frames, TimeSpec &ts) override {
const AutoMutex lock(mFrameCountersMutex);
@@ -244,6 +261,10 @@ struct NullSink : public DevicePortSink {
, mInitialFrames(frames)
, mFrames(frames) {}
+ static int getLatencyMs(const AudioConfig &) {
+ return 1;
+ }
+
Result getPresentationPosition(uint64_t &frames, TimeSpec &ts) override {
const AutoMutex lock(mFrameCountersMutex);
@@ -377,6 +398,22 @@ nullsink:
return NullSink::create(cfg, readerBufferSizeHint, frames);
}
+int DevicePortSink::getLatencyMs(const DeviceAddress &address, const AudioConfig &cfg) {
+ switch (xsd::stringToAudioDevice(address.deviceType)) {
+ default:
+ ALOGW("%s:%d unsupported device: '%s'", __func__, __LINE__, address.deviceType.c_str());
+ return FAILURE(-1);
+
+ case xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT:
+ case xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER:
+ return TinyalsaSink::getLatencyMs(cfg);
+
+ case xsd::AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX:
+ case xsd::AudioDevice::AUDIO_DEVICE_OUT_BUS:
+ return NullSink::getLatencyMs(cfg);
+ }
+}
+
bool DevicePortSink::validateDeviceAddress(const DeviceAddress& address) {
switch (xsd::stringToAudioDevice(address.deviceType)) {
default:
diff --git a/audio/device_port_sink.h b/audio/device_port_sink.h
index 0276b25a..9e9e3c5a 100644
--- a/audio/device_port_sink.h
+++ b/audio/device_port_sink.h
@@ -40,6 +40,7 @@ struct DevicePortSink {
const hidl_vec<AudioInOutFlag> &,
uint64_t &frames);
+ static int getLatencyMs(const DeviceAddress &, const AudioConfig &);
static bool validateDeviceAddress(const DeviceAddress &);
};
diff --git a/audio/device_port_source.cpp b/audio/device_port_source.cpp
index e4c4528b..c3d9b846 100644
--- a/audio/device_port_source.cpp
+++ b/audio/device_port_source.cpp
@@ -50,6 +50,13 @@ namespace {
constexpr int kMaxJitterUs = 3000; // Enforced by CTS, should be <= 6ms
struct TinyalsaSource : public DevicePortSource {
+ // Mostly magic numbers.
+ // In pcm, the hardware works with `period_size` granularity.
+ // The `period_count` is the number of `period_size` units in the pcm
+ // buffer.
+ static constexpr size_t kPcmPeriodCount = 8;
+ static constexpr size_t kPcmPeriodSizeMultiplier = 2;
+
TinyalsaSource(unsigned pcmCard, unsigned pcmDevice,
const AudioConfig &cfg, uint64_t &frames)
: mStartNs(systemTime(SYSTEM_TIME_MONOTONIC))
@@ -62,7 +69,8 @@ struct TinyalsaSource : public DevicePortSource {
, mPcm(talsa::pcmOpen(pcmCard, pcmDevice,
util::countChannels(cfg.base.channelMask),
cfg.base.sampleRateHz,
- cfg.frameCount,
+ kPcmPeriodCount,
+ kPcmPeriodSizeMultiplier * cfg.frameCount / kPcmPeriodCount,
false /* isOut */)) {
if (mPcm) {
LOG_ALWAYS_FATAL_IF(!talsa::pcmPrepare(mPcm.get()));
diff --git a/audio/stream_out.cpp b/audio/stream_out.cpp
index 0c8e518f..1eabed37 100644
--- a/audio/stream_out.cpp
+++ b/audio/stream_out.cpp
@@ -212,8 +212,16 @@ struct WriteThread : public IOThread {
IStreamOut::WriteStatus doGetLatency() {
IStreamOut::WriteStatus status;
- status.retval = Result::OK;
- status.reply.latencyMs = mStream->getLatency();
+ const int latencyMs =
+ DevicePortSink::getLatencyMs(mStream->getDeviceAddress(),
+ mStream->getAudioConfig());
+
+ if (latencyMs >= 0) {
+ status.retval = Result::OK;
+ status.reply.latencyMs = latencyMs;
+ } else {
+ status.retval = Result::INVALID_STATE;
+ }
return status;
}
@@ -358,7 +366,10 @@ Return<void> StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) {
}
Return<uint32_t> StreamOut::getLatency() {
- return mCommon.getFrameCount() * 1000 / mCommon.getSampleRate();
+ const int latencyMs = DevicePortSink::getLatencyMs(getDeviceAddress(), getAudioConfig());
+
+ return (latencyMs >= 0) ? latencyMs :
+ (mCommon.getFrameCount() * 1000 / mCommon.getSampleRate());
}
Return<Result> StreamOut::setVolume(float left, float right) {
diff --git a/audio/talsa.cpp b/audio/talsa.cpp
index 4bc0c4f6..a0fc73cb 100644
--- a/audio/talsa.cpp
+++ b/audio/talsa.cpp
@@ -105,16 +105,16 @@ std::unique_ptr<pcm_t, PcmDeleter> pcmOpen(const unsigned int dev,
const unsigned int card,
const unsigned int nChannels,
const size_t sampleRateHz,
- const size_t frameCount,
+ const size_t periodCount,
+ const size_t periodSize,
const bool isOut) {
struct pcm_config pcm_config;
memset(&pcm_config, 0, sizeof(pcm_config));
pcm_config.channels = nChannels;
pcm_config.rate = sampleRateHz;
- pcm_config.period_count = 8; // Approx interrupts per buffer
- // Approx frames between interrupts
- pcm_config.period_size = 2 * frameCount / pcm_config.period_count;
+ pcm_config.period_count = periodCount; // Approx interrupts per buffer
+ pcm_config.period_size = periodSize; // Approx frames between interrupts
pcm_config.format = PCM_FORMAT_S16_LE;
PcmPtr pcm =
@@ -125,8 +125,8 @@ std::unique_ptr<pcm_t, PcmDeleter> pcmOpen(const unsigned int dev,
return pcm;
} else {
ALOGE("%s:%d pcm_open failed for nChannels=%u sampleRateHz=%zu "
- "frameCount=%zu isOut=%d with %s", __func__, __LINE__,
- nChannels, sampleRateHz, frameCount, isOut,
+ "period_count=%zu period_size=%zu isOut=%d with %s", __func__, __LINE__,
+ nChannels, sampleRateHz, periodCount, periodSize, isOut,
pcm_get_error(pcm.get()));
return FAILURE(nullptr);
}
diff --git a/audio/talsa.h b/audio/talsa.h
index c77b08f3..60241584 100644
--- a/audio/talsa.h
+++ b/audio/talsa.h
@@ -31,7 +31,9 @@ constexpr unsigned int kPcmCard = 0;
typedef struct pcm pcm_t;
struct PcmDeleter { void operator()(pcm_t *x) const; };
typedef std::unique_ptr<pcm_t, PcmDeleter> PcmPtr;
-PcmPtr pcmOpen(unsigned int dev, unsigned int card, unsigned int nChannels, size_t sampleRateHz, size_t frameCount, bool isOut);
+PcmPtr pcmOpen(unsigned int dev, unsigned int card, unsigned int nChannels,
+ size_t sampleRateHz, size_t periodCount, size_t periodSize,
+ bool isOut);
bool pcmPrepare(pcm_t *pcm);
bool pcmStart(pcm_t *pcm);
bool pcmStop(pcm_t *pcm);
diff --git a/emulator-info.txt b/emulator-info.txt
index 13def537..43c68fc3 100644
--- a/emulator-info.txt
+++ b/emulator-info.txt
@@ -1,2 +1,2 @@
# Emulator (stable) version
-require version-emulator=8681204
+require version-emulator=8735603