blob: 3bc889ca5ff13b207202c729c5b7eb9b4700526c [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <array>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <system/audio_effects/effect_uuid.h>
#include "effect-impl/EffectTypes.h"
#include "LVM.h"
namespace aidl::android::hardware::audio::effect {
namespace lvm {
constexpr inline size_t MAX_NUM_PRESETS = 10;
constexpr inline size_t MAX_NUM_BANDS = 5;
constexpr inline size_t MAX_CALL_SIZE = 256;
constexpr inline int BASS_BOOST_CUP_LOAD_ARM9E = 150; // Expressed in 0.1 MIPS
constexpr inline int VIRTUALIZER_CUP_LOAD_ARM9E = 120; // Expressed in 0.1 MIPS
constexpr inline int EQUALIZER_CUP_LOAD_ARM9E = 220; // Expressed in 0.1 MIPS
constexpr inline int VOLUME_CUP_LOAD_ARM9E = 0; // Expressed in 0.1 MIPS
constexpr inline int BUNDLE_MEM_USAGE = 25; // Expressed in kB
constexpr inline int PRESET_CUSTOM = -1;
static const std::vector<Equalizer::BandFrequency> kEqBandFrequency = {{0, 30000, 120000},
{1, 120001, 460000},
{2, 460001, 1800000},
{3, 1800001, 7000000},
{4, 7000001, 20000000}};
/*
Frequencies in Hz
Note: If these frequencies change, please update LimitLevel values accordingly.
*/
constexpr inline std::array<uint16_t, MAX_NUM_BANDS> kPresetsFrequencies = {60, 230, 910, 3600,
14000};
/* Q factor multiplied by 100 */
constexpr inline std::array<uint16_t, MAX_NUM_BANDS> kPresetsQFactors = {96, 96, 96, 96, 96};
constexpr inline std::array<std::array<int16_t, MAX_NUM_BANDS>, MAX_NUM_PRESETS> kSoftPresets = {
{{3, 0, 0, 0, 3}, /* Normal Preset */
{5, 3, -2, 4, 4}, /* Classical Preset */
{6, 0, 2, 4, 1}, /* Dance Preset */
{0, 0, 0, 0, 0}, /* Flat Preset */
{3, 0, 0, 2, -1}, /* Folk Preset */
{4, 1, 9, 3, 0}, /* Heavy Metal Preset */
{5, 3, 0, 1, 3}, /* Hip Hop Preset */
{4, 2, -2, 2, 5}, /* Jazz Preset */
{-1, 2, 5, 1, -2}, /* Pop Preset */
{5, 3, -1, 3, 5}}}; /* Rock Preset */
static const std::vector<Equalizer::Preset> kEqPresets = {
{0, "Normal"}, {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
{5, "Heavy Metal"}, {6, "Hip Hop"}, {7, "Jazz"}, {8, "Pop"}, {9, "Rock"}};
const std::vector<Range::EqualizerRange> kEqRanges = {
MAKE_RANGE(Equalizer, preset, 0, MAX_NUM_PRESETS - 1),
MAKE_RANGE(Equalizer, bandLevels,
std::vector<Equalizer::BandLevel>{
Equalizer::BandLevel({.index = 0, .levelMb = -15})},
std::vector<Equalizer::BandLevel>{
Equalizer::BandLevel({.index = MAX_NUM_BANDS - 1, .levelMb = 15})}),
/* capability definition */
MAKE_RANGE(Equalizer, bandFrequencies, kEqBandFrequency, kEqBandFrequency),
MAKE_RANGE(Equalizer, presets, kEqPresets, kEqPresets),
/* get only parameters with range min > max */
MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({}))};
static const Capability kEqCap = {.range = kEqRanges};
static const std::string kEqualizerEffectName = "EqualizerBundle";
static const Descriptor kEqualizerDesc = {
.common = {.id = {.type = getEffectTypeUuidEqualizer(),
.uuid = getEffectImplUuidEqualizerBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = kEqualizerEffectName,
.implementor = "NXP Software Ltd."},
.capability = kEqCap};
static const int mMaxStrengthSupported = 1000;
static const std::vector<Range::BassBoostRange> kBassBoostRanges = {
MAKE_RANGE(BassBoost, strengthPm, 0, mMaxStrengthSupported)};
static const Capability kBassBoostCap = {.range = kBassBoostRanges};
static const std::string kBassBoostEffectName = "Dynamic Bass Boost";
static const Descriptor kBassBoostDesc = {
.common = {.id = {.type = getEffectTypeUuidBassBoost(),
.uuid = getEffectImplUuidBassBoostBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL,
.deviceIndication = true},
.cpuLoad = BASS_BOOST_CUP_LOAD_ARM9E,
.memoryUsage = BUNDLE_MEM_USAGE,
.name = kBassBoostEffectName,
.implementor = "NXP Software Ltd."},
.capability = kBassBoostCap};
static const std::vector<Range::VirtualizerRange> kVirtualizerRanges = {
MAKE_RANGE(Virtualizer, strengthPm, 0, mMaxStrengthSupported)};
static const Capability kVirtualizerCap = {.range = kVirtualizerRanges};
static const std::string kVirtualizerEffectName = "Virtualizer";
static const Descriptor kVirtualizerDesc = {
.common = {.id = {.type = getEffectTypeUuidVirtualizer(),
.uuid = getEffectImplUuidVirtualizerBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::LAST,
.volume = Flags::Volume::CTRL,
.deviceIndication = true},
.cpuLoad = VIRTUALIZER_CUP_LOAD_ARM9E,
.memoryUsage = BUNDLE_MEM_USAGE,
.name = kVirtualizerEffectName,
.implementor = "NXP Software Ltd."},
.capability = kVirtualizerCap};
static const std::vector<Range::VolumeRange> kVolumeRanges = {
MAKE_RANGE(Volume, levelDb, -9600, 0)};
static const Capability kVolumeCap = {.range = kVolumeRanges};
static const std::string kVolumeEffectName = "Volume";
static const Descriptor kVolumeDesc = {
.common = {.id = {.type = getEffectTypeUuidVolume(),
.uuid = getEffectImplUuidVolumeBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::LAST,
.volume = Flags::Volume::CTRL},
.cpuLoad = VOLUME_CUP_LOAD_ARM9E,
.memoryUsage = BUNDLE_MEM_USAGE,
.name = kVolumeEffectName,
.implementor = "NXP Software Ltd."},
.capability = kVolumeCap};
/* The following tables have been computed using the actual levels measured by the output of
* white noise or pink noise (IEC268-1) for the EQ and BassBoost Effects. These are estimates of
* the actual energy that 'could' be present in the given band.
* If the frequency values in EQNB_5BandPresetsFrequencies change, these values might need to be
* updated.
*/
constexpr inline std::array<float, MAX_NUM_BANDS> kBandEnergyCoefficient = {7.56, 9.69, 9.59, 7.37,
2.88};
constexpr inline std::array<float, MAX_NUM_BANDS - 1> kBandEnergyCrossCoefficient = {126.0, 115.0,
125.0, 104.0};
constexpr inline std::array<float, MAX_NUM_BANDS> kBassBoostEnergyCrossCoefficient = {
221.21, 208.10, 28.16, 0.0, 0.0};
constexpr inline float kBassBoostEnergyCoefficient = 9.00;
constexpr inline float kVirtualizerContribution = 1.9;
enum class BundleEffectType {
BASS_BOOST,
VIRTUALIZER,
EQUALIZER,
VOLUME,
};
inline std::ostream& operator<<(std::ostream& out, const BundleEffectType& type) {
switch (type) {
case BundleEffectType::BASS_BOOST:
return out << "BASS_BOOST";
case BundleEffectType::VIRTUALIZER:
return out << "VIRTUALIZER";
case BundleEffectType::EQUALIZER:
return out << "EQUALIZER";
case BundleEffectType::VOLUME:
return out << "VOLUME";
}
return out << "EnumBundleEffectTypeError";
}
inline std::ostream& operator<<(std::ostream& out, const LVM_ReturnStatus_en& status) {
switch (status) {
case LVM_SUCCESS:
return out << "LVM_SUCCESS";
case LVM_ALIGNMENTERROR:
return out << "LVM_ALIGNMENTERROR";
case LVM_NULLADDRESS:
return out << "LVM_NULLADDRESS";
case LVM_OUTOFRANGE:
return out << "LVM_OUTOFRANGE";
case LVM_INVALIDNUMSAMPLES:
return out << "LVM_INVALIDNUMSAMPLES";
case LVM_WRONGAUDIOTIME:
return out << "LVM_WRONGAUDIOTIME";
case LVM_ALGORITHMDISABLED:
return out << "LVM_ALGORITHMDISABLED";
case LVM_ALGORITHMPSA:
return out << "LVM_ALGORITHMPSA";
case LVM_RETURNSTATUS_DUMMY:
return out << "LVM_RETURNSTATUS_DUMMY";
}
return out << "EnumLvmRetStatusError";
}
#define GOTO_IF_LVM_ERROR(status, tag, log) \
do { \
LVM_ReturnStatus_en temp = (status); \
if (temp != LVM_SUCCESS) { \
LOG(ERROR) << __func__ << " return status: " << temp << " " << (log); \
goto tag; \
} \
} while (0)
} // namespace lvm
} // namespace aidl::android::hardware::audio::effect