1 /* 2 * Copyright (C) 2020 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 #ifndef ANDROID_EFFECTHAPTICGENERATOR_H_ 18 #define ANDROID_EFFECTHAPTICGENERATOR_H_ 19 20 #include <functional> 21 #include <vector> 22 #include <map> 23 24 #include <hardware/audio_effect.h> 25 #include <system/audio_effect.h> 26 #include <vibrator/ExternalVibrationUtils.h> 27 28 #include "Processors.h" 29 30 namespace android::audio_effect::haptic_generator { 31 32 //----------------------------------------------------------------------------- 33 // Definition 34 //----------------------------------------------------------------------------- 35 36 enum hapticgenerator_state_t { 37 HAPTICGENERATOR_STATE_UNINITIALIZED, 38 HAPTICGENERATOR_STATE_INITIALIZED, 39 HAPTICGENERATOR_STATE_ACTIVE, 40 }; 41 42 // parameters for each haptic generator 43 struct HapticGeneratorParam { 44 uint32_t hapticChannelSource[2]; // The audio channels used to generate haptic channels. 45 // The first channel will be used to generate HAPTIC_A, 46 // The second channel will be used to generate HAPTIC_B 47 // The value will be offset of audio channel 48 uint32_t audioChannelCount; 49 uint32_t hapticChannelCount; 50 51 // A map from track id to haptic intensity. 52 std::map<int, os::HapticScale> id2Intensity; 53 os::HapticScale maxHapticIntensity; // max intensity will be used to scale haptic data. 54 55 float resonantFrequency; 56 float bpfQ; 57 float slowEnvNormalizationPower; 58 float bsfZeroQ; 59 float bsfPoleQ; 60 float distortionCornerFrequency; 61 float distortionInputGain; 62 float distortionCubeThreshold; 63 float distortionOutputGain; 64 }; 65 66 // A structure to keep all shared pointers for all processors in HapticGenerator. 67 struct HapticGeneratorProcessorsRecord { 68 std::vector<std::shared_ptr<HapticBiquadFilter>> filters; 69 std::vector<std::shared_ptr<Ramp>> ramps; 70 std::vector<std::shared_ptr<SlowEnvelope>> slowEnvs; 71 std::vector<std::shared_ptr<Distortion>> distortions; 72 73 // Cache band-pass filter and band-stop filter for updating parameters 74 // according to vibrator info 75 std::shared_ptr<HapticBiquadFilter> bpf; 76 std::shared_ptr<HapticBiquadFilter> bsf; 77 }; 78 79 // A structure to keep all the context for HapticGenerator. 80 struct HapticGeneratorContext { 81 const struct effect_interface_s *itfe; 82 effect_config_t config; 83 hapticgenerator_state_t state; 84 struct HapticGeneratorParam param; 85 size_t audioDataBytesPerFrame; 86 87 // A cache for all shared pointers of the HapticGenerator 88 struct HapticGeneratorProcessorsRecord processorsRecord; 89 90 // Using a vector of functions to record the processing chain for haptic-generating algorithm. 91 // The three parameters of the processing functions are pointer to output buffer, pointer to 92 // input buffer and frame count. 93 std::vector<std::function<void(float*, const float*, size_t)>> processingChain; 94 95 // inputBuffer is where to keep input buffer for the generating algorithm. It will be 96 // constructed according to HapticGeneratorParam.hapticChannelSource. 97 std::vector<float> inputBuffer; 98 99 // outputBuffer is a buffer having the same length as inputBuffer. It can be used as 100 // intermediate buffer in the generating algorithm. 101 std::vector<float> outputBuffer; 102 }; 103 104 //----------------------------------------------------------------------------- 105 // Effect API 106 //----------------------------------------------------------------------------- 107 108 int32_t HapticGeneratorLib_Create(const effect_uuid_t *uuid, 109 int32_t sessionId, 110 int32_t ioId, 111 effect_handle_t *handle); 112 113 int32_t HapticGeneratorLib_Release(effect_handle_t handle); 114 115 int32_t HapticGeneratorLib_GetDescriptor(const effect_uuid_t *uuid, 116 effect_descriptor_t *descriptor); 117 118 int32_t HapticGenerator_Process(effect_handle_t self, 119 audio_buffer_t *inBuffer, 120 audio_buffer_t *outBuffer); 121 122 int32_t HapticGenerator_Command(effect_handle_t self, 123 uint32_t cmdCode, 124 uint32_t cmdSize, 125 void *cmdData, 126 uint32_t *replySize, 127 void *replyData); 128 129 int32_t HapticGenerator_GetDescriptor(effect_handle_t self, 130 effect_descriptor_t *descriptor); 131 132 } // namespace android::audio_effect::haptic_generator 133 134 #endif // ANDROID_EFFECTHAPTICGENERATOR_H_ 135