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