1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include "effect-impl/EffectContext.h" 20 #include "Processors.h" 21 22 #include <vibrator/ExternalVibrationUtils.h> 23 24 #include <cstddef> 25 #include <map> 26 27 namespace aidl::android::hardware::audio::effect { 28 29 enum HapticGeneratorState { 30 HAPTIC_GENERATOR_STATE_UNINITIALIZED, 31 HAPTIC_GENERATOR_STATE_INITIALIZED, 32 HAPTIC_GENERATOR_STATE_ACTIVE, 33 }; 34 35 struct HapticGeneratorParam { 36 // The audio channels used to generate haptic channels. The first channel will be used to 37 // generate HAPTIC_A, The second channel will be used to generate HAPTIC_B. 38 // The value will be offset of audio channel 39 int mHapticChannelSource[2]; 40 41 int mHapticChannelCount; 42 int mAudioChannelCount; 43 44 std::map<int, HapticGenerator::VibratorScale> mHapticScales; 45 // max intensity will be used to scale haptic data. 46 HapticGenerator::VibratorScale mMaxVibratorScale; 47 48 HapticGenerator::VibratorInformation mVibratorInfo; 49 }; 50 51 // A structure to keep all shared pointers for all processors in HapticGenerator. 52 struct HapticGeneratorProcessorsRecord { 53 std::vector<std::shared_ptr<HapticBiquadFilter>> filters; 54 std::vector<std::shared_ptr<::android::audio_effect::haptic_generator::Ramp>> ramps; 55 std::vector<std::shared_ptr<::android::audio_effect::haptic_generator::SlowEnvelope>> slowEnvs; 56 std::vector<std::shared_ptr<::android::audio_effect::haptic_generator::Distortion>> distortions; 57 58 // Cache band-pass filter and band-stop filter for updating parameters 59 // according to vibrator info 60 std::shared_ptr<HapticBiquadFilter> bpf; 61 std::shared_ptr<HapticBiquadFilter> bsf; 62 }; 63 64 class HapticGeneratorContext final : public EffectContext { 65 public: 66 HapticGeneratorContext(int statusDepth, const Parameter::Common& common); 67 ~HapticGeneratorContext(); 68 RetCode enable(); 69 RetCode disable(); 70 void reset(); 71 72 RetCode setHgHapticScales(const std::vector<HapticGenerator::HapticScale>& hapticScales); 73 std::vector<HapticGenerator::HapticScale> getHgHapticScales() const; 74 75 RetCode setHgVibratorInformation(const HapticGenerator::VibratorInformation& vibratorInfo); 76 HapticGenerator::VibratorInformation getHgVibratorInformation() const; 77 78 IEffect::Status process(float* in, float* out, int samples); 79 80 RetCode setCommon(const Parameter::Common& common) override; 81 82 private: 83 static constexpr float DEFAULT_RESONANT_FREQUENCY = 150.0f; 84 static constexpr float DEFAULT_BSF_ZERO_Q = 8.0f; 85 static constexpr float DEFAULT_BSF_POLE_Q = 4.0f; 86 static constexpr float DEFAULT_DISTORTION_OUTPUT_GAIN = 1.5f; 87 static constexpr float DEFAULT_BPF_Q = 1.0f; 88 static constexpr float DEFAULT_SLOW_ENV_NORMALIZATION_POWER = -0.8f; 89 static constexpr float DEFAULT_DISTORTION_CORNER_FREQUENCY = 300.0f; 90 static constexpr float DEFAULT_DISTORTION_INPUT_GAIN = 0.3f; 91 static constexpr float DEFAULT_DISTORTION_CUBE_THRESHOLD = 0.1f; 92 93 HapticGeneratorState mState; 94 HapticGeneratorParam mParams; 95 int mSampleRate; 96 int64_t mFrameCount = 0; 97 98 // A cache for all shared pointers of the HapticGenerator 99 struct HapticGeneratorProcessorsRecord mProcessorsRecord; 100 101 // Using a vector of functions to record the processing chain for haptic-generating algorithm. 102 // The three parameters of the processing functions are pointer to output buffer, pointer to 103 // input buffer and frame count. 104 std::vector<std::function<void(float*, const float*, size_t)>> mProcessingChain; 105 106 // inputBuffer is where to keep input buffer for the generating algorithm. It will be 107 // constructed according to hapticChannelSource. 108 std::vector<float> mInputBuffer; 109 110 // outputBuffer is a buffer having the same length as inputBuffer. It can be used as 111 // intermediate buffer in the generating algorithm. 112 std::vector<float> mOutputBuffer; 113 114 void init_params(const Parameter::Common& common); 115 void configure(); 116 117 float getDistortionOutputGain() const; 118 float getFloatProperty(const std::string& key, float defaultValue) const; 119 void addBiquadFilter(std::shared_ptr<HapticBiquadFilter> filter); 120 void buildProcessingChain(); 121 float* runProcessingChain(float* buf1, float* buf2, size_t frameCount); 122 123 std::string paramToString(const struct HapticGeneratorParam& param) const; 124 std::string contextToString() const; 125 }; 126 127 } // namespace aidl::android::hardware::audio::effect 128