From 784a48b793578b9370f54f272b6dc8dab7147fa7 Mon Sep 17 00:00:00 2001 From: lixiangpeng5 Date: Thu, 19 Sep 2024 04:10:31 +0000 Subject: [PATCH] fix custom haptic for preset Signed-off-by: lixiangpeng5 Change-Id: I0aa5a1a726eb4d3b4398a742cfc06e5855d37cc3 --- .../include/custom_vibration_matcher.h | 13 +- .../src/custom_vibration_matcher.cpp | 114 ++++++++++++++---- .../adapter/include/compatible_connection.h | 1 + .../adapter/include/hdi_connection.h | 1 + .../adapter/src/compatible_connection.cpp | 6 + .../adapter/src/hdi_connection.cpp | 12 ++ .../include/i_vibrator_hdi_connection.h | 3 + .../include/vibrator_hdi_connection.h | 1 + .../interface/src/vibrator_hdi_connection.cpp | 7 ++ .../src/vibrator_thread.cpp | 2 +- 10 files changed, 131 insertions(+), 29 deletions(-) diff --git a/services/miscdevice_service/haptic_matcher/include/custom_vibration_matcher.h b/services/miscdevice_service/haptic_matcher/include/custom_vibration_matcher.h index be4898e..4019151 100644 --- a/services/miscdevice_service/haptic_matcher/include/custom_vibration_matcher.h +++ b/services/miscdevice_service/haptic_matcher/include/custom_vibration_matcher.h @@ -16,6 +16,7 @@ #ifndef CUSTOM_VIBRATION_MATCHER_H #define CUSTOM_VIBRATION_MATCHER_H +#include #include #include #include @@ -27,24 +28,30 @@ namespace OHOS { namespace Sensors { class CustomVibrationMatcher { public: - CustomVibrationMatcher() = default; ~CustomVibrationMatcher() = default; + static CustomVibrationMatcher &GetInstance(); int32_t TransformTime(const VibratePackage &package, std::vector &compositeEffects); int32_t TransformEffect(const VibratePackage &package, std::vector &compositeEffects); private: + DISALLOW_COPY_AND_MOVE(CustomVibrationMatcher); + CustomVibrationMatcher(); static int32_t Interpolation(int32_t x1, int32_t x2, int32_t y1, int32_t y2, int32_t x); VibratePattern MixedWaveProcess(const VibratePackage &package); void PreProcessEvent(VibrateEvent &event); std::vector MergeCurve(const std::vector &curveLeft, const std::vector &curveRight); + void NormalizedWaveInfo(); void ProcessContinuousEvent(const VibrateEvent &event, int32_t &preStartTime, int32_t &preDuration, std::vector &compositeEffects); void ProcessContinuousEventSlice(const VibrateSlice &slice, int32_t &preStartTime, int32_t &preDuration, std::vector &compositeEffects); void ProcessTransientEvent(const VibrateEvent &event, int32_t &preStartTime, int32_t &preDuration, std::vector &compositeEffects); + + std::vector hdfWaveInfos_; + std::map> waveInfos_; }; -} // namespace Sensors -} // namespace OHOS +} // namespace Sensors +} // namespace OHOS #endif // CUSTOM_VIBRATION_MATCHER_H diff --git a/services/miscdevice_service/haptic_matcher/src/custom_vibration_matcher.cpp b/services/miscdevice_service/haptic_matcher/src/custom_vibration_matcher.cpp index b24eddc..5c3d631 100644 --- a/services/miscdevice_service/haptic_matcher/src/custom_vibration_matcher.cpp +++ b/services/miscdevice_service/haptic_matcher/src/custom_vibration_matcher.cpp @@ -16,9 +16,9 @@ #include "custom_vibration_matcher.h" #include -#include #include "sensors_errors.h" +#include "vibrator_hdi_connection.h" #undef LOG_TAG #define LOG_TAG "CustomVibrationMatcher" @@ -26,34 +26,83 @@ namespace OHOS { namespace Sensors { namespace { -const std::map> TRANSIENT_VIBRATION_INFOS = { - {0x28, {0x4d, 0x4d, 0x0b}}, {0x2c, {0x2a, 0x64, 0x07}}, {0x30, {0x44, 0x52, 0x16}}, - {0x3c, {0x45, 0x34, 0x0a}}, {0x40, {0x2e, 0x43, 0x0a}}, {0x48, {0x51, 0x52, 0x0a}}, - {0x4c, {0x3a, 0x0c, 0x0f}}, {0x50, {0x64, 0x20, 0x14}}, {0x54, {0x55, 0x34, 0x1c}}, - {0x5c, {0x32, 0x0c, 0x13}}, {0x60, {0x12, 0x07, 0x0a}} -}; constexpr int32_t FREQUENCY_MIN = 0; constexpr int32_t FREQUENCY_MAX = 100; constexpr int32_t INTENSITY_MIN = 0; constexpr int32_t INTENSITY_MAX = 100; -constexpr int32_t TRANSIENT_GRADE_NUM = 4; +constexpr int32_t VIBRATOR_DELAY = 20; constexpr int32_t CONTINUOUS_GRADE_NUM = 8; constexpr int32_t CONTINUOUS_GRADE_MASK = 100; constexpr float ROUND_OFFSET = 0.5; -constexpr float TRANSIENT_GRADE_GAIN = 0.25; constexpr float CONTINUOUS_GRADE_SCALE = 100. / 8; constexpr float INTENSITY_WEIGHT = 0.5; constexpr float FREQUENCY_WEIGHT = 0.5; constexpr float WEIGHT_SUM_INIT = 100; -constexpr int32_t STOP_WAVEFORM = 0; constexpr int32_t EFFECT_ID_BOUNDARY = 1000; constexpr int32_t DURATION_MAX = 1600; constexpr float CURVE_INTENSITY_SCALE = 100.00; +const float EPSILON = 0.00001; constexpr int32_t SLICE_STEP = 50; constexpr int32_t CONTINUOUS_VIBRATION_DURATION_MIN = 15; constexpr int32_t INDEX_MIN_RESTRICT = 1; +constexpr int32_t WAVE_INFO_DIMENSION = 3; } // namespace +CustomVibrationMatcher::CustomVibrationMatcher() +{ + auto &VibratorDevice = VibratorHdiConnection::GetInstance(); + int32_t ret = VibratorDevice.GetAllWaveInfo(hdfWaveInfos_); + if (ret != ERR_OK) { + MISC_HILOGE("GetAllWaveInfo failed infoSize:%{public}zu", hdfWaveInfos_.size()); + return; + } + if (!hdfWaveInfos_.empty()) { + for (auto it = hdfWaveInfos_.begin(); it != hdfWaveInfos_.end(); ++it) { + MISC_HILOGI("waveId:%{public}d, intensity:%{public}f, frequency:%{public}f, duration:%{public}d", + it->waveId, it->intensity, it->frequency, it->duration); + } + NormalizedWaveInfo(); + } +} + +void CustomVibrationMatcher::NormalizedWaveInfo() +{ + CALL_LOG_ENTER; + auto firstIt = hdfWaveInfos_.begin(); + float maxIntensity = firstIt->intensity; + float minFrequency = firstIt->frequency; + float maxFrequency = firstIt->frequency; + for (auto it = hdfWaveInfos_.begin(); it != hdfWaveInfos_.end(); ++it) { + maxIntensity = (maxIntensity > it->intensity) ? maxIntensity : it->intensity; + minFrequency = (minFrequency < it->frequency) ? minFrequency : it->frequency; + maxFrequency = (maxFrequency > it->frequency) ? maxFrequency : it->frequency; + } + + float intensityEqualValue = maxIntensity / INTENSITY_MAX; + float frequencyEqualValue = (maxFrequency - minFrequency) / FREQUENCY_MAX; + if ((std::abs(intensityEqualValue) <= EPSILON) || (std::abs(frequencyEqualValue) <= EPSILON)) { + MISC_HILOGE("The equal value of intensity or frequency is zero"); + return; + } + for (auto it = hdfWaveInfos_.begin(); it != hdfWaveInfos_.end(); ++it) { + std::vector normalizedValue; + normalizedValue.push_back(static_cast(it->intensity / intensityEqualValue)); + normalizedValue.push_back(static_cast((it->frequency - minFrequency) / frequencyEqualValue)); + normalizedValue.push_back(it->duration); + waveInfos_[it->waveId] = normalizedValue; + } + for (auto it = waveInfos_.begin(); it != waveInfos_.end(); ++it) { + MISC_HILOGI("waveId:%{public}d, intensity:%{public}d, frequency:%{public}d, duration:%{public}d", + it->first, it->second[0], it->second[1], it->second[WAVE_INFO_DIMENSION - 1]); + } +} + +CustomVibrationMatcher &CustomVibrationMatcher::GetInstance() +{ + static CustomVibrationMatcher instance; + return instance; +} + int32_t CustomVibrationMatcher::TransformTime(const VibratePackage &package, std::vector &compositeEffects) { @@ -68,6 +117,8 @@ int32_t CustomVibrationMatcher::TransformTime(const VibratePackage &package, TimeEffect timeEffect; timeEffect.delay = event.time - frontTime; timeEffect.time = event.duration; + timeEffect.intensity = event.intensity; + timeEffect.frequency = event.frequency; CompositeEffect compositeEffect; compositeEffect.timeEffect = timeEffect; compositeEffects.push_back(compositeEffect); @@ -76,6 +127,8 @@ int32_t CustomVibrationMatcher::TransformTime(const VibratePackage &package, TimeEffect timeEffect; timeEffect.delay = flatPattern.events.back().duration; timeEffect.time = 0; + timeEffect.intensity = 0; + timeEffect.frequency = 0; CompositeEffect compositeEffect; compositeEffect.timeEffect = timeEffect; compositeEffects.push_back(compositeEffect); @@ -94,8 +147,16 @@ int32_t CustomVibrationMatcher::TransformEffect(const VibratePackage &package, int32_t preStartTime = flatPattern.startTime; int32_t preDuration = 0; for (const VibrateEvent &event : flatPattern.events) { - if (event.tag == EVENT_TAG_CONTINUOUS) { - ProcessContinuousEvent(event, preStartTime, preDuration, compositeEffects); + if ((event.tag == EVENT_TAG_CONTINUOUS) || waveInfos_.empty()) { + PrimitiveEffect primitiveEffect; + primitiveEffect.delay = event.time - preStartTime; + primitiveEffect.effectId = event.duration; + primitiveEffect.intensity = event.intensity; + CompositeEffect compositeEffect; + compositeEffect.primitiveEffect = primitiveEffect; + compositeEffects.push_back(compositeEffect); + preStartTime = event.time; + preDuration = event.duration; } else if (event.tag == EVENT_TAG_TRANSIENT) { ProcessTransientEvent(event, preStartTime, preDuration, compositeEffects); } else { @@ -105,7 +166,8 @@ int32_t CustomVibrationMatcher::TransformEffect(const VibratePackage &package, } PrimitiveEffect primitiveEffect; primitiveEffect.delay = preDuration; - primitiveEffect.effectId = STOP_WAVEFORM; + primitiveEffect.effectId = 0; + primitiveEffect.intensity = 0; CompositeEffect compositeEffect; compositeEffect.primitiveEffect = primitiveEffect; compositeEffects.push_back(compositeEffect); @@ -120,9 +182,12 @@ VibratePattern CustomVibrationMatcher::MixedWaveProcess(const VibratePackage &pa for (VibrateEvent event : pattern.events) { event.time += pattern.startTime; PreProcessEvent(event); - if ((outputEvents.empty()) || - (event.time >= (outputEvents.back().time + outputEvents.back().duration)) || - (outputEvents.back().tag == EVENT_TAG_TRANSIENT)) { + if ((outputEvents.empty()) || (outputEvents.back().tag == EVENT_TAG_TRANSIENT)) { + outputEvents.emplace_back(event); + } else if ((event.time >= (outputEvents.back().time + outputEvents.back().duration))) { + int32_t diffTime = event.time - outputEvents.back().time - outputEvents.back().duration; + outputEvents.back().duration += ((diffTime < VIBRATOR_DELAY) ? (diffTime - VIBRATOR_DELAY) : 0); + outputEvents.back().duration = std::max(outputEvents.back().duration, 0); outputEvents.emplace_back(event); } else { VibrateEvent &lastEvent = outputEvents.back(); @@ -317,22 +382,21 @@ void CustomVibrationMatcher::ProcessTransientEvent(const VibrateEvent &event, in { int32_t matchId = 0; float minWeightSum = WEIGHT_SUM_INIT; - for (const auto &transientInfo : TRANSIENT_VIBRATION_INFOS) { + for (const auto &transientInfo : waveInfos_) { int32_t id = transientInfo.first; const std::vector &info = transientInfo.second; + float intensityDistance = std::abs(event.intensity - info[0]); float frequencyDistance = std::abs(event.frequency - info[1]); - for (int32_t j = 0; j < TRANSIENT_GRADE_NUM; ++j) { - float intensityDistance = std::abs(event.intensity - info[0] * (1 - j * TRANSIENT_GRADE_GAIN)); - float weightSum = INTENSITY_WEIGHT * intensityDistance + FREQUENCY_WEIGHT * frequencyDistance; - if (weightSum < minWeightSum) { - minWeightSum = weightSum; - matchId = id + j; - } + float weightSum = INTENSITY_WEIGHT * intensityDistance + FREQUENCY_WEIGHT * frequencyDistance; + if (weightSum < minWeightSum) { + minWeightSum = weightSum; + matchId = id; } } PrimitiveEffect primitiveEffect; primitiveEffect.delay = event.time - preStartTime; - primitiveEffect.effectId = matchId; + primitiveEffect.effectId = (-matchId); + primitiveEffect.intensity = INTENSITY_MAX; CompositeEffect compositeEffect; compositeEffect.primitiveEffect = primitiveEffect; compositeEffects.push_back(compositeEffect); diff --git a/services/miscdevice_service/hdi_connection/adapter/include/compatible_connection.h b/services/miscdevice_service/hdi_connection/adapter/include/compatible_connection.h index da6e5b5..ad11c9f 100644 --- a/services/miscdevice_service/hdi_connection/adapter/include/compatible_connection.h +++ b/services/miscdevice_service/hdi_connection/adapter/include/compatible_connection.h @@ -41,6 +41,7 @@ public: int32_t PlayPattern(const VibratePattern &pattern) override; int32_t DestroyHdiConnection() override; int32_t StartByIntensity(const std::string &effect, int32_t intensity) override; + int32_t GetAllWaveInfo(std::vector &waveInfos) override; private: DISALLOW_COPY_AND_MOVE(CompatibleConnection); diff --git a/services/miscdevice_service/hdi_connection/adapter/include/hdi_connection.h b/services/miscdevice_service/hdi_connection/adapter/include/hdi_connection.h index abdfc72..196488c 100644 --- a/services/miscdevice_service/hdi_connection/adapter/include/hdi_connection.h +++ b/services/miscdevice_service/hdi_connection/adapter/include/hdi_connection.h @@ -43,6 +43,7 @@ public: int32_t DestroyHdiConnection() override; void ProcessDeathObserver(const wptr &object); int32_t StartByIntensity(const std::string &effect, int32_t intensity) override; + int32_t GetAllWaveInfo(std::vector &waveInfos) override; private: DISALLOW_COPY_AND_MOVE(HdiConnection); diff --git a/services/miscdevice_service/hdi_connection/adapter/src/compatible_connection.cpp b/services/miscdevice_service/hdi_connection/adapter/src/compatible_connection.cpp index 3ad529f..8a09d86 100644 --- a/services/miscdevice_service/hdi_connection/adapter/src/compatible_connection.cpp +++ b/services/miscdevice_service/hdi_connection/adapter/src/compatible_connection.cpp @@ -206,5 +206,11 @@ int32_t CompatibleConnection::StartByIntensity(const std::string &effect, int32_ g_vibrateMode = HDF_VIBRATOR_MODE_PRESET; return ERR_OK; } + +int32_t CompatibleConnection::GetAllWaveInfo(std::vector &waveInfos) +{ + return ERR_OK; +} + } // namespace Sensors } // namespace OHOS diff --git a/services/miscdevice_service/hdi_connection/adapter/src/hdi_connection.cpp b/services/miscdevice_service/hdi_connection/adapter/src/hdi_connection.cpp index 6c5ee47..699c34d 100644 --- a/services/miscdevice_service/hdi_connection/adapter/src/hdi_connection.cpp +++ b/services/miscdevice_service/hdi_connection/adapter/src/hdi_connection.cpp @@ -276,5 +276,17 @@ int32_t HdiConnection::StartByIntensity(const std::string &effect, int32_t inten } return ERR_OK; } + +int32_t HdiConnection::GetAllWaveInfo(std::vector &waveInfos) +{ + CHKPR(vibratorInterface_, ERR_INVALID_VALUE); + int32_t vibratorId = 1; + int32_t ret = vibratorInterface_->GetAllWaveInfo(vibratorId, waveInfos); + if (ret != ERR_OK) { + MISC_HILOGE("GetAllWaveInfo failed"); + } + return ret; +} + } // namespace Sensors } // namespace OHOS diff --git a/services/miscdevice_service/hdi_connection/interface/include/i_vibrator_hdi_connection.h b/services/miscdevice_service/hdi_connection/interface/include/i_vibrator_hdi_connection.h index 09ad7a0..340826d 100644 --- a/services/miscdevice_service/hdi_connection/interface/include/i_vibrator_hdi_connection.h +++ b/services/miscdevice_service/hdi_connection/interface/include/i_vibrator_hdi_connection.h @@ -22,6 +22,7 @@ #include #include "v1_2/vibrator_types.h" +#include "v1_3/ivibrator_interface.h" #include "vibrator_infos.h" namespace OHOS { @@ -37,6 +38,7 @@ using OHOS::HDI::Vibrator::V1_2::HapticCapacity; using OHOS::HDI::Vibrator::V1_2::HapticPaket; using OHOS::HDI::Vibrator::V1_2::HapticEvent; using OHOS::HDI::Vibrator::V1_1::HdfEffectInfo; +using OHOS::HDI::Vibrator::V1_3::HdfWaveInformation; #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM using OHOS::HDI::Vibrator::V1_1::HdfEffectType; using OHOS::HDI::Vibrator::V1_1::HDF_EFFECT_TYPE_TIME; @@ -65,6 +67,7 @@ public: virtual int32_t GetVibratorCapacity(VibratorCapacity &capacity) = 0; virtual int32_t PlayPattern(const VibratePattern &pattern) = 0; virtual int32_t StartByIntensity(const std::string &effect, int32_t intensity) = 0; + virtual int32_t GetAllWaveInfo(std::vector &waveInfos) = 0; private: DISALLOW_COPY_AND_MOVE(IVibratorHdiConnection); diff --git a/services/miscdevice_service/hdi_connection/interface/include/vibrator_hdi_connection.h b/services/miscdevice_service/hdi_connection/interface/include/vibrator_hdi_connection.h index 938fb26..07418b9 100644 --- a/services/miscdevice_service/hdi_connection/interface/include/vibrator_hdi_connection.h +++ b/services/miscdevice_service/hdi_connection/interface/include/vibrator_hdi_connection.h @@ -40,6 +40,7 @@ public: int32_t GetVibratorCapacity(VibratorCapacity &capacity) override; int32_t PlayPattern(const VibratePattern &pattern) override; int32_t StartByIntensity(const std::string &effect, int32_t intensity) override; + int32_t GetAllWaveInfo(std::vector &waveInfos) override; private: DISALLOW_COPY_AND_MOVE(VibratorHdiConnection); diff --git a/services/miscdevice_service/hdi_connection/interface/src/vibrator_hdi_connection.cpp b/services/miscdevice_service/hdi_connection/interface/src/vibrator_hdi_connection.cpp index 015189e..7dac910 100644 --- a/services/miscdevice_service/hdi_connection/interface/src/vibrator_hdi_connection.cpp +++ b/services/miscdevice_service/hdi_connection/interface/src/vibrator_hdi_connection.cpp @@ -159,5 +159,12 @@ int32_t VibratorHdiConnection::StartByIntensity(const std::string &effect, int32 } return ERR_OK; } + +int32_t VibratorHdiConnection::GetAllWaveInfo(std::vector &waveInfos) +{ + CHKPR(iVibratorHdiConnection_, VIBRATOR_HDF_CONNECT_ERR); + return iVibratorHdiConnection_->GetAllWaveInfo(waveInfos); +} + } // namespace Sensors } // namespace OHOS diff --git a/services/miscdevice_service/src/vibrator_thread.cpp b/services/miscdevice_service/src/vibrator_thread.cpp index 3ea67a2..6e45393 100644 --- a/services/miscdevice_service/src/vibrator_thread.cpp +++ b/services/miscdevice_service/src/vibrator_thread.cpp @@ -129,7 +129,7 @@ int32_t VibratorThread::PlayCustomByHdHptic(const VibrateInfo &info) int32_t VibratorThread::PlayCustomByCompositeEffect(const VibrateInfo &info) { - CustomVibrationMatcher matcher; + auto &matcher = CustomVibrationMatcher::GetInstance(); HdfCompositeEffect hdfCompositeEffect; if (info.mode == VIBRATE_CUSTOM_COMPOSITE_EFFECT) { hdfCompositeEffect.type = HDF_EFFECT_TYPE_PRIMITIVE; -- Gitee