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 #include <cstdint>
18 #include <cstring>
19 #include <optional>
20 #define LOG_TAG "AidlConversionVirtualizer"
21 //#define LOG_NDEBUG 0
22 
23 #include <error/expected_utils.h>
24 #include <media/AidlConversionCppNdk.h>
25 #include <media/AidlConversionNdk.h>
26 #include <media/AidlConversionEffect.h>
27 #include <system/audio_effects/aidl_effects_utils.h>
28 #include <system/audio_effects/effect_virtualizer.h>
29 
30 #include <utils/Log.h>
31 
32 #include "AidlConversionVirtualizer.h"
33 
34 namespace android {
35 namespace effect {
36 
37 using ::aidl::android::aidl_utils::statusTFromBinderStatus;
38 using ::aidl::android::getParameterSpecificField;
39 using ::aidl::android::hardware::audio::effect::Parameter;
40 using ::aidl::android::hardware::audio::effect::Range;
41 using ::aidl::android::hardware::audio::effect::Virtualizer;
42 using ::aidl::android::hardware::audio::effect::VendorExtension;
43 using ::aidl::android::media::audio::common::AudioDeviceDescription;
44 using ::android::status_t;
45 using utils::EffectParamReader;
46 using utils::EffectParamWriter;
47 
setParameter(EffectParamReader & param)48 status_t AidlConversionVirtualizer::setParameter(EffectParamReader& param) {
49     uint32_t type = 0;
50     if (OK != param.readFromParameter(&type)) {
51         ALOGE("%s invalid param %s", __func__, param.toString().c_str());
52         return BAD_VALUE;
53     }
54     Parameter aidlParam;
55     switch (type) {
56         case VIRTUALIZER_PARAM_STRENGTH: {
57             int16_t strength = 0;
58             if (OK != param.readFromValue(&strength)) {
59                 ALOGE("%s invalid param %s for type %d", __func__, param.toString().c_str(), type);
60                 return BAD_VALUE;
61             }
62             aidlParam = MAKE_SPECIFIC_PARAMETER(Virtualizer, virtualizer, strengthPm, strength);
63             break;
64         }
65         case VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE: {
66             audio_devices_t deviceType;
67             if (OK != param.readFromValue(&deviceType)) {
68                 ALOGE("%s invalid param %s for type %d", __func__, param.toString().c_str(), type);
69                 return BAD_VALUE;
70             }
71             AudioDeviceDescription deviceDesc = VALUE_OR_RETURN_STATUS(
72                     ::aidl::android::legacy2aidl_audio_devices_t_AudioDeviceDescription(
73                             deviceType));
74             aidlParam = MAKE_SPECIFIC_PARAMETER(Virtualizer, virtualizer, device, deviceDesc);
75             break;
76         }
77         default: {
78             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
79             VendorExtension ext = VALUE_OR_RETURN_STATUS(
80                     aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
81             aidlParam = MAKE_SPECIFIC_PARAMETER(Virtualizer, virtualizer, vendor, ext);
82             break;
83         }
84     }
85     return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
86 }
87 
getParameter(EffectParamWriter & param)88 status_t AidlConversionVirtualizer::getParameter(EffectParamWriter& param) {
89     uint32_t type = 0;
90     if (OK != param.readFromParameter(&type)) {
91         ALOGE("%s invalid param %s", __func__, param.toString().c_str());
92         param.setStatus(BAD_VALUE);
93         return BAD_VALUE;
94     }
95     Parameter aidlParam;
96     switch (type) {
97         case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED: {
98             // an invalid range indicates not setting support for this parameter
99             uint32_t support =
100                     ::aidl::android::hardware::audio::effect::isRangeValid<Range::Tag::virtualizer>(
101                             Virtualizer::strengthPm, mDesc.capability);
102             return param.writeToValue(&support);
103         }
104         case VIRTUALIZER_PARAM_STRENGTH: {
105             Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Virtualizer, virtualizerTag,
106                                                           Virtualizer::strengthPm);
107             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
108             int16_t strength = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
109                     aidlParam, Virtualizer, virtualizer, Virtualizer::strengthPm, int32_t));
110             return param.writeToValue(&strength);
111         }
112         case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES: {
113             audio_channel_mask_t mask;
114             audio_devices_t device;
115             if (OK != param.readFromParameter(&mask) || OK != param.readFromParameter(&device)) {
116                 ALOGW("%s illegal param %s", __func__, param.toString().c_str());
117                 return BAD_VALUE;
118             }
119             Virtualizer::SpeakerAnglesPayload payload = {
120                     .layout = VALUE_OR_RETURN_STATUS(
121                             ::aidl::android::legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
122                                     mask, false)),
123                     .device = VALUE_OR_RETURN_STATUS(
124                             ::aidl::android::legacy2aidl_audio_devices_t_AudioDeviceDescription(
125                                     device))};
126             Virtualizer::Id vId = UNION_MAKE(Virtualizer::Id, speakerAnglesPayload, payload);
127             Parameter::Id id = UNION_MAKE(Parameter::Id, virtualizerTag, vId);
128             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
129             const auto& angles = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
130                     aidlParam, Virtualizer, virtualizer, Virtualizer::speakerAngles,
131                     std::vector<Virtualizer::ChannelAngle>));
132             for (const auto& angle : angles) {
133                 const audio_channel_mask_t chMask = ::aidl::android::
134                         aidl2legacy_AudioChannelLayout_layout_audio_channel_mask_t_bits(
135                                 angle.channel, false);
136                 if (OK != param.writeToValue(&chMask) ||
137                     OK != param.writeToValue(&angle.azimuthDegree) ||
138                     OK != param.writeToValue(&angle.elevationDegree)) {
139                     ALOGW("%s can't write angles to param %s", __func__, param.toString().c_str());
140                     return BAD_VALUE;
141                 }
142             }
143             return OK;
144         }
145         case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE: {
146             Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Virtualizer, virtualizerTag,
147                                                           Virtualizer::device);
148             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
149             AudioDeviceDescription device = VALUE_OR_RETURN_STATUS(
150                     GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Virtualizer, virtualizer,
151                                                  Virtualizer::device, AudioDeviceDescription));
152             const audio_devices_t deviceType = VALUE_OR_RETURN_STATUS(
153                     ::aidl::android::aidl2legacy_AudioDeviceDescription_audio_devices_t(device));
154             return param.writeToValue(&deviceType);
155         }
156         default: {
157             VENDOR_EXTENSION_GET_AND_RETURN(Virtualizer, virtualizer, param);
158         }
159     }
160 }
161 
162 } // namespace effect
163 } // namespace android
164