Loading services/audiopolicy/service/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ cc_library_shared { "libsensorprivacy", "libshmemcompat", "libutils", "libstagefright_foundation", "android.media.audio.common.types-V1-cpp", "audioclient-types-aidl-cpp", "audioflinger-aidl-cpp", Loading services/audiopolicy/service/Spatializer.cpp +138 −9 Original line number Diff line number Diff line Loading @@ -29,8 +29,10 @@ #include <audio_utils/fixedfft.h> #include <cutils/bitops.h> #include <hardware/sensors.h> #include <media/ShmemCompat.h> #include <media/audiohal/EffectsFactoryHalInterface.h> #include <media/stagefright/foundation/AHandler.h> #include <media/stagefright/foundation/AMessage.h> #include <media/ShmemCompat.h> #include <mediautils/ServiceUtilities.h> #include <utils/Thread.h> Loading @@ -49,7 +51,6 @@ using media::SpatializationMode; using media::SpatializerHeadTrackingMode; using media::SensorPoseProvider; using namespace std::chrono_literals; #define VALUE_OR_RETURN_BINDER_STATUS(x) \ Loading @@ -65,6 +66,90 @@ using namespace std::chrono_literals; // --------------------------------------------------------------------------- class Spatializer::EngineCallbackHandler : public AHandler { public: EngineCallbackHandler(wp<Spatializer> spatializer) : mSpatializer(spatializer) { } enum { // Device state callbacks kWhatOnFramesProcessed, // AudioEffect::EVENT_FRAMES_PROCESSED kWhatOnHeadToStagePose, // SpatializerPoseController::Listener::onHeadToStagePose kWhatOnActualModeChange, // SpatializerPoseController::Listener::onActualModeChange }; static constexpr const char *kNumFramesKey = "numFrames"; static constexpr const char *kModeKey = "mode"; static constexpr const char *kTranslation0Key = "translation0"; static constexpr const char *kTranslation1Key = "translation1"; static constexpr const char *kTranslation2Key = "translation2"; static constexpr const char *kRotation0Key = "rotation0"; static constexpr const char *kRotation1Key = "rotation1"; static constexpr const char *kRotation2Key = "rotation2"; void onMessageReceived(const sp<AMessage> &msg) override { switch (msg->what()) { case kWhatOnFramesProcessed: { sp<Spatializer> spatializer = mSpatializer.promote(); if (spatializer == nullptr) { ALOGW("%s: Cannot promote spatializer", __func__); return; } int numFrames; if (!msg->findInt32(kNumFramesKey, &numFrames)) { ALOGE("%s: Cannot find num frames!", __func__); return; } if (numFrames > 0) { spatializer->calculateHeadPose(); } } break; case kWhatOnHeadToStagePose: { sp<Spatializer> spatializer = mSpatializer.promote(); if (spatializer == nullptr) { ALOGW("%s: Cannot promote spatializer", __func__); return; } std::vector<float> headToStage(sHeadPoseKeys.size()); for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) { if (!msg->findFloat(sHeadPoseKeys[i], &headToStage[i])) { ALOGE("%s: Cannot find kTranslation0Key!", __func__); return; } } spatializer->onHeadToStagePoseMsg(headToStage); } break; case kWhatOnActualModeChange: { sp<Spatializer> spatializer = mSpatializer.promote(); if (spatializer == nullptr) { ALOGW("%s: Cannot promote spatializer", __func__); return; } int mode; if (!msg->findInt32(EngineCallbackHandler::kModeKey, &mode)) { ALOGE("%s: Cannot find actualMode!", __func__); return; } spatializer->onActualModeChangeMsg(static_cast<HeadTrackingMode>(mode)); } break; default: LOG_ALWAYS_FATAL("Invalid callback message %d", msg->what()); } } private: wp<Spatializer> mSpatializer; }; const std::vector<const char *> Spatializer::sHeadPoseKeys = { Spatializer::EngineCallbackHandler::kTranslation0Key, Spatializer::EngineCallbackHandler::kTranslation1Key, Spatializer::EngineCallbackHandler::kTranslation2Key, Spatializer::EngineCallbackHandler::kRotation0Key, Spatializer::EngineCallbackHandler::kRotation1Key, Spatializer::EngineCallbackHandler::kRotation2Key, }; // --------------------------------------------------------------------------- sp<Spatializer> Spatializer::create(SpatializerPolicyCallback *callback) { sp<Spatializer> spatializer; Loading Loading @@ -107,8 +192,26 @@ Spatializer::Spatializer(effect_descriptor_t engineDescriptor, SpatializerPolicy ALOGV("%s", __func__); } void Spatializer::onFirstRef() { mLooper = new ALooper; mLooper->setName("Spatializer-looper"); mLooper->start( /*runOnCallingThread*/false, /*canCallJava*/ false, PRIORITY_AUDIO); mHandler = new EngineCallbackHandler(this); mLooper->registerHandler(mHandler); } Spatializer::~Spatializer() { ALOGV("%s", __func__); if (mLooper != nullptr) { mLooper->stop(); mLooper->unregisterHandler(mHandler->id()); } mLooper.clear(); mHandler.clear(); } status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) { Loading Loading @@ -391,23 +494,44 @@ Status Spatializer::getSupportedModes(std::vector<SpatializationMode> *modes) { // SpatializerPoseController::Listener void Spatializer::onHeadToStagePose(const Pose3f& headToStage) { ALOGV("%s", __func__); sp<media::INativeSpatializerCallback> callback; auto vec = headToStage.toVector(); LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(), "%s invalid head to stage vector size %zu", __func__, vec.size()); sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler); for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) { msg->setFloat(sHeadPoseKeys[i], vec[i]); } msg->post(); } void Spatializer::onHeadToStagePoseMsg(const std::vector<float>& headToStage) { ALOGV("%s", __func__); sp<media::INativeSpatializerCallback> callback; { std::lock_guard lock(mLock); callback = mSpatializerCallback; if (mEngine != nullptr) { setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, vec); setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage); } } if (callback != nullptr) { callback->onHeadToSoundStagePoseUpdated(vec); callback->onHeadToSoundStagePoseUpdated(headToStage); } } void Spatializer::onActualModeChange(HeadTrackingMode mode) { ALOGV("onActualModeChange(%d)", (int) mode); ALOGV("%s(%d)", __func__, (int)mode); sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler); msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode)); msg->post(); } void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) { ALOGV("%s(%d)", __func__, (int) mode); sp<media::INativeSpatializerCallback> callback; SpatializerHeadTrackingMode spatializerMode; { Loading Loading @@ -534,9 +658,7 @@ void Spatializer::engineCallback(int32_t event, void *user, void *info) { case AudioEffect::EVENT_FRAMES_PROCESSED: { int frames = info == nullptr ? 0 : *(int*)info; ALOGD("%s frames processed %d for me %p", __func__, frames, me); if (frames > 0) { me->calculateHeadPose(); } me->postFramesProcessedMsg(frames); } break; default: ALOGD("%s event %d", __func__, event); Loading @@ -544,6 +666,13 @@ void Spatializer::engineCallback(int32_t event, void *user, void *info) { } } void Spatializer::postFramesProcessedMsg(int frames) { sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnFramesProcessed, mHandler); msg->setInt32(EngineCallbackHandler::kNumFramesKey, frames); msg->post(); } // --------------------------------------------------------------------------- Spatializer::EffectClient::EffectClient(const sp<media::IEffectClient>& effectClient, Loading services/audiopolicy/service/Spatializer.h +19 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <android/media/SpatializerHeadTrackingMode.h> #include <android/sensor.h> #include <media/audiohal/EffectHalInterface.h> #include <media/stagefright/foundation/ALooper.h> #include <media/AudioEffect.h> #include <system/audio_effects/effect_spatializer.h> Loading Loading @@ -91,6 +92,9 @@ class Spatializer : public media::BnSpatializer, ~Spatializer() override; /** RefBase */ void onFirstRef(); /** ISpatializer, see ISpatializer.aidl */ binder::Status release() override; binder::Status getSupportedLevels(std::vector<media::SpatializationLevel>* levels) override; Loading Loading @@ -138,6 +142,8 @@ class Spatializer : public media::BnSpatializer, /** Gets the channel mask, sampling rate and format set for the spatializer input. */ audio_config_base_t getAudioInConfig() const; void calculateHeadPose(); /** An implementation of an IEffect interface that can be used to pass advanced parameters to * the spatializer engine. All APis are noop (i.e. the interface cannot be used to control * the effect) except for passing parameters via the command() API. */ Loading Loading @@ -176,7 +182,9 @@ private: void onHeadToStagePose(const media::Pose3f& headToStage) override; void onActualModeChange(media::HeadTrackingMode mode) override; void calculateHeadPose(); void onHeadToStagePoseMsg(const std::vector<float>& headToStage); void onActualModeChangeMsg(media::HeadTrackingMode mode); static ConversionResult<ASensorRef> getSensorFromHandle(int handle); Loading Loading @@ -251,6 +259,8 @@ private: return mEngine->setParameter(p); } void postFramesProcessedMsg(int frames); /** Effect engine descriptor */ const effect_descriptor_t mEngineDescriptor; /** Callback interface to parent audio policy service */ Loading Loading @@ -298,6 +308,14 @@ private: std::vector<media::SpatializationMode> mSpatializationModes; std::vector<audio_channel_mask_t> mChannelMasks; bool mSupportsHeadTracking; // Looper thread for mEngine callbacks class EngineCallbackHandler; sp<ALooper> mLooper; sp<EngineCallbackHandler> mHandler; static const std::vector<const char *> sHeadPoseKeys; }; Loading Loading
services/audiopolicy/service/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ cc_library_shared { "libsensorprivacy", "libshmemcompat", "libutils", "libstagefright_foundation", "android.media.audio.common.types-V1-cpp", "audioclient-types-aidl-cpp", "audioflinger-aidl-cpp", Loading
services/audiopolicy/service/Spatializer.cpp +138 −9 Original line number Diff line number Diff line Loading @@ -29,8 +29,10 @@ #include <audio_utils/fixedfft.h> #include <cutils/bitops.h> #include <hardware/sensors.h> #include <media/ShmemCompat.h> #include <media/audiohal/EffectsFactoryHalInterface.h> #include <media/stagefright/foundation/AHandler.h> #include <media/stagefright/foundation/AMessage.h> #include <media/ShmemCompat.h> #include <mediautils/ServiceUtilities.h> #include <utils/Thread.h> Loading @@ -49,7 +51,6 @@ using media::SpatializationMode; using media::SpatializerHeadTrackingMode; using media::SensorPoseProvider; using namespace std::chrono_literals; #define VALUE_OR_RETURN_BINDER_STATUS(x) \ Loading @@ -65,6 +66,90 @@ using namespace std::chrono_literals; // --------------------------------------------------------------------------- class Spatializer::EngineCallbackHandler : public AHandler { public: EngineCallbackHandler(wp<Spatializer> spatializer) : mSpatializer(spatializer) { } enum { // Device state callbacks kWhatOnFramesProcessed, // AudioEffect::EVENT_FRAMES_PROCESSED kWhatOnHeadToStagePose, // SpatializerPoseController::Listener::onHeadToStagePose kWhatOnActualModeChange, // SpatializerPoseController::Listener::onActualModeChange }; static constexpr const char *kNumFramesKey = "numFrames"; static constexpr const char *kModeKey = "mode"; static constexpr const char *kTranslation0Key = "translation0"; static constexpr const char *kTranslation1Key = "translation1"; static constexpr const char *kTranslation2Key = "translation2"; static constexpr const char *kRotation0Key = "rotation0"; static constexpr const char *kRotation1Key = "rotation1"; static constexpr const char *kRotation2Key = "rotation2"; void onMessageReceived(const sp<AMessage> &msg) override { switch (msg->what()) { case kWhatOnFramesProcessed: { sp<Spatializer> spatializer = mSpatializer.promote(); if (spatializer == nullptr) { ALOGW("%s: Cannot promote spatializer", __func__); return; } int numFrames; if (!msg->findInt32(kNumFramesKey, &numFrames)) { ALOGE("%s: Cannot find num frames!", __func__); return; } if (numFrames > 0) { spatializer->calculateHeadPose(); } } break; case kWhatOnHeadToStagePose: { sp<Spatializer> spatializer = mSpatializer.promote(); if (spatializer == nullptr) { ALOGW("%s: Cannot promote spatializer", __func__); return; } std::vector<float> headToStage(sHeadPoseKeys.size()); for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) { if (!msg->findFloat(sHeadPoseKeys[i], &headToStage[i])) { ALOGE("%s: Cannot find kTranslation0Key!", __func__); return; } } spatializer->onHeadToStagePoseMsg(headToStage); } break; case kWhatOnActualModeChange: { sp<Spatializer> spatializer = mSpatializer.promote(); if (spatializer == nullptr) { ALOGW("%s: Cannot promote spatializer", __func__); return; } int mode; if (!msg->findInt32(EngineCallbackHandler::kModeKey, &mode)) { ALOGE("%s: Cannot find actualMode!", __func__); return; } spatializer->onActualModeChangeMsg(static_cast<HeadTrackingMode>(mode)); } break; default: LOG_ALWAYS_FATAL("Invalid callback message %d", msg->what()); } } private: wp<Spatializer> mSpatializer; }; const std::vector<const char *> Spatializer::sHeadPoseKeys = { Spatializer::EngineCallbackHandler::kTranslation0Key, Spatializer::EngineCallbackHandler::kTranslation1Key, Spatializer::EngineCallbackHandler::kTranslation2Key, Spatializer::EngineCallbackHandler::kRotation0Key, Spatializer::EngineCallbackHandler::kRotation1Key, Spatializer::EngineCallbackHandler::kRotation2Key, }; // --------------------------------------------------------------------------- sp<Spatializer> Spatializer::create(SpatializerPolicyCallback *callback) { sp<Spatializer> spatializer; Loading Loading @@ -107,8 +192,26 @@ Spatializer::Spatializer(effect_descriptor_t engineDescriptor, SpatializerPolicy ALOGV("%s", __func__); } void Spatializer::onFirstRef() { mLooper = new ALooper; mLooper->setName("Spatializer-looper"); mLooper->start( /*runOnCallingThread*/false, /*canCallJava*/ false, PRIORITY_AUDIO); mHandler = new EngineCallbackHandler(this); mLooper->registerHandler(mHandler); } Spatializer::~Spatializer() { ALOGV("%s", __func__); if (mLooper != nullptr) { mLooper->stop(); mLooper->unregisterHandler(mHandler->id()); } mLooper.clear(); mHandler.clear(); } status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) { Loading Loading @@ -391,23 +494,44 @@ Status Spatializer::getSupportedModes(std::vector<SpatializationMode> *modes) { // SpatializerPoseController::Listener void Spatializer::onHeadToStagePose(const Pose3f& headToStage) { ALOGV("%s", __func__); sp<media::INativeSpatializerCallback> callback; auto vec = headToStage.toVector(); LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(), "%s invalid head to stage vector size %zu", __func__, vec.size()); sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler); for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) { msg->setFloat(sHeadPoseKeys[i], vec[i]); } msg->post(); } void Spatializer::onHeadToStagePoseMsg(const std::vector<float>& headToStage) { ALOGV("%s", __func__); sp<media::INativeSpatializerCallback> callback; { std::lock_guard lock(mLock); callback = mSpatializerCallback; if (mEngine != nullptr) { setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, vec); setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage); } } if (callback != nullptr) { callback->onHeadToSoundStagePoseUpdated(vec); callback->onHeadToSoundStagePoseUpdated(headToStage); } } void Spatializer::onActualModeChange(HeadTrackingMode mode) { ALOGV("onActualModeChange(%d)", (int) mode); ALOGV("%s(%d)", __func__, (int)mode); sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler); msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode)); msg->post(); } void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) { ALOGV("%s(%d)", __func__, (int) mode); sp<media::INativeSpatializerCallback> callback; SpatializerHeadTrackingMode spatializerMode; { Loading Loading @@ -534,9 +658,7 @@ void Spatializer::engineCallback(int32_t event, void *user, void *info) { case AudioEffect::EVENT_FRAMES_PROCESSED: { int frames = info == nullptr ? 0 : *(int*)info; ALOGD("%s frames processed %d for me %p", __func__, frames, me); if (frames > 0) { me->calculateHeadPose(); } me->postFramesProcessedMsg(frames); } break; default: ALOGD("%s event %d", __func__, event); Loading @@ -544,6 +666,13 @@ void Spatializer::engineCallback(int32_t event, void *user, void *info) { } } void Spatializer::postFramesProcessedMsg(int frames) { sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnFramesProcessed, mHandler); msg->setInt32(EngineCallbackHandler::kNumFramesKey, frames); msg->post(); } // --------------------------------------------------------------------------- Spatializer::EffectClient::EffectClient(const sp<media::IEffectClient>& effectClient, Loading
services/audiopolicy/service/Spatializer.h +19 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <android/media/SpatializerHeadTrackingMode.h> #include <android/sensor.h> #include <media/audiohal/EffectHalInterface.h> #include <media/stagefright/foundation/ALooper.h> #include <media/AudioEffect.h> #include <system/audio_effects/effect_spatializer.h> Loading Loading @@ -91,6 +92,9 @@ class Spatializer : public media::BnSpatializer, ~Spatializer() override; /** RefBase */ void onFirstRef(); /** ISpatializer, see ISpatializer.aidl */ binder::Status release() override; binder::Status getSupportedLevels(std::vector<media::SpatializationLevel>* levels) override; Loading Loading @@ -138,6 +142,8 @@ class Spatializer : public media::BnSpatializer, /** Gets the channel mask, sampling rate and format set for the spatializer input. */ audio_config_base_t getAudioInConfig() const; void calculateHeadPose(); /** An implementation of an IEffect interface that can be used to pass advanced parameters to * the spatializer engine. All APis are noop (i.e. the interface cannot be used to control * the effect) except for passing parameters via the command() API. */ Loading Loading @@ -176,7 +182,9 @@ private: void onHeadToStagePose(const media::Pose3f& headToStage) override; void onActualModeChange(media::HeadTrackingMode mode) override; void calculateHeadPose(); void onHeadToStagePoseMsg(const std::vector<float>& headToStage); void onActualModeChangeMsg(media::HeadTrackingMode mode); static ConversionResult<ASensorRef> getSensorFromHandle(int handle); Loading Loading @@ -251,6 +259,8 @@ private: return mEngine->setParameter(p); } void postFramesProcessedMsg(int frames); /** Effect engine descriptor */ const effect_descriptor_t mEngineDescriptor; /** Callback interface to parent audio policy service */ Loading Loading @@ -298,6 +308,14 @@ private: std::vector<media::SpatializationMode> mSpatializationModes; std::vector<audio_channel_mask_t> mChannelMasks; bool mSupportsHeadTracking; // Looper thread for mEngine callbacks class EngineCallbackHandler; sp<ALooper> mLooper; sp<EngineCallbackHandler> mHandler; static const std::vector<const char *> sHeadPoseKeys; }; Loading