Loading audio/aidl/default/Android.bp +15 −0 Original line number Diff line number Diff line Loading @@ -46,11 +46,20 @@ cc_library { "SoundDose.cpp", ], shared_libs: [ "libaudio_aidl_conversion_common_ndk", "libaudioutils", "libbase", "libbinder_ndk", "libcutils", "libutils", ], cflags: [ "-Wall", "-Wextra", "-Werror", "-Wthread-safety", "-DBACKEND_NDK", ], visibility: [ "//hardware/interfaces/audio/aidl/sounddose/default", ], Loading Loading @@ -111,8 +120,12 @@ cc_library { shared_libs: [ "android.hardware.bluetooth.audio-V3-ndk", "libaudio_aidl_conversion_common_ndk", "libaudioutils", "libaudioutils_nonvndk", "libbluetooth_audio_session_aidl", "liblog", "libmedia_helper", "libmediautils_vendor", "libstagefright_foundation", ], export_shared_lib_headers: [ Loading Loading @@ -143,8 +156,10 @@ cc_binary { ], shared_libs: [ "android.hardware.bluetooth.audio-V3-ndk", "libaudioutils_nonvndk", "libaudio_aidl_conversion_common_ndk", "libbluetooth_audio_session_aidl", "liblog", "libmedia_helper", "libstagefright_foundation", ], Loading audio/aidl/default/Module.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -213,6 +213,11 @@ ndk::ScopedAStatus Module::createStreamContext( StreamContext::DebugParameters params{mDebug.streamTransientStateDelayMs, mVendorDebug.forceTransientBurst, mVendorDebug.forceSynchronousDrain}; std::shared_ptr<ISoundDose> soundDose; if (!getSoundDose(&soundDose).isOk()) { LOG(ERROR) << __func__ << ": could not create sound dose instance"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } StreamContext temp( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), Loading @@ -220,7 +225,7 @@ ndk::ScopedAStatus Module::createStreamContext( portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, params); asyncCallback, outEventCallback, mSoundDose.getInstance(), params); if (temp.isValid()) { *out_context = std::move(temp); } else { Loading audio/aidl/default/SoundDose.cpp +89 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,15 @@ #include "core-impl/SoundDose.h" #include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h> #include <android-base/logging.h> #include <media/AidlConversionCppNdk.h> #include <utils/Timers.h> using aidl::android::hardware::audio::core::sounddose::ISoundDose; using aidl::android::media::audio::common::AudioDevice; using aidl::android::media::audio::common::AudioDeviceDescription; using aidl::android::media::audio::common::AudioFormatDescription; namespace aidl::android::hardware::audio::core::sounddose { Loading @@ -28,11 +36,16 @@ ndk::ScopedAStatus SoundDose::setOutputRs2UpperBound(float in_rs2ValueDbA) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } ::android::audio_utils::lock_guard l(mMutex); mRs2Value = in_rs2ValueDbA; if (mMelProcessor != nullptr) { mMelProcessor->setOutputRs2UpperBound(in_rs2ValueDbA); } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus SoundDose::getOutputRs2UpperBound(float* _aidl_return) { ::android::audio_utils::lock_guard l(mMutex); *_aidl_return = mRs2Value; LOG(DEBUG) << __func__ << ": returning " << *_aidl_return; return ndk::ScopedAStatus::ok(); Loading @@ -44,6 +57,8 @@ ndk::ScopedAStatus SoundDose::registerSoundDoseCallback( LOG(ERROR) << __func__ << ": Callback is nullptr"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } ::android::audio_utils::lock_guard l(mCbMutex); if (mCallback != nullptr) { LOG(ERROR) << __func__ << ": Sound dose callback was already registered"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); Loading @@ -51,7 +66,81 @@ ndk::ScopedAStatus SoundDose::registerSoundDoseCallback( mCallback = in_callback; LOG(DEBUG) << __func__ << ": Registered sound dose callback "; return ndk::ScopedAStatus::ok(); } void SoundDose::setAudioDevice(const AudioDevice& audioDevice) { ::android::audio_utils::lock_guard l(mCbMutex); mAudioDevice = audioDevice; } void SoundDose::startDataProcessor(uint32_t sampleRate, uint32_t channelCount, const AudioFormatDescription& aidlFormat) { ::android::audio_utils::lock_guard l(mMutex); const auto result = aidl2legacy_AudioFormatDescription_audio_format_t(aidlFormat); const audio_format_t format = result.value_or(AUDIO_FORMAT_INVALID); if (mMelProcessor == nullptr) { // we don't have the deviceId concept on the vendor side so just pass 0 mMelProcessor = ::android::sp<::android::audio_utils::MelProcessor>::make( sampleRate, channelCount, format, mMelCallback, /*deviceId=*/0, mRs2Value); } else { mMelProcessor->updateAudioFormat(sampleRate, channelCount, format); } } void SoundDose::process(const void* buffer, size_t bytes) { ::android::audio_utils::lock_guard l(mMutex); if (mMelProcessor != nullptr) { mMelProcessor->process(buffer, bytes); } } void SoundDose::onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length, audio_port_handle_t deviceId __attribute__((__unused__))) const { ::android::audio_utils::lock_guard l(mCbMutex); if (!mAudioDevice.has_value()) { LOG(WARNING) << __func__ << ": New mel values without a registered device"; return; } if (mCallback == nullptr) { LOG(ERROR) << __func__ << ": New mel values without a registered callback"; return; } ISoundDose::IHalSoundDoseCallback::MelRecord melRecord; melRecord.timestamp = nanoseconds_to_seconds(systemTime()); melRecord.melValues = std::vector<float>(mels.begin() + offset, mels.begin() + offset + length); mCallback->onNewMelValues(melRecord, mAudioDevice.value()); } void SoundDose::MelCallback::onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length, audio_port_handle_t deviceId __attribute__((__unused__))) const { mSoundDose.onNewMelValues(mels, offset, length, deviceId); } void SoundDose::onMomentaryExposure(float currentMel, audio_port_handle_t deviceId __attribute__((__unused__))) const { ::android::audio_utils::lock_guard l(mCbMutex); if (!mAudioDevice.has_value()) { LOG(WARNING) << __func__ << ": Momentary exposure without a registered device"; return; } if (mCallback == nullptr) { LOG(ERROR) << __func__ << ": Momentary exposure without a registered callback"; return; } mCallback->onMomentaryExposureWarning(currentMel, mAudioDevice.value()); } void SoundDose::MelCallback::onMomentaryExposure(float currentMel, audio_port_handle_t deviceId __attribute__((__unused__))) const { mSoundDose.onMomentaryExposure(currentMel, deviceId); } } // namespace aidl::android::hardware::audio::core::sounddose audio/aidl/default/Stream.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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. Loading audio/aidl/default/include/core-impl/Module.h +1 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,7 @@ class Module : public BnModule { bool mMicMute = false; bool mMasterMute = false; float mMasterVolume = 1.0f; ChildInterface<sounddose::ISoundDose> mSoundDose; ChildInterface<sounddose::SoundDose> mSoundDose; std::optional<bool> mIsMmapSupported; protected: Loading Loading
audio/aidl/default/Android.bp +15 −0 Original line number Diff line number Diff line Loading @@ -46,11 +46,20 @@ cc_library { "SoundDose.cpp", ], shared_libs: [ "libaudio_aidl_conversion_common_ndk", "libaudioutils", "libbase", "libbinder_ndk", "libcutils", "libutils", ], cflags: [ "-Wall", "-Wextra", "-Werror", "-Wthread-safety", "-DBACKEND_NDK", ], visibility: [ "//hardware/interfaces/audio/aidl/sounddose/default", ], Loading Loading @@ -111,8 +120,12 @@ cc_library { shared_libs: [ "android.hardware.bluetooth.audio-V3-ndk", "libaudio_aidl_conversion_common_ndk", "libaudioutils", "libaudioutils_nonvndk", "libbluetooth_audio_session_aidl", "liblog", "libmedia_helper", "libmediautils_vendor", "libstagefright_foundation", ], export_shared_lib_headers: [ Loading Loading @@ -143,8 +156,10 @@ cc_binary { ], shared_libs: [ "android.hardware.bluetooth.audio-V3-ndk", "libaudioutils_nonvndk", "libaudio_aidl_conversion_common_ndk", "libbluetooth_audio_session_aidl", "liblog", "libmedia_helper", "libstagefright_foundation", ], Loading
audio/aidl/default/Module.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -213,6 +213,11 @@ ndk::ScopedAStatus Module::createStreamContext( StreamContext::DebugParameters params{mDebug.streamTransientStateDelayMs, mVendorDebug.forceTransientBurst, mVendorDebug.forceSynchronousDrain}; std::shared_ptr<ISoundDose> soundDose; if (!getSoundDose(&soundDose).isOk()) { LOG(ERROR) << __func__ << ": could not create sound dose instance"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } StreamContext temp( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), Loading @@ -220,7 +225,7 @@ ndk::ScopedAStatus Module::createStreamContext( portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, params); asyncCallback, outEventCallback, mSoundDose.getInstance(), params); if (temp.isValid()) { *out_context = std::move(temp); } else { Loading
audio/aidl/default/SoundDose.cpp +89 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,15 @@ #include "core-impl/SoundDose.h" #include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h> #include <android-base/logging.h> #include <media/AidlConversionCppNdk.h> #include <utils/Timers.h> using aidl::android::hardware::audio::core::sounddose::ISoundDose; using aidl::android::media::audio::common::AudioDevice; using aidl::android::media::audio::common::AudioDeviceDescription; using aidl::android::media::audio::common::AudioFormatDescription; namespace aidl::android::hardware::audio::core::sounddose { Loading @@ -28,11 +36,16 @@ ndk::ScopedAStatus SoundDose::setOutputRs2UpperBound(float in_rs2ValueDbA) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } ::android::audio_utils::lock_guard l(mMutex); mRs2Value = in_rs2ValueDbA; if (mMelProcessor != nullptr) { mMelProcessor->setOutputRs2UpperBound(in_rs2ValueDbA); } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus SoundDose::getOutputRs2UpperBound(float* _aidl_return) { ::android::audio_utils::lock_guard l(mMutex); *_aidl_return = mRs2Value; LOG(DEBUG) << __func__ << ": returning " << *_aidl_return; return ndk::ScopedAStatus::ok(); Loading @@ -44,6 +57,8 @@ ndk::ScopedAStatus SoundDose::registerSoundDoseCallback( LOG(ERROR) << __func__ << ": Callback is nullptr"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } ::android::audio_utils::lock_guard l(mCbMutex); if (mCallback != nullptr) { LOG(ERROR) << __func__ << ": Sound dose callback was already registered"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); Loading @@ -51,7 +66,81 @@ ndk::ScopedAStatus SoundDose::registerSoundDoseCallback( mCallback = in_callback; LOG(DEBUG) << __func__ << ": Registered sound dose callback "; return ndk::ScopedAStatus::ok(); } void SoundDose::setAudioDevice(const AudioDevice& audioDevice) { ::android::audio_utils::lock_guard l(mCbMutex); mAudioDevice = audioDevice; } void SoundDose::startDataProcessor(uint32_t sampleRate, uint32_t channelCount, const AudioFormatDescription& aidlFormat) { ::android::audio_utils::lock_guard l(mMutex); const auto result = aidl2legacy_AudioFormatDescription_audio_format_t(aidlFormat); const audio_format_t format = result.value_or(AUDIO_FORMAT_INVALID); if (mMelProcessor == nullptr) { // we don't have the deviceId concept on the vendor side so just pass 0 mMelProcessor = ::android::sp<::android::audio_utils::MelProcessor>::make( sampleRate, channelCount, format, mMelCallback, /*deviceId=*/0, mRs2Value); } else { mMelProcessor->updateAudioFormat(sampleRate, channelCount, format); } } void SoundDose::process(const void* buffer, size_t bytes) { ::android::audio_utils::lock_guard l(mMutex); if (mMelProcessor != nullptr) { mMelProcessor->process(buffer, bytes); } } void SoundDose::onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length, audio_port_handle_t deviceId __attribute__((__unused__))) const { ::android::audio_utils::lock_guard l(mCbMutex); if (!mAudioDevice.has_value()) { LOG(WARNING) << __func__ << ": New mel values without a registered device"; return; } if (mCallback == nullptr) { LOG(ERROR) << __func__ << ": New mel values without a registered callback"; return; } ISoundDose::IHalSoundDoseCallback::MelRecord melRecord; melRecord.timestamp = nanoseconds_to_seconds(systemTime()); melRecord.melValues = std::vector<float>(mels.begin() + offset, mels.begin() + offset + length); mCallback->onNewMelValues(melRecord, mAudioDevice.value()); } void SoundDose::MelCallback::onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length, audio_port_handle_t deviceId __attribute__((__unused__))) const { mSoundDose.onNewMelValues(mels, offset, length, deviceId); } void SoundDose::onMomentaryExposure(float currentMel, audio_port_handle_t deviceId __attribute__((__unused__))) const { ::android::audio_utils::lock_guard l(mCbMutex); if (!mAudioDevice.has_value()) { LOG(WARNING) << __func__ << ": Momentary exposure without a registered device"; return; } if (mCallback == nullptr) { LOG(ERROR) << __func__ << ": Momentary exposure without a registered callback"; return; } mCallback->onMomentaryExposureWarning(currentMel, mAudioDevice.value()); } void SoundDose::MelCallback::onMomentaryExposure(float currentMel, audio_port_handle_t deviceId __attribute__((__unused__))) const { mSoundDose.onMomentaryExposure(currentMel, deviceId); } } // namespace aidl::android::hardware::audio::core::sounddose
audio/aidl/default/Stream.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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. Loading
audio/aidl/default/include/core-impl/Module.h +1 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,7 @@ class Module : public BnModule { bool mMicMute = false; bool mMasterMute = false; float mMasterVolume = 1.0f; ChildInterface<sounddose::ISoundDose> mSoundDose; ChildInterface<sounddose::SoundDose> mSoundDose; std::optional<bool> mIsMmapSupported; protected: Loading