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 _EFFECT_HAPTIC_GENERATOR_PROCESSORS_H_ 18 #define _EFFECT_HAPTIC_GENERATOR_PROCESSORS_H_ 19 20 #include <sys/types.h> 21 22 #include <memory> 23 #include <vector> 24 25 #include <audio_utils/BiquadFilter.h> 26 27 using HapticBiquadFilter = android::audio_utils::BiquadFilter<float>; 28 using BiquadFilterCoefficients = std::array<float, android::audio_utils::kBiquadNumCoefs>; 29 30 namespace android::audio_effect::haptic_generator { 31 32 // A class providing a process function that makes input data non-negative. 33 class Ramp { 34 public: 35 explicit Ramp(size_t channelCount); 36 37 void process(float *out, const float *in, size_t frameCount); 38 39 private: 40 const size_t mChannelCount; 41 }; 42 43 44 class SlowEnvelope { 45 public: 46 SlowEnvelope(float cornerFrequency, float sampleRate, 47 float normalizationPower, float envOffset, 48 size_t channelCount); 49 50 void process(float *out, const float *in, size_t frameCount); 51 52 void setNormalizationPower(float normalizationPower); 53 54 void clear(); 55 56 private: 57 const std::shared_ptr<HapticBiquadFilter> mLpf; 58 std::vector<float> mLpfInBuffer; 59 std::vector<float> mLpfOutBuffer; 60 float mNormalizationPower; 61 const float mEnvOffset; 62 const float mChannelCount; 63 }; 64 65 66 // A class providing a process function that compressively distorts a waveforms 67 class Distortion { 68 public: 69 Distortion(float cornerFrequency, float sampleRate, 70 float inputGain, float cubeThreshold, 71 float outputGain, size_t channelCount); 72 73 void process(float *out, const float *in, size_t frameCount); 74 75 void setCornerFrequency(float cornerFrequency); 76 void setInputGain(float inputGain); 77 void setCubeThrehold(float cubeThreshold); 78 void setOutputGain(float outputGain); 79 80 void clear(); 81 82 private: 83 const std::shared_ptr<HapticBiquadFilter> mLpf; 84 std::vector<float> mLpfInBuffer; 85 float mSampleRate; 86 float mCornerFrequency; 87 float mInputGain; 88 float mCubeThreshold; 89 float mOutputGain; 90 const size_t mChannelCount; 91 }; 92 93 // Helper functions 94 95 BiquadFilterCoefficients cascadeFirstOrderFilters(const BiquadFilterCoefficients &coefs1, 96 const BiquadFilterCoefficients &coefs2); 97 98 BiquadFilterCoefficients lpfCoefs(const float cornerFrequency, const float sampleRate); 99 100 BiquadFilterCoefficients bpfCoefs(const float ringingFrequency, 101 const float q, 102 const float sampleRate); 103 104 BiquadFilterCoefficients bsfCoefs(const float ringingFrequency, 105 const float zq, 106 const float pq, 107 const float sampleRate); 108 109 std::shared_ptr<HapticBiquadFilter> createLPF(const float cornerFrequency, 110 const float sampleRate, 111 const size_t channelCount); 112 113 // Create two cascaded LPF with same corner frequency. 114 std::shared_ptr<HapticBiquadFilter> createLPF2(const float cornerFrequency, 115 const float sampleRate, 116 const size_t channelCount); 117 118 // Create two cascaded HPF with same corner frequency. 119 std::shared_ptr<HapticBiquadFilter> createHPF2(const float cornerFrequency, 120 const float sampleRate, 121 const size_t channelCount); 122 123 std::shared_ptr<HapticBiquadFilter> createBPF(const float ringingFrequency, 124 const float q, 125 const float sampleRate, 126 const size_t channelCount); 127 128 std::shared_ptr<HapticBiquadFilter> createBSF(const float ringingFrequency, 129 const float zq, 130 const float pq, 131 const float sampleRate, 132 const size_t channelCount); 133 134 } // namespace android::audio_effect::haptic_generator 135 136 #endif // _EFFECT_HAPTIC_GENERATOR_PROCESSORS_H_ 137