Add adaptive haptics scaling to external vibrations
Converting the usage of haptic intensity, which only covers the scale
level, to HapticScale which includes both scale level and adaptive
haptics scale.
Bug: 305957324
Test: N/A
Change-Id: Ib3a5b83e20707207affbbe6dbc0586669ae4841b
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 57b860d..f9ae2d4 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -441,10 +441,10 @@
track->prepareForAdjustChannels(mFrameCount);
}
} break;
- case HAPTIC_INTENSITY: {
- const os::HapticScale hapticIntensity = static_cast<os::HapticScale>(valueInt);
- if (track->mHapticIntensity != hapticIntensity) {
- track->mHapticIntensity = hapticIntensity;
+ case HAPTIC_SCALE: {
+ const os::HapticScale hapticScale = *reinterpret_cast<os::HapticScale*>(value);
+ if (track->mHapticScale != hapticScale) {
+ track->mHapticScale = hapticScale;
}
} break;
case HAPTIC_MAX_AMPLITUDE: {
@@ -585,7 +585,7 @@
t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
// haptic
t->mHapticPlaybackEnabled = false;
- t->mHapticIntensity = os::HapticScale::NONE;
+ t->mHapticScale = {/*level=*/os::HapticLevel::NONE };
t->mHapticMaxAmplitude = NAN;
t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
t->mMixerHapticChannelCount = 0;
@@ -636,7 +636,7 @@
switch (t->mMixerFormat) {
// Mixer format should be AUDIO_FORMAT_PCM_FLOAT.
case AUDIO_FORMAT_PCM_FLOAT: {
- os::scaleHapticData((float*) buffer, sampleCount, t->mHapticIntensity,
+ os::scaleHapticData((float*) buffer, sampleCount, t->mHapticScale,
t->mHapticMaxAmplitude);
} break;
default:
diff --git a/media/libaudioprocessing/include/media/AudioMixer.h b/media/libaudioprocessing/include/media/AudioMixer.h
index b39fb92..f558fd5 100644
--- a/media/libaudioprocessing/include/media/AudioMixer.h
+++ b/media/libaudioprocessing/include/media/AudioMixer.h
@@ -49,7 +49,7 @@
DOWNMIX_TYPE = 0x4004,
// for haptic
HAPTIC_ENABLED = 0x4007, // Set haptic data from this track should be played or not.
- HAPTIC_INTENSITY = 0x4008, // Set the intensity to play haptic data.
+ HAPTIC_SCALE = 0x4008, // Set the scale to play haptic data.
HAPTIC_MAX_AMPLITUDE = 0x4009, // Set the max amplitude allowed for haptic data.
// for target TIMESTRETCH
PLAYBACK_RATE = 0x4300, // Configure timestretch on this track name;
@@ -141,7 +141,7 @@
// Haptic
bool mHapticPlaybackEnabled;
- os::HapticScale mHapticIntensity;
+ os::HapticScale mHapticScale;
float mHapticMaxAmplitude;
audio_channel_mask_t mHapticChannelMask;
uint32_t mHapticChannelCount;
diff --git a/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp b/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp
index a8892d8..5d9886c 100644
--- a/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp
+++ b/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp
@@ -145,7 +145,7 @@
memset(context->param.hapticChannelSource, 0, sizeof(context->param.hapticChannelSource));
context->param.hapticChannelCount = 0;
context->param.audioChannelCount = 0;
- context->param.maxHapticIntensity = os::HapticScale::MUTE;
+ context->param.maxHapticIntensity = os::HapticLevel::MUTE;
context->param.resonantFrequency = DEFAULT_RESONANT_FREQUENCY;
context->param.bpfQ = 1.0f;
@@ -316,9 +316,10 @@
return -EINVAL;
}
int id = *(int *) value;
- os::HapticScale hapticIntensity = static_cast<os::HapticScale>(*((int *) value + 1));
+ os::HapticLevel hapticIntensity =
+ static_cast<os::HapticLevel>(*((int *) value + 1));
ALOGD("Setting haptic intensity as %d", static_cast<int>(hapticIntensity));
- if (hapticIntensity == os::HapticScale::MUTE) {
+ if (hapticIntensity == os::HapticLevel::MUTE) {
context->param.id2Intensity.erase(id);
} else {
context->param.id2Intensity.emplace(id, hapticIntensity);
@@ -478,7 +479,7 @@
return -ENODATA;
}
- if (context->param.maxHapticIntensity == os::HapticScale::MUTE) {
+ if (context->param.maxHapticIntensity == os::HapticLevel::MUTE) {
// Haptic channels are muted, not need to generate haptic data.
return 0;
}
@@ -504,8 +505,9 @@
float* hapticOutBuffer = HapticGenerator_runProcessingChain(
context->processingChain, context->inputBuffer.data(),
context->outputBuffer.data(), inBuffer->frameCount);
- os::scaleHapticData(hapticOutBuffer, hapticSampleCount, context->param.maxHapticIntensity,
- context->param.maxHapticAmplitude);
+ os::scaleHapticData(hapticOutBuffer, hapticSampleCount,
+ { /*level=*/context->param.maxHapticIntensity},
+ context->param.maxHapticAmplitude);
// For haptic data, the haptic playback thread will copy the data from effect input buffer,
// which contains haptic data at the end of the buffer, directly to sink buffer.
diff --git a/media/libeffects/hapticgenerator/EffectHapticGenerator.h b/media/libeffects/hapticgenerator/EffectHapticGenerator.h
index 85e961f..f122c0a 100644
--- a/media/libeffects/hapticgenerator/EffectHapticGenerator.h
+++ b/media/libeffects/hapticgenerator/EffectHapticGenerator.h
@@ -49,8 +49,8 @@
uint32_t hapticChannelCount;
// A map from track id to haptic intensity.
- std::map<int, os::HapticScale> id2Intensity;
- os::HapticScale maxHapticIntensity; // max intensity will be used to scale haptic data.
+ std::map<int, os::HapticLevel> id2Intensity;
+ os::HapticLevel maxHapticIntensity; // max intensity will be used to scale haptic data.
float maxHapticAmplitude; // max amplitude will be used to limit haptic data absolute values.
float resonantFrequency;
diff --git a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
index e671543..5c38d17 100644
--- a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
+++ b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
@@ -174,7 +174,7 @@
runProcessingChain(mInputBuffer.data(), mOutputBuffer.data(), mFrameCount);
::android::os::scaleHapticData(
hapticOutBuffer, hapticSampleCount,
- static_cast<::android::os::HapticScale>(mParams.mMaxVibratorScale),
+ {/*level=*/static_cast<::android::os::HapticLevel>(mParams.mMaxVibratorScale) },
mParams.mVibratorInfo.qFactor);
// For haptic data, the haptic playback thread will copy the data from effect input
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index a02657e..b270813 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1536,7 +1536,7 @@
return IAfEffectModule::isSpatializer(&mDescriptor.type);
}
-status_t EffectModule::setHapticIntensity_l(int id, os::HapticScale intensity) {
+status_t EffectModule::setHapticScale_l(int id, os::HapticScale hapticScale) {
if (mStatus != NO_ERROR) {
return mStatus;
}
@@ -1551,7 +1551,7 @@
param->vsize = sizeof(int32_t) * 2;
*(int32_t*)param->data = HG_PARAM_HAPTIC_INTENSITY;
*((int32_t*)param->data + 1) = id;
- *((int32_t*)param->data + 2) = static_cast<int32_t>(intensity);
+ *((int32_t*)param->data + 2) = static_cast<int32_t>(hapticScale.getLevel());
std::vector<uint8_t> response;
status_t status = command(EFFECT_CMD_SET_PARAM, request, sizeof(int32_t), &response);
if (status == NO_ERROR) {
@@ -2674,11 +2674,11 @@
return false;
}
-void EffectChain::setHapticIntensity_l(int id, os::HapticScale intensity)
+void EffectChain::setHapticScale_l(int id, os::HapticScale hapticScale)
{
audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mEffects.size(); ++i) {
- mEffects[i]->setHapticIntensity_l(id, intensity);
+ mEffects[i]->setHapticScale_l(id, hapticScale);
}
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 6e34e9b..46c44a6 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -233,7 +233,7 @@
bool isHapticGenerator() const final;
bool isSpatializer() const final;
- status_t setHapticIntensity_l(int id, os::HapticScale intensity) final
+ status_t setHapticScale_l(int id, os::HapticScale hapticScale) final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex;
status_t setVibratorInfo_l(const media::AudioVibratorInfo& vibratorInfo) final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex;
@@ -520,7 +520,7 @@
// Requires either IAfThreadBase::mutex() or EffectChain::mutex() held
bool containsHapticGeneratingEffect_l() final;
- void setHapticIntensity_l(int id, os::HapticScale intensity) final
+ void setHapticScale_l(int id, os::HapticScale hapticScale) final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
sp<EffectCallbackInterface> effectCallback() const final { return mEffectCallback; }
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index 82436a3..fd4dd62 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -180,7 +180,7 @@
static bool isSpatializer(const effect_uuid_t* type);
virtual bool isSpatializer() const = 0;
- virtual status_t setHapticIntensity_l(int id, os::HapticScale intensity)
+ virtual status_t setHapticScale_l(int id, os::HapticScale hapticScale)
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex = 0;
virtual status_t setVibratorInfo_l(const media::AudioVibratorInfo& vibratorInfo)
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex = 0;
@@ -319,7 +319,7 @@
virtual bool containsHapticGeneratingEffect_l() = 0;
- virtual void setHapticIntensity_l(int id, os::HapticScale intensity)
+ virtual void setHapticScale_l(int id, os::HapticScale hapticScale)
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
virtual sp<EffectCallbackInterface> effectCallback() const = 0;
diff --git a/services/audioflinger/IAfTrack.h b/services/audioflinger/IAfTrack.h
index ac4ed36..8ed44c6 100644
--- a/services/audioflinger/IAfTrack.h
+++ b/services/audioflinger/IAfTrack.h
@@ -339,12 +339,12 @@
/** Set haptic playback of the track is enabled or not, should be
* set after query or get callback from vibrator service */
virtual void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) = 0;
- /** Return at what intensity to play haptics, used in mixer. */
- virtual os::HapticScale getHapticIntensity() const = 0;
+ /** Return the haptics scale, used in mixer. */
+ virtual os::HapticScale getHapticScale() const = 0;
/** Return the maximum amplitude allowed for haptics data, used in mixer. */
virtual float getHapticMaxAmplitude() const = 0;
- /** Set intensity of haptic playback, should be set after querying vibrator service. */
- virtual void setHapticIntensity(os::HapticScale hapticIntensity) = 0;
+ /** Set scale for haptic playback, should be set after querying vibrator service. */
+ virtual void setHapticScale(os::HapticScale hapticScale) = 0;
/** Set maximum amplitude allowed for haptic data, should be set after querying
* vibrator service.
*/
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 826ba65..6c22e21 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -174,15 +174,15 @@
void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) final {
mHapticPlaybackEnabled = hapticPlaybackEnabled;
}
- /** Return at what intensity to play haptics, used in mixer. */
- os::HapticScale getHapticIntensity() const final { return mHapticIntensity; }
+ /** Return the haptics scale, used in mixer. */
+ os::HapticScale getHapticScale() const final { return mHapticScale; }
/** Return the maximum amplitude allowed for haptics data, used in mixer. */
float getHapticMaxAmplitude() const final { return mHapticMaxAmplitude; }
/** Set intensity of haptic playback, should be set after querying vibrator service. */
- void setHapticIntensity(os::HapticScale hapticIntensity) final {
- if (os::isValidHapticScale(hapticIntensity)) {
- mHapticIntensity = hapticIntensity;
- setHapticPlaybackEnabled(mHapticIntensity != os::HapticScale::MUTE);
+ void setHapticScale(os::HapticScale hapticScale) final {
+ if (os::isValidHapticScale(hapticScale)) {
+ mHapticScale = hapticScale;
+ setHapticPlaybackEnabled(!mHapticScale.isScaleMute());
}
}
/** Set maximum amplitude allowed for haptic data, should be set after querying
@@ -329,8 +329,8 @@
sp<OpPlayAudioMonitor> mOpPlayAudioMonitor;
bool mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
- // intensity to play haptic data
- os::HapticScale mHapticIntensity = os::HapticScale::MUTE;
+ // scale to play haptic data
+ os::HapticScale mHapticScale = os::HapticScale::mute();
// max amplitude allowed for haptic data
float mHapticMaxAmplitude = NAN;
class AudioVibrationController : public os::BnExternalVibrationController {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 767c502..aaf4923 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2901,7 +2901,7 @@
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.
mutex().unlock();
- const os::HapticScale intensity = afutils::onExternalVibrationStart(
+ const os::HapticScale hapticScale = afutils::onExternalVibrationStart(
track->getExternalVibration());
std::optional<media::AudioVibratorInfo> vibratorInfo;
{
@@ -2911,7 +2911,7 @@
vibratorInfo = std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
}
mutex().lock();
- track->setHapticIntensity(intensity);
+ track->setHapticScale(hapticScale);
if (vibratorInfo) {
track->setHapticMaxAmplitude(vibratorInfo->maxAmplitude);
}
@@ -2927,7 +2927,8 @@
// Set haptic intensity for effect
if (chain != nullptr) {
- chain->setHapticIntensity_l(track->id(), intensity);
+ // TODO(b/324559333): Add adaptive haptics scaling support for the HapticGenerator.
+ chain->setHapticScale_l(track->id(), hapticScale);
}
}
@@ -4810,7 +4811,7 @@
// When the track is stop, set the haptic intensity as MUTE
// for the HapticGenerator effect.
if (chain != nullptr) {
- chain->setHapticIntensity_l(track->id(), os::HapticScale::MUTE);
+ chain->setHapticScale_l(track->id(), os::HapticScale::mute());
}
}
@@ -5170,7 +5171,7 @@
// audio to FastMixer
fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer
fastTrack->mHapticPlaybackEnabled = mHapticChannelMask != AUDIO_CHANNEL_NONE;
- fastTrack->mHapticIntensity = os::HapticScale::NONE;
+ fastTrack->mHapticScale = {/*level=*/os::HapticLevel::NONE };
fastTrack->mHapticMaxAmplitude = NAN;
fastTrack->mGeneration++;
state->mFastTracksGen++;
@@ -5728,7 +5729,7 @@
fastTrack->mChannelMask = track->channelMask();
fastTrack->mFormat = track->format();
fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
- fastTrack->mHapticIntensity = track->getHapticIntensity();
+ fastTrack->mHapticScale = track->getHapticScale();
fastTrack->mHapticMaxAmplitude = track->getHapticMaxAmplitude();
fastTrack->mGeneration++;
state->mTrackMask |= 1 << j;
@@ -6089,10 +6090,11 @@
trackId,
AudioMixer::TRACK,
AudioMixer::HAPTIC_ENABLED, (void *)(uintptr_t)track->getHapticPlaybackEnabled());
+ const os::HapticScale hapticScale = track->getHapticScale();
mAudioMixer->setParameter(
- trackId,
- AudioMixer::TRACK,
- AudioMixer::HAPTIC_INTENSITY, (void *)(uintptr_t)track->getHapticIntensity());
+ trackId,
+ AudioMixer::TRACK,
+ AudioMixer::HAPTIC_SCALE, (void *)&hapticScale);
const float hapticMaxAmplitude = track->getHapticMaxAmplitude();
mAudioMixer->setParameter(
trackId,
diff --git a/services/audioflinger/afutils/Vibrator.cpp b/services/audioflinger/afutils/Vibrator.cpp
index ab15a09..7c99ca9 100644
--- a/services/audioflinger/afutils/Vibrator.cpp
+++ b/services/audioflinger/afutils/Vibrator.cpp
@@ -20,6 +20,7 @@
#include "Vibrator.h"
+#include <android/os/ExternalVibrationScale.h>
#include <android/os/IExternalVibratorService.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
@@ -46,14 +47,15 @@
os::HapticScale onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration) {
if (externalVibration->getAudioAttributes().flags & AUDIO_FLAG_MUTE_HAPTIC) {
ALOGD("%s, mute haptic according to audio attributes flag", __func__);
- return os::HapticScale::MUTE;
+ return os::HapticScale::mute();
}
const sp<os::IExternalVibratorService> evs = getExternalVibratorService();
if (evs != nullptr) {
- int32_t ret;
+
+ os::ExternalVibrationScale ret;
binder::Status status = evs->onExternalVibrationStart(*externalVibration, &ret);
if (status.isOk()) {
- ALOGD("%s, start external vibration with intensity as %d", __func__, ret);
+ ALOGD("%s, start external vibration with intensity as %d", __func__, ret.scaleLevel);
return os::ExternalVibration::externalVibrationScaleToHapticScale(ret);
}
}
@@ -61,7 +63,7 @@
__func__,
evs == nullptr ? "external vibration service not found"
: "error when querying intensity");
- return os::HapticScale::MUTE;
+ return os::HapticScale::mute();
}
void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration) {
diff --git a/services/audioflinger/fastpath/FastMixer.cpp b/services/audioflinger/fastpath/FastMixer.cpp
index e0a15c1..1d41b3f 100644
--- a/services/audioflinger/fastpath/FastMixer.cpp
+++ b/services/audioflinger/fastpath/FastMixer.cpp
@@ -178,8 +178,8 @@
(void *)(uintptr_t)mSinkChannelMask);
mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_ENABLED,
(void *)(uintptr_t)fastTrack->mHapticPlaybackEnabled);
- mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_INTENSITY,
- (void *)(uintptr_t)fastTrack->mHapticIntensity);
+ mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_SCALE,
+ (void *)(&(fastTrack->mHapticScale)));
mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_MAX_AMPLITUDE,
(void *)(&(fastTrack->mHapticMaxAmplitude)));
diff --git a/services/audioflinger/fastpath/FastMixerState.h b/services/audioflinger/fastpath/FastMixerState.h
index 8ab6d25..0a56f92 100644
--- a/services/audioflinger/fastpath/FastMixerState.h
+++ b/services/audioflinger/fastpath/FastMixerState.h
@@ -54,7 +54,7 @@
audio_format_t mFormat = AUDIO_FORMAT_INVALID; // track format
int mGeneration = 0; // increment when any field is assigned
bool mHapticPlaybackEnabled = false; // haptic playback is enabled or not
- os::HapticScale mHapticIntensity = os::HapticScale::MUTE; // intensity of haptic data
+ os::HapticScale mHapticScale = os::HapticScale::mute(); // scale of haptic data
float mHapticMaxAmplitude = NAN; // max amplitude allowed for haptic data
};