Support scaling haptic data in HapticGenerator
Move function of scaling haptic data from AudioMixer to vibrator
library. Scaling haptic data in HapticGenerator according to the haptic
intensity.
Bug: 136490803
Test: play audio-coupled-haptic files
Test: play audio with HapticGenerator effect
Change-Id: I6bac63c085332ea87cc6612a8f2f368ad7ef7826
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index fde583c..136ae98 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -399,7 +399,7 @@
return ret;
}
}
- return AudioMixer::HAPTIC_SCALE_MUTE;
+ return static_cast<int>(os::HapticScale::MUTE);
}
/* static */
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 01dd203..d3ad908 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -98,6 +98,7 @@
#include <private/media/AudioTrackShared.h>
#include <vibrator/ExternalVibration.h>
+#include <vibrator/ExternalVibrationUtils.h>
#include "android/media/BnAudioRecord.h"
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index c192b85..9ee47c9 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1537,6 +1537,33 @@
return isHapticGenerator(&mDescriptor.type);
}
+status_t AudioFlinger::EffectModule::setHapticIntensity(int id, int intensity)
+{
+ if (mStatus != NO_ERROR) {
+ return mStatus;
+ }
+ if (!isHapticGenerator()) {
+ ALOGW("Should not set haptic intensity for effects that are not HapticGenerator");
+ return INVALID_OPERATION;
+ }
+
+ uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 3];
+ effect_param_t *param = (effect_param_t*) buf32;
+ param->psize = sizeof(int32_t);
+ 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) = intensity;
+ uint32_t size = sizeof(int32_t);
+ status_t status = command(
+ EFFECT_CMD_SET_PARAM, sizeof(effect_param_t) + param->psize + param->vsize,
+ param, &size, ¶m->status);
+ if (status == NO_ERROR) {
+ status = param->status;
+ }
+ return status;
+}
+
static std::string dumpInOutBuffer(bool isInput, const sp<EffectBufferHalInterface> &buffer) {
std::stringstream ss;
@@ -2411,6 +2438,14 @@
return false;
}
+void AudioFlinger::EffectChain::setHapticIntensity_l(int id, int intensity)
+{
+ Mutex::Autolock _l(mLock);
+ for (size_t i = 0; i < mEffects.size(); ++i) {
+ mEffects[i]->setHapticIntensity(id, intensity);
+ }
+}
+
void AudioFlinger::EffectChain::syncHalEffectsState()
{
Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 036f855..3cc5a44 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -261,6 +261,8 @@
static bool isHapticGenerator(const effect_uuid_t* type);
bool isHapticGenerator() const;
+ status_t setHapticIntensity(int id, int intensity);
+
void dump(int fd, const Vector<String16>& args);
private:
@@ -509,6 +511,8 @@
bool containsHapticGeneratingEffect_l();
+ void setHapticIntensity_l(int id, int intensity);
+
sp<EffectCallbackInterface> effectCallback() const { return mEffectCallback; }
wp<ThreadBase> thread() const { return mEffectCallback->thread(); }
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index 396c797..857d3de 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -23,6 +23,7 @@
#include <media/ExtendedAudioBufferProvider.h>
#include <media/nbaio/NBAIO.h>
#include <media/nblog/NBLog.h>
+#include <vibrator/ExternalVibrationUtils.h>
#include "FastThreadState.h"
namespace android {
@@ -49,8 +50,7 @@
audio_format_t mFormat; // track format
int mGeneration; // increment when any field is assigned
bool mHapticPlaybackEnabled = false; // haptic playback is enabled or not
- AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE; // intensity of
- // haptic data
+ os::HapticScale mHapticIntensity = os::HapticScale::MUTE; // intensity of haptic data
};
// Represents a single state of the fast mixer
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index d8eebf3..d05c8b8 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -159,12 +159,12 @@
mHapticPlaybackEnabled = hapticPlaybackEnabled;
}
/** Return at what intensity to play haptics, used in mixer. */
- AudioMixer::haptic_intensity_t getHapticIntensity() const { return mHapticIntensity; }
+ os::HapticScale getHapticIntensity() const { return mHapticIntensity; }
/** Set intensity of haptic playback, should be set after querying vibrator service. */
- void setHapticIntensity(AudioMixer::haptic_intensity_t hapticIntensity) {
- if (AudioMixer::isValidHapticIntensity(hapticIntensity)) {
+ void setHapticIntensity(os::HapticScale hapticIntensity) {
+ if (os::isValidHapticScale(hapticIntensity)) {
mHapticIntensity = hapticIntensity;
- setHapticPlaybackEnabled(mHapticIntensity != AudioMixer::HAPTIC_SCALE_MUTE);
+ setHapticPlaybackEnabled(mHapticIntensity != os::HapticScale::MUTE);
}
}
sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
@@ -265,7 +265,7 @@
bool mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
// intensity to play haptic data
- AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE;
+ os::HapticScale mHapticIntensity = os::HapticScale::MUTE;
class AudioVibrationController : public os::BnExternalVibrationController {
public:
explicit AudioVibrationController(Track* track) : mTrack(track) {}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b6a50a5..92f18c1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2548,7 +2548,7 @@
const int intensity = AudioFlinger::onExternalVibrationStart(
track->getExternalVibration());
mLock.lock();
- track->setHapticIntensity(static_cast<AudioMixer::haptic_intensity_t>(intensity));
+ track->setHapticIntensity(static_cast<os::HapticScale>(intensity));
// Haptic playback should be enabled by vibrator service.
if (track->getHapticPlaybackEnabled()) {
// Disable haptic playback of all active track to ensure only
@@ -2557,6 +2557,11 @@
t->setHapticPlaybackEnabled(false);
}
}
+
+ // Set haptic intensity for effect
+ if (chain != nullptr) {
+ chain->setHapticIntensity_l(track->id(), intensity);
+ }
}
track->mResetDone = false;
@@ -4130,6 +4135,12 @@
// call Tracks.mute/unmute which also require thread's lock.
AudioFlinger::onExternalVibrationStop(track->getExternalVibration());
mLock.lock();
+
+ // When the track is stop, set the haptic intensity as MUTE
+ // for the HapticGenerator effect.
+ if (chain != nullptr) {
+ chain->setHapticIntensity_l(track->id(), static_cast<int>(os::HapticScale::MUTE));
+ }
}
}
}
@@ -4472,7 +4483,7 @@
// audio to FastMixer
fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer
fastTrack->mHapticPlaybackEnabled = mHapticChannelMask != AUDIO_CHANNEL_NONE;
- fastTrack->mHapticIntensity = AudioMixer::HAPTIC_SCALE_NONE;
+ fastTrack->mHapticIntensity = os::HapticScale::NONE;
fastTrack->mGeneration++;
state->mFastTracksGen++;
state->mTrackMask = 1;