audio: remove effects and tests

* See [1] and [2] for reference and comments.

[1]: 346a56239e
[2]: 765b1a3a3d
This commit is contained in:
Konsta
2025-10-22 18:13:55 +03:00
parent a76bafa9f4
commit 451c17acd0
59 changed files with 0 additions and 6823 deletions

View File

@@ -202,94 +202,6 @@ cc_binary {
installable: false, //installed in apex com.android.hardware.audio
}
cc_test {
name: "audio_policy_config_xml_converter_tests",
vendor_available: true,
defaults: [
"latest_android_media_audio_common_types_ndk_static",
"latest_android_hardware_audio_core_ndk_static",
],
shared_libs: [
"libaudio_aidl_conversion_common_ndk",
"libaudioaidlcommon",
"libaudioutils",
"libbase",
"libbinder_ndk",
"libcutils",
"libfmq",
"libmedia_helper",
"libstagefright_foundation",
"libutils",
"libxml2",
],
header_libs: [
"libaudio_system_headers",
"libaudioaidl_headers",
"libxsdc-utils",
],
generated_sources: [
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
generated_headers: [
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
srcs: [
"AudioPolicyConfigXmlConverter.cpp",
"tests/AudioPolicyConfigXmlConverterTest.cpp",
],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
"-Wthread-safety",
"-DBACKEND_NDK",
],
test_suites: ["general-tests"],
}
cc_test {
name: "audio_alsa_utils_tests",
vendor_available: true,
defaults: [
"latest_android_media_audio_common_types_ndk_static",
"latest_android_hardware_audio_core_ndk_static",
],
static_libs: [
"libalsautilsv2",
"libtinyalsav2",
],
shared_libs: [
"libaudio_aidl_conversion_common_ndk",
"libaudioaidlcommon",
"libaudioutils",
"libbase",
"libbinder_ndk",
"libcutils",
"libfmq",
"libmedia_helper",
"libstagefright_foundation",
"libutils",
],
header_libs: [
"libaudio_system_headers",
"libaudioaidl_headers",
],
srcs: [
"alsa/Utils.cpp",
"tests/AlsaUtilsTest.cpp",
],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
"-Wthread-safety",
"-DBACKEND_NDK",
],
test_suites: ["general-tests"],
}
cc_defaults {
name: "aidlaudioeffectservice_defaults",
defaults: [
@@ -324,15 +236,6 @@ cc_defaults {
],
}
filegroup {
name: "effectCommonFile",
srcs: [
"EffectContext.cpp",
"EffectThread.cpp",
"EffectImpl.cpp",
],
}
cc_binary {
name: "android.hardware.audio.effect.service-aidl.example",
relative_install_path: "hw",

View File

@@ -1,193 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#include <memory>
#include <unordered_set>
#define LOG_TAG "AHAL_AcousticEchoCancelerSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "AcousticEchoCancelerSw.h"
using aidl::android::hardware::audio::effect::AcousticEchoCancelerSw;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidAcousticEchoCancelerSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::Range;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAcousticEchoCancelerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<AcousticEchoCancelerSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAcousticEchoCancelerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = AcousticEchoCancelerSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string AcousticEchoCancelerSw::kEffectName = "AcousticEchoCancelerSw";
const std::vector<Range::AcousticEchoCancelerRange> AcousticEchoCancelerSw::kRanges = {
MAKE_RANGE(AcousticEchoCanceler, echoDelayUs, 0, 500),
/* mobile mode not supported, and not settable */
MAKE_RANGE(AcousticEchoCanceler, mobileMode, false, false)};
const Capability AcousticEchoCancelerSw::kCapability = {.range = AcousticEchoCancelerSw::kRanges};
const Descriptor AcousticEchoCancelerSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidAcousticEchoCanceler(),
.uuid = getEffectImplUuidAcousticEchoCancelerSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::PRE_PROC,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::NONE},
.name = AcousticEchoCancelerSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = AcousticEchoCancelerSw::kCapability};
ndk::ScopedAStatus AcousticEchoCancelerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus AcousticEchoCancelerSw::setParameterSpecific(
const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::acousticEchoCanceler != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::acousticEchoCanceler>();
RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = param.getTag();
switch (tag) {
case AcousticEchoCanceler::echoDelayUs: {
RETURN_IF(mContext->setEchoDelay(param.get<AcousticEchoCanceler::echoDelayUs>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "echoDelayNotSupported");
return ndk::ScopedAStatus::ok();
}
case AcousticEchoCanceler::mobileMode: {
RETURN_IF(true == param.get<AcousticEchoCanceler::mobileMode>(), EX_ILLEGAL_ARGUMENT,
"SettingmobileModeSupported");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
}
}
}
ndk::ScopedAStatus AcousticEchoCancelerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::acousticEchoCancelerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto specificId = id.get<Parameter::Id::acousticEchoCancelerTag>();
auto specificIdTag = specificId.getTag();
switch (specificIdTag) {
case AcousticEchoCanceler::Id::commonTag:
return getParameterAcousticEchoCanceler(
specificId.get<AcousticEchoCanceler::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
}
}
ndk::ScopedAStatus AcousticEchoCancelerSw::getParameterAcousticEchoCanceler(
const AcousticEchoCanceler::Tag& tag, Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
AcousticEchoCanceler param;
switch (tag) {
case AcousticEchoCanceler::echoDelayUs: {
param.set<AcousticEchoCanceler::echoDelayUs>(mContext->getEchoDelay());
break;
}
case AcousticEchoCanceler::mobileMode: {
param.set<AcousticEchoCanceler::mobileMode>(false);
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
}
}
specific->set<Parameter::Specific::acousticEchoCanceler>(param);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> AcousticEchoCancelerSw::createContext(
const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<AcousticEchoCancelerSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode AcousticEchoCancelerSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status AcousticEchoCancelerSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode AcousticEchoCancelerSwContext::setEchoDelay(int echoDelayUs) {
mEchoDelayUs = echoDelayUs;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,74 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <aidl/android/hardware/audio/effect/Range.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class AcousticEchoCancelerSwContext final : public EffectContext {
public:
AcousticEchoCancelerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setEchoDelay(int echoDelayUs);
int getEchoDelay() const { return mEchoDelayUs; }
private:
int mEchoDelayUs = 0;
};
class AcousticEchoCancelerSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
AcousticEchoCancelerSw() { LOG(DEBUG) << __func__; }
~AcousticEchoCancelerSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
private:
static const std::vector<Range::AcousticEchoCancelerRange> kRanges;
std::shared_ptr<AcousticEchoCancelerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libaecsw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"AcousticEchoCancelerSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -21,28 +21,6 @@ apex {
"android.hardware.audio.service-aidl.example",
"android.hardware.audio.effect.service-aidl.example",
],
native_shared_libs: [
"libaecsw",
"libagc1sw",
"libagc2sw",
"libbassboostsw",
"libbundleaidl",
"libdownmixaidl",
"libdynamicsprocessingaidl",
"libenvreverbsw",
"libequalizersw",
"libextensioneffect",
"libhapticgeneratoraidl",
"libloudnessenhanceraidl",
"libnssw",
"libpreprocessingaidl",
"libpresetreverbsw",
"libreverbaidl",
"libspatializersw",
"libvirtualizersw",
"libvisualizeraidl",
"libvolumesw",
],
prebuilts: [
"android.hardware.audio.service-aidl.example.rc",
"android.hardware.audio.service-aidl.xml",

View File

@@ -28,27 +28,6 @@
name of a library .so file on the target device.
-->
<libraries>
<library name="aecsw" path="libaecsw.so"/>
<library name="agc1sw" path="libagc1sw.so"/>
<library name="agc2sw" path="libagc2sw.so"/>
<library name="bassboostsw" path="libbassboostsw.so"/>
<library name="bundle" path="libbundleaidl.so"/>
<library name="downmix" path="libdownmixaidl.so"/>
<library name="dynamics_processing" path="libdynamicsprocessingaidl.so"/>
<library name="equalizersw" path="libequalizersw.so"/>
<library name="erasersw" path="liberasersw.so"/>
<library name="haptic_generator" path="libhapticgeneratoraidl.so"/>
<library name="loudness_enhancer" path="libloudnessenhanceraidl.so"/>
<library name="nssw" path="libnssw.so"/>
<library name="env_reverbsw" path="libenvreverbsw.so"/>
<library name="pre_processing" path="libpreprocessingaidl.so"/>
<library name="preset_reverbsw" path="libpresetreverbsw.so"/>
<library name="reverb" path="libreverbaidl.so"/>
<library name="virtualizersw" path="libvirtualizersw.so"/>
<library name="visualizer" path="libvisualizeraidl.so"/>
<library name="volumesw" path="libvolumesw.so"/>
<library name="extensioneffect" path="libextensioneffect.so"/>
<library name="spatializersw" path="libspatializersw.so"/>
</libraries>
<!-- list of effects to load.
@@ -72,33 +51,8 @@
-->
<effects>
<effect name="automatic_gain_control_v2" library="pre_processing" uuid="89f38e65-d4d2-4d64-ad0e-2b3e799ea886"/>
<effect name="bassboost" library="bundle" uuid="8631f300-72e2-11df-b57e-0002a5d5c51b"/>
<effect name="downmix" library="downmix" uuid="93f04452-e4fe-41cc-91f9-e475b6d1d69f"/>
<effect name="dynamics_processing" library="dynamics_processing" uuid="e0e6539b-1781-7261-676f-6d7573696340"/>
<effect name="eraser" library="erasersw" uuid="fa81ab46-588b-11ed-9b6a-0242ac120002"/>
<effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
<effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
<effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
<effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
<effect name="reverb_pre_aux" library="reverb" uuid="f29a1400-a3bb-11df-8ddc-0002a5d5c51b"/>
<effect name="reverb_pre_ins" library="reverb" uuid="172cdf00-a3bc-11df-a72f-0002a5d5c51b"/>
<effect name="virtualizer" library="bundle" uuid="1d4033c0-8557-11df-9f2d-0002a5d5c51b"/>
<effect name="visualizer" library="visualizer" uuid="d069d9e0-8329-11df-9168-0002a5d5c51b"/>
<effect name="volume" library="bundle" uuid="119341a0-8469-11df-81f9-0002a5d5c51b"/>
<effect name="equalizer" library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
<effect name="extension_effect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002" type="fa81de0e-588b-11ed-9b6a-0242ac120002"/>
<effect name="acoustic_echo_canceler" library="pre_processing" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
<effect name="noise_suppression" library="pre_processing" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
</effects>
<preprocess>
<stream type="voice_communication">
<apply effect="acoustic_echo_canceler"/>
<apply effect="noise_suppression"/>
</stream>
</preprocess>
<!-- Audio pre processor configurations.
The pre processor configuration is described in a "preprocess" element and consists in a
list of elements each describing pre processor settings for a given use case or "stream".

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libagc1sw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"AutomaticGainControlV1Sw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,224 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
#define LOG_TAG "AHAL_AutomaticGainControlV1Sw"
#include <android-base/logging.h>
#include <system/audio_effects/effect_uuid.h>
#include "AutomaticGainControlV1Sw.h"
using aidl::android::hardware::audio::effect::AutomaticGainControlV1Sw;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidAutomaticGainControlV1Sw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV1;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV1Sw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV1Sw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV1Sw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = AutomaticGainControlV1Sw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string AutomaticGainControlV1Sw::kEffectName = "AutomaticGainControlV1Sw";
const std::vector<Range::AutomaticGainControlV1Range> AutomaticGainControlV1Sw::kRanges = {
MAKE_RANGE(AutomaticGainControlV1, targetPeakLevelDbFs, -3100, 0),
MAKE_RANGE(AutomaticGainControlV1, maxCompressionGainDb, 0, 9000)};
const Capability AutomaticGainControlV1Sw::kCapability = {
.range = AutomaticGainControlV1Sw::kRanges};
const Descriptor AutomaticGainControlV1Sw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidAutomaticGainControlV1(),
.uuid = getEffectImplUuidAutomaticGainControlV1Sw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = AutomaticGainControlV1Sw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = AutomaticGainControlV1Sw::kCapability};
ndk::ScopedAStatus AutomaticGainControlV1Sw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus AutomaticGainControlV1Sw::setParameterSpecific(
const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::automaticGainControlV1 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::automaticGainControlV1>();
RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = param.getTag();
switch (tag) {
case AutomaticGainControlV1::targetPeakLevelDbFs: {
RETURN_IF(mContext->setTargetPeakLevel(
param.get<AutomaticGainControlV1::targetPeakLevelDbFs>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "targetPeakLevelNotSupported");
return ndk::ScopedAStatus::ok();
}
case AutomaticGainControlV1::maxCompressionGainDb: {
RETURN_IF(mContext->setMaxCompressionGain(
param.get<AutomaticGainControlV1::maxCompressionGainDb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "maxCompressionGainNotSupported");
return ndk::ScopedAStatus::ok();
}
case AutomaticGainControlV1::enableLimiter: {
RETURN_IF(
mContext->setEnableLimiter(
param.get<AutomaticGainControlV1::enableLimiter>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "enableLimiterNotSupported");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
}
}
}
ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::automaticGainControlV1Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto specificId = id.get<Parameter::Id::automaticGainControlV1Tag>();
auto specificIdTag = specificId.getTag();
switch (specificIdTag) {
case AutomaticGainControlV1::Id::commonTag:
return getParameterAutomaticGainControlV1(
specificId.get<AutomaticGainControlV1::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
}
}
ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterAutomaticGainControlV1(
const AutomaticGainControlV1::Tag& tag, Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
AutomaticGainControlV1 param;
switch (tag) {
case AutomaticGainControlV1::targetPeakLevelDbFs: {
param.set<AutomaticGainControlV1::targetPeakLevelDbFs>(mContext->getTargetPeakLevel());
break;
}
case AutomaticGainControlV1::maxCompressionGainDb: {
param.set<AutomaticGainControlV1::maxCompressionGainDb>(
mContext->getMaxCompressionGain());
break;
}
case AutomaticGainControlV1::enableLimiter: {
param.set<AutomaticGainControlV1::enableLimiter>(mContext->getEnableLimiter());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
}
}
specific->set<Parameter::Specific::automaticGainControlV1>(param);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::createContext(
const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext =
std::make_shared<AutomaticGainControlV1SwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode AutomaticGainControlV1Sw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status AutomaticGainControlV1Sw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode AutomaticGainControlV1SwContext::setTargetPeakLevel(int targetPeakLevel) {
mTargetPeakLevel = targetPeakLevel;
return RetCode::SUCCESS;
}
int AutomaticGainControlV1SwContext::getTargetPeakLevel() {
return mTargetPeakLevel;
}
RetCode AutomaticGainControlV1SwContext::setMaxCompressionGain(int maxCompressionGain) {
mMaxCompressionGain = maxCompressionGain;
return RetCode::SUCCESS;
}
int AutomaticGainControlV1SwContext::getMaxCompressionGain() {
return mMaxCompressionGain;
}
RetCode AutomaticGainControlV1SwContext::setEnableLimiter(bool enableLimiter) {
mEnableLimiter = enableLimiter;
return RetCode::SUCCESS;
}
bool AutomaticGainControlV1SwContext::getEnableLimiter() {
return mEnableLimiter;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,76 +0,0 @@
/*
* Copyright (C) 2023 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 "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class AutomaticGainControlV1SwContext final : public EffectContext {
public:
AutomaticGainControlV1SwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setTargetPeakLevel(int targetPeakLevel);
int getTargetPeakLevel();
RetCode setMaxCompressionGain(int maxCompressionGainDb);
int getMaxCompressionGain();
RetCode setEnableLimiter(bool enableLimiter);
bool getEnableLimiter();
private:
int mTargetPeakLevel = 0;
int mMaxCompressionGain = 0;
bool mEnableLimiter = false;
};
class AutomaticGainControlV1Sw final : public EffectImpl {
public:
static const std::string kEffectName;
static const bool kStrengthSupported;
static const Capability kCapability;
static const Descriptor kDescriptor;
AutomaticGainControlV1Sw() { LOG(DEBUG) << __func__; }
~AutomaticGainControlV1Sw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
private:
static const std::vector<Range::AutomaticGainControlV1Range> kRanges;
std::shared_ptr<AutomaticGainControlV1SwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterAutomaticGainControlV1(const AutomaticGainControlV1::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libagc2sw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"AutomaticGainControlV2Sw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,228 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#include <memory>
#define LOG_TAG "AHAL_AutomaticGainControlV2Sw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "AutomaticGainControlV2Sw.h"
using aidl::android::hardware::audio::effect::AutomaticGainControlV2Sw;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidAutomaticGainControlV2Sw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV2;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV2Sw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV2Sw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV2Sw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = AutomaticGainControlV2Sw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string AutomaticGainControlV2Sw::kEffectName = "AutomaticGainControlV2Sw";
const std::vector<Range::AutomaticGainControlV2Range> AutomaticGainControlV2Sw::kRanges = {
MAKE_RANGE(AutomaticGainControlV2, fixedDigitalGainMb, 0, 50000),
MAKE_RANGE(AutomaticGainControlV2, saturationMarginMb, 0, 10000)};
const Capability AutomaticGainControlV2Sw::kCapability = {
.range = AutomaticGainControlV2Sw::kRanges};
const Descriptor AutomaticGainControlV2Sw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidAutomaticGainControlV2(),
.uuid = getEffectImplUuidAutomaticGainControlV2Sw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = AutomaticGainControlV2Sw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = AutomaticGainControlV2Sw::kCapability};
ndk::ScopedAStatus AutomaticGainControlV2Sw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus AutomaticGainControlV2Sw::setParameterSpecific(
const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::automaticGainControlV2 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::automaticGainControlV2>();
RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = param.getTag();
switch (tag) {
case AutomaticGainControlV2::fixedDigitalGainMb: {
RETURN_IF(mContext->setDigitalGain(
param.get<AutomaticGainControlV2::fixedDigitalGainMb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
return ndk::ScopedAStatus::ok();
}
case AutomaticGainControlV2::levelEstimator: {
RETURN_IF(mContext->setLevelEstimator(
param.get<AutomaticGainControlV2::levelEstimator>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
return ndk::ScopedAStatus::ok();
}
case AutomaticGainControlV2::saturationMarginMb: {
RETURN_IF(mContext->setSaturationMargin(
param.get<AutomaticGainControlV2::saturationMarginMb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
}
}
}
ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::automaticGainControlV2Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto specificId = id.get<Parameter::Id::automaticGainControlV2Tag>();
auto specificIdTag = specificId.getTag();
switch (specificIdTag) {
case AutomaticGainControlV2::Id::commonTag:
return getParameterAutomaticGainControlV2(
specificId.get<AutomaticGainControlV2::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
}
}
ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterAutomaticGainControlV2(
const AutomaticGainControlV2::Tag& tag, Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
AutomaticGainControlV2 param;
switch (tag) {
case AutomaticGainControlV2::fixedDigitalGainMb: {
param.set<AutomaticGainControlV2::fixedDigitalGainMb>(mContext->getDigitalGain());
break;
}
case AutomaticGainControlV2::levelEstimator: {
param.set<AutomaticGainControlV2::levelEstimator>(mContext->getLevelEstimator());
break;
}
case AutomaticGainControlV2::saturationMarginMb: {
param.set<AutomaticGainControlV2::saturationMarginMb>(mContext->getSaturationMargin());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
}
}
specific->set<Parameter::Specific::automaticGainControlV2>(param);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::createContext(
const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext =
std::make_shared<AutomaticGainControlV2SwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode AutomaticGainControlV2Sw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status AutomaticGainControlV2Sw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode AutomaticGainControlV2SwContext::setDigitalGain(int gain) {
mDigitalGain = gain;
return RetCode::SUCCESS;
}
int AutomaticGainControlV2SwContext::getDigitalGain() {
return mDigitalGain;
}
RetCode AutomaticGainControlV2SwContext::setLevelEstimator(
AutomaticGainControlV2::LevelEstimator levelEstimator) {
mLevelEstimator = levelEstimator;
return RetCode::SUCCESS;
}
AutomaticGainControlV2::LevelEstimator AutomaticGainControlV2SwContext::getLevelEstimator() {
return mLevelEstimator;
}
RetCode AutomaticGainControlV2SwContext::setSaturationMargin(int margin) {
mSaturationMargin = margin;
return RetCode::SUCCESS;
}
int AutomaticGainControlV2SwContext::getSaturationMargin() {
return mSaturationMargin;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,82 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class AutomaticGainControlV2SwContext final : public EffectContext {
public:
AutomaticGainControlV2SwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setDigitalGain(int gain);
int getDigitalGain();
RetCode setLevelEstimator(AutomaticGainControlV2::LevelEstimator levelEstimator);
AutomaticGainControlV2::LevelEstimator getLevelEstimator();
RetCode setSaturationMargin(int margin);
int getSaturationMargin();
private:
int mDigitalGain = 0;
AutomaticGainControlV2::LevelEstimator mLevelEstimator =
AutomaticGainControlV2::LevelEstimator::RMS;
int mSaturationMargin = 0;
};
class AutomaticGainControlV2Sw final : public EffectImpl {
public:
static const std::string kEffectName;
static const bool kStrengthSupported;
static const Capability kCapability;
static const Descriptor kDescriptor;
AutomaticGainControlV2Sw() { LOG(DEBUG) << __func__; }
~AutomaticGainControlV2Sw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
private:
static const std::vector<Range::AutomaticGainControlV2Range> kRanges;
std::shared_ptr<AutomaticGainControlV2SwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterAutomaticGainControlV2(const AutomaticGainControlV2::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libbassboostsw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"BassBoostSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,176 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#include <memory>
#define LOG_TAG "AHAL_BassBoostSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "BassBoostSw.h"
using aidl::android::hardware::audio::effect::BassBoostSw;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidBassBoostProxy;
using aidl::android::hardware::audio::effect::getEffectImplUuidBassBoostSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidBassBoostSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<BassBoostSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidBassBoostSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = BassBoostSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string BassBoostSw::kEffectName = "BassBoostSw";
const std::vector<Range::BassBoostRange> BassBoostSw::kRanges = {
MAKE_RANGE(BassBoost, strengthPm, 0, 1000)};
const Capability BassBoostSw::kCapability = {.range = {BassBoostSw::kRanges}};
const Descriptor BassBoostSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidBassBoost(),
.uuid = getEffectImplUuidBassBoostSw()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = BassBoostSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = BassBoostSw::kCapability};
ndk::ScopedAStatus BassBoostSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BassBoostSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::bassBoost != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& bbParam = specific.get<Parameter::Specific::bassBoost>();
RETURN_IF(!inRange(bbParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = bbParam.getTag();
switch (tag) {
case BassBoost::strengthPm: {
const auto strength = bbParam.get<BassBoost::strengthPm>();
RETURN_IF(mContext->setBbStrengthPm(strength) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
"strengthPmNotSupported");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"BassBoostTagNotSupported");
}
}
}
ndk::ScopedAStatus BassBoostSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::bassBoostTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto bbId = id.get<Parameter::Id::bassBoostTag>();
auto bbIdTag = bbId.getTag();
switch (bbIdTag) {
case BassBoost::Id::commonTag:
return getParameterBassBoost(bbId.get<BassBoost::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"BassBoostTagNotSupported");
}
}
ndk::ScopedAStatus BassBoostSw::getParameterBassBoost(const BassBoost::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
BassBoost bbParam;
switch (tag) {
case BassBoost::strengthPm: {
bbParam.set<BassBoost::strengthPm>(mContext->getBbStrengthPm());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"BassBoostTagNotSupported");
}
}
specific->set<Parameter::Specific::bassBoost>(bbParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> BassBoostSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<BassBoostSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode BassBoostSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status BassBoostSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode BassBoostSwContext::setBbStrengthPm(int strength) {
mStrength = strength;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,73 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class BassBoostSwContext final : public EffectContext {
public:
BassBoostSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setBbStrengthPm(int strength);
int getBbStrengthPm() const { return mStrength; }
private:
int mStrength = 0;
};
class BassBoostSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
BassBoostSw() { LOG(DEBUG) << __func__; }
~BassBoostSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
private:
static const std::vector<Range::BassBoostRange> kRanges;
std::shared_ptr<BassBoostSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libdownmixsw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"DownmixSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default",
],
}

View File

@@ -1,164 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#define LOG_TAG "AHAL_DownmixSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "DownmixSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::DownmixSw;
using aidl::android::hardware::audio::effect::getEffectImplUuidDownmixSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDownmixSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<DownmixSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDownmixSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = DownmixSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string DownmixSw::kEffectName = "DownmixSw";
const Descriptor DownmixSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidDownmix(),
.uuid = getEffectImplUuidDownmixSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = kEffectName,
.implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus DownmixSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus DownmixSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::downmix != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& dmParam = specific.get<Parameter::Specific::downmix>();
auto tag = dmParam.getTag();
switch (tag) {
case Downmix::type: {
RETURN_IF(mContext->setDmType(dmParam.get<Downmix::type>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setTypeFailed");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"DownmixTagNotSupported");
}
}
}
ndk::ScopedAStatus DownmixSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::downmixTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto dmId = id.get<Parameter::Id::downmixTag>();
auto dmIdTag = dmId.getTag();
switch (dmIdTag) {
case Downmix::Id::commonTag:
return getParameterDownmix(dmId.get<Downmix::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"DownmixTagNotSupported");
}
}
ndk::ScopedAStatus DownmixSw::getParameterDownmix(const Downmix::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
Downmix dmParam;
switch (tag) {
case Downmix::type: {
dmParam.set<Downmix::type>(mContext->getDmType());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"DownmixTagNotSupported");
}
}
specific->set<Parameter::Specific::downmix>(dmParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> DownmixSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<DownmixSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode DownmixSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status DownmixSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,77 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class DownmixSwContext final : public EffectContext {
public:
DownmixSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setDmType(Downmix::Type type) {
// TODO : Add implementation to apply new type
mType = type;
return RetCode::SUCCESS;
}
Downmix::Type getDmType() const { return mType; }
private:
Downmix::Type mType = Downmix::Type::STRIP;
};
class DownmixSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
DownmixSw() { LOG(DEBUG) << __func__; }
~DownmixSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int sample)
REQUIRES(mImplMutex) override;
private:
std::shared_ptr<DownmixSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libdynamicsprocessingsw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"DynamicsProcessingSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default",
],
}

View File

@@ -1,523 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#include <set>
#include <unordered_set>
#define LOG_TAG "AHAL_DynamicsProcessingSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "DynamicsProcessingSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::DynamicsProcessingSw;
using aidl::android::hardware::audio::effect::getEffectImplUuidDynamicsProcessingSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDynamicsProcessingSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<DynamicsProcessingSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDynamicsProcessingSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = DynamicsProcessingSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string DynamicsProcessingSw::kEffectName = "DynamicsProcessingSw";
const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMin =
DynamicsProcessing::EqBandConfig({.channel = 0,
.band = 0,
.enable = false,
.cutoffFrequencyHz = 220,
.gainDb = std::numeric_limits<float>::min()});
const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMax =
DynamicsProcessing::EqBandConfig({.channel = std::numeric_limits<int>::max(),
.band = std::numeric_limits<int>::max(),
.enable = true,
.cutoffFrequencyHz = 20000,
.gainDb = std::numeric_limits<float>::max()});
const Range::DynamicsProcessingRange DynamicsProcessingSw::kPreEqBandRange = {
.min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
{DynamicsProcessingSw::kEqBandConfigMin}),
.max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
{DynamicsProcessingSw::kEqBandConfigMax})};
const Range::DynamicsProcessingRange DynamicsProcessingSw::kPostEqBandRange = {
.min = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
{DynamicsProcessingSw::kEqBandConfigMin}),
.max = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
{DynamicsProcessingSw::kEqBandConfigMax})};
const std::vector<Range::DynamicsProcessingRange> DynamicsProcessingSw::kRanges = {
DynamicsProcessingSw::kPreEqBandRange, DynamicsProcessingSw::kPostEqBandRange};
const Capability DynamicsProcessingSw::kCapability = {.range = DynamicsProcessingSw::kRanges};
const Descriptor DynamicsProcessingSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidDynamicsProcessing(),
.uuid = getEffectImplUuidDynamicsProcessingSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::POST_PROC,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = DynamicsProcessingSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = DynamicsProcessingSw::kCapability};
ndk::ScopedAStatus DynamicsProcessingSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus DynamicsProcessingSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::dynamicsProcessing != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
LOG(INFO) << __func__ << specific.toString();
auto& dpParam = specific.get<Parameter::Specific::dynamicsProcessing>();
auto tag = dpParam.getTag();
switch (tag) {
case DynamicsProcessing::engineArchitecture: {
RETURN_IF(mContext->setEngineArchitecture(
dpParam.get<DynamicsProcessing::engineArchitecture>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setEngineArchitectureFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::preEq: {
RETURN_IF(mContext->setPreEqChannelCfgs(dpParam.get<DynamicsProcessing::preEq>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setPreEqChannelCfgsFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::postEq: {
RETURN_IF(mContext->setPostEqChannelCfgs(dpParam.get<DynamicsProcessing::postEq>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setPostEqChannelCfgsFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::mbc: {
RETURN_IF(mContext->setMbcChannelCfgs(dpParam.get<DynamicsProcessing::mbc>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setMbcChannelCfgsFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::preEqBand: {
RETURN_IF(mContext->setPreEqBandCfgs(dpParam.get<DynamicsProcessing::preEqBand>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setPreEqBandCfgsFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::postEqBand: {
RETURN_IF(mContext->setPostEqBandCfgs(dpParam.get<DynamicsProcessing::postEqBand>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setPostEqBandCfgsFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::mbcBand: {
RETURN_IF(mContext->setMbcBandCfgs(dpParam.get<DynamicsProcessing::mbcBand>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setMbcBandCfgsFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::limiter: {
RETURN_IF(mContext->setLimiterCfgs(dpParam.get<DynamicsProcessing::limiter>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "limiterCfgsFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::inputGain: {
RETURN_IF(mContext->setInputGainCfgs(dpParam.get<DynamicsProcessing::inputGain>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "inputGainCfgFailed");
return ndk::ScopedAStatus::ok();
}
case DynamicsProcessing::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
}
}
}
ndk::ScopedAStatus DynamicsProcessingSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::dynamicsProcessingTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto dpId = id.get<Parameter::Id::dynamicsProcessingTag>();
auto dpIdTag = dpId.getTag();
switch (dpIdTag) {
case DynamicsProcessing::Id::commonTag:
return getParameterDynamicsProcessing(dpId.get<DynamicsProcessing::Id::commonTag>(),
specific);
case DynamicsProcessing::Id::vendorExtensionTag:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(dpIdTag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
}
}
ndk::ScopedAStatus DynamicsProcessingSw::getParameterDynamicsProcessing(
const DynamicsProcessing::Tag& tag, Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
DynamicsProcessing dpParam;
switch (tag) {
case DynamicsProcessing::Tag::engineArchitecture: {
dpParam.set<DynamicsProcessing::engineArchitecture>(mContext->getEngineArchitecture());
break;
}
case DynamicsProcessing::Tag::preEq: {
dpParam.set<DynamicsProcessing::preEq>(mContext->getPreEqChannelCfgs());
break;
}
case DynamicsProcessing::Tag::postEq: {
dpParam.set<DynamicsProcessing::postEq>(mContext->getPostEqChannelCfgs());
break;
}
case DynamicsProcessing::Tag::mbc: {
dpParam.set<DynamicsProcessing::mbc>(mContext->getMbcChannelCfgs());
break;
}
case DynamicsProcessing::Tag::preEqBand: {
dpParam.set<DynamicsProcessing::preEqBand>(mContext->getPreEqBandCfgs());
break;
}
case DynamicsProcessing::Tag::postEqBand: {
dpParam.set<DynamicsProcessing::postEqBand>(mContext->getPostEqBandCfgs());
break;
}
case DynamicsProcessing::Tag::mbcBand: {
dpParam.set<DynamicsProcessing::mbcBand>(mContext->getMbcBandCfgs());
break;
}
case DynamicsProcessing::Tag::limiter: {
dpParam.set<DynamicsProcessing::limiter>(mContext->getLimiterCfgs());
break;
}
case DynamicsProcessing::Tag::inputGain: {
dpParam.set<DynamicsProcessing::inputGain>(mContext->getInputGainCfgs());
break;
}
case DynamicsProcessing::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
}
}
specific->set<Parameter::Specific::dynamicsProcessing>(dpParam);
LOG(INFO) << __func__ << specific->toString();
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> DynamicsProcessingSw::createContext(
const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<DynamicsProcessingSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode DynamicsProcessingSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status DynamicsProcessingSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode DynamicsProcessingSwContext::setCommon(const Parameter::Common& common) {
if (auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
return ret;
}
mCommon = common;
mChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
common.input.base.channelMask);
resizeChannels();
resizeBands();
LOG(INFO) << __func__ << mCommon.toString();
return RetCode::SUCCESS;
}
RetCode DynamicsProcessingSwContext::setEngineArchitecture(
const DynamicsProcessing::EngineArchitecture& cfg) {
RETURN_VALUE_IF(!validateEngineConfig(cfg), RetCode::ERROR_ILLEGAL_PARAMETER,
"illegalEngineConfig");
if (mEngineSettings == cfg) {
LOG(INFO) << __func__ << " not change in engine, do nothing";
return RetCode::SUCCESS;
}
mEngineSettings = cfg;
resizeBands();
return RetCode::SUCCESS;
}
RetCode DynamicsProcessingSwContext::setChannelCfgs(
const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,
std::vector<DynamicsProcessing::ChannelConfig>& targetCfgs,
const DynamicsProcessing::StageEnablement& stage) {
RETURN_VALUE_IF(!stage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER, "stageNotInUse");
RetCode ret = RetCode::SUCCESS;
std::unordered_set<int> channelSet;
for (auto& cfg : cfgs) {
if (cfg.channel < 0 || (size_t)cfg.channel >= mChannelCount) {
LOG(ERROR) << __func__ << " skip illegal channel config " << cfg.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
continue;
}
if (0 != channelSet.count(cfg.channel)) {
LOG(WARNING) << __func__ << " duplicated channel " << cfg.channel;
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
} else {
channelSet.insert(cfg.channel);
}
targetCfgs[cfg.channel] = cfg;
}
return ret;
}
RetCode DynamicsProcessingSwContext::setPreEqChannelCfgs(
const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
return setChannelCfgs(cfgs, mPreEqChCfgs, mEngineSettings.preEqStage);
}
RetCode DynamicsProcessingSwContext::setPostEqChannelCfgs(
const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
return setChannelCfgs(cfgs, mPostEqChCfgs, mEngineSettings.postEqStage);
}
RetCode DynamicsProcessingSwContext::setMbcChannelCfgs(
const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
return setChannelCfgs(cfgs, mMbcChCfgs, mEngineSettings.mbcStage);
}
RetCode DynamicsProcessingSwContext::setEqBandCfgs(
const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
std::vector<DynamicsProcessing::EqBandConfig>& targetCfgs,
const DynamicsProcessing::StageEnablement& stage,
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
RETURN_VALUE_IF(!stage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER, "eqStageNotInUse");
RetCode ret = RetCode::SUCCESS;
std::set<std::pair<int /* channel */, int /* band */>> bandSet;
for (auto& cfg : cfgs) {
if (0 != bandSet.count({cfg.channel, cfg.band})) {
LOG(WARNING) << __func__ << " duplicated band " << cfg.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
} else {
bandSet.insert({cfg.channel, cfg.band});
}
if (!validateEqBandConfig(cfg, mChannelCount, stage.bandCount, channelConfig)) {
LOG(WARNING) << __func__ << " skip invalid band " << cfg.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
continue;
}
targetCfgs[cfg.channel * stage.bandCount + cfg.band] = cfg;
}
return ret;
}
RetCode DynamicsProcessingSwContext::setPreEqBandCfgs(
const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
return setEqBandCfgs(cfgs, mPreEqChBands, mEngineSettings.preEqStage, mPreEqChCfgs);
}
RetCode DynamicsProcessingSwContext::setPostEqBandCfgs(
const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
return setEqBandCfgs(cfgs, mPostEqChBands, mEngineSettings.postEqStage, mPostEqChCfgs);
}
RetCode DynamicsProcessingSwContext::setMbcBandCfgs(
const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs) {
RETURN_VALUE_IF(!mEngineSettings.mbcStage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER,
"mbcNotInUse");
RetCode ret = RetCode::SUCCESS;
std::set<std::pair<int /* channel */, int /* band */>> bandSet;
int bandCount = mEngineSettings.mbcStage.bandCount;
std::vector<bool> filled(mChannelCount * bandCount, false);
for (auto& it : cfgs) {
if (0 != bandSet.count({it.channel, it.band})) {
LOG(WARNING) << __func__ << " duplicated band " << it.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
} else {
bandSet.insert({it.channel, it.band});
}
if (!validateMbcBandConfig(it, mChannelCount, mEngineSettings.mbcStage.bandCount,
mMbcChCfgs)) {
LOG(WARNING) << __func__ << " skip invalid band " << it.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
continue;
}
mMbcChBands[it.channel * bandCount + it.band] = it;
}
return ret;
}
RetCode DynamicsProcessingSwContext::setLimiterCfgs(
const std::vector<DynamicsProcessing::LimiterConfig>& cfgs) {
RETURN_VALUE_IF(!mEngineSettings.limiterInUse, RetCode::ERROR_ILLEGAL_PARAMETER,
"limiterNotInUse");
RetCode ret = RetCode::SUCCESS;
std::unordered_set<int> channelSet;
for (auto& it : cfgs) {
if (0 != channelSet.count(it.channel)) {
LOG(WARNING) << __func__ << " duplicated channel " << it.channel;
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
} else {
channelSet.insert(it.channel);
}
if (!validateLimiterConfig(it, mChannelCount)) {
LOG(WARNING) << __func__ << " skip invalid limiter " << it.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
continue;
}
mLimiterCfgs[it.channel] = it;
}
return ret;
}
void DynamicsProcessingSwContext::resizeChannels() {
if (mPreEqChCfgs.size() != mChannelCount) {
mPreEqChCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
}
if (mPostEqChCfgs.size() != mChannelCount) {
mPostEqChCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
}
if (mMbcChCfgs.size() != mChannelCount) {
mMbcChCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
}
if (mLimiterCfgs.size() != mChannelCount) {
mLimiterCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
}
if (mInputGainCfgs.size() != mChannelCount) {
mInputGainCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
}
}
void DynamicsProcessingSwContext::resizeBands() {
if (mPreEqChBands.size() != (size_t)(mChannelCount * mEngineSettings.preEqStage.bandCount)) {
mPreEqChBands.resize(mChannelCount * mEngineSettings.preEqStage.bandCount,
{.channel = kInvalidChannelId});
}
if (mPostEqChBands.size() != (size_t)(mChannelCount * mEngineSettings.postEqStage.bandCount)) {
mPostEqChBands.resize(mChannelCount * mEngineSettings.postEqStage.bandCount,
{.channel = kInvalidChannelId});
}
if (mMbcChBands.size() != (size_t)(mChannelCount * mEngineSettings.mbcStage.bandCount)) {
mMbcChBands.resize(mChannelCount * mEngineSettings.mbcStage.bandCount,
{.channel = kInvalidChannelId});
}
}
RetCode DynamicsProcessingSwContext::setInputGainCfgs(
const std::vector<DynamicsProcessing::InputGain>& cfgs) {
for (const auto& cfg : cfgs) {
RETURN_VALUE_IF(cfg.channel < 0 || (size_t)cfg.channel >= mChannelCount,
RetCode::ERROR_ILLEGAL_PARAMETER, "invalidChannel");
mInputGainCfgs[cfg.channel] = cfg;
}
return RetCode::SUCCESS;
}
std::vector<DynamicsProcessing::InputGain> DynamicsProcessingSwContext::getInputGainCfgs() {
std::vector<DynamicsProcessing::InputGain> ret;
std::copy_if(mInputGainCfgs.begin(), mInputGainCfgs.end(), std::back_inserter(ret),
[&](const auto& gain) { return gain.channel != kInvalidChannelId; });
return ret;
}
bool DynamicsProcessingSwContext::validateStageEnablement(
const DynamicsProcessing::StageEnablement& enablement) {
return !enablement.inUse || (enablement.inUse && enablement.bandCount > 0);
}
bool DynamicsProcessingSwContext::validateEngineConfig(
const DynamicsProcessing::EngineArchitecture& engine) {
return engine.preferredProcessingDurationMs >= 0 &&
validateStageEnablement(engine.preEqStage) &&
validateStageEnablement(engine.postEqStage) && validateStageEnablement(engine.mbcStage);
}
bool DynamicsProcessingSwContext::validateEqBandConfig(
const DynamicsProcessing::EqBandConfig& band, int maxChannel, int maxBand,
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
return band.channel >= 0 && band.channel < maxChannel &&
(size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
band.band >= 0 && band.band < maxBand;
}
bool DynamicsProcessingSwContext::validateMbcBandConfig(
const DynamicsProcessing::MbcBandConfig& band, int maxChannel, int maxBand,
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
return band.channel >= 0 && band.channel < maxChannel &&
(size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
band.band >= 0 && band.band < maxBand && band.attackTimeMs >= 0 &&
band.releaseTimeMs >= 0 && band.ratio >= 0 && band.thresholdDb <= 0 &&
band.kneeWidthDb <= 0 && band.noiseGateThresholdDb <= 0 && band.expanderRatio >= 0;
}
bool DynamicsProcessingSwContext::validateLimiterConfig(
const DynamicsProcessing::LimiterConfig& limiter, int maxChannel) {
return limiter.channel >= 0 && limiter.channel < maxChannel && limiter.attackTimeMs >= 0 &&
limiter.releaseTimeMs >= 0 && limiter.ratio >= 0 && limiter.thresholdDb <= 0;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,142 +0,0 @@
/*
* 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 <cstdlib>
#include <memory>
#include <vector>
#include <Utils.h>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class DynamicsProcessingSwContext final : public EffectContext {
public:
DynamicsProcessingSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common),
mChannelCount(::aidl::android::hardware::audio::common::getChannelCount(
common.input.base.channelMask)),
mPreEqChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
mPostEqChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
mMbcChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
mLimiterCfgs(mChannelCount, {.channel = kInvalidChannelId}) {
LOG(DEBUG) << __func__;
}
// utils
RetCode setChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,
std::vector<DynamicsProcessing::ChannelConfig>& targetCfgs,
const DynamicsProcessing::StageEnablement& engineSetting);
RetCode setEqBandCfgs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
std::vector<DynamicsProcessing::EqBandConfig>& targetCfgs,
const DynamicsProcessing::StageEnablement& stage,
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig);
// set params
RetCode setCommon(const Parameter::Common& common) override;
RetCode setEngineArchitecture(const DynamicsProcessing::EngineArchitecture& cfg);
RetCode setPreEqChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs);
RetCode setPostEqChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs);
RetCode setMbcChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs);
RetCode setPreEqBandCfgs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
RetCode setPostEqBandCfgs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
RetCode setMbcBandCfgs(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs);
RetCode setLimiterCfgs(const std::vector<DynamicsProcessing::LimiterConfig>& cfgs);
RetCode setInputGainCfgs(const std::vector<DynamicsProcessing::InputGain>& cfgs);
// get params
DynamicsProcessing::EngineArchitecture getEngineArchitecture() { return mEngineSettings; }
std::vector<DynamicsProcessing::ChannelConfig> getPreEqChannelCfgs() { return mPreEqChCfgs; }
std::vector<DynamicsProcessing::ChannelConfig> getPostEqChannelCfgs() { return mPostEqChCfgs; }
std::vector<DynamicsProcessing::ChannelConfig> getMbcChannelCfgs() { return mMbcChCfgs; }
std::vector<DynamicsProcessing::EqBandConfig> getPreEqBandCfgs() { return mPreEqChBands; }
std::vector<DynamicsProcessing::EqBandConfig> getPostEqBandCfgs() { return mPostEqChBands; }
std::vector<DynamicsProcessing::MbcBandConfig> getMbcBandCfgs() { return mMbcChBands; }
std::vector<DynamicsProcessing::LimiterConfig> getLimiterCfgs() { return mLimiterCfgs; }
std::vector<DynamicsProcessing::InputGain> getInputGainCfgs();
private:
static constexpr int32_t kInvalidChannelId = -1;
size_t mChannelCount = 0;
DynamicsProcessing::EngineArchitecture mEngineSettings;
// Channel config vector with size of mChannelCount
std::vector<DynamicsProcessing::ChannelConfig> mPreEqChCfgs;
std::vector<DynamicsProcessing::ChannelConfig> mPostEqChCfgs;
std::vector<DynamicsProcessing::ChannelConfig> mMbcChCfgs;
std::vector<DynamicsProcessing::LimiterConfig> mLimiterCfgs;
std::vector<DynamicsProcessing::InputGain> mInputGainCfgs;
// Band config vector with size of mChannelCount * bandCount
std::vector<DynamicsProcessing::EqBandConfig> mPreEqChBands;
std::vector<DynamicsProcessing::EqBandConfig> mPostEqChBands;
std::vector<DynamicsProcessing::MbcBandConfig> mMbcChBands;
bool validateStageEnablement(const DynamicsProcessing::StageEnablement& enablement);
bool validateEngineConfig(const DynamicsProcessing::EngineArchitecture& engine);
bool validateEqBandConfig(const DynamicsProcessing::EqBandConfig& band, int maxChannel,
int maxBand,
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig);
bool validateMbcBandConfig(const DynamicsProcessing::MbcBandConfig& band, int maxChannel,
int maxBand,
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig);
bool validateLimiterConfig(const DynamicsProcessing::LimiterConfig& limiter, int maxChannel);
void resizeChannels();
void resizeBands();
}; // DynamicsProcessingSwContext
class DynamicsProcessingSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
DynamicsProcessingSw() { LOG(DEBUG) << __func__; }
~DynamicsProcessingSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
private:
static const DynamicsProcessing::EqBandConfig kEqBandConfigMin;
static const DynamicsProcessing::EqBandConfig kEqBandConfigMax;
static const Range::DynamicsProcessingRange kPreEqBandRange;
static const Range::DynamicsProcessingRange kPostEqBandRange;
static const std::vector<Range::DynamicsProcessingRange> kRanges;
std::shared_ptr<DynamicsProcessingSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
}; // DynamicsProcessingSw
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libenvreverbsw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"EnvReverbSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,327 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#include <unordered_set>
#define LOG_TAG "AHAL_EnvReverbSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "EnvReverbSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::EnvReverbSw;
using aidl::android::hardware::audio::effect::getEffectImplUuidEnvReverbSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<EnvReverbSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = EnvReverbSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
const std::vector<Range::EnvironmentalReverbRange> EnvReverbSw::kRanges = {
MAKE_RANGE(EnvironmentalReverb, roomLevelMb, -6000, 0),
MAKE_RANGE(EnvironmentalReverb, roomHfLevelMb, -4000, 0),
MAKE_RANGE(EnvironmentalReverb, decayTimeMs, 0, 7000),
MAKE_RANGE(EnvironmentalReverb, decayHfRatioPm, 100, 2000),
MAKE_RANGE(EnvironmentalReverb, reflectionsLevelMb, -6000, 0),
MAKE_RANGE(EnvironmentalReverb, reflectionsDelayMs, 0, 65),
MAKE_RANGE(EnvironmentalReverb, levelMb, -6000, 0),
MAKE_RANGE(EnvironmentalReverb, delayMs, 0, 65),
MAKE_RANGE(EnvironmentalReverb, diffusionPm, 0, 1000),
MAKE_RANGE(EnvironmentalReverb, densityPm, 0, 1000)};
const Capability EnvReverbSw::kCapability = {
.range = Range::make<Range::environmentalReverb>(EnvReverbSw::kRanges)};
const Descriptor EnvReverbSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidEnvReverb(),
.uuid = getEffectImplUuidEnvReverbSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = EnvReverbSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = EnvReverbSw::kCapability};
ndk::ScopedAStatus EnvReverbSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus EnvReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::environmentalReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
RETURN_IF(!inRange(erParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = erParam.getTag();
switch (tag) {
case EnvironmentalReverb::roomLevelMb: {
RETURN_IF(mContext->setErRoomLevel(erParam.get<EnvironmentalReverb::roomLevelMb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::roomHfLevelMb: {
RETURN_IF(
mContext->setErRoomHfLevel(erParam.get<EnvironmentalReverb::roomHfLevelMb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::decayTimeMs: {
RETURN_IF(mContext->setErDecayTime(erParam.get<EnvironmentalReverb::decayTimeMs>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::decayHfRatioPm: {
RETURN_IF(
mContext->setErDecayHfRatio(
erParam.get<EnvironmentalReverb::decayHfRatioPm>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::reflectionsLevelMb: {
RETURN_IF(mContext->setErReflectionsLevel(
erParam.get<EnvironmentalReverb::reflectionsLevelMb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setReflectionsLevelFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::reflectionsDelayMs: {
RETURN_IF(mContext->setErReflectionsDelay(
erParam.get<EnvironmentalReverb::reflectionsDelayMs>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setReflectionsDelayFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::levelMb: {
RETURN_IF(mContext->setErLevel(erParam.get<EnvironmentalReverb::levelMb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setLevelFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::delayMs: {
RETURN_IF(mContext->setErDelay(erParam.get<EnvironmentalReverb::delayMs>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDelayFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::diffusionPm: {
RETURN_IF(mContext->setErDiffusion(erParam.get<EnvironmentalReverb::diffusionPm>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDiffusionFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::densityPm: {
RETURN_IF(mContext->setErDensity(erParam.get<EnvironmentalReverb::densityPm>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDensityFailed");
return ndk::ScopedAStatus::ok();
}
case EnvironmentalReverb::bypass: {
RETURN_IF(mContext->setErBypass(erParam.get<EnvironmentalReverb::bypass>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setBypassFailed");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
}
}
}
ndk::ScopedAStatus EnvReverbSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::environmentalReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto erId = id.get<Parameter::Id::environmentalReverbTag>();
auto erIdTag = erId.getTag();
switch (erIdTag) {
case EnvironmentalReverb::Id::commonTag:
return getParameterEnvironmentalReverb(erId.get<EnvironmentalReverb::Id::commonTag>(),
specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(erIdTag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
}
}
ndk::ScopedAStatus EnvReverbSw::getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
EnvironmentalReverb erParam;
switch (tag) {
case EnvironmentalReverb::roomLevelMb: {
erParam.set<EnvironmentalReverb::roomLevelMb>(mContext->getErRoomLevel());
break;
}
case EnvironmentalReverb::roomHfLevelMb: {
erParam.set<EnvironmentalReverb::roomHfLevelMb>(mContext->getErRoomHfLevel());
break;
}
case EnvironmentalReverb::decayTimeMs: {
erParam.set<EnvironmentalReverb::decayTimeMs>(mContext->getErDecayTime());
break;
}
case EnvironmentalReverb::decayHfRatioPm: {
erParam.set<EnvironmentalReverb::decayHfRatioPm>(mContext->getErDecayHfRatio());
break;
}
case EnvironmentalReverb::reflectionsLevelMb: {
erParam.set<EnvironmentalReverb::reflectionsLevelMb>(mContext->getErReflectionsLevel());
break;
}
case EnvironmentalReverb::reflectionsDelayMs: {
erParam.set<EnvironmentalReverb::reflectionsDelayMs>(mContext->getErReflectionsDelay());
break;
}
case EnvironmentalReverb::levelMb: {
erParam.set<EnvironmentalReverb::levelMb>(mContext->getErLevel());
break;
}
case EnvironmentalReverb::delayMs: {
erParam.set<EnvironmentalReverb::delayMs>(mContext->getErDelay());
break;
}
case EnvironmentalReverb::diffusionPm: {
erParam.set<EnvironmentalReverb::diffusionPm>(mContext->getErDiffusion());
break;
}
case EnvironmentalReverb::densityPm: {
erParam.set<EnvironmentalReverb::densityPm>(mContext->getErDensity());
break;
}
case EnvironmentalReverb::bypass: {
erParam.set<EnvironmentalReverb::bypass>(mContext->getErBypass());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
}
}
specific->set<Parameter::Specific::environmentalReverb>(erParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> EnvReverbSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<EnvReverbSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode EnvReverbSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status EnvReverbSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
mRoomLevel = roomLevel;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
mRoomHfLevel = roomHfLevel;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
mDecayTime = decayTime;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
mDecayHfRatio = decayHfRatio;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErLevel(int level) {
mLevel = level;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDelay(int delay) {
mDelay = delay;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
mDiffusion = diffusion;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDensity(int density) {
mDensity = density;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,122 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class EnvReverbSwContext final : public EffectContext {
public:
EnvReverbSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setErRoomLevel(int roomLevel);
int getErRoomLevel() const { return mRoomLevel; }
RetCode setErRoomHfLevel(int roomHfLevel);
int getErRoomHfLevel() const { return mRoomHfLevel; }
RetCode setErDecayTime(int decayTime);
int getErDecayTime() const { return mDecayTime; }
RetCode setErDecayHfRatio(int decayHfRatio);
int getErDecayHfRatio() const { return mDecayHfRatio; }
RetCode setErLevel(int level);
int getErLevel() const { return mLevel; }
RetCode setErDelay(int delay);
int getErDelay() const { return mDelay; }
RetCode setErDiffusion(int diffusion);
int getErDiffusion() const { return mDiffusion; }
RetCode setErDensity(int density);
int getErDensity() const { return mDensity; }
RetCode setErBypass(bool bypass) {
mBypass = bypass;
return RetCode::SUCCESS;
}
bool getErBypass() const { return mBypass; }
RetCode setErReflectionsDelay(int delay) {
mReflectionsDelayMs = delay;
return RetCode::SUCCESS;
}
bool getErReflectionsDelay() const { return mReflectionsDelayMs; }
RetCode setErReflectionsLevel(int level) {
mReflectionsLevelMb = level;
return RetCode::SUCCESS;
}
bool getErReflectionsLevel() const { return mReflectionsLevelMb; }
private:
int mRoomLevel = -6000; // Default room level
int mRoomHfLevel = 0; // Default room hf level
int mDecayTime = 1000; // Default decay time
int mDecayHfRatio = 500; // Default decay hf ratio
int mLevel = -6000; // Default level
int mDelay = 40; // Default delay
int mReflectionsLevelMb = 0;
int mReflectionsDelayMs = 0;
int mDiffusion = 1000; // Default diffusion
int mDensity = 1000; // Default density
bool mBypass = false; // Default bypass
};
class EnvReverbSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
EnvReverbSw() { LOG(DEBUG) << __func__; }
~EnvReverbSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::EnvironmentalReverbRange> kRanges;
std::shared_ptr<EnvReverbSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libequalizersw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"EqualizerSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,218 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#define LOG_TAG "AHAL_EqualizerSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "EqualizerSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::EqualizerSw;
using aidl::android::hardware::audio::effect::getEffectImplUuidEqualizerSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEqualizerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<EqualizerSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEqualizerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = EqualizerSw::kDesc;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string EqualizerSw::kEffectName = "EqualizerSw";
const std::vector<Equalizer::BandFrequency> EqualizerSw::kBandFrequency = {{0, 30000, 120000},
{1, 120001, 460000},
{2, 460001, 1800000},
{3, 1800001, 7000000},
{4, 7000001, 20000000}};
const std::vector<Equalizer::Preset> EqualizerSw::kPresets = {
{0, "Normal"}, {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
{5, "Heavy Metal"}, {6, "Hip Hop"}, {7, "Jazz"}, {8, "Pop"}, {9, "Rock"}};
/**
* Use the same min and max to build a capability represented by Range.
*/
const std::vector<Range::EqualizerRange> EqualizerSw::kRanges = {
MAKE_RANGE(Equalizer, preset, 0, EqualizerSw::kPresets.size() - 1),
MAKE_RANGE(Equalizer, bandLevels,
std::vector<Equalizer::BandLevel>{
Equalizer::BandLevel({.index = 0, .levelMb = -15})},
std::vector<Equalizer::BandLevel>{Equalizer::BandLevel(
{.index = EqualizerSwContext::kMaxBandNumber - 1, .levelMb = 15})}),
/* capability definition */
MAKE_RANGE(Equalizer, bandFrequencies, EqualizerSw::kBandFrequency,
EqualizerSw::kBandFrequency),
MAKE_RANGE(Equalizer, presets, EqualizerSw::kPresets, EqualizerSw::kPresets),
/* centerFreqMh is get only, set invalid range min > max */
MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({0}))};
const Capability EqualizerSw::kEqCap = {.range = EqualizerSw::kRanges};
const Descriptor EqualizerSw::kDesc = {.common = {.id = {.type = getEffectTypeUuidEqualizer(),
.uuid = getEffectImplUuidEqualizerSw()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = EqualizerSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = EqualizerSw::kEqCap};
ndk::ScopedAStatus EqualizerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDesc.toString();
*_aidl_return = kDesc;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus EqualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::equalizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& eqParam = specific.get<Parameter::Specific::equalizer>();
RETURN_IF(!inRange(eqParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = eqParam.getTag();
switch (tag) {
case Equalizer::preset: {
RETURN_IF(mContext->setEqPreset(eqParam.get<Equalizer::preset>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setBandLevelsFailed");
return ndk::ScopedAStatus::ok();
}
case Equalizer::bandLevels: {
RETURN_IF(mContext->setEqBandLevels(eqParam.get<Equalizer::bandLevels>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setBandLevelsFailed");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"EqTagNotSupported");
}
}
LOG(ERROR) << __func__ << " unsupported eq param tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"ParamNotSupported");
}
ndk::ScopedAStatus EqualizerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::equalizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto eqId = id.get<Parameter::Id::equalizerTag>();
auto eqIdTag = eqId.getTag();
switch (eqIdTag) {
case Equalizer::Id::commonTag:
return getParameterEqualizer(eqId.get<Equalizer::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " tag " << toString(eqIdTag) << " not supported";
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"EqualizerTagNotSupported");
}
}
ndk::ScopedAStatus EqualizerSw::getParameterEqualizer(const Equalizer::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
Equalizer eqParam;
switch (tag) {
case Equalizer::bandLevels: {
eqParam.set<Equalizer::bandLevels>(mContext->getEqBandLevels());
break;
}
case Equalizer::preset: {
eqParam.set<Equalizer::preset>(mContext->getEqPreset());
break;
}
case Equalizer::centerFreqMh: {
eqParam.set<Equalizer::centerFreqMh>(mContext->getCenterFreqs());
break;
}
case Equalizer::bandFrequencies: {
eqParam.set<Equalizer::bandFrequencies>(kBandFrequency);
break;
}
case Equalizer::presets: {
eqParam.set<Equalizer::presets>(kPresets);
break;
}
default: {
LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"unsupportedTag");
}
}
specific->set<Parameter::Specific::equalizer>(eqParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> EqualizerSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<EqualizerSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode EqualizerSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status EqualizerSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,122 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class EqualizerSwContext final : public EffectContext {
public:
EqualizerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setEqPreset(const int& presetIdx) {
if (presetIdx < 0 || presetIdx >= kMaxPresetNumber) {
return RetCode::ERROR_ILLEGAL_PARAMETER;
}
mPreset = presetIdx;
return RetCode::SUCCESS;
}
int getEqPreset() { return mPreset; }
RetCode setEqBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels) {
if (bandLevels.size() > kMaxBandNumber) {
LOG(ERROR) << __func__ << " return because size exceed " << kMaxBandNumber;
return RetCode::ERROR_ILLEGAL_PARAMETER;
}
RetCode ret = RetCode::SUCCESS;
for (auto& it : bandLevels) {
if (it.index >= kMaxBandNumber || it.index < 0) {
LOG(ERROR) << __func__ << " index illegal, skip: " << it.index << " - "
<< it.levelMb;
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
} else {
mBandLevels[it.index] = it.levelMb;
}
}
return ret;
}
std::vector<Equalizer::BandLevel> getEqBandLevels() {
std::vector<Equalizer::BandLevel> bandLevels;
for (int i = 0; i < kMaxBandNumber; i++) {
bandLevels.push_back({i, mBandLevels[i]});
}
return bandLevels;
}
std::vector<int> getCenterFreqs() {
return {std::begin(kPresetsFrequencies), std::end(kPresetsFrequencies)};
}
static const int kMaxBandNumber = 5;
static const int kMaxPresetNumber = 10;
static const int kCustomPreset = -1;
private:
static constexpr std::array<uint16_t, kMaxBandNumber> kPresetsFrequencies = {60, 230, 910, 3600,
14000};
// preset band level
int mPreset = kCustomPreset;
int32_t mBandLevels[kMaxBandNumber] = {3, 0, 0, 0, 3};
// Add equalizer specific context for processing here
};
class EqualizerSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kEqCap;
static const Descriptor kDesc;
EqualizerSw() { LOG(DEBUG) << __func__; }
~EqualizerSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Equalizer::BandFrequency> kBandFrequency;
static const std::vector<Equalizer::Preset> kPresets;
static const std::vector<Range::EqualizerRange> kRanges;
ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Tag& tag,
Parameter::Specific* specific) REQUIRES(mImplMutex);
std::shared_ptr<EqualizerSwContext> mContext;
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2024 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "liberasersw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"Eraser.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,270 +0,0 @@
/*
* Copyright (C) 2024 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.
*/
#define LOG_TAG "AHAL_Eraser"
#include "Eraser.h"
#include <android-base/logging.h>
#include <system/audio_effects/effect_uuid.h>
#include <optional>
using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::EraserSw;
using aidl::android::hardware::audio::effect::getEffectImplUuidEraserSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidEraser;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEraserSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (!instanceSpp) {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
*instanceSpp = ndk::SharedRefBase::make<EraserSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEraserSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = EraserSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string EraserSw::kEffectName = "EraserSw";
const Descriptor EraserSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidEraser(), .uuid = getEffectImplUuidEraserSw()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.hwAcceleratorMode = Flags::HardwareAccelerator::NONE},
.name = EraserSw::kEffectName,
.implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus EraserSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus EraserSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::eraser != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::eraser>();
return mContext->setParam(param.getTag(), param);
}
ndk::ScopedAStatus EraserSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto tag = id.getTag();
RETURN_IF(Parameter::Id::eraserTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto eraserId = id.get<Parameter::Id::eraserTag>();
auto eraserTag = eraserId.getTag();
switch (eraserTag) {
case Eraser::Id::commonTag: {
auto specificTag = eraserId.get<Eraser::Id::commonTag>();
std::optional<Eraser> param = mContext->getParam(specificTag);
if (!param.has_value()) {
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"EraserTagNotSupported");
}
specific->set<Parameter::Specific::eraser>(param.value());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"EraserTagNotSupported");
}
}
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> EraserSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<EraserSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode EraserSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
EraserSw::~EraserSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus EraserSw::command(CommandId command) {
std::lock_guard lg(mImplMutex);
RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
switch (command) {
case CommandId::START:
RETURN_OK_IF(mState == State::PROCESSING);
mState = State::PROCESSING;
mContext->enable();
startThread();
RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
"notifyEventFlagNotEmptyFailed");
break;
case CommandId::STOP:
RETURN_OK_IF(mState == State::IDLE || mState == State::DRAINING);
if (mVersion < kDrainSupportedVersion) {
mState = State::IDLE;
stopThread();
mContext->disable();
} else {
mState = State::DRAINING;
startDraining();
mContext->startDraining();
}
RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
"notifyEventFlagNotEmptyFailed");
break;
case CommandId::RESET:
mState = State::IDLE;
RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
"notifyEventFlagNotEmptyFailed");
stopThread();
mImplContext->disable();
mImplContext->reset();
mImplContext->resetBuffer();
break;
default:
LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"CommandIdNotSupported");
}
LOG(VERBOSE) << getEffectNameWithVersion() << __func__
<< " transfer to state: " << toString(mState);
return ndk::ScopedAStatus::ok();
}
// Processing method running in EffectWorker thread.
IEffect::Status EraserSw::effectProcessImpl(float* in, float* out, int samples) {
RETURN_VALUE_IF(!mContext, (IEffect::Status{EX_NULL_POINTER, 0, 0}), "nullContext");
IEffect::Status procStatus{STATUS_NOT_ENOUGH_DATA, 0, 0};
procStatus = mContext->process(in, out, samples);
if (mState == State::DRAINING && procStatus.status == STATUS_NOT_ENOUGH_DATA) {
drainingComplete_l();
}
return procStatus;
}
void EraserSw::drainingComplete_l() {
if (mState != State::DRAINING) return;
LOG(DEBUG) << getEffectNameWithVersion() << __func__;
finishDraining();
mState = State::IDLE;
}
EraserSwContext::EraserSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
EraserSwContext::~EraserSwContext() {
LOG(DEBUG) << __func__;
}
template <typename TAG>
std::optional<Eraser> EraserSwContext::getParam(TAG tag) {
if (mParamsMap.find(tag) != mParamsMap.end()) {
return mParamsMap.at(tag);
}
return std::nullopt;
}
template <typename TAG>
ndk::ScopedAStatus EraserSwContext::setParam(TAG tag, Eraser eraser) {
mParamsMap[tag] = eraser;
return ndk::ScopedAStatus::ok();
}
IEffect::Status EraserSwContext::process(float* in, float* out, int samples) {
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
IEffect::Status procStatus = {EX_ILLEGAL_ARGUMENT, 0, 0};
const auto inputChannelCount = getChannelCount(mCommon.input.base.channelMask);
const auto outputChannelCount = getChannelCount(mCommon.output.base.channelMask);
if (inputChannelCount < outputChannelCount) {
LOG(ERROR) << __func__ << " invalid channel count, in: " << inputChannelCount
<< " out: " << outputChannelCount;
return procStatus;
}
if (samples <= 0 || 0 != samples % inputChannelCount) {
LOG(ERROR) << __func__ << " invalid samples: " << samples;
return procStatus;
}
const int iFrames = samples / inputChannelCount;
const float gainPerSample = 1.f / iFrames;
for (int i = 0; i < iFrames; i++) {
if (isDraining()) {
const float gain = (iFrames - i - 1) * gainPerSample;
for (size_t c = 0; c < outputChannelCount; c++) {
out[c] = in[c] * gain;
}
} else {
std::memcpy(out, in, outputChannelCount * sizeof(float));
}
in += inputChannelCount;
out += outputChannelCount;
}
// drain for one cycle
if (isDraining()) {
procStatus.status = STATUS_NOT_ENOUGH_DATA;
finishDraining();
} else {
procStatus.status = STATUS_OK;
}
procStatus.fmqConsumed = static_cast<int32_t>(iFrames * inputChannelCount);
procStatus.fmqProduced = static_cast<int32_t>(iFrames * outputChannelCount);
return procStatus;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) 2024 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 "effect-impl/EffectContext.h"
#include "effect-impl/EffectImpl.h"
#include <fmq/AidlMessageQueue.h>
#include <unordered_map>
#include <vector>
namespace aidl::android::hardware::audio::effect {
class EraserSwContext final : public EffectContext {
public:
EraserSwContext(int statusDepth, const Parameter::Common& common);
~EraserSwContext() final;
template <typename TAG>
std::optional<Eraser> getParam(TAG tag);
template <typename TAG>
ndk::ScopedAStatus setParam(TAG tag, Eraser eraser);
IEffect::Status process(float* in, float* out, int samples);
private:
std::unordered_map<Eraser::Tag, Eraser> mParamsMap;
};
class EraserSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
~EraserSw() final;
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) final;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) final;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) final;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) final;
RetCode releaseContext() REQUIRES(mImplMutex) final;
std::string getEffectName() final { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) final;
ndk::ScopedAStatus command(CommandId command) final;
void drainingComplete_l() REQUIRES(mImplMutex);
private:
static const std::vector<Range::SpatializerRange> kRanges;
std::shared_ptr<EraserSwContext> mContext GUARDED_BY(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libextensioneffect",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"ExtensionEffect.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,143 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
#include <algorithm>
#include <cstddef>
#include <memory>
#include <unordered_set>
#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
#define LOG_TAG "AHAL_ExtensionEffect"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "ExtensionEffect.h"
using aidl::android::hardware::audio::effect::DefaultExtension;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::ExtensionEffect;
using aidl::android::hardware::audio::effect::getEffectImplUuidExtension;
using aidl::android::hardware::audio::effect::getEffectTypeUuidExtension;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::Range;
using aidl::android::hardware::audio::effect::VendorExtension;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidExtension()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<ExtensionEffect>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidExtension()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = ExtensionEffect::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string ExtensionEffect::kEffectName = "ExtensionEffectExample";
const Descriptor ExtensionEffect::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidExtension(),
.uuid = getEffectImplUuidExtension(),
.proxy = std::nullopt},
.name = ExtensionEffect::kEffectName,
.implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus ExtensionEffect::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus ExtensionEffect::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::vendorEffect != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& vendorEffect = specific.get<Parameter::Specific::vendorEffect>();
std::optional<DefaultExtension> defaultExt;
RETURN_IF(STATUS_OK != vendorEffect.extension.getParcelable(&defaultExt), EX_ILLEGAL_ARGUMENT,
"getParcelableFailed");
RETURN_IF(!defaultExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableNull");
RETURN_IF(mContext->setParams(defaultExt->bytes) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
"paramNotSupported");
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus ExtensionEffect::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::vendorEffectTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto extensionId = id.get<Parameter::Id::vendorEffectTag>();
std::optional<DefaultExtension> defaultIdExt;
RETURN_IF(STATUS_OK != extensionId.extension.getParcelable(&defaultIdExt), EX_ILLEGAL_ARGUMENT,
"getIdParcelableFailed");
RETURN_IF(!defaultIdExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableIdNull");
VendorExtension extension;
DefaultExtension defaultExt;
defaultExt.bytes = mContext->getParams(defaultIdExt->bytes);
RETURN_IF(STATUS_OK != extension.extension.setParcelable(defaultExt), EX_ILLEGAL_ARGUMENT,
"setParcelableFailed");
specific->set<Parameter::Specific::vendorEffect>(extension);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> ExtensionEffect::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<ExtensionEffectContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode ExtensionEffect::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status ExtensionEffect::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) 2023 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <memory>
#include <vector>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class ExtensionEffectContext final : public EffectContext {
public:
ExtensionEffectContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setParams(const std::vector<uint8_t>& params) {
mParams = params;
return RetCode::SUCCESS;
}
std::vector<uint8_t> getParams(std::vector<uint8_t> id __unused) const { return mParams; }
private:
std::vector<uint8_t> mParams;
};
class ExtensionEffect final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
ExtensionEffect() { LOG(DEBUG) << __func__; }
~ExtensionEffect() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
private:
std::shared_ptr<ExtensionEffectContext> mContext GUARDED_BY(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libhapticgeneratorsw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"HapticGeneratorSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default",
],
}

View File

@@ -1,194 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#define LOG_TAG "AHAL_HapticGeneratorSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "HapticGeneratorSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidHapticGeneratorSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator;
using aidl::android::hardware::audio::effect::HapticGeneratorSw;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidHapticGeneratorSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<HapticGeneratorSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidHapticGeneratorSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = HapticGeneratorSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string HapticGeneratorSw::kEffectName = "HapticGeneratorSw";
/* Effect descriptor */
const Descriptor HapticGeneratorSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidHapticGenerator(),
.uuid = getEffectImplUuidHapticGeneratorSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = HapticGeneratorSw::kEffectName,
.implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus HapticGeneratorSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus HapticGeneratorSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::hapticGenerator != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& hgParam = specific.get<Parameter::Specific::hapticGenerator>();
auto tag = hgParam.getTag();
switch (tag) {
case HapticGenerator::hapticScales: {
RETURN_IF(mContext->setHgHapticScales(hgParam.get<HapticGenerator::hapticScales>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "HapticScaleNotSupported");
return ndk::ScopedAStatus::ok();
}
case HapticGenerator::vibratorInfo: {
RETURN_IF(mContext->setHgVibratorInformation(
hgParam.get<HapticGenerator::vibratorInfo>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "VibratorInfoNotSupported");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
}
}
}
ndk::ScopedAStatus HapticGeneratorSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::hapticGeneratorTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto hgId = id.get<Parameter::Id::hapticGeneratorTag>();
auto hgIdTag = hgId.getTag();
switch (hgIdTag) {
case HapticGenerator::Id::commonTag:
return getParameterHapticGenerator(hgId.get<HapticGenerator::Id::commonTag>(),
specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
}
}
ndk::ScopedAStatus HapticGeneratorSw::getParameterHapticGenerator(const HapticGenerator::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
HapticGenerator hgParam;
switch (tag) {
case HapticGenerator::hapticScales: {
hgParam.set<HapticGenerator::hapticScales>(mContext->getHgHapticScales());
break;
}
case HapticGenerator::vibratorInfo: {
hgParam.set<HapticGenerator::vibratorInfo>(mContext->getHgVibratorInformation());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
}
}
specific->set<Parameter::Specific::hapticGenerator>(hgParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> HapticGeneratorSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<HapticGeneratorSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode HapticGeneratorSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status HapticGeneratorSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode HapticGeneratorSwContext::setHgHapticScales(
const std::vector<HapticGenerator::HapticScale>& hapticScales) {
// Assume any audio track ID is valid
for (auto& it : hapticScales) {
mHapticScales[it.id] = it;
}
return RetCode::SUCCESS;
}
std::vector<HapticGenerator::HapticScale> HapticGeneratorSwContext::getHgHapticScales() const {
std::vector<HapticGenerator::HapticScale> result;
std::transform(mHapticScales.begin(), mHapticScales.end(), std::back_inserter(result),
[](auto& scaleIt) { return scaleIt.second; });
return result;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,90 +0,0 @@
/*
* 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 <cstdlib>
#include <map>
#include <memory>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class HapticGeneratorSwContext final : public EffectContext {
public:
HapticGeneratorSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setHgHapticScales(const std::vector<HapticGenerator::HapticScale>& hapticScales);
std::vector<HapticGenerator::HapticScale> getHgHapticScales() const;
RetCode setHgVibratorInformation(const HapticGenerator::VibratorInformation& vibratorInfo) {
// All float values are valid for resonantFrequencyHz, qFactor, maxAmplitude
mVibratorInformation = vibratorInfo;
return RetCode::SUCCESS;
}
HapticGenerator::VibratorInformation getHgVibratorInformation() const {
return mVibratorInformation;
}
private:
static constexpr float DEFAULT_RESONANT_FREQUENCY = 150.0f;
static constexpr float DEFAULT_Q_FACTOR = 1.0f;
static constexpr float DEFAULT_MAX_AMPLITUDE = 0.0f;
std::map<int /* trackID */, HapticGenerator::HapticScale> mHapticScales;
HapticGenerator::VibratorInformation mVibratorInformation = {
DEFAULT_RESONANT_FREQUENCY, DEFAULT_Q_FACTOR, DEFAULT_MAX_AMPLITUDE};
};
class HapticGeneratorSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Descriptor kDescriptor;
HapticGeneratorSw() { LOG(DEBUG) << __func__; }
~HapticGeneratorSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
std::shared_ptr<HapticGeneratorSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterHapticGenerator(const HapticGenerator::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libloudnessenhancersw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"LoudnessEnhancerSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default",
],
}

View File

@@ -1,167 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#define LOG_TAG "AHAL_LoudnessEnhancerSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "LoudnessEnhancerSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidLoudnessEnhancerSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::LoudnessEnhancerSw;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidLoudnessEnhancerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<LoudnessEnhancerSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidLoudnessEnhancerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = LoudnessEnhancerSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string LoudnessEnhancerSw::kEffectName = "LoudnessEnhancerSw";
const Descriptor LoudnessEnhancerSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidLoudnessEnhancer(),
.uuid = getEffectImplUuidLoudnessEnhancerSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = LoudnessEnhancerSw::kEffectName,
.implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus LoudnessEnhancerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus LoudnessEnhancerSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::loudnessEnhancer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& leParam = specific.get<Parameter::Specific::loudnessEnhancer>();
auto tag = leParam.getTag();
switch (tag) {
case LoudnessEnhancer::gainMb: {
RETURN_IF(mContext->setLeGainMb(leParam.get<LoudnessEnhancer::gainMb>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setGainMbFailed");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
}
}
}
ndk::ScopedAStatus LoudnessEnhancerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::loudnessEnhancerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto leId = id.get<Parameter::Id::loudnessEnhancerTag>();
auto leIdTag = leId.getTag();
switch (leIdTag) {
case LoudnessEnhancer::Id::commonTag:
return getParameterLoudnessEnhancer(leId.get<LoudnessEnhancer::Id::commonTag>(),
specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(leIdTag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
}
}
ndk::ScopedAStatus LoudnessEnhancerSw::getParameterLoudnessEnhancer(
const LoudnessEnhancer::Tag& tag, Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
LoudnessEnhancer leParam;
switch (tag) {
case LoudnessEnhancer::gainMb: {
leParam.set<LoudnessEnhancer::gainMb>(mContext->getLeGainMb());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
}
}
specific->set<Parameter::Specific::loudnessEnhancer>(leParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> LoudnessEnhancerSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<LoudnessEnhancerSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode LoudnessEnhancerSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status LoudnessEnhancerSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,76 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class LoudnessEnhancerSwContext final : public EffectContext {
public:
LoudnessEnhancerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setLeGainMb(int gainMb) {
// TODO : Add implementation to apply new gain
mGainMb = gainMb;
return RetCode::SUCCESS;
}
int getLeGainMb() const { return mGainMb; }
private:
int mGainMb = 0; // Default Gain
};
class LoudnessEnhancerSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Descriptor kDescriptor;
LoudnessEnhancerSw() { LOG(DEBUG) << __func__; }
~LoudnessEnhancerSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
std::shared_ptr<LoudnessEnhancerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterLoudnessEnhancer(const LoudnessEnhancer::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libnssw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"NoiseSuppressionSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,189 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#include <memory>
#define LOG_TAG "AHAL_NoiseSuppressionSw"
#define LOG_TAG "AHAL_NoiseSuppressionSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "NoiseSuppressionSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidNoiseSuppressionSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::NoiseSuppressionSw;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidNoiseSuppressionSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<NoiseSuppressionSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidNoiseSuppressionSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = NoiseSuppressionSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string NoiseSuppressionSw::kEffectName = "NoiseSuppressionSw";
const Descriptor NoiseSuppressionSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidNoiseSuppression(),
.uuid = getEffectImplUuidNoiseSuppressionSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::PRE_PROC,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::NONE},
.name = NoiseSuppressionSw::kEffectName,
.implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus NoiseSuppressionSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus NoiseSuppressionSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::noiseSuppression != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::noiseSuppression>();
auto tag = param.getTag();
switch (tag) {
case NoiseSuppression::level: {
RETURN_IF(mContext->setLevel(param.get<NoiseSuppression::level>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "levelNotSupported");
return ndk::ScopedAStatus::ok();
}
case NoiseSuppression::type: {
RETURN_IF(mContext->setType(param.get<NoiseSuppression::type>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "typeNotSupported");
return ndk::ScopedAStatus::ok();
}
case NoiseSuppression::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
}
}
}
ndk::ScopedAStatus NoiseSuppressionSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::noiseSuppressionTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto specificId = id.get<Parameter::Id::noiseSuppressionTag>();
auto specificIdTag = specificId.getTag();
switch (specificIdTag) {
case NoiseSuppression::Id::commonTag:
return getParameterNoiseSuppression(specificId.get<NoiseSuppression::Id::commonTag>(),
specific);
case NoiseSuppression::Id::vendorExtensionTag: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
}
}
}
ndk::ScopedAStatus NoiseSuppressionSw::getParameterNoiseSuppression(
const NoiseSuppression::Tag& tag, Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
NoiseSuppression param;
switch (tag) {
case NoiseSuppression::level: {
param.set<NoiseSuppression::level>(mContext->getLevel());
break;
}
case NoiseSuppression::type: {
param.set<NoiseSuppression::type>(mContext->getType());
break;
}
case NoiseSuppression::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
}
}
specific->set<Parameter::Specific::noiseSuppression>(param);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> NoiseSuppressionSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<NoiseSuppressionSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode NoiseSuppressionSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status NoiseSuppressionSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode NoiseSuppressionSwContext::setLevel(NoiseSuppression::Level level) {
mLevel = level;
return RetCode::SUCCESS;
}
NoiseSuppression::Level NoiseSuppressionSwContext::getLevel() {
return mLevel;
}
RetCode NoiseSuppressionSwContext::setType(NoiseSuppression::Type type) {
mType = type;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,77 +0,0 @@
/*
* 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 <cstdlib>
#include <memory>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class NoiseSuppressionSwContext final : public EffectContext {
public:
NoiseSuppressionSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setLevel(NoiseSuppression::Level level);
NoiseSuppression::Level getLevel();
RetCode setType(NoiseSuppression::Type type);
NoiseSuppression::Type getType() { return mType; }
private:
NoiseSuppression::Level mLevel = NoiseSuppression::Level::LOW;
NoiseSuppression::Type mType = NoiseSuppression::Type::SINGLE_CHANNEL;
};
class NoiseSuppressionSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const bool kStrengthSupported;
static const Descriptor kDescriptor;
NoiseSuppressionSw() { LOG(DEBUG) << __func__; }
~NoiseSuppressionSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
private:
std::shared_ptr<NoiseSuppressionSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterNoiseSuppression(const NoiseSuppression::Tag& tag,
Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libpresetreverbsw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"PresetReverbSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,181 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#define LOG_TAG "AHAL_PresetReverbSw"
#include <android-base/logging.h>
#include <android/binder_enums.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "PresetReverbSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidPresetReverbSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::PresetReverbSw;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidPresetReverbSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<PresetReverbSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidPresetReverbSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = PresetReverbSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string PresetReverbSw::kEffectName = "PresetReverbSw";
const std::vector<PresetReverb::Presets> PresetReverbSw::kSupportedPresets{
ndk::enum_range<PresetReverb::Presets>().begin(),
ndk::enum_range<PresetReverb::Presets>().end()};
const std::vector<Range::PresetReverbRange> PresetReverbSw::kRanges = {
MAKE_RANGE(PresetReverb, supportedPresets, PresetReverbSw::kSupportedPresets,
PresetReverbSw::kSupportedPresets)};
const Capability PresetReverbSw::kCapability = {
.range = Range::make<Range::presetReverb>(PresetReverbSw::kRanges)};
const Descriptor PresetReverbSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidPresetReverb(),
.uuid = getEffectImplUuidPresetReverbSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = PresetReverbSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = PresetReverbSw::kCapability};
ndk::ScopedAStatus PresetReverbSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PresetReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::presetReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& prParam = specific.get<Parameter::Specific::presetReverb>();
RETURN_IF(!inRange(prParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = prParam.getTag();
switch (tag) {
case PresetReverb::preset: {
RETURN_IF(
mContext->setPRPreset(prParam.get<PresetReverb::preset>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setPresetFailed");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"PresetReverbTagNotSupported");
}
}
}
ndk::ScopedAStatus PresetReverbSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::presetReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto prId = id.get<Parameter::Id::presetReverbTag>();
auto prIdTag = prId.getTag();
switch (prIdTag) {
case PresetReverb::Id::commonTag:
return getParameterPresetReverb(prId.get<PresetReverb::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"PresetReverbTagNotSupported");
}
}
ndk::ScopedAStatus PresetReverbSw::getParameterPresetReverb(const PresetReverb::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
PresetReverb prParam;
switch (tag) {
case PresetReverb::preset: {
prParam.set<PresetReverb::preset>(mContext->getPRPreset());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"PresetReverbTagNotSupported");
}
}
specific->set<Parameter::Specific::presetReverb>(prParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> PresetReverbSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<PresetReverbSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode PresetReverbSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status PresetReverbSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,78 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class PresetReverbSwContext final : public EffectContext {
public:
PresetReverbSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setPRPreset(PresetReverb::Presets preset) {
// TODO : Add implementation to modify Presets
mPreset = preset;
return RetCode::SUCCESS;
}
PresetReverb::Presets getPRPreset() const { return mPreset; }
private:
PresetReverb::Presets mPreset = PresetReverb::Presets::NONE;
};
class PresetReverbSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const std::vector<PresetReverb::Presets> kSupportedPresets;
static const std::vector<Range::PresetReverbRange> kRanges;
static const Capability kCapability;
static const Descriptor kDescriptor;
PresetReverbSw() { LOG(DEBUG) << __func__; }
~PresetReverbSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
std::shared_ptr<PresetReverbSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Tag& tag,
Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libspatializersw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"SpatializerSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,225 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
#define LOG_TAG "AHAL_SpatializerSw"
#include "SpatializerSw.h"
#include <android-base/logging.h>
#include <system/audio_effects/effect_uuid.h>
#include <optional>
using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidSpatializerSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::SpatializerSw;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioUuid;
using aidl::android::media::audio::common::HeadTracking;
using aidl::android::media::audio::common::Spatialization;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidSpatializerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (!instanceSpp) {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
*instanceSpp = ndk::SharedRefBase::make<SpatializerSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidSpatializerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = SpatializerSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string SpatializerSw::kEffectName = "SpatializerSw";
const AudioChannelLayout kSupportedChannelMask =
AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
AudioChannelLayout::LAYOUT_5POINT1);
const std::vector<Range::SpatializerRange> SpatializerSw::kRanges = {
MAKE_RANGE(Spatializer, supportedChannelLayout, {kSupportedChannelMask},
{kSupportedChannelMask}),
MAKE_RANGE(Spatializer, spatializationLevel, Spatialization::Level::NONE,
Spatialization::Level::BED_PLUS_OBJECTS),
MAKE_RANGE(Spatializer, spatializationMode, Spatialization::Mode::BINAURAL,
Spatialization::Mode::TRANSAURAL),
MAKE_RANGE(Spatializer, headTrackingSensorId, std::numeric_limits<int>::min(),
std::numeric_limits<int>::max()),
MAKE_RANGE(Spatializer, headTrackingMode, HeadTracking::Mode::OTHER,
HeadTracking::Mode::RELATIVE_SCREEN),
MAKE_RANGE(Spatializer, headTrackingConnectionMode,
HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED,
HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_TUNNEL)};
const Capability SpatializerSw::kCapability = {.range = {SpatializerSw::kRanges}};
const Descriptor SpatializerSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidSpatializer(),
.uuid = getEffectImplUuidSpatializerSw()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.hwAcceleratorMode = Flags::HardwareAccelerator::NONE},
.name = SpatializerSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = SpatializerSw::kCapability};
ndk::ScopedAStatus SpatializerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus SpatializerSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::spatializer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::spatializer>();
RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
return mContext->setParam(param.getTag(), param);
}
ndk::ScopedAStatus SpatializerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto tag = id.getTag();
RETURN_IF(Parameter::Id::spatializerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto spatializerId = id.get<Parameter::Id::spatializerTag>();
auto spatializerTag = spatializerId.getTag();
switch (spatializerTag) {
case Spatializer::Id::commonTag: {
auto specificTag = spatializerId.get<Spatializer::Id::commonTag>();
std::optional<Spatializer> param = mContext->getParam(specificTag);
if (!param.has_value()) {
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "SpatializerTagNotSupported");
}
specific->set<Parameter::Specific::spatializer>(param.value());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"SpatializerTagNotSupported");
}
}
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> SpatializerSw::createContext(const Parameter::Common& common) {
if (common.input.base.channelMask != kSupportedChannelMask) {
LOG(ERROR) << __func__
<< " channelMask not supported: " << common.input.base.channelMask.toString();
return nullptr;
}
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<SpatializerSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode SpatializerSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
SpatializerSw::~SpatializerSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
// Processing method running in EffectWorker thread.
IEffect::Status SpatializerSw::effectProcessImpl(float* in, float* out, int samples) {
RETURN_VALUE_IF(!mContext, (IEffect::Status{EX_NULL_POINTER, 0, 0}), "nullContext");
return mContext->process(in, out, samples);
}
SpatializerSwContext::SpatializerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
SpatializerSwContext::~SpatializerSwContext() {
LOG(DEBUG) << __func__;
}
template <typename TAG>
std::optional<Spatializer> SpatializerSwContext::getParam(TAG tag) {
if (mParamsMap.find(tag) != mParamsMap.end()) {
return mParamsMap.at(tag);
}
if (tag == Spatializer::supportedChannelLayout) {
return Spatializer::make<Spatializer::supportedChannelLayout>(
{AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
AudioChannelLayout::LAYOUT_5POINT1)});
}
return std::nullopt;
}
template <typename TAG>
ndk::ScopedAStatus SpatializerSwContext::setParam(TAG tag, Spatializer spatializer) {
RETURN_IF(tag == Spatializer::supportedChannelLayout, EX_ILLEGAL_ARGUMENT,
"supportedChannelLayoutGetOnly");
mParamsMap[tag] = spatializer;
return ndk::ScopedAStatus::ok();
}
IEffect::Status SpatializerSwContext::process(float* in, float* out, int samples) {
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
IEffect::Status status = {EX_ILLEGAL_ARGUMENT, 0, 0};
const auto inputChannelCount = getChannelCount(mCommon.input.base.channelMask);
const auto outputChannelCount = getChannelCount(mCommon.output.base.channelMask);
if (outputChannelCount < 2 || inputChannelCount < outputChannelCount) {
LOG(ERROR) << __func__ << " invalid channel count, in: " << inputChannelCount
<< " out: " << outputChannelCount;
return status;
}
int iFrames = samples / inputChannelCount;
for (int i = 0; i < iFrames; i++) {
std::memcpy(out, in, outputChannelCount);
in += inputChannelCount;
out += outputChannelCount;
}
return {STATUS_OK, static_cast<int32_t>(iFrames * inputChannelCount),
static_cast<int32_t>(iFrames * outputChannelCount)};
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,70 +0,0 @@
/*
* Copyright (C) 2023 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 "effect-impl/EffectContext.h"
#include "effect-impl/EffectImpl.h"
#include <fmq/AidlMessageQueue.h>
#include <unordered_map>
#include <vector>
namespace aidl::android::hardware::audio::effect {
class SpatializerSwContext final : public EffectContext {
public:
SpatializerSwContext(int statusDepth, const Parameter::Common& common);
~SpatializerSwContext();
template <typename TAG>
std::optional<Spatializer> getParam(TAG tag);
template <typename TAG>
ndk::ScopedAStatus setParam(TAG tag, Spatializer spatializer);
IEffect::Status process(float* in, float* out, int samples);
private:
std::unordered_map<Spatializer::Tag, Spatializer> mParamsMap;
};
class SpatializerSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
~SpatializerSw();
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
private:
static const std::vector<Range::SpatializerRange> kRanges;
std::shared_ptr<SpatializerSwContext> mContext GUARDED_BY(mImplMutex) = nullptr;
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,253 +0,0 @@
/*
* Copyright (C) 2024 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.
*/
#define LOG_TAG "AlsaUtilsTest"
#include <alsa/Utils.h>
#include <android-base/macros.h>
#include <audio_utils/primitives.h>
#include <gtest/gtest.h>
#include <log/log.h>
extern "C" {
#include <tinyalsa/pcm.h>
}
namespace alsa = ::aidl::android::hardware::audio::core::alsa;
namespace {
const static constexpr float kInt16tTolerance = 4;
const static constexpr float kIntTolerance = 1;
const static constexpr float kFloatTolerance = 1e-4;
const static constexpr float kUnityGain = 1;
const static constexpr int32_t kInt24Min = -(1 << 23);
const static constexpr int32_t kInt24Max = (1 << 23) - 1;
const static constexpr float kFloatMin = -1;
const static constexpr float kFloatMax = 1;
const static int32_t kQ8_23Min = 0x80000000;
const static int32_t kQ8_23Max = 0x7FFFFFFF;
const static std::vector<int16_t> kInt16Buffer = {10000, 100, 0, INT16_MAX,
INT16_MIN, -2500, 1000, -5800};
const static std::vector<float> kFloatBuffer = {0.5, -0.6, kFloatMin, 0.01, kFloatMax, 0.0};
const static std::vector<int32_t> kInt32Buffer = {100, 0, 8000, INT32_MAX, INT32_MIN, -300};
const static std::vector<int32_t> kQ8_23Buffer = {
kQ8_23Min, kQ8_23Max, 0x00000000, 0x00000001, 0x00400000, static_cast<int32_t>(0xFFD33333)};
const static std::vector<int32_t> kInt24Buffer = {200, 10, -100, 0, kInt24Min, kInt24Max};
template <typename T>
void* CopyToBuffer(int& bytesToTransfer, std::vector<T>& destBuffer,
const std::vector<T>& srcBuffer) {
bytesToTransfer = srcBuffer.size() * sizeof(T);
destBuffer = srcBuffer;
return destBuffer.data();
}
template <typename T>
void VerifyTypedBufferResults(const std::vector<T>& bufferWithGain, const std::vector<T>& srcBuffer,
float gain, float tolerance) {
for (size_t i = 0; i < srcBuffer.size(); i++) {
EXPECT_NEAR(srcBuffer[i] * gain, static_cast<float>(bufferWithGain[i]), tolerance);
}
}
template <typename T>
void VerifyTypedBufferResultsWithClamp(const std::vector<T>& bufferWithGain,
const std::vector<T>& srcBuffer, float gain, float tolerance,
T minValue, T maxValue) {
for (size_t i = 0; i < srcBuffer.size(); i++) {
float expectedResult = std::clamp(srcBuffer[i] * gain, static_cast<float>(minValue),
static_cast<float>(maxValue));
EXPECT_NEAR(expectedResult, static_cast<float>(bufferWithGain[i]), tolerance);
}
}
} // namespace
using ApplyGainTestParameters = std::tuple<pcm_format, int, float>;
enum { INDEX_PCM_FORMAT, INDEX_CHANNEL_COUNT, INDEX_GAIN };
class ApplyGainTest : public ::testing::TestWithParam<ApplyGainTestParameters> {
protected:
void SetUp() override;
void VerifyBufferResult(const pcm_format pcmFormat, const float gain);
void VerifyBufferResultWithClamp(const pcm_format pcmFormat, const float gain);
pcm_format mPcmFormat;
int mBufferSizeBytes;
void* mBuffer;
private:
std::vector<int16_t> mInt16BufferToConvert;
std::vector<float> mFloatBufferToConvert;
std::vector<int32_t> mInt32BufferToConvert;
std::vector<int32_t> mQ8_23BufferToConvert;
std::vector<int32_t> mInt24BufferToConvert;
};
void ApplyGainTest::SetUp() {
mPcmFormat = std::get<INDEX_PCM_FORMAT>(GetParam());
switch (mPcmFormat) {
case PCM_FORMAT_S16_LE:
mBuffer = CopyToBuffer(mBufferSizeBytes, mInt16BufferToConvert, kInt16Buffer);
break;
case PCM_FORMAT_FLOAT_LE:
mBuffer = CopyToBuffer(mBufferSizeBytes, mFloatBufferToConvert, kFloatBuffer);
break;
case PCM_FORMAT_S32_LE:
mBuffer = CopyToBuffer(mBufferSizeBytes, mInt32BufferToConvert, kInt32Buffer);
break;
case PCM_FORMAT_S24_LE:
mBuffer = CopyToBuffer(mBufferSizeBytes, mQ8_23BufferToConvert, kQ8_23Buffer);
break;
case PCM_FORMAT_S24_3LE: {
std::vector<int32_t> original32BitBuffer(kInt24Buffer.begin(), kInt24Buffer.end());
for (auto& val : original32BitBuffer) {
val <<= 8;
}
mInt24BufferToConvert = std::vector<int32_t>(kInt24Buffer.size());
mBufferSizeBytes = kInt24Buffer.size() * 3 * sizeof(uint8_t);
memcpy_to_p24_from_i32(reinterpret_cast<uint8_t*>(mInt24BufferToConvert.data()),
original32BitBuffer.data(), kInt24Buffer.size());
mBuffer = mInt24BufferToConvert.data();
} break;
default:
FAIL() << "Unsupported pcm format: " << mPcmFormat;
return;
}
}
void ApplyGainTest::VerifyBufferResult(const pcm_format pcmFormat, const float gain) {
switch (pcmFormat) {
case PCM_FORMAT_S16_LE:
VerifyTypedBufferResults(mInt16BufferToConvert, kInt16Buffer, gain, kInt16tTolerance);
break;
case PCM_FORMAT_FLOAT_LE:
VerifyTypedBufferResults(mFloatBufferToConvert, kFloatBuffer, gain, kFloatTolerance);
break;
case PCM_FORMAT_S32_LE:
VerifyTypedBufferResults(mInt32BufferToConvert, kInt32Buffer, gain, kIntTolerance);
break;
case PCM_FORMAT_S24_LE: {
for (size_t i = 0; i < kQ8_23Buffer.size(); i++) {
EXPECT_NEAR(float_from_q8_23(kQ8_23Buffer[i]) * gain,
static_cast<float>(float_from_q8_23(mQ8_23BufferToConvert[i])),
kFloatTolerance);
}
} break;
case PCM_FORMAT_S24_3LE: {
size_t bufferSize = kInt24Buffer.size();
std::vector<int32_t> result32BitBuffer(bufferSize);
memcpy_to_i32_from_p24(result32BitBuffer.data(),
reinterpret_cast<uint8_t*>(mInt24BufferToConvert.data()),
bufferSize);
for (size_t i = 0; i < bufferSize; i++) {
EXPECT_NEAR(kInt24Buffer[i] * gain, result32BitBuffer[i] >> 8, kIntTolerance);
}
} break;
default:
return;
}
}
void ApplyGainTest::VerifyBufferResultWithClamp(const pcm_format pcmFormat, const float gain) {
switch (pcmFormat) {
case PCM_FORMAT_S16_LE:
VerifyTypedBufferResultsWithClamp(mInt16BufferToConvert, kInt16Buffer, gain,
kInt16tTolerance, static_cast<int16_t>(INT16_MIN),
static_cast<int16_t>(INT16_MAX));
break;
case PCM_FORMAT_FLOAT_LE:
VerifyTypedBufferResultsWithClamp(mFloatBufferToConvert, kFloatBuffer, gain,
kFloatTolerance, kFloatMin, kFloatMax);
break;
case PCM_FORMAT_S32_LE:
VerifyTypedBufferResultsWithClamp(mInt32BufferToConvert, kInt32Buffer, gain,
kIntTolerance, INT32_MIN, INT32_MAX);
break;
case PCM_FORMAT_S24_LE: {
for (size_t i = 0; i < kQ8_23Buffer.size(); i++) {
float expectedResult =
std::clamp(float_from_q8_23(kQ8_23Buffer[i]) * gain,
float_from_q8_23(kQ8_23Min), float_from_q8_23(kQ8_23Max));
EXPECT_NEAR(expectedResult,
static_cast<float>(float_from_q8_23(mQ8_23BufferToConvert[i])),
kFloatTolerance);
}
} break;
case PCM_FORMAT_S24_3LE: {
size_t bufferSize = kInt24Buffer.size();
std::vector<int32_t> result32BitBuffer(bufferSize);
memcpy_to_i32_from_p24(result32BitBuffer.data(),
reinterpret_cast<uint8_t*>(mInt24BufferToConvert.data()),
bufferSize);
for (size_t i = 0; i < bufferSize; i++) {
result32BitBuffer[i] >>= 8;
}
VerifyTypedBufferResultsWithClamp(result32BitBuffer, kInt24Buffer, gain, kIntTolerance,
kInt24Min, kInt24Max);
} break;
default:
return;
}
}
TEST_P(ApplyGainTest, ApplyGain) {
float gain = std::get<INDEX_GAIN>(GetParam());
int channelCount = std::get<INDEX_CHANNEL_COUNT>(GetParam());
alsa::applyGain(mBuffer, gain, mBufferSizeBytes, mPcmFormat, channelCount);
if (gain <= kUnityGain) {
VerifyBufferResult(mPcmFormat, gain);
} else {
VerifyBufferResultWithClamp(mPcmFormat, gain);
}
}
std::string GetApplyGainTestName(const testing::TestParamInfo<ApplyGainTestParameters>& info) {
std::string testNameStr;
switch (std::get<INDEX_PCM_FORMAT>(info.param)) {
case PCM_FORMAT_S16_LE:
testNameStr = "S16_LE";
break;
case PCM_FORMAT_FLOAT_LE:
testNameStr = "Float_LE";
break;
case PCM_FORMAT_S32_LE:
testNameStr = "S32_LE";
break;
case PCM_FORMAT_S24_LE:
testNameStr = "S24_LE";
break;
case PCM_FORMAT_S24_3LE:
testNameStr = "S24_3LE";
break;
default:
testNameStr = "UnsupportedPcmFormat";
break;
}
testNameStr += std::get<INDEX_CHANNEL_COUNT>(info.param) == 1 ? "_Mono_" : "_Stereo_";
testNameStr += std::get<INDEX_GAIN>(info.param) <= kUnityGain ? "WithoutClamp" : "WithClamp";
return testNameStr;
}
INSTANTIATE_TEST_SUITE_P(PerPcmFormat, ApplyGainTest,
testing::Combine(testing::Values(PCM_FORMAT_S16_LE, PCM_FORMAT_FLOAT_LE,
PCM_FORMAT_S32_LE, PCM_FORMAT_S24_LE,
PCM_FORMAT_S24_3LE),
testing::Values(1, 2), testing::Values(0.6f, 1.5f)),
GetApplyGainTestName);

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
// #include <memory>
// #include <string>
// #include <vector>
#include <android-base/macros.h>
#include <gtest/gtest.h>
#define LOG_TAG "AudioPolicyConfigXmlConverterTest"
#include <log/log.h>
#include <core-impl/AudioPolicyConfigXmlConverter.h>
#include <media/AidlConversionCppNdk.h>
using aidl::android::hardware::audio::core::internal::AudioPolicyConfigXmlConverter;
using aidl::android::media::audio::common::AudioFormatDescription;
namespace {
void ValidateAudioFormatDescription(const AudioFormatDescription& format) {
auto conv = ::aidl::android::aidl2legacy_AudioFormatDescription_audio_format_t(format);
ASSERT_TRUE(conv.ok()) << format.toString();
}
} // namespace
TEST(AudioPolicyConfigXmlConverterTest, DefaultSurroundSoundConfigIsValid) {
auto config = AudioPolicyConfigXmlConverter::getDefaultSurroundSoundConfig();
for (const auto& family : config.formatFamilies) {
EXPECT_NO_FATAL_FAILURE(ValidateAudioFormatDescription(family.primaryFormat));
SCOPED_TRACE(family.primaryFormat.toString());
for (const auto& sub : family.subFormats) {
EXPECT_NO_FATAL_FAILURE(ValidateAudioFormatDescription(sub));
}
}
}

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libvirtualizersw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"VirtualizerSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,228 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#include <optional>
#define LOG_TAG "AHAL_VirtualizerSw"
#include <Utils.h>
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "VirtualizerSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidVirtualizerSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VirtualizerSw;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVirtualizerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<VirtualizerSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVirtualizerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = VirtualizerSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string VirtualizerSw::kEffectName = "VirtualizerSw";
const std::vector<Range::VirtualizerRange> VirtualizerSw::kRanges = {
MAKE_RANGE(Virtualizer, strengthPm, 0, 1000),
/* speakerAngle is get-only, set min > max */
MAKE_RANGE(Virtualizer, speakerAngles, {Virtualizer::ChannelAngle({.channel = 1})},
{Virtualizer::ChannelAngle({.channel = 0})})};
const Capability VirtualizerSw::kCapability = {
.range = Range::make<Range::virtualizer>(VirtualizerSw::kRanges)};
const Descriptor VirtualizerSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidVirtualizer(),
.uuid = getEffectImplUuidVirtualizerSw()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = VirtualizerSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = VirtualizerSw::kCapability};
ndk::ScopedAStatus VirtualizerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus VirtualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::virtualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
auto& vrParam = specific.get<Parameter::Specific::virtualizer>();
RETURN_IF(!inRange(vrParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = vrParam.getTag();
switch (tag) {
case Virtualizer::strengthPm: {
RETURN_IF(mContext->setVrStrength(vrParam.get<Virtualizer::strengthPm>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setStrengthPmFailed");
return ndk::ScopedAStatus::ok();
}
case Virtualizer::device: {
RETURN_IF(mContext->setForcedDevice(vrParam.get<Virtualizer::device>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
return ndk::ScopedAStatus::ok();
}
case Virtualizer::speakerAngles:
FALLTHROUGH_INTENDED;
case Virtualizer::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
}
}
}
ndk::ScopedAStatus VirtualizerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::virtualizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto vrId = id.get<Parameter::Id::virtualizerTag>();
auto vrIdTag = vrId.getTag();
switch (vrIdTag) {
case Virtualizer::Id::commonTag:
return getParameterVirtualizer(vrId.get<Virtualizer::Id::commonTag>(), specific);
case Virtualizer::Id::speakerAnglesPayload:
return getSpeakerAngles(vrId.get<Virtualizer::Id::speakerAnglesPayload>(), specific);
case Virtualizer::Id::vendorExtensionTag: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
}
}
}
ndk::ScopedAStatus VirtualizerSw::getParameterVirtualizer(const Virtualizer::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
Virtualizer vrParam;
switch (tag) {
case Virtualizer::strengthPm: {
vrParam.set<Virtualizer::strengthPm>(mContext->getVrStrength());
break;
}
case Virtualizer::device: {
vrParam.set<Virtualizer::device>(mContext->getForcedDevice());
break;
}
case Virtualizer::speakerAngles:
FALLTHROUGH_INTENDED;
case Virtualizer::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
}
}
specific->set<Parameter::Specific::virtualizer>(vrParam);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus VirtualizerSw::getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
Parameter::Specific* specific) {
std::vector<Virtualizer::ChannelAngle> angles;
const auto chNum = ::aidl::android::hardware::audio::common::getChannelCount(payload.layout);
if (chNum == 1) {
angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
.azimuthDegree = 0,
.elevationDegree = 0}};
} else if (chNum == 2) {
angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
.azimuthDegree = -90,
.elevationDegree = 0},
{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_RIGHT,
.azimuthDegree = 90,
.elevationDegree = 0}};
} else {
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"supportUpTo2Ch");
}
Virtualizer param = Virtualizer::make<Virtualizer::speakerAngles>(angles);
specific->set<Parameter::Specific::virtualizer>(param);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> VirtualizerSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<VirtualizerSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode VirtualizerSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status VirtualizerSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode VirtualizerSwContext::setVrStrength(int strength) {
mStrength = strength;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,83 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class VirtualizerSwContext final : public EffectContext {
public:
VirtualizerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setVrStrength(int strength);
int getVrStrength() const { return mStrength; }
RetCode setForcedDevice(
const ::aidl::android::media::audio::common::AudioDeviceDescription& device) {
mForceDevice = device;
return RetCode::SUCCESS;
}
aidl::android::media::audio::common::AudioDeviceDescription getForcedDevice() const {
return mForceDevice;
}
private:
int mStrength = 0;
::aidl::android::media::audio::common::AudioDeviceDescription mForceDevice;
};
class VirtualizerSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
VirtualizerSw() { LOG(DEBUG) << __func__; }
~VirtualizerSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::VirtualizerRange> kRanges;
std::shared_ptr<VirtualizerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Tag& tag,
Parameter::Specific* specific) REQUIRES(mImplMutex);
ndk::ScopedAStatus getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libvisualizersw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"VisualizerSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default",
],
}

View File

@@ -1,230 +0,0 @@
/*
* 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.
*/
#define LOG_TAG "AHAL_VisualizerSw"
#include <android-base/logging.h>
#include <system/audio_effects/effect_uuid.h>
#include "VisualizerSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidVisualizerSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VisualizerSw;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVisualizerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<VisualizerSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVisualizerSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = VisualizerSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string VisualizerSw::kEffectName = "VisualizerSw";
/* capabilities */
const std::vector<Range::VisualizerRange> VisualizerSw::kRanges = {
MAKE_RANGE(Visualizer, latencyMs, 0, VisualizerSwContext::kMaxLatencyMs),
MAKE_RANGE(Visualizer, captureSamples, VisualizerSwContext::kMinCaptureSize,
VisualizerSwContext::kMaxCaptureSize)};
const Capability VisualizerSw::kCapability = {
.range = Range::make<Range::visualizer>(VisualizerSw::kRanges)};
const Descriptor VisualizerSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidVisualizer(),
.uuid = getEffectImplUuidVisualizerSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::NONE},
.name = VisualizerSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = VisualizerSw::kCapability};
ndk::ScopedAStatus VisualizerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus VisualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::visualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
auto& vsParam = specific.get<Parameter::Specific::visualizer>();
RETURN_IF(!inRange(vsParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = vsParam.getTag();
switch (tag) {
case Visualizer::captureSamples: {
RETURN_IF(mContext->setVsCaptureSize(vsParam.get<Visualizer::captureSamples>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setCaptureSizeFailed");
return ndk::ScopedAStatus::ok();
}
case Visualizer::scalingMode: {
RETURN_IF(mContext->setVsScalingMode(vsParam.get<Visualizer::scalingMode>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setScalingModeFailed");
return ndk::ScopedAStatus::ok();
}
case Visualizer::measurementMode: {
RETURN_IF(mContext->setVsMeasurementMode(vsParam.get<Visualizer::measurementMode>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setMeasurementModeFailed");
return ndk::ScopedAStatus::ok();
}
case Visualizer::latencyMs: {
RETURN_IF(mContext->setVsLatency(vsParam.get<Visualizer::latencyMs>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setLatencyFailed");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VisualizerTagNotSupported");
}
}
}
ndk::ScopedAStatus VisualizerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::visualizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto vsId = id.get<Parameter::Id::visualizerTag>();
auto vsIdTag = vsId.getTag();
switch (vsIdTag) {
case Visualizer::Id::commonTag:
return getParameterVisualizer(vsId.get<Visualizer::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VisualizerTagNotSupported");
}
}
ndk::ScopedAStatus VisualizerSw::getParameterVisualizer(const Visualizer::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
Visualizer vsParam;
switch (tag) {
case Visualizer::captureSamples: {
vsParam.set<Visualizer::captureSamples>(mContext->getVsCaptureSize());
break;
}
case Visualizer::scalingMode: {
vsParam.set<Visualizer::scalingMode>(mContext->getVsScalingMode());
break;
}
case Visualizer::measurementMode: {
vsParam.set<Visualizer::measurementMode>(mContext->getVsMeasurementMode());
break;
}
case Visualizer::measurement: {
vsParam.set<Visualizer::measurement>(mContext->getVsMeasurement());
break;
}
case Visualizer::captureSampleBuffer: {
vsParam.set<Visualizer::captureSampleBuffer>(mContext->getVsCaptureSampleBuffer());
break;
}
case Visualizer::latencyMs: {
vsParam.set<Visualizer::latencyMs>(mContext->getVsLatency());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VisualizerTagNotSupported");
}
}
specific->set<Parameter::Specific::visualizer>(vsParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> VisualizerSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<VisualizerSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode VisualizerSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status VisualizerSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode VisualizerSwContext::setVsCaptureSize(int captureSize) {
mCaptureSize = captureSize;
return RetCode::SUCCESS;
}
RetCode VisualizerSwContext::setVsScalingMode(Visualizer::ScalingMode scalingMode) {
mScalingMode = scalingMode;
return RetCode::SUCCESS;
}
RetCode VisualizerSwContext::setVsMeasurementMode(Visualizer::MeasurementMode measurementMode) {
mMeasurementMode = measurementMode;
return RetCode::SUCCESS;
}
RetCode VisualizerSwContext::setVsLatency(int latency) {
mLatency = latency;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,96 +0,0 @@
/*
* 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 <vector>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <system/audio_effects/effect_visualizer.h>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class VisualizerSwContext final : public EffectContext {
public:
// need align the min/max capture size to VISUALIZER_CAPTURE_SIZE_MIN and
// VISUALIZER_CAPTURE_SIZE_MAX because of limitation in audio_utils fixedfft.
static constexpr int32_t kMinCaptureSize = VISUALIZER_CAPTURE_SIZE_MIN;
static constexpr int32_t kMaxCaptureSize = VISUALIZER_CAPTURE_SIZE_MAX;
static constexpr int32_t kMaxLatencyMs = 3000;
VisualizerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
mCaptureSampleBuffer.resize(kMaxCaptureSize);
fill(mCaptureSampleBuffer.begin(), mCaptureSampleBuffer.end(), 0x80);
}
RetCode setVsCaptureSize(int captureSize);
int getVsCaptureSize() const { return mCaptureSize; }
RetCode setVsScalingMode(Visualizer::ScalingMode scalingMode);
Visualizer::ScalingMode getVsScalingMode() const { return mScalingMode; }
RetCode setVsMeasurementMode(Visualizer::MeasurementMode measurementMode);
Visualizer::MeasurementMode getVsMeasurementMode() const { return mMeasurementMode; }
RetCode setVsLatency(int latency);
int getVsLatency() const { return mLatency; }
Visualizer::Measurement getVsMeasurement() const { return mMeasurement; }
std::vector<uint8_t> getVsCaptureSampleBuffer() const { return mCaptureSampleBuffer; }
private:
int mCaptureSize = kMaxCaptureSize;
Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
int mLatency = 0;
const Visualizer::Measurement mMeasurement = {0, 0};
std::vector<uint8_t> mCaptureSampleBuffer;
};
class VisualizerSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
VisualizerSw() { LOG(DEBUG) << __func__; }
~VisualizerSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::VisualizerRange> kRanges;
std::shared_ptr<VisualizerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterVisualizer(const Visualizer::Tag& tag,
Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,40 +0,0 @@
/*
* 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.
*/
package {
default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_shared {
name: "libvolumesw",
defaults: [
"aidlaudioeffectservice_defaults",
],
srcs: [
"VolumeSw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
visibility: [
"//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}

View File

@@ -1,191 +0,0 @@
/*
* 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.
*/
#include <algorithm>
#include <cstddef>
#define LOG_TAG "AHAL_VolumeSw"
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
#include <system/audio_effects/effect_uuid.h>
#include "VolumeSw.h"
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectImplUuidVolumeSw;
using aidl::android::hardware::audio::effect::getEffectTypeUuidVolume;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VolumeSw;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVolumeSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
*instanceSpp = ndk::SharedRefBase::make<VolumeSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
LOG(ERROR) << __func__ << " invalid input parameter!";
return EX_ILLEGAL_ARGUMENT;
}
}
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVolumeSw()) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
*_aidl_return = VolumeSw::kDescriptor;
return EX_NONE;
}
namespace aidl::android::hardware::audio::effect {
const std::string VolumeSw::kEffectName = "VolumeSw";
const std::vector<Range::VolumeRange> VolumeSw::kRanges = {MAKE_RANGE(Volume, levelDb, -9600, 0)};
const Capability VolumeSw::kCapability = {.range = Range::make<Range::volume>(VolumeSw::kRanges)};
const Descriptor VolumeSw::kDescriptor = {
.common = {.id = {.type = getEffectTypeUuidVolume(),
.uuid = getEffectImplUuidVolumeSw(),
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = VolumeSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = VolumeSw::kCapability};
ndk::ScopedAStatus VolumeSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus VolumeSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::volume != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
auto& volParam = specific.get<Parameter::Specific::volume>();
RETURN_IF(!inRange(volParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = volParam.getTag();
switch (tag) {
case Volume::levelDb: {
RETURN_IF(mContext->setVolLevel(volParam.get<Volume::levelDb>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "LevelNotSupported");
return ndk::ScopedAStatus::ok();
}
case Volume::mute: {
RETURN_IF(mContext->setVolMute(volParam.get<Volume::mute>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "MuteNotSupported");
return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VolumeTagNotSupported");
}
}
}
ndk::ScopedAStatus VolumeSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::volumeTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
auto volId = id.get<Parameter::Id::volumeTag>();
auto volIdTag = volId.getTag();
switch (volIdTag) {
case Volume::Id::commonTag:
return getParameterVolume(volId.get<Volume::Id::commonTag>(), specific);
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VolumeTagNotSupported");
}
}
ndk::ScopedAStatus VolumeSw::getParameterVolume(const Volume::Tag& tag,
Parameter::Specific* specific) {
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
Volume volParam;
switch (tag) {
case Volume::levelDb: {
volParam.set<Volume::levelDb>(mContext->getVolLevel());
break;
}
case Volume::mute: {
volParam.set<Volume::mute>(mContext->getVolMute());
break;
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VolumeTagNotSupported");
}
}
specific->set<Parameter::Specific::volume>(volParam);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> VolumeSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
} else {
mContext = std::make_shared<VolumeSwContext>(1 /* statusFmqDepth */, common);
}
return mContext;
}
RetCode VolumeSw::releaseContext() {
if (mContext) {
mContext.reset();
}
return RetCode::SUCCESS;
}
// Processing method running in EffectWorker thread.
IEffect::Status VolumeSw::effectProcessImpl(float* in, float* out, int samples) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
for (int i = 0; i < samples; i++) {
*out++ = *in++;
}
return {STATUS_OK, samples, samples};
}
RetCode VolumeSwContext::setVolLevel(int level) {
mLevel = level;
return RetCode::SUCCESS;
}
RetCode VolumeSwContext::setVolMute(bool mute) {
// TODO : Add implementation to modify mute
mMute = mute;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View File

@@ -1,80 +0,0 @@
/*
* 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 <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class VolumeSwContext final : public EffectContext {
public:
VolumeSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setVolLevel(int level);
int getVolLevel() const { return mLevel; }
RetCode setVolMute(bool mute);
bool getVolMute() const { return mMute; }
private:
int mLevel = 0;
bool mMute = false;
};
class VolumeSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const Capability kCapability;
static const Descriptor kDescriptor;
VolumeSw() { LOG(DEBUG) << __func__; }
~VolumeSw() {
cleanUp();
LOG(DEBUG) << __func__;
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
REQUIRES(mImplMutex) override;
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
REQUIRES(mImplMutex) override;
RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::VolumeRange> kRanges;
std::shared_ptr<VolumeSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific)
REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect