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 45 bool isBypassing() const; 46 bool isTunnel() const; 47 bool isBypassingOrTunnel() const; 48 49 ::aidl::android::hardware::audio::effect::Descriptor getDescriptor() const; 50 status_t reopen(); 51 52 size_t getAudioChannelCount() const; 53 size_t getHapticChannelCount() const; 54 55 uint8_t mOutputAccessMode = EFFECT_BUFFER_ACCESS_WRITE; 56 57 protected: 58 const int32_t mSessionId; 59 const int32_t mIoId; 60 const ::aidl::android::hardware::audio::effect::Descriptor mDesc; 61 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect; 62 // whether the effect is instantiated on an input stream 63 const bool mIsInputStream; 64 ::aidl::android::hardware::audio::effect::Parameter::Common mCommon; 65 66 EffectConversionHelperAidl( 67 std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect, 68 int32_t sessionId, int32_t ioId, 69 const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxy); 70 71 status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 72 void* pReplyData); 73 status_t handleGetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 74 void* pReplyData); 75 76 private: 77 const bool mIsProxyEffect; 78 79 static constexpr int kDefaultframeCount = 0x100; 80 81 template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> numericPointerToString(T * pt)82 static inline std::string numericPointerToString(T* pt) { 83 return pt ? std::to_string(*pt) : "nullptr"; 84 } 85 86 const aidl::android::media::audio::common::AudioConfig kDefaultAudioConfig = { 87 .base = {.sampleRate = 44100, 88 .channelMask = aidl::android::media::audio::common::AudioChannelLayout::make< 89 aidl::android::media::audio::common::AudioChannelLayout::layoutMask>( 90 aidl::android::media::audio::common::AudioChannelLayout:: 91 LAYOUT_STEREO), 92 .format = {.type = aidl::android::media::audio::common::AudioFormatType::PCM, 93 .pcm = aidl::android::media::audio::common::PcmType::FLOAT_32_BIT}}, 94 .frameCount = kDefaultframeCount}; 95 96 // command handler map 97 typedef status_t (EffectConversionHelperAidl::*CommandHandler)(uint32_t /* cmdSize */, 98 const void* /* pCmdData */, 99 uint32_t* /* replySize */, 100 void* /* pReplyData */); 101 static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap; 102 // data and status FMQ 103 std::shared_ptr<StatusMQ> mStatusQ = nullptr; 104 std::shared_ptr<DataMQ> mInputQ = nullptr, mOutputQ = nullptr; 105 106 struct EventFlagDeleter { operatorEventFlagDeleter107 void operator()(::android::hardware::EventFlag* flag) const { 108 if (flag) { 109 ::android::hardware::EventFlag::deleteEventFlag(&flag); 110 } 111 } 112 }; 113 std::shared_ptr<android::hardware::EventFlag> mEfGroup = nullptr; 114 status_t updateEventFlags(); 115 void updateDataMqs( 116 const ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn& ret); 117 void updateMqsAndEventFlags( 118 const ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn& ret); 119 120 status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 121 void* pReplyData); 122 status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 123 void* pReplyData); 124 status_t handleGetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 125 void* pReplyData); 126 status_t handleEnable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 127 void* pReplyData); 128 status_t handleDisable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 129 void* pReplyData); 130 status_t handleReset(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 131 void* pReplyData); 132 status_t handleSetAudioSource(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 133 void* pReplyData); 134 status_t handleSetAudioMode(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 135 void* pReplyData); 136 status_t handleSetDevice(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 137 void* pReplyData); 138 status_t handleSetVolume(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 139 void* pReplyData); 140 status_t handleSetOffload(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 141 void* pReplyData); 142 status_t handleVisualizerCapture(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 143 void* pReplyData); 144 status_t handleVisualizerMeasure(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize, 145 void* pReplyData); 146 147 // implemented by conversion of each effect 148 virtual status_t setParameter(utils::EffectParamReader& param) = 0; 149 virtual status_t getParameter(utils::EffectParamWriter& param) = 0; visualizerCapture(uint32_t * replySize __unused,void * pReplyData __unused)150 virtual status_t visualizerCapture(uint32_t* replySize __unused, void* pReplyData __unused) { 151 return BAD_VALUE; 152 } visualizerMeasure(uint32_t * replySize __unused,void * pReplyData __unused)153 virtual status_t visualizerMeasure(uint32_t* replySize __unused, void* pReplyData __unused) { 154 return BAD_VALUE; 155 } 156 }; 157 158 } // namespace effect 159 } // namespace android 160