Loading core/jni/android_media_AudioTrack.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #include "android_media_AudioErrors.h" #include "android_media_PlaybackParams.h" #include "android_media_DeviceCallback.h" #include "android_media_VolumeShaper.h" #include <cinttypes> Loading Loading @@ -64,6 +65,7 @@ struct audio_attributes_fields_t { static audio_track_fields_t javaAudioTrackFields; static audio_attributes_fields_t javaAudioAttrFields; static PlaybackParams::fields_t gPlaybackParamsFields; static VolumeShaperHelper::fields_t gVolumeShaperFields; struct audiotrack_callback_cookie { jclass audioTrack_class; Loading Loading @@ -1178,6 +1180,50 @@ static jint android_media_AudioTrack_get_FCC_8(JNIEnv *env, jobject thiz) { return FCC_8; } // Pass through the arguments to the AudioFlinger track implementation. static jint android_media_AudioTrack_apply_volume_shaper(JNIEnv *env, jobject thiz, jobject jconfig, jobject joperation) { // NOTE: hard code here to prevent platform issues. Must match VolumeShaper.java const int VOLUME_SHAPER_INVALID_OPERATION = -38; sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == nullptr) { return (jint)VOLUME_SHAPER_INVALID_OPERATION; } sp<VolumeShaper::Configuration> configuration; sp<VolumeShaper::Operation> operation; if (jconfig != nullptr) { configuration = VolumeShaperHelper::convertJobjectToConfiguration( env, gVolumeShaperFields, jconfig); ALOGV("applyVolumeShaper configuration: %s", configuration->toString().c_str()); } if (joperation != nullptr) { operation = VolumeShaperHelper::convertJobjectToOperation( env, gVolumeShaperFields, joperation); ALOGV("applyVolumeShaper operation: %s", operation->toString().c_str()); } VolumeShaper::Status status = lpTrack->applyVolumeShaper(configuration, operation); if (status == INVALID_OPERATION) { status = VOLUME_SHAPER_INVALID_OPERATION; } return (jint)status; // if status < 0 an error, else a VolumeShaper id } // Pass through the arguments to the AudioFlinger track implementation. static jobject android_media_AudioTrack_get_volume_shaper_state(JNIEnv *env, jobject thiz, jint id) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == nullptr) { return (jobject)nullptr; } sp<VolumeShaper::State> state = lpTrack->getVolumeShaperState((int)id); if (state.get() == nullptr) { return (jobject)nullptr; } return VolumeShaperHelper::convertStateToJobject(env, gVolumeShaperFields, state); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -1242,6 +1288,12 @@ static const JNINativeMethod gMethods[] = { {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", (void *)android_media_AudioTrack_disableDeviceCallback}, {"native_get_FCC_8", "()I", (void *)android_media_AudioTrack_get_FCC_8}, {"native_applyVolumeShaper", "(Landroid/media/VolumeShaper$Configuration;Landroid/media/VolumeShaper$Operation;)I", (void *)android_media_AudioTrack_apply_volume_shaper}, {"native_getVolumeShaperState", "(I)Landroid/media/VolumeShaper$State;", (void *)android_media_AudioTrack_get_volume_shaper_state}, }; Loading Loading @@ -1312,6 +1364,7 @@ int register_android_media_AudioTrack(JNIEnv *env) // initialize PlaybackParams field info gPlaybackParamsFields.init(env); gVolumeShaperFields.init(env); return res; } Loading media/java/android/media/AudioTrack.java +17 −0 Original line number Diff line number Diff line Loading @@ -1741,6 +1741,17 @@ public class AudioTrack extends PlayerBase return setStereoVolume(gain, gain); } @Override /* package */ int playerApplyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { return native_applyVolumeShaper(configuration, operation); } @Override /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) { return native_getVolumeShaperState(id); } /** * Sets the playback sample rate for this track. This sets the sampling rate at which Loading Loading @@ -3093,6 +3104,12 @@ public class AudioTrack extends PlayerBase private native final void native_disableDeviceCallback(); static private native int native_get_FCC_8(); private native int native_applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation); private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id); //--------------------------------------------------------- // Utility methods //------------------ Loading media/java/android/media/IPlayer.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.media; import android.media.VolumeShaper; /** * @hide Loading @@ -27,4 +28,6 @@ interface IPlayer { oneway void setVolume(float vol); oneway void setPan(float pan); oneway void setStartDelayMs(int delayMs); oneway void applyVolumeShaper(in VolumeShaper.Configuration configuration, in VolumeShaper.Operation operation); } media/java/android/media/MediaPlayer.java +18 −0 Original line number Diff line number Diff line Loading @@ -1331,6 +1331,24 @@ public class MediaPlayer extends PlayerBase stop(); } @Override /* package */ int playerApplyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { return native_applyVolumeShaper(configuration, operation); } @Override /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) { return native_getVolumeShaperState(id); } private native int native_applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation); private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id); /** * Set the low-level power management behavior for this MediaPlayer. This * can be used when the MediaPlayer is not playing through a SurfaceHolder Loading media/java/android/media/PlayerBase.java +45 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; import android.app.AppOpsManager; import android.content.Context; import android.media.VolumeShaper; import android.os.Binder; import android.os.IBinder; import android.os.Parcel; Loading Loading @@ -357,6 +359,42 @@ public abstract class PlayerBase { * @param rightVolume the right volume to use if muting is false */ abstract void playerSetVolume(boolean muting, float leftVolume, float rightVolume); /** * Abstract method to apply a {@link VolumeShaper.Configuration} * and a {@link VolumeShaper.Operation} to the Player. * This should be overridden by the Player to call into the native * VolumeShaper implementation. Multiple {@code VolumeShapers} may be * concurrently active for a given Player, each accessible by the * {@code VolumeShaper} id. * * The {@code VolumeShaper} implementation caches the id returned * when applying a fully specified configuration * from {VolumeShaper.Configuration.Builder} to track later * operation changes requested on it. * * @param configuration a {@code VolumeShaper.Configuration} object * created by {@link VolumeShaper.Configuration.Builder} or * an created from a {@code VolumeShaper} id * by the {@link VolumeShaper.Configuration} constructor. * @param operation a {@code VolumeShaper.Operation}. * @return a negative error status or a * non-negative {@code VolumeShaper} id on success. */ /* package */ abstract int playerApplyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation); /** * Abstract method to get the current VolumeShaper state. * @param id the {@code VolumeShaper} id returned from * sending a fully specified {@code VolumeShaper.Configuration} * through {@link #playerApplyVolumeShaper} * @return a {@code VolumeShaper.State} object or null if * there is no {@code VolumeShaper} for the id. */ /* package */ abstract @Nullable VolumeShaper.State playerGetVolumeShaperState(int id); abstract int playerSetAuxEffectSendLevel(boolean muting, float level); abstract void playerStart(); abstract void playerPause(); Loading Loading @@ -396,6 +434,13 @@ public abstract class PlayerBase { public void setStartDelayMs(int delayMs) { baseSetStartDelayMs(delayMs); } @Override public void applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { /* void */ playerApplyVolumeShaper(configuration, operation); } }; //===================================================================== Loading Loading
core/jni/android_media_AudioTrack.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #include "android_media_AudioErrors.h" #include "android_media_PlaybackParams.h" #include "android_media_DeviceCallback.h" #include "android_media_VolumeShaper.h" #include <cinttypes> Loading Loading @@ -64,6 +65,7 @@ struct audio_attributes_fields_t { static audio_track_fields_t javaAudioTrackFields; static audio_attributes_fields_t javaAudioAttrFields; static PlaybackParams::fields_t gPlaybackParamsFields; static VolumeShaperHelper::fields_t gVolumeShaperFields; struct audiotrack_callback_cookie { jclass audioTrack_class; Loading Loading @@ -1178,6 +1180,50 @@ static jint android_media_AudioTrack_get_FCC_8(JNIEnv *env, jobject thiz) { return FCC_8; } // Pass through the arguments to the AudioFlinger track implementation. static jint android_media_AudioTrack_apply_volume_shaper(JNIEnv *env, jobject thiz, jobject jconfig, jobject joperation) { // NOTE: hard code here to prevent platform issues. Must match VolumeShaper.java const int VOLUME_SHAPER_INVALID_OPERATION = -38; sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == nullptr) { return (jint)VOLUME_SHAPER_INVALID_OPERATION; } sp<VolumeShaper::Configuration> configuration; sp<VolumeShaper::Operation> operation; if (jconfig != nullptr) { configuration = VolumeShaperHelper::convertJobjectToConfiguration( env, gVolumeShaperFields, jconfig); ALOGV("applyVolumeShaper configuration: %s", configuration->toString().c_str()); } if (joperation != nullptr) { operation = VolumeShaperHelper::convertJobjectToOperation( env, gVolumeShaperFields, joperation); ALOGV("applyVolumeShaper operation: %s", operation->toString().c_str()); } VolumeShaper::Status status = lpTrack->applyVolumeShaper(configuration, operation); if (status == INVALID_OPERATION) { status = VOLUME_SHAPER_INVALID_OPERATION; } return (jint)status; // if status < 0 an error, else a VolumeShaper id } // Pass through the arguments to the AudioFlinger track implementation. static jobject android_media_AudioTrack_get_volume_shaper_state(JNIEnv *env, jobject thiz, jint id) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == nullptr) { return (jobject)nullptr; } sp<VolumeShaper::State> state = lpTrack->getVolumeShaperState((int)id); if (state.get() == nullptr) { return (jobject)nullptr; } return VolumeShaperHelper::convertStateToJobject(env, gVolumeShaperFields, state); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -1242,6 +1288,12 @@ static const JNINativeMethod gMethods[] = { {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", (void *)android_media_AudioTrack_disableDeviceCallback}, {"native_get_FCC_8", "()I", (void *)android_media_AudioTrack_get_FCC_8}, {"native_applyVolumeShaper", "(Landroid/media/VolumeShaper$Configuration;Landroid/media/VolumeShaper$Operation;)I", (void *)android_media_AudioTrack_apply_volume_shaper}, {"native_getVolumeShaperState", "(I)Landroid/media/VolumeShaper$State;", (void *)android_media_AudioTrack_get_volume_shaper_state}, }; Loading Loading @@ -1312,6 +1364,7 @@ int register_android_media_AudioTrack(JNIEnv *env) // initialize PlaybackParams field info gPlaybackParamsFields.init(env); gVolumeShaperFields.init(env); return res; } Loading
media/java/android/media/AudioTrack.java +17 −0 Original line number Diff line number Diff line Loading @@ -1741,6 +1741,17 @@ public class AudioTrack extends PlayerBase return setStereoVolume(gain, gain); } @Override /* package */ int playerApplyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { return native_applyVolumeShaper(configuration, operation); } @Override /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) { return native_getVolumeShaperState(id); } /** * Sets the playback sample rate for this track. This sets the sampling rate at which Loading Loading @@ -3093,6 +3104,12 @@ public class AudioTrack extends PlayerBase private native final void native_disableDeviceCallback(); static private native int native_get_FCC_8(); private native int native_applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation); private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id); //--------------------------------------------------------- // Utility methods //------------------ Loading
media/java/android/media/IPlayer.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.media; import android.media.VolumeShaper; /** * @hide Loading @@ -27,4 +28,6 @@ interface IPlayer { oneway void setVolume(float vol); oneway void setPan(float pan); oneway void setStartDelayMs(int delayMs); oneway void applyVolumeShaper(in VolumeShaper.Configuration configuration, in VolumeShaper.Operation operation); }
media/java/android/media/MediaPlayer.java +18 −0 Original line number Diff line number Diff line Loading @@ -1331,6 +1331,24 @@ public class MediaPlayer extends PlayerBase stop(); } @Override /* package */ int playerApplyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { return native_applyVolumeShaper(configuration, operation); } @Override /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) { return native_getVolumeShaperState(id); } private native int native_applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation); private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id); /** * Set the low-level power management behavior for this MediaPlayer. This * can be used when the MediaPlayer is not playing through a SurfaceHolder Loading
media/java/android/media/PlayerBase.java +45 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; import android.app.AppOpsManager; import android.content.Context; import android.media.VolumeShaper; import android.os.Binder; import android.os.IBinder; import android.os.Parcel; Loading Loading @@ -357,6 +359,42 @@ public abstract class PlayerBase { * @param rightVolume the right volume to use if muting is false */ abstract void playerSetVolume(boolean muting, float leftVolume, float rightVolume); /** * Abstract method to apply a {@link VolumeShaper.Configuration} * and a {@link VolumeShaper.Operation} to the Player. * This should be overridden by the Player to call into the native * VolumeShaper implementation. Multiple {@code VolumeShapers} may be * concurrently active for a given Player, each accessible by the * {@code VolumeShaper} id. * * The {@code VolumeShaper} implementation caches the id returned * when applying a fully specified configuration * from {VolumeShaper.Configuration.Builder} to track later * operation changes requested on it. * * @param configuration a {@code VolumeShaper.Configuration} object * created by {@link VolumeShaper.Configuration.Builder} or * an created from a {@code VolumeShaper} id * by the {@link VolumeShaper.Configuration} constructor. * @param operation a {@code VolumeShaper.Operation}. * @return a negative error status or a * non-negative {@code VolumeShaper} id on success. */ /* package */ abstract int playerApplyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation); /** * Abstract method to get the current VolumeShaper state. * @param id the {@code VolumeShaper} id returned from * sending a fully specified {@code VolumeShaper.Configuration} * through {@link #playerApplyVolumeShaper} * @return a {@code VolumeShaper.State} object or null if * there is no {@code VolumeShaper} for the id. */ /* package */ abstract @Nullable VolumeShaper.State playerGetVolumeShaperState(int id); abstract int playerSetAuxEffectSendLevel(boolean muting, float level); abstract void playerStart(); abstract void playerPause(); Loading Loading @@ -396,6 +434,13 @@ public abstract class PlayerBase { public void setStartDelayMs(int delayMs) { baseSetStartDelayMs(delayMs); } @Override public void applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { /* void */ playerApplyVolumeShaper(configuration, operation); } }; //===================================================================== Loading