diff options
-rw-r--r-- | core/api/current.txt | 2 | ||||
-rw-r--r-- | core/jni/android_media_AudioTrack.cpp | 40 | ||||
-rw-r--r-- | media/java/android/media/AudioTrack.java | 61 |
3 files changed, 103 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 8224a754ec69..be9dccce637a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -19852,6 +19852,7 @@ package android.media { method public android.media.AudioDeviceInfo getPreferredDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); + method @IntRange(from=1) public int getStartThresholdInFrames(); method public int getState(); method public int getStreamType(); method public boolean getTimestamp(android.media.AudioTimestamp); @@ -19882,6 +19883,7 @@ package android.media { method public int setPositionNotificationPeriod(int); method public boolean setPreferredDevice(android.media.AudioDeviceInfo); method public int setPresentation(@NonNull android.media.AudioPresentation); + method @IntRange(from=1) public int setStartThresholdInFrames(@IntRange(from=1) int); method @Deprecated protected void setState(int); method @Deprecated public int setStereoVolume(float, float); method public int setVolume(float); diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 065c79b8601f..452f55a0ba97 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -1419,6 +1419,42 @@ static jint android_media_AudioTrack_getDualMonoMode(JNIEnv *env, jobject thiz, return nativeToJavaStatus(status); } +static jint android_media_AudioTrack_getStartThresholdInFrames(JNIEnv *env, jobject thiz) { + sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); + if (lpTrack == nullptr) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve AudioTrack pointer for getStartThresholdInFrames()"); + return (jint)AUDIO_JAVA_ERROR; + } + const ssize_t result = lpTrack->getStartThresholdInFrames(); + if (result <= 0) { + jniThrowExceptionFmt(env, "java/lang/IllegalStateException", + "Internal error detected in getStartThresholdInFrames() = %zd", + result); + return (jint)AUDIO_JAVA_ERROR; + } + return (jint)result; // this should be a positive value. +} + +static jint android_media_AudioTrack_setStartThresholdInFrames(JNIEnv *env, jobject thiz, + jint startThresholdInFrames) { + sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); + if (lpTrack == nullptr) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve AudioTrack pointer for setStartThresholdInFrames()"); + return (jint)AUDIO_JAVA_ERROR; + } + // non-positive values of startThresholdInFrames are not allowed by the Java layer. + const ssize_t result = lpTrack->setStartThresholdInFrames(startThresholdInFrames); + if (result <= 0) { + jniThrowExceptionFmt(env, "java/lang/IllegalStateException", + "Internal error detected in setStartThresholdInFrames() = %zd", + result); + return (jint)AUDIO_JAVA_ERROR; + } + return (jint)result; // this should be a positive value. +} + // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = { @@ -1496,6 +1532,10 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioTrack_getAudioDescriptionMixLeveldB}, {"native_set_dual_mono_mode", "(I)I", (void *)android_media_AudioTrack_setDualMonoMode}, {"native_get_dual_mono_mode", "([I)I", (void *)android_media_AudioTrack_getDualMonoMode}, + {"native_setStartThresholdInFrames", "(I)I", + (void *)android_media_AudioTrack_setStartThresholdInFrames}, + {"native_getStartThresholdInFrames", "()I", + (void *)android_media_AudioTrack_getStartThresholdInFrames}, }; // field names found in android/media/AudioTrack.java diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 1b05c3b57256..b265ebfc02a0 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -2077,6 +2077,65 @@ public class AudioTrack extends PlayerBase } /** + * Sets the streaming start threshold for an <code>AudioTrack</code>. + * <p> The streaming start threshold is the buffer level that the written audio + * data must reach for audio streaming to start after {@link #play()} is called. + * <p> For compressed streams, the size of a frame is considered to be exactly one byte. + * + * @param startThresholdInFrames the desired start threshold. + * @return the actual start threshold in frames value. This is + * an integer between 1 to the buffer capacity + * (see {@link #getBufferCapacityInFrames()}), + * and might change if the output sink changes after track creation. + * @throws IllegalStateException if the track is not initialized or the + * track transfer mode is not {@link #MODE_STREAM}. + * @throws IllegalArgumentException if startThresholdInFrames is not positive. + * @see #getStartThresholdInFrames() + */ + public @IntRange(from = 1) int setStartThresholdInFrames( + @IntRange (from = 1) int startThresholdInFrames) { + if (mState != STATE_INITIALIZED) { + throw new IllegalStateException("AudioTrack is not initialized"); + } + if (mDataLoadMode != MODE_STREAM) { + throw new IllegalStateException("AudioTrack must be a streaming track"); + } + if (startThresholdInFrames < 1) { + throw new IllegalArgumentException("startThresholdInFrames " + + startThresholdInFrames + " must be positive"); + } + return native_setStartThresholdInFrames(startThresholdInFrames); + } + + /** + * Returns the streaming start threshold of the <code>AudioTrack</code>. + * <p> The streaming start threshold is the buffer level that the written audio + * data must reach for audio streaming to start after {@link #play()} is called. + * When an <code>AudioTrack</code> is created, the streaming start threshold + * is the buffer capacity in frames. If the buffer size in frames is reduced + * by {@link #setBufferSizeInFrames(int)} to a value smaller than the start threshold + * then that value will be used instead for the streaming start threshold. + * <p> For compressed streams, the size of a frame is considered to be exactly one byte. + * + * @return the current start threshold in frames value. This is + * an integer between 1 to the buffer capacity + * (see {@link #getBufferCapacityInFrames()}), + * and might change if the output sink changes after track creation. + * @throws IllegalStateException if the track is not initialized or the + * track is not {@link #MODE_STREAM}. + * @see #setStartThresholdInFrames(int) + */ + public @IntRange (from = 1) int getStartThresholdInFrames() { + if (mState != STATE_INITIALIZED) { + throw new IllegalStateException("AudioTrack is not initialized"); + } + if (mDataLoadMode != MODE_STREAM) { + throw new IllegalStateException("AudioTrack must be a streaming track"); + } + return native_getStartThresholdInFrames(); + } + + /** * Returns the frame count of the native <code>AudioTrack</code> buffer. * @return current size in frames of the <code>AudioTrack</code> buffer. * @throws IllegalStateException @@ -4179,6 +4238,8 @@ public class AudioTrack extends PlayerBase private native int native_get_audio_description_mix_level_db(float[] level); private native int native_set_dual_mono_mode(int dualMonoMode); private native int native_get_dual_mono_mode(int[] dualMonoMode); + private native int native_setStartThresholdInFrames(int startThresholdInFrames); + private native int native_getStartThresholdInFrames(); //--------------------------------------------------------- // Utility methods |