From 3c8b6ce171e2805c02d914c4ac85542e06449b20 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 31 Oct 2023 11:20:30 -0700 Subject: [PATCH] CSD: Add default AIDL HAL implementation ** Partial upstream of ag/24854732. Only the interface part is ** included. This should enable the sound dose gts on cuttlefish devices. The sound dose HAL uses the internal MelProcessor to compute the MELs which are reported to the framework. Test: atest GtsAudioTestCases:SoundDoseTest Bug: 301527435 Change-Id: Ifc505a0171bc8b4d3f5cf65d950fa5c0f812087f Merged-In: Ifc505a0171bc8b4d3f5cf65d950fa5c0f812087f --- audio/aidl/default/Module.cpp | 3 ++- audio/aidl/default/Stream.cpp | 12 ++++++++++++ audio/aidl/default/include/core-impl/Module.h | 2 +- audio/aidl/default/include/core-impl/SoundDose.h | 16 ++++++++++++++-- audio/aidl/default/include/core-impl/Stream.h | 10 ++++++++++ .../default/include/core-impl/StreamPrimary.h | 4 ++++ audio/aidl/default/primary/StreamPrimary.cpp | 15 ++++++++++++++- 7 files changed, 57 insertions(+), 5 deletions(-) diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp index 10450099e1..a77397d5b6 100644 --- a/audio/aidl/default/Module.cpp +++ b/audio/aidl/default/Module.cpp @@ -242,7 +242,8 @@ ndk::ScopedAStatus Module::createStreamContext( portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, portConfigIt->ext.get().handle, std::make_unique(frameSize * in_bufferSizeFrames), - asyncCallback, outEventCallback, params); + asyncCallback, outEventCallback, + std::weak_ptr{}, params); if (temp.isValid()) { *out_context = std::move(temp); } else { diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp index f7298c0286..f00e35833a 100644 --- a/audio/aidl/default/Stream.cpp +++ b/audio/aidl/default/Stream.cpp @@ -90,6 +90,14 @@ bool StreamContext::isValid() const { return true; } +void StreamContext::startStreamDataProcessor() { + auto streamDataProcessor = mStreamDataProcessor.lock(); + if (streamDataProcessor != nullptr) { + streamDataProcessor->startDataProcessor(mSampleRate, getChannelCount(mChannelLayout), + mFormat); + } +} + void StreamContext::reset() { mCommandMQ.reset(); mReplyMQ.reset(); @@ -593,6 +601,10 @@ bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* rep fatal = true; LOG(ERROR) << __func__ << ": write failed: " << status; } + auto streamDataProcessor = mContext->getStreamDataProcessor().lock(); + if (streamDataProcessor != nullptr) { + streamDataProcessor->process(mDataBuffer.get(), actualFrameCount * frameSize); + } } else { if (mContext->getAsyncCallback() == nullptr) { usleep(3000); // Simulate blocking transfer delay. diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h index 718c07d973..d92d54bda1 100644 --- a/audio/aidl/default/include/core-impl/Module.h +++ b/audio/aidl/default/include/core-impl/Module.h @@ -175,7 +175,7 @@ class Module : public BnModule { bool mMicMute = false; bool mMasterMute = false; float mMasterVolume = 1.0f; - ChildInterface mSoundDose; + ChildInterface mSoundDose; std::optional mIsMmapSupported; protected: diff --git a/audio/aidl/default/include/core-impl/SoundDose.h b/audio/aidl/default/include/core-impl/SoundDose.h index 2a069d9bac..c0edc9fe22 100644 --- a/audio/aidl/default/include/core-impl/SoundDose.h +++ b/audio/aidl/default/include/core-impl/SoundDose.h @@ -20,11 +20,23 @@ #include #include - -using aidl::android::media::audio::common::AudioDevice; +#include namespace aidl::android::hardware::audio::core::sounddose { +// Interface used for processing the data received by a stream. +class StreamDataProcessorInterface { + public: + virtual ~StreamDataProcessorInterface() = default; + + virtual void startDataProcessor( + uint32_t samplerate, uint32_t channelCount, + const ::aidl::android::media::audio::common::AudioFormatDescription& format) = 0; + virtual void setAudioDevice( + const ::aidl::android::media::audio::common::AudioDevice& audioDevice) = 0; + virtual void process(const void* buffer, size_t size) = 0; +}; + class SoundDose : public BnSoundDose { public: SoundDose() : mRs2Value(DEFAULT_MAX_RS2){}; diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h index 88fddec233..daa920d9b5 100644 --- a/audio/aidl/default/include/core-impl/Stream.h +++ b/audio/aidl/default/include/core-impl/Stream.h @@ -44,6 +44,7 @@ #include #include "core-impl/ChildInterface.h" +#include "core-impl/SoundDose.h" #include "core-impl/utils.h" namespace aidl::android::hardware::audio::core { @@ -87,6 +88,7 @@ class StreamContext { int32_t mixPortHandle, std::unique_ptr dataMQ, std::shared_ptr asyncCallback, std::shared_ptr outEventCallback, + std::weak_ptr streamDataProcessor, DebugParameters debugParameters) : mCommandMQ(std::move(commandMQ)), mInternalCommandCookie(std::rand()), @@ -100,6 +102,7 @@ class StreamContext { mDataMQ(std::move(dataMQ)), mAsyncCallback(asyncCallback), mOutEventCallback(outEventCallback), + mStreamDataProcessor(streamDataProcessor), mDebugParameters(debugParameters) {} StreamContext(StreamContext&& other) : mCommandMQ(std::move(other.mCommandMQ)), @@ -114,6 +117,7 @@ class StreamContext { mDataMQ(std::move(other.mDataMQ)), mAsyncCallback(std::move(other.mAsyncCallback)), mOutEventCallback(std::move(other.mOutEventCallback)), + mStreamDataProcessor(std::move(other.mStreamDataProcessor)), mDebugParameters(std::move(other.mDebugParameters)), mFrameCount(other.mFrameCount) {} StreamContext& operator=(StreamContext&& other) { @@ -129,6 +133,7 @@ class StreamContext { mDataMQ = std::move(other.mDataMQ); mAsyncCallback = std::move(other.mAsyncCallback); mOutEventCallback = std::move(other.mOutEventCallback); + mStreamDataProcessor = std::move(other.mStreamDataProcessor); mDebugParameters = std::move(other.mDebugParameters); mFrameCount = other.mFrameCount; return *this; @@ -154,6 +159,10 @@ class StreamContext { std::shared_ptr getOutEventCallback() const { return mOutEventCallback; } + std::weak_ptr getStreamDataProcessor() const { + return mStreamDataProcessor; + } + void startStreamDataProcessor(); int getPortId() const { return mPortId; } ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); } int getTransientStateDelayMs() const { return mDebugParameters.transientStateDelayMs; } @@ -179,6 +188,7 @@ class StreamContext { std::unique_ptr mDataMQ; std::shared_ptr mAsyncCallback; std::shared_ptr mOutEventCallback; // Only used by output streams + std::weak_ptr mStreamDataProcessor; DebugParameters mDebugParameters; long mFrameCount = 0; }; diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h index b3ddd0bd53..b64b749ec5 100644 --- a/audio/aidl/default/include/core-impl/StreamPrimary.h +++ b/audio/aidl/default/include/core-impl/StreamPrimary.h @@ -79,6 +79,10 @@ class StreamOutPrimary final : public StreamOut, ndk::ScopedAStatus getHwVolume(std::vector* _aidl_return) override; ndk::ScopedAStatus setHwVolume(const std::vector& in_channelVolumes) override; + + ndk::ScopedAStatus setConnectedDevices( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) + override; }; } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp index e01be8a3c6..17de2baf7a 100644 --- a/audio/aidl/default/primary/StreamPrimary.cpp +++ b/audio/aidl/default/primary/StreamPrimary.cpp @@ -37,7 +37,9 @@ using android::base::GetBoolProperty; namespace aidl::android::hardware::audio::core { StreamPrimary::StreamPrimary(StreamContext* context, const Metadata& metadata) - : StreamAlsa(context, metadata, 3 /*readWriteRetries*/), mIsInput(isInput(metadata)) {} + : StreamAlsa(context, metadata, 3 /*readWriteRetries*/), mIsInput(isInput(metadata)) { + context->startStreamDataProcessor(); +} std::vector StreamPrimary::getDeviceProfiles() { static const std::vector kBuiltInSource{ @@ -183,4 +185,15 @@ ndk::ScopedAStatus StreamOutPrimary::setHwVolume(const std::vector& in_ch return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus StreamOutPrimary::setConnectedDevices( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) { + if (!devices.empty()) { + auto streamDataProcessor = mContextInstance.getStreamDataProcessor().lock(); + if (streamDataProcessor != nullptr) { + streamDataProcessor->setAudioDevice(devices[0]); + } + } + return StreamSwitcher::setConnectedDevices(devices); +} + } // namespace aidl::android::hardware::audio::core