Loading core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -20678,6 +20678,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); Loading Loading @@ -20708,6 +20709,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); core/jni/android_media_AudioTrack.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -1450,6 +1450,42 @@ static void android_media_AudioTrack_setPlayerIId(JNIEnv *env, jobject thiz, jin track->setPlayerIId(playerIId); } 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[] = { Loading Loading @@ -1530,6 +1566,10 @@ static const JNINativeMethod gMethods[] = { {"native_setLogSessionId", "(Ljava/lang/String;)V", (void *)android_media_AudioTrack_setLogSessionId}, {"native_setPlayerIId", "(I)V", (void *)android_media_AudioTrack_setPlayerIId}, {"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 Loading media/java/android/media/AudioTrack.java +61 −0 Original line number Diff line number Diff line Loading @@ -2085,6 +2085,65 @@ public class AudioTrack extends PlayerBase return native_get_buffer_capacity_frames(); } /** * 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. Loading Loading @@ -4239,6 +4298,8 @@ public class AudioTrack extends PlayerBase private native int native_set_dual_mono_mode(int dualMonoMode); private native int native_get_dual_mono_mode(int[] dualMonoMode); private native void native_setLogSessionId(@Nullable String logSessionId); private native int native_setStartThresholdInFrames(int startThresholdInFrames); private native int native_getStartThresholdInFrames(); /** * Sets the audio service Player Interface Id. Loading Loading
core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -20678,6 +20678,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); Loading Loading @@ -20708,6 +20709,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);
core/jni/android_media_AudioTrack.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -1450,6 +1450,42 @@ static void android_media_AudioTrack_setPlayerIId(JNIEnv *env, jobject thiz, jin track->setPlayerIId(playerIId); } 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[] = { Loading Loading @@ -1530,6 +1566,10 @@ static const JNINativeMethod gMethods[] = { {"native_setLogSessionId", "(Ljava/lang/String;)V", (void *)android_media_AudioTrack_setLogSessionId}, {"native_setPlayerIId", "(I)V", (void *)android_media_AudioTrack_setPlayerIId}, {"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 Loading
media/java/android/media/AudioTrack.java +61 −0 Original line number Diff line number Diff line Loading @@ -2085,6 +2085,65 @@ public class AudioTrack extends PlayerBase return native_get_buffer_capacity_frames(); } /** * 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. Loading Loading @@ -4239,6 +4298,8 @@ public class AudioTrack extends PlayerBase private native int native_set_dual_mono_mode(int dualMonoMode); private native int native_get_dual_mono_mode(int[] dualMonoMode); private native void native_setLogSessionId(@Nullable String logSessionId); private native int native_setStartThresholdInFrames(int startThresholdInFrames); private native int native_getStartThresholdInFrames(); /** * Sets the audio service Player Interface Id. Loading