• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #include <memory>
19 #include <vector>
20 
21 #include <Utils.h>
22 #include <android-base/logging.h>
23 #include <fmq/AidlMessageQueue.h>
24 
25 #include <aidl/android/hardware/audio/effect/BnEffect.h>
26 #include "EffectTypes.h"
27 
28 namespace aidl::android::hardware::audio::effect {
29 
30 class EffectContext {
31   public:
32     typedef ::android::AidlMessageQueue<
33             IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
34             StatusMQ;
35     typedef ::android::AidlMessageQueue<
36             float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
37             DataMQ;
38 
EffectContext(size_t statusDepth,const Parameter::Common & common)39     EffectContext(size_t statusDepth, const Parameter::Common& common) {
40         auto& input = common.input;
41         auto& output = common.output;
42 
43         LOG_ALWAYS_FATAL_IF(
44                 input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
45                 "inputFormatNotFloat");
46         LOG_ALWAYS_FATAL_IF(output.base.format.pcm !=
47                                     aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
48                             "outputFormatNotFloat");
49         mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
50                 input.base.format, input.base.channelMask);
51         mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
52                 output.base.format, output.base.channelMask);
53         // in/outBuffer size in float (FMQ data format defined for DataMQ)
54         size_t inBufferSizeInFloat = input.frameCount * mInputFrameSize / sizeof(float);
55         size_t outBufferSizeInFloat = output.frameCount * mOutputFrameSize / sizeof(float);
56 
57         // only status FMQ use the EventFlag
58         mStatusMQ = std::make_shared<StatusMQ>(statusDepth, true /*configureEventFlagWord*/);
59         mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
60         mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
61 
62         if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
63             LOG(ERROR) << __func__ << " created invalid FMQ";
64         }
65         mWorkBuffer.reserve(std::max(inBufferSizeInFloat, outBufferSizeInFloat));
66         mCommon = common;
67     }
~EffectContext()68     virtual ~EffectContext() {}
69 
getStatusFmq()70     std::shared_ptr<StatusMQ> getStatusFmq() { return mStatusMQ; }
getInputDataFmq()71     std::shared_ptr<DataMQ> getInputDataFmq() { return mInputMQ; }
getOutputDataFmq()72     std::shared_ptr<DataMQ> getOutputDataFmq() { return mOutputMQ; }
73 
getWorkBuffer()74     float* getWorkBuffer() { return static_cast<float*>(mWorkBuffer.data()); }
75 
76     // reset buffer status by abandon input data in FMQ
resetBuffer()77     void resetBuffer() {
78         auto buffer = static_cast<float*>(mWorkBuffer.data());
79         std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
80         mInputMQ->read(buffer, mInputMQ->availableToRead());
81     }
82 
dupeFmq(IEffect::OpenEffectReturn * effectRet)83     void dupeFmq(IEffect::OpenEffectReturn* effectRet) {
84         if (effectRet) {
85             effectRet->statusMQ = mStatusMQ->dupeDesc();
86             effectRet->inputDataMQ = mInputMQ->dupeDesc();
87             effectRet->outputDataMQ = mOutputMQ->dupeDesc();
88         }
89     }
getInputFrameSize()90     size_t getInputFrameSize() { return mInputFrameSize; }
getOutputFrameSize()91     size_t getOutputFrameSize() { return mOutputFrameSize; }
getSessionId()92     int getSessionId() { return mCommon.session; }
getIoHandle()93     int getIoHandle() { return mCommon.ioHandle; }
94 
setOutputDevice(const std::vector<aidl::android::media::audio::common::AudioDeviceDescription> & device)95     virtual RetCode setOutputDevice(
96             const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
97                     device) {
98         mOutputDevice = device;
99         return RetCode::SUCCESS;
100     }
101 
102     virtual std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
getOutputDevice()103     getOutputDevice() {
104         return mOutputDevice;
105     }
106 
setAudioMode(const aidl::android::media::audio::common::AudioMode & mode)107     virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) {
108         mMode = mode;
109         return RetCode::SUCCESS;
110     }
getAudioMode()111     virtual aidl::android::media::audio::common::AudioMode getAudioMode() { return mMode; }
112 
setAudioSource(const aidl::android::media::audio::common::AudioSource & source)113     virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source) {
114         mSource = source;
115         return RetCode::SUCCESS;
116     }
getAudioSource()117     virtual aidl::android::media::audio::common::AudioSource getAudioSource() { return mSource; }
118 
setVolumeStereo(const Parameter::VolumeStereo & volumeStereo)119     virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) {
120         mVolumeStereo = volumeStereo;
121         return RetCode::SUCCESS;
122     }
getVolumeStereo()123     virtual Parameter::VolumeStereo getVolumeStereo() { return mVolumeStereo; }
124 
setCommon(const Parameter::Common & common)125     virtual RetCode setCommon(const Parameter::Common& common) {
126         mCommon = common;
127         LOG(VERBOSE) << __func__ << mCommon.toString();
128         return RetCode::SUCCESS;
129     }
getCommon()130     virtual Parameter::Common getCommon() {
131         LOG(VERBOSE) << __func__ << mCommon.toString();
132         return mCommon;
133     }
134 
135   protected:
136     // common parameters
137     size_t mInputFrameSize;
138     size_t mOutputFrameSize;
139     Parameter::Common mCommon;
140     std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice;
141     aidl::android::media::audio::common::AudioMode mMode;
142     aidl::android::media::audio::common::AudioSource mSource;
143     Parameter::VolumeStereo mVolumeStereo;
144 
145   private:
146     // fmq and buffers
147     std::shared_ptr<StatusMQ> mStatusMQ;
148     std::shared_ptr<DataMQ> mInputMQ;
149     std::shared_ptr<DataMQ> mOutputMQ;
150     // TODO handle effect process input and output
151     // work buffer set by effect instances, the access and update are in same thread
152     std::vector<float> mWorkBuffer;
153 };
154 }  // namespace aidl::android::hardware::audio::effect
155