diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-07-21 20:17:55 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-07-21 20:17:55 +0000 |
commit | c43f00402151642661c29968c40843a242765194 (patch) | |
tree | cd2e595133402ce536bbaf5c3522975bcad17b83 | |
parent | 2832e3fff0df6a6692aa19954e808d10243cabe5 (diff) | |
parent | 449875fdd48ca7fc5d01faeb932d0b8a5f775701 (diff) | |
download | goldfish-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.cpp | 39 | ||||
-rw-r--r-- | audio/device_port_sink.h | 1 | ||||
-rw-r--r-- | audio/device_port_source.cpp | 10 | ||||
-rw-r--r-- | audio/stream_out.cpp | 17 | ||||
-rw-r--r-- | audio/talsa.cpp | 12 | ||||
-rw-r--r-- | audio/talsa.h | 4 | ||||
-rw-r--r-- | emulator-info.txt | 2 |
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 |