1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <utils/Errors.h> 20 21 #include <aidl/android/hardware/audio/effect/BpEffect.h> 22 #include <fmq/AidlMessageQueue.h> 23 #include <system/audio_effect.h> 24 #include <system/audio_effects/audio_effects_utils.h> 25 26 namespace android { 27 namespace effect { 28 29 class EffectConversionHelperAidl { 30 public: 31 status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize, 32 void* pReplyData); ~EffectConversionHelperAidl()33 virtual ~EffectConversionHelperAidl() {} 34 35 using StatusMQ = ::android::AidlMessageQueue< 36 ::aidl::android::hardware::audio::effect::IEffect::Status, 37 ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>; 38 using DataMQ = ::android::AidlMessageQueue< 39 float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>; getStatusMQ()40 std::shared_ptr<StatusMQ> getStatusMQ() { return mStatusQ; } getInputMQ()41 std::shared_ptr<DataMQ> getInputMQ() { return mInputQ; } getOutputMQ()42 std::shared_ptr<DataMQ> getOutputMQ() { return mOutputQ; } getEventFlagGroup()43 std::shared_ptr<android::hardware::EventFlag> getEventFlagGroup() { return mEfGroup; } 44 bool isBypassing() const; 45 46 ::aidl::android::hardware::audio::effect::Descriptor getDescriptor() const; 47 48 protected: 49 const int32_t mSessionId; 50 const int32_t mIoId; 51 const ::aidl::android::hardware::audio::effect::Descriptor mDesc; 52 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect; 53 // whether the effect is instantiated on an input stream 54 const bool mIsInputStream; 55 ::aidl::android::hardware::audio::effect::Parameter::Common mCommon; 56 57 EffectConversionHelperAidl( 58 std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect, 59 int32_t sessionId, int32_t ioId, 60 const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxy); 61 62 status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 63 void* pReplyData); 64 status_t handleGetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 65 void* pReplyData); 66 67 private: 68 const aidl::android::media::audio::common::AudioFormatDescription kDefaultFormatDescription = { 69 .type = aidl::android::media::audio::common::AudioFormatType::PCM, 70 .pcm = aidl::android::media::audio::common::PcmType::FLOAT_32_BIT}; 71 const bool mIsProxyEffect; 72 73 static constexpr int kDefaultframeCount = 0x100; 74 75 template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> numericPointerToString(T * pt)76 static inline std::string numericPointerToString(T* pt) { 77 return pt ? std::to_string(*pt) : "nullptr"; 78 } 79 80 using AudioChannelLayout = aidl::android::media::audio::common::AudioChannelLayout; 81 const aidl::android::media::audio::common::AudioConfig kDefaultAudioConfig = { 82 .base = {.sampleRate = 44100, 83 .channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>( 84 AudioChannelLayout::LAYOUT_STEREO), 85 .format = kDefaultFormatDescription}, 86 .frameCount = kDefaultframeCount}; 87 // command handler map 88 typedef status_t (EffectConversionHelperAidl::*CommandHandler)(uint32_t /* cmdSize */, 89 const void* /* pCmdData */, 90 uint32_t* /* replySize */, 91 void* /* pReplyData */); 92 static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap; 93 // data and status FMQ 94 std::shared_ptr<StatusMQ> mStatusQ = nullptr; 95 std::shared_ptr<DataMQ> mInputQ = nullptr, mOutputQ = nullptr; 96 97 98 struct EventFlagDeleter { operatorEventFlagDeleter99 void operator()(::android::hardware::EventFlag* flag) const { 100 if (flag) { 101 ::android::hardware::EventFlag::deleteEventFlag(&flag); 102 } 103 } 104 }; 105 std::shared_ptr<android::hardware::EventFlag> mEfGroup = nullptr; 106 status_t updateEventFlags(); 107 108 status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 109 void* pReplyData); 110 status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 111 void* pReplyData); 112 status_t handleGetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 113 void* pReplyData); 114 status_t handleEnable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 115 void* pReplyData); 116 status_t handleDisable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 117 void* pReplyData); 118 status_t handleReset(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 119 void* pReplyData); 120 status_t handleSetAudioSource(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 121 void* pReplyData); 122 status_t handleSetAudioMode(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 123 void* pReplyData); 124 status_t handleSetDevice(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 125 void* pReplyData); 126 status_t handleSetVolume(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 127 void* pReplyData); 128 status_t handleSetOffload(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 129 void* pReplyData); 130 status_t handleVisualizerCapture(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 131 void* pReplyData); 132 status_t handleVisualizerMeasure(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 133 void* pReplyData); 134 135 // implemented by conversion of each effect 136 virtual status_t setParameter(utils::EffectParamReader& param) = 0; 137 virtual status_t getParameter(utils::EffectParamWriter& param) = 0; visualizerCapture(uint32_t * replySize __unused,void * pReplyData __unused)138 virtual status_t visualizerCapture(uint32_t* replySize __unused, void* pReplyData __unused) { 139 return BAD_VALUE; 140 } visualizerMeasure(uint32_t * replySize __unused,void * pReplyData __unused)141 virtual status_t visualizerMeasure(uint32_t* replySize __unused, void* pReplyData __unused) { 142 return BAD_VALUE; 143 } 144 }; 145 146 } // namespace effect 147 } // namespace android 148