Add HapticGenerator.
Add HapticGenertor, which is an audio effect that can generate haptic data from audio data. Bug: 136490803 Test: atest HapticGeneratorTest Change-Id: Ib677f0ad82ae4a164546300c7a86760cdb6a52b4
This commit is contained in:
committed by
Jean-Michel Trivi
parent
0542513368
commit
2ea6a26b4d
@@ -27905,6 +27905,7 @@ package android.media.audiofx {
|
||||
field public static final java.util.UUID EFFECT_TYPE_DYNAMICS_PROCESSING;
|
||||
field public static final java.util.UUID EFFECT_TYPE_ENV_REVERB;
|
||||
field public static final java.util.UUID EFFECT_TYPE_EQUALIZER;
|
||||
field @NonNull public static final java.util.UUID EFFECT_TYPE_HAPTIC_GENERATOR;
|
||||
field public static final java.util.UUID EFFECT_TYPE_LOUDNESS_ENHANCER;
|
||||
field public static final java.util.UUID EFFECT_TYPE_NS;
|
||||
field public static final java.util.UUID EFFECT_TYPE_PRESET_REVERB;
|
||||
@@ -28257,6 +28258,13 @@ package android.media.audiofx {
|
||||
field public short numBands;
|
||||
}
|
||||
|
||||
public class HapticGenerator extends android.media.audiofx.AudioEffect implements java.lang.AutoCloseable {
|
||||
method public void close();
|
||||
method @NonNull public static android.media.audiofx.HapticGenerator create(int);
|
||||
method public static boolean isAvailable();
|
||||
method public int setEnabled(boolean);
|
||||
}
|
||||
|
||||
public class LoudnessEnhancer extends android.media.audiofx.AudioEffect {
|
||||
ctor public LoudnessEnhancer(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.RuntimeException, java.lang.UnsupportedOperationException;
|
||||
method public float getTargetGain() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
|
||||
|
||||
@@ -53,6 +53,7 @@ import java.util.UUID;
|
||||
* <li> {@link android.media.audiofx.PresetReverb}</li>
|
||||
* <li> {@link android.media.audiofx.EnvironmentalReverb}</li>
|
||||
* <li> {@link android.media.audiofx.DynamicsProcessing}</li>
|
||||
* <li> {@link android.media.audiofx.HapticGenerator}</li>
|
||||
* </ul>
|
||||
* <p>To apply the audio effect to a specific AudioTrack or MediaPlayer instance,
|
||||
* the application must specify the audio session ID of that instance when creating the AudioEffect.
|
||||
@@ -145,6 +146,14 @@ public class AudioEffect {
|
||||
public static final UUID EFFECT_TYPE_DYNAMICS_PROCESSING = UUID
|
||||
.fromString("7261676f-6d75-7369-6364-28e2fd3ac39e");
|
||||
|
||||
/**
|
||||
* UUID for Haptic Generator.
|
||||
*/
|
||||
// This is taken from system/media/audio/include/system/audio_effects/effect_hapticgenerator.h
|
||||
@NonNull
|
||||
public static final UUID EFFECT_TYPE_HAPTIC_GENERATOR = UUID
|
||||
.fromString("1411e6d6-aecd-4021-a1cf-a6aceb0d71e5");
|
||||
|
||||
/**
|
||||
* Null effect UUID. See {@link AudioEffect(UUID, UUID, int, int)} for use.
|
||||
* @hide
|
||||
@@ -225,7 +234,8 @@ public class AudioEffect {
|
||||
* {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
|
||||
* {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
|
||||
* {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
|
||||
* {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.
|
||||
* {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING},
|
||||
* {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}.
|
||||
* </li>
|
||||
* <li>uuid: UUID for this particular implementation</li>
|
||||
* <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li>
|
||||
@@ -246,8 +256,9 @@ public class AudioEffect {
|
||||
* {@link AudioEffect#EFFECT_TYPE_AGC}, {@link AudioEffect#EFFECT_TYPE_BASS_BOOST},
|
||||
* {@link AudioEffect#EFFECT_TYPE_ENV_REVERB}, {@link AudioEffect#EFFECT_TYPE_EQUALIZER},
|
||||
* {@link AudioEffect#EFFECT_TYPE_NS}, {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}
|
||||
* {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}
|
||||
* or {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.<br>
|
||||
* {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
|
||||
* {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING},
|
||||
* or {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}.<br>
|
||||
* For reverberation, bass boost, EQ and virtualizer, the UUID
|
||||
* corresponds to the OpenSL ES Interface ID.
|
||||
*/
|
||||
@@ -284,7 +295,8 @@ public class AudioEffect {
|
||||
* {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
|
||||
* {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB},
|
||||
* {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
|
||||
* {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.
|
||||
* {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING},
|
||||
* {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}.
|
||||
* @param uuid UUID for this particular implementation
|
||||
* @param connectMode {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}
|
||||
* @param name human readable effect name
|
||||
|
||||
128
media/java/android/media/audiofx/HapticGenerator.java
Normal file
128
media/java/android/media/audiofx/HapticGenerator.java
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.media.audiofx;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.media.AudioManager;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Haptic Generator(HG).
|
||||
* <p>HG is an audio post-processor which generates haptic data based on the audio channels. The
|
||||
* generated haptic data is sent along with audio data down to the audio HAL, which will require the
|
||||
* device to support audio-coupled-haptic playback. In that case, the effect will only be created on
|
||||
* device supporting audio-coupled-haptic playback. Call {@link HapticGenerator#isAvailable()} to
|
||||
* check if the device supports this effect.
|
||||
* <p>An application can create a HapticGenerator object to initiate and control this audio effect
|
||||
* in the audio framework. An application can set which audio channel to be used to generate
|
||||
* haptic data.
|
||||
* <p>To attach the HapticGenerator to a particular AudioTrack or MediaPlayer, specify the audio
|
||||
* session ID of this AudioTrack or MediaPlayer when constructing the HapticGenerator.
|
||||
* <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
|
||||
* <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling audio
|
||||
* effects.
|
||||
*/
|
||||
public class HapticGenerator extends AudioEffect implements AutoCloseable {
|
||||
|
||||
private static final String TAG = "HapticGenerator";
|
||||
|
||||
// For every HapticGenerator, it contains a volume control effect so that the volume control
|
||||
// will always be handled in the effect chain. In that case, the HapticGenerator can generate
|
||||
// haptic data based on the raw audio data.
|
||||
private AudioEffect mVolumeControlEffect;
|
||||
|
||||
public static boolean isAvailable() {
|
||||
return AudioManager.isHapticPlaybackSupported()
|
||||
&& AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_HAPTIC_GENERATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HapticGenerator and attaches it to the given audio session.
|
||||
* Use {@link android.media.AudioTrack#getAudioSessionId()} or
|
||||
* {@link android.media.MediaPlayer#getAudioSessionId()} to
|
||||
* apply this effect on specific AudioTrack or MediaPlayer instance.
|
||||
*
|
||||
* @param audioSession system wide unique audio session identifier. The HapticGenerator will be
|
||||
* applied to the players with the same audio session.
|
||||
* @return HapticGenerator created or null if the device does not support HapticGenerator or
|
||||
* the audio session is invalid.
|
||||
* @throws java.lang.IllegalArgumentException when HapticGenerator is not supported
|
||||
* @throws java.lang.UnsupportedOperationException when the effect library is not loaded.
|
||||
* @throws java.lang.RuntimeException for all other error
|
||||
*/
|
||||
public static @NonNull HapticGenerator create(int audioSession) {
|
||||
return new HapticGenerator(audioSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param audioSession system wide unique audio session identifier. The HapticGenerator will be
|
||||
* attached to the MediaPlayer or AudioTrack in the same audio session.
|
||||
* @throws java.lang.IllegalArgumentException
|
||||
* @throws java.lang.UnsupportedOperationException
|
||||
* @throws java.lang.RuntimeException
|
||||
*/
|
||||
private HapticGenerator(int audioSession) {
|
||||
super(EFFECT_TYPE_HAPTIC_GENERATOR, EFFECT_TYPE_NULL, 0, audioSession);
|
||||
mVolumeControlEffect = new AudioEffect(
|
||||
AudioEffect.EFFECT_TYPE_NULL,
|
||||
UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
|
||||
0,
|
||||
audioSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the effect.
|
||||
*
|
||||
* @param enabled the requested enable state
|
||||
* @return {@link #SUCCESS} in case of success, {@link #ERROR_INVALID_OPERATION}
|
||||
* or {@link #ERROR_DEAD_OBJECT} in case of failure.
|
||||
*/
|
||||
@Override
|
||||
public int setEnabled(boolean enabled) {
|
||||
int ret = super.setEnabled(enabled);
|
||||
if (ret == SUCCESS) {
|
||||
if (mVolumeControlEffect == null
|
||||
|| mVolumeControlEffect.setEnabled(enabled) != SUCCESS) {
|
||||
Log.w(TAG, "Failed to enable volume control effect for HapticGenerator");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the native AudioEffect resources.
|
||||
*/
|
||||
@Override
|
||||
public void release() {
|
||||
if (mVolumeControlEffect != null) {
|
||||
mVolumeControlEffect.release();
|
||||
}
|
||||
super.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the resources that are held by the effect.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@@ -27666,6 +27666,7 @@ package android.media.audiofx {
|
||||
field public static final java.util.UUID EFFECT_TYPE_DYNAMICS_PROCESSING;
|
||||
field public static final java.util.UUID EFFECT_TYPE_ENV_REVERB;
|
||||
field public static final java.util.UUID EFFECT_TYPE_EQUALIZER;
|
||||
field @NonNull public static final java.util.UUID EFFECT_TYPE_HAPTIC_GENERATOR;
|
||||
field public static final java.util.UUID EFFECT_TYPE_LOUDNESS_ENHANCER;
|
||||
field public static final java.util.UUID EFFECT_TYPE_NS;
|
||||
field public static final java.util.UUID EFFECT_TYPE_PRESET_REVERB;
|
||||
@@ -28018,6 +28019,13 @@ package android.media.audiofx {
|
||||
field public short numBands;
|
||||
}
|
||||
|
||||
public class HapticGenerator extends android.media.audiofx.AudioEffect implements java.lang.AutoCloseable {
|
||||
method public void close();
|
||||
method @NonNull public static android.media.audiofx.HapticGenerator create(int);
|
||||
method public static boolean isAvailable();
|
||||
method public int setEnabled(boolean);
|
||||
}
|
||||
|
||||
public class LoudnessEnhancer extends android.media.audiofx.AudioEffect {
|
||||
ctor public LoudnessEnhancer(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.RuntimeException, java.lang.UnsupportedOperationException;
|
||||
method public float getTargetGain() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
|
||||
|
||||
Reference in New Issue
Block a user