• 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 <array>
19 
20 #include <aidl/android/hardware/audio/effect/BnEffect.h>
21 #include <system/audio_effects/effect_uuid.h>
22 
23 #include "effect-impl/EffectTypes.h"
24 #include "LVM.h"
25 
26 namespace aidl::android::hardware::audio::effect {
27 namespace lvm {
28 
29 constexpr inline size_t MAX_NUM_PRESETS = 10;
30 constexpr inline size_t MAX_NUM_BANDS = 5;
31 constexpr inline size_t MAX_CALL_SIZE = 256;
32 constexpr inline int BASS_BOOST_CUP_LOAD_ARM9E = 150;   // Expressed in 0.1 MIPS
33 constexpr inline int VIRTUALIZER_CUP_LOAD_ARM9E = 120;  // Expressed in 0.1 MIPS
34 constexpr inline int EQUALIZER_CUP_LOAD_ARM9E = 220;    // Expressed in 0.1 MIPS
35 constexpr inline int VOLUME_CUP_LOAD_ARM9E = 0;         // Expressed in 0.1 MIPS
36 constexpr inline int BUNDLE_MEM_USAGE = 25;             // Expressed in kB
37 constexpr inline int PRESET_CUSTOM = -1;
38 
39 static const std::vector<Equalizer::BandFrequency> kEqBandFrequency = {{0, 30000, 120000},
40                                                                        {1, 120001, 460000},
41                                                                        {2, 460001, 1800000},
42                                                                        {3, 1800001, 7000000},
43                                                                        {4, 7000001, 20000000}};
44 
45 /*
46 Frequencies in Hz
47 Note: If these frequencies change, please update LimitLevel values accordingly.
48 */
49 constexpr inline std::array<uint16_t, MAX_NUM_BANDS> kPresetsFrequencies = {60, 230, 910, 3600,
50                                                                             14000};
51 
52 /* Q factor multiplied by 100 */
53 constexpr inline std::array<uint16_t, MAX_NUM_BANDS> kPresetsQFactors = {96, 96, 96, 96, 96};
54 
55 constexpr inline std::array<std::array<int16_t, MAX_NUM_BANDS>, MAX_NUM_PRESETS> kSoftPresets = {
56         {{3, 0, 0, 0, 3},    /* Normal Preset */
57          {5, 3, -2, 4, 4},   /* Classical Preset */
58          {6, 0, 2, 4, 1},    /* Dance Preset */
59          {0, 0, 0, 0, 0},    /* Flat Preset */
60          {3, 0, 0, 2, -1},   /* Folk Preset */
61          {4, 1, 9, 3, 0},    /* Heavy Metal Preset */
62          {5, 3, 0, 1, 3},    /* Hip Hop Preset */
63          {4, 2, -2, 2, 5},   /* Jazz Preset */
64          {-1, 2, 5, 1, -2},  /* Pop Preset */
65          {5, 3, -1, 3, 5}}}; /* Rock Preset */
66 
67 static const std::vector<Equalizer::Preset> kEqPresets = {
68         {-1, "Custom"}, {0, "Normal"}, {1, "Classical"},   {2, "Dance"},
69         {3, "Flat"},    {4, "Folk"},   {5, "Heavy Metal"}, {6, "Hip Hop"},
70         {7, "Jazz"},    {8, "Pop"},    {9, "Rock"}};
71 
72 const std::vector<Range::EqualizerRange> kEqRanges = {
73         MAKE_RANGE(Equalizer, preset, 0, MAX_NUM_PRESETS - 1),
74         MAKE_RANGE(Equalizer, bandLevels,
75                    std::vector<Equalizer::BandLevel>{
76                            Equalizer::BandLevel({.index = 0, .levelMb = -1500})},
77                    std::vector<Equalizer::BandLevel>{
78                            Equalizer::BandLevel({.index = MAX_NUM_BANDS - 1, .levelMb = 1500})}),
79         /* capability definition */
80         MAKE_RANGE(Equalizer, bandFrequencies, kEqBandFrequency, kEqBandFrequency),
81         MAKE_RANGE(Equalizer, presets, kEqPresets, kEqPresets),
82         /* get only parameters with range min > max */
83         MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({}))};
84 static const Capability kEqCap = {.range = kEqRanges};
85 static const std::string kEqualizerEffectName = "EqualizerBundle";
86 static const Descriptor kEqualizerDesc = {
87         .common = {.id = {.type = getEffectTypeUuidEqualizer(),
88                           .uuid = getEffectImplUuidEqualizerBundle()},
89                    .flags = {.type = Flags::Type::INSERT,
90                              .insert = Flags::Insert::FIRST,
91                              .volume = Flags::Volume::CTRL},
92                    .name = kEqualizerEffectName,
93                    .implementor = "NXP Software Ltd."},
94         .capability = kEqCap};
95 
96 static const int mMaxStrengthSupported = 1000;
97 static const std::vector<Range::BassBoostRange> kBassBoostRanges = {
98         MAKE_RANGE(BassBoost, strengthPm, 0, mMaxStrengthSupported)};
99 static const Capability kBassBoostCap = {.range = kBassBoostRanges};
100 static const std::string kBassBoostEffectName = "Dynamic Bass Boost";
101 static const Descriptor kBassBoostDesc = {
102         .common = {.id = {.type = getEffectTypeUuidBassBoost(),
103                           .uuid = getEffectImplUuidBassBoostBundle()},
104                    .flags = {.type = Flags::Type::INSERT,
105                              .insert = Flags::Insert::FIRST,
106                              .volume = Flags::Volume::CTRL,
107                              .deviceIndication = true},
108                    .cpuLoad = BASS_BOOST_CUP_LOAD_ARM9E,
109                    .memoryUsage = BUNDLE_MEM_USAGE,
110                    .name = kBassBoostEffectName,
111                    .implementor = "NXP Software Ltd."},
112         .capability = kBassBoostCap};
113 
114 static const std::vector<Range::VirtualizerRange> kVirtualizerRanges = {
115         MAKE_RANGE(Virtualizer, strengthPm, 0, mMaxStrengthSupported)};
116 static const Capability kVirtualizerCap = {.range = kVirtualizerRanges};
117 static const std::string kVirtualizerEffectName = "Virtualizer";
118 
119 static const Descriptor kVirtualizerDesc = {
120         .common = {.id = {.type = getEffectTypeUuidVirtualizer(),
121                           .uuid = getEffectImplUuidVirtualizerBundle()},
122                    .flags = {.type = Flags::Type::INSERT,
123                              .insert = Flags::Insert::LAST,
124                              .volume = Flags::Volume::CTRL,
125                              .deviceIndication = true},
126                    .cpuLoad = VIRTUALIZER_CUP_LOAD_ARM9E,
127                    .memoryUsage = BUNDLE_MEM_USAGE,
128                    .name = kVirtualizerEffectName,
129                    .implementor = "NXP Software Ltd."},
130         .capability = kVirtualizerCap};
131 
132 static const std::vector<Range::VolumeRange> kVolumeRanges = {MAKE_RANGE(Volume, levelDb, -96, 0)};
133 static const Capability kVolumeCap = {.range = kVolumeRanges};
134 static const std::string kVolumeEffectName = "Volume";
135 static const Descriptor kVolumeDesc = {
136         .common = {.id = {.type = getEffectTypeUuidVolume(),
137                           .uuid = getEffectImplUuidVolumeBundle()},
138                    .flags = {.type = Flags::Type::INSERT,
139                              .insert = Flags::Insert::LAST,
140                              .volume = Flags::Volume::CTRL},
141                    .cpuLoad = VOLUME_CUP_LOAD_ARM9E,
142                    .memoryUsage = BUNDLE_MEM_USAGE,
143                    .name = kVolumeEffectName,
144                    .implementor = "NXP Software Ltd."},
145         .capability = kVolumeCap};
146 
147 /* The following tables have been computed using the actual levels measured by the output of
148  * white noise or pink noise (IEC268-1) for the EQ and BassBoost Effects. These are estimates of
149  * the actual energy that 'could' be present in the given band.
150  * If the frequency values in EQNB_5BandPresetsFrequencies change, these values might need to be
151  * updated.
152  */
153 constexpr inline std::array<float, MAX_NUM_BANDS> kBandEnergyCoefficient = {7.56, 9.69, 9.59, 7.37,
154                                                                             2.88};
155 
156 constexpr inline std::array<float, MAX_NUM_BANDS - 1> kBandEnergyCrossCoefficient = {126.0, 115.0,
157                                                                                      125.0, 104.0};
158 
159 constexpr inline std::array<float, MAX_NUM_BANDS> kBassBoostEnergyCrossCoefficient = {
160         221.21, 208.10, 28.16, 0.0, 0.0};
161 
162 constexpr inline float kBassBoostEnergyCoefficient = 9.00;
163 
164 constexpr inline float kVirtualizerContribution = 1.9;
165 
166 enum class BundleEffectType {
167     BASS_BOOST,
168     VIRTUALIZER,
169     EQUALIZER,
170     VOLUME,
171 };
172 
173 inline std::ostream& operator<<(std::ostream& out, const BundleEffectType& type) {
174     switch (type) {
175         case BundleEffectType::BASS_BOOST:
176             return out << "BASS_BOOST";
177         case BundleEffectType::VIRTUALIZER:
178             return out << "VIRTUALIZER";
179         case BundleEffectType::EQUALIZER:
180             return out << "EQUALIZER";
181         case BundleEffectType::VOLUME:
182             return out << "VOLUME";
183     }
184     return out << "EnumBundleEffectTypeError";
185 }
186 
187 inline std::ostream& operator<<(std::ostream& out, const LVM_ReturnStatus_en& status) {
188     switch (status) {
189         case LVM_SUCCESS:
190             return out << "LVM_SUCCESS";
191         case LVM_ALIGNMENTERROR:
192             return out << "LVM_ALIGNMENTERROR";
193         case LVM_NULLADDRESS:
194             return out << "LVM_NULLADDRESS";
195         case LVM_OUTOFRANGE:
196             return out << "LVM_OUTOFRANGE";
197         case LVM_INVALIDNUMSAMPLES:
198             return out << "LVM_INVALIDNUMSAMPLES";
199         case LVM_WRONGAUDIOTIME:
200             return out << "LVM_WRONGAUDIOTIME";
201         case LVM_ALGORITHMDISABLED:
202             return out << "LVM_ALGORITHMDISABLED";
203         case LVM_ALGORITHMPSA:
204             return out << "LVM_ALGORITHMPSA";
205         case LVM_RETURNSTATUS_DUMMY:
206             return out << "LVM_RETURNSTATUS_DUMMY";
207     }
208     return out << "EnumLvmRetStatusError";
209 }
210 
211 #define GOTO_IF_LVM_ERROR(status, tag, log)                                       \
212     do {                                                                          \
213         LVM_ReturnStatus_en temp = (status);                                      \
214         if (temp != LVM_SUCCESS) {                                                \
215             LOG(ERROR) << __func__ << " return status: " << temp << " " << (log); \
216             goto tag;                                                             \
217         }                                                                         \
218     } while (0)
219 
220 }  // namespace lvm
221 }  // namespace aidl::android::hardware::audio::effect
222