Merge "AudioTrack: Enable deep buffer mode from Java"
This commit is contained in:
committed by
Android (Google) Code Review
commit
2fa71dd04a
@@ -20382,7 +20382,7 @@ package android.media {
|
||||
field public static final android.os.Parcelable.Creator<android.media.AudioAttributes> CREATOR;
|
||||
field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1
|
||||
field public static final int FLAG_HW_AV_SYNC = 16; // 0x10
|
||||
field public static final int FLAG_LOW_LATENCY = 256; // 0x100
|
||||
field public static final deprecated int FLAG_LOW_LATENCY = 256; // 0x100
|
||||
field public static final int USAGE_ALARM = 4; // 0x4
|
||||
field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb
|
||||
field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc
|
||||
@@ -20823,6 +20823,7 @@ package android.media {
|
||||
method protected deprecated int getNativeFrameCount();
|
||||
method public static int getNativeOutputSampleRate(int);
|
||||
method public int getNotificationMarkerPosition();
|
||||
method public int getPerformanceMode();
|
||||
method public int getPlayState();
|
||||
method public int getPlaybackHeadPosition();
|
||||
method public android.media.PlaybackParams getPlaybackParams();
|
||||
@@ -20869,6 +20870,9 @@ package android.media {
|
||||
field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd
|
||||
field public static final int MODE_STATIC = 0; // 0x0
|
||||
field public static final int MODE_STREAM = 1; // 0x1
|
||||
field public static final int PERFORMANCE_MODE_LOW_LATENCY = 1; // 0x1
|
||||
field public static final int PERFORMANCE_MODE_NONE = 0; // 0x0
|
||||
field public static final int PERFORMANCE_MODE_POWER_SAVING = 2; // 0x2
|
||||
field public static final int PLAYSTATE_PAUSED = 2; // 0x2
|
||||
field public static final int PLAYSTATE_PLAYING = 3; // 0x3
|
||||
field public static final int PLAYSTATE_STOPPED = 1; // 0x1
|
||||
@@ -20886,6 +20890,7 @@ package android.media {
|
||||
method public android.media.AudioTrack.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setAudioFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setPerformanceMode(int);
|
||||
method public android.media.AudioTrack.Builder setSessionId(int) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setTransferMode(int) throws java.lang.IllegalArgumentException;
|
||||
}
|
||||
|
||||
@@ -21937,7 +21937,7 @@ package android.media {
|
||||
field public static final int FLAG_BYPASS_MUTE = 128; // 0x80
|
||||
field public static final int FLAG_HW_AV_SYNC = 16; // 0x10
|
||||
field public static final int FLAG_HW_HOTWORD = 32; // 0x20
|
||||
field public static final int FLAG_LOW_LATENCY = 256; // 0x100
|
||||
field public static final deprecated int FLAG_LOW_LATENCY = 256; // 0x100
|
||||
field public static final int USAGE_ALARM = 4; // 0x4
|
||||
field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb
|
||||
field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc
|
||||
@@ -22423,6 +22423,7 @@ package android.media {
|
||||
method protected deprecated int getNativeFrameCount();
|
||||
method public static int getNativeOutputSampleRate(int);
|
||||
method public int getNotificationMarkerPosition();
|
||||
method public int getPerformanceMode();
|
||||
method public int getPlayState();
|
||||
method public int getPlaybackHeadPosition();
|
||||
method public android.media.PlaybackParams getPlaybackParams();
|
||||
@@ -22469,6 +22470,9 @@ package android.media {
|
||||
field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd
|
||||
field public static final int MODE_STATIC = 0; // 0x0
|
||||
field public static final int MODE_STREAM = 1; // 0x1
|
||||
field public static final int PERFORMANCE_MODE_LOW_LATENCY = 1; // 0x1
|
||||
field public static final int PERFORMANCE_MODE_NONE = 0; // 0x0
|
||||
field public static final int PERFORMANCE_MODE_POWER_SAVING = 2; // 0x2
|
||||
field public static final int PLAYSTATE_PAUSED = 2; // 0x2
|
||||
field public static final int PLAYSTATE_PLAYING = 3; // 0x3
|
||||
field public static final int PLAYSTATE_STOPPED = 1; // 0x1
|
||||
@@ -22486,6 +22490,7 @@ package android.media {
|
||||
method public android.media.AudioTrack.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setAudioFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setPerformanceMode(int);
|
||||
method public android.media.AudioTrack.Builder setSessionId(int) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setTransferMode(int) throws java.lang.IllegalArgumentException;
|
||||
}
|
||||
|
||||
@@ -20472,7 +20472,7 @@ package android.media {
|
||||
field public static final android.os.Parcelable.Creator<android.media.AudioAttributes> CREATOR;
|
||||
field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1
|
||||
field public static final int FLAG_HW_AV_SYNC = 16; // 0x10
|
||||
field public static final int FLAG_LOW_LATENCY = 256; // 0x100
|
||||
field public static final deprecated int FLAG_LOW_LATENCY = 256; // 0x100
|
||||
field public static final int USAGE_ALARM = 4; // 0x4
|
||||
field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb
|
||||
field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc
|
||||
@@ -20913,6 +20913,7 @@ package android.media {
|
||||
method protected deprecated int getNativeFrameCount();
|
||||
method public static int getNativeOutputSampleRate(int);
|
||||
method public int getNotificationMarkerPosition();
|
||||
method public int getPerformanceMode();
|
||||
method public int getPlayState();
|
||||
method public int getPlaybackHeadPosition();
|
||||
method public android.media.PlaybackParams getPlaybackParams();
|
||||
@@ -20959,6 +20960,9 @@ package android.media {
|
||||
field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd
|
||||
field public static final int MODE_STATIC = 0; // 0x0
|
||||
field public static final int MODE_STREAM = 1; // 0x1
|
||||
field public static final int PERFORMANCE_MODE_LOW_LATENCY = 1; // 0x1
|
||||
field public static final int PERFORMANCE_MODE_NONE = 0; // 0x0
|
||||
field public static final int PERFORMANCE_MODE_POWER_SAVING = 2; // 0x2
|
||||
field public static final int PLAYSTATE_PAUSED = 2; // 0x2
|
||||
field public static final int PLAYSTATE_PLAYING = 3; // 0x3
|
||||
field public static final int PLAYSTATE_STOPPED = 1; // 0x1
|
||||
@@ -20976,6 +20980,7 @@ package android.media {
|
||||
method public android.media.AudioTrack.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setAudioFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setPerformanceMode(int);
|
||||
method public android.media.AudioTrack.Builder setSessionId(int) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioTrack.Builder setTransferMode(int) throws java.lang.IllegalArgumentException;
|
||||
}
|
||||
|
||||
@@ -971,6 +971,18 @@ static jint android_media_AudioTrack_get_underrun_count(JNIEnv *env, jobject th
|
||||
return (jint)lpTrack->getUnderrunCount();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static jint android_media_AudioTrack_get_flags(JNIEnv *env, jobject thiz) {
|
||||
sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
|
||||
|
||||
if (lpTrack == NULL) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Unable to retrieve AudioTrack pointer for getFlags()");
|
||||
return (jint)AUDIO_JAVA_ERROR;
|
||||
}
|
||||
return (jint)lpTrack->getFlags();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static jint android_media_AudioTrack_get_timestamp(JNIEnv *env, jobject thiz, jlongArray jTimestamp) {
|
||||
sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
|
||||
@@ -1212,6 +1224,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"native_get_position", "()I", (void *)android_media_AudioTrack_get_position},
|
||||
{"native_get_latency", "()I", (void *)android_media_AudioTrack_get_latency},
|
||||
{"native_get_underrun_count", "()I", (void *)android_media_AudioTrack_get_underrun_count},
|
||||
{"native_get_flags", "()I", (void *)android_media_AudioTrack_get_flags},
|
||||
{"native_get_timestamp", "([J)I", (void *)android_media_AudioTrack_get_timestamp},
|
||||
{"native_set_loop", "(III)I", (void *)android_media_AudioTrack_set_loop},
|
||||
{"native_reload_static", "()I", (void *)android_media_AudioTrack_reload},
|
||||
|
||||
@@ -306,12 +306,26 @@ public final class AudioAttributes implements Parcelable {
|
||||
* until there are no glitches.
|
||||
* This tuning step should be done while playing silence.
|
||||
* This technique provides a compromise between latency and glitch rate.
|
||||
*
|
||||
* @deprecated Use {@link AudioTrack.Builder#setPerformanceMode(int)} with
|
||||
* {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY} to control performance.
|
||||
*/
|
||||
public final static int FLAG_LOW_LATENCY = 0x1 << 8;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Flag requesting a deep buffer path when creating an {@code AudioTrack}.
|
||||
*
|
||||
* A deep buffer path, if available, may consume less power and is
|
||||
* suitable for media playback where latency is not a concern.
|
||||
* Use {@link AudioTrack.Builder#setPerformanceMode(int)} with
|
||||
* {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING} to enable.
|
||||
*/
|
||||
public final static int FLAG_DEEP_BUFFER = 0x1 << 9;
|
||||
|
||||
private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO |
|
||||
FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY |
|
||||
FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY;
|
||||
FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER;
|
||||
private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
|
||||
FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
|
||||
|
||||
@@ -541,6 +555,8 @@ public final class AudioAttributes implements Parcelable {
|
||||
|
||||
/**
|
||||
* Sets the combination of flags.
|
||||
*
|
||||
* This is a bitwise OR with the existing flags.
|
||||
* @param flags a combination of {@link AudioAttributes#FLAG_AUDIBILITY_ENFORCED},
|
||||
* {@link AudioAttributes#FLAG_HW_AV_SYNC}.
|
||||
* @return the same Builder instance.
|
||||
@@ -551,6 +567,17 @@ public final class AudioAttributes implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Replaces flags.
|
||||
* @param flags any combination of {@link AudioAttributes#FLAG_ALL}.
|
||||
* @return the same Builder instance.
|
||||
*/
|
||||
public Builder replaceFlags(int flags) {
|
||||
mFlags = flags & AudioAttributes.FLAG_ALL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Adds a Bundle of data
|
||||
|
||||
@@ -214,6 +214,66 @@ public class AudioTrack extends PlayerBase
|
||||
*/
|
||||
public final static int WRITE_NON_BLOCKING = 1;
|
||||
|
||||
/** @hide */
|
||||
@IntDef({
|
||||
PERFORMANCE_MODE_NONE,
|
||||
PERFORMANCE_MODE_LOW_LATENCY,
|
||||
PERFORMANCE_MODE_POWER_SAVING
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PerformanceMode {}
|
||||
|
||||
/**
|
||||
* Default performance mode for an {@link AudioTrack}.
|
||||
*/
|
||||
public static final int PERFORMANCE_MODE_NONE = 0;
|
||||
|
||||
/**
|
||||
* Low latency performance mode for an {@link AudioTrack}.
|
||||
* If the device supports it, this mode
|
||||
* enables a lower latency path through to the audio output sink.
|
||||
* Effects may no longer work with such an {@code AudioTrack} and
|
||||
* the sample rate must match that of the output sink.
|
||||
* <p>
|
||||
* Applications should be aware that low latency requires careful
|
||||
* buffer management, with smaller chunks of audio data written by each
|
||||
* {@code write()} call.
|
||||
* <p>
|
||||
* If this flag is used without specifying a {@code bufferSizeInBytes} then the
|
||||
* {@code AudioTrack}'s actual buffer size may be too small.
|
||||
* It is recommended that a fairly
|
||||
* large buffer should be specified when the {@code AudioTrack} is created.
|
||||
* Then the actual size can be reduced by calling
|
||||
* {@link #setBufferSizeInFrames(int)}. The buffer size can be optimized
|
||||
* by lowering it after each {@code write()} call until the audio glitches,
|
||||
* which is detected by calling
|
||||
* {@link #getUnderrunCount()}. Then the buffer size can be increased
|
||||
* until there are no glitches.
|
||||
* This tuning step should be done while playing silence.
|
||||
* This technique provides a compromise between latency and glitch rate.
|
||||
*/
|
||||
public static final int PERFORMANCE_MODE_LOW_LATENCY = 1;
|
||||
|
||||
/**
|
||||
* Power saving performance mode for an {@link AudioTrack}.
|
||||
* If the device supports it, this
|
||||
* mode will enable a lower power path to the audio output sink.
|
||||
* In addition, this lower power path typically will have
|
||||
* deeper internal buffers and better underrun resistance,
|
||||
* with a tradeoff of higher latency.
|
||||
* <p>
|
||||
* In this mode, applications should attempt to use a larger buffer size
|
||||
* and deliver larger chunks of audio data per {@code write()} call.
|
||||
* Use {@link #getBufferSizeInFrames()} to determine
|
||||
* the actual buffer size of the {@code AudioTrack} as it may have increased
|
||||
* to accommodate a deeper buffer.
|
||||
*/
|
||||
public static final int PERFORMANCE_MODE_POWER_SAVING = 2;
|
||||
|
||||
// keep in sync with system/media/audio/include/system/audio-base.h
|
||||
private static final int AUDIO_OUTPUT_FLAG_FAST = 0x4;
|
||||
private static final int AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Member variables
|
||||
//--------------------
|
||||
@@ -648,6 +708,7 @@ public class AudioTrack extends PlayerBase
|
||||
private int mBufferSizeInBytes;
|
||||
private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
|
||||
private int mMode = MODE_STREAM;
|
||||
private int mPerformanceMode = PERFORMANCE_MODE_NONE;
|
||||
|
||||
/**
|
||||
* Constructs a new Builder with the default values as described above.
|
||||
@@ -751,6 +812,32 @@ public class AudioTrack extends PlayerBase
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link AudioTrack} performance mode. This is an advisory request which
|
||||
* may not be supported by the particular device, and the framework is free
|
||||
* to ignore such request if it is incompatible with other requests or hardware.
|
||||
*
|
||||
* @param performanceMode one of
|
||||
* {@link AudioTrack#PERFORMANCE_MODE_NONE},
|
||||
* {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY},
|
||||
* or {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING}.
|
||||
* @return the same Builder instance.
|
||||
* @throws IllegalArgumentException if {@code performanceMode} is not valid.
|
||||
*/
|
||||
public @NonNull Builder setPerformanceMode(@PerformanceMode int performanceMode) {
|
||||
switch (performanceMode) {
|
||||
case PERFORMANCE_MODE_NONE:
|
||||
case PERFORMANCE_MODE_LOW_LATENCY:
|
||||
case PERFORMANCE_MODE_POWER_SAVING:
|
||||
mPerformanceMode = performanceMode;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid performance mode " + performanceMode);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an {@link AudioTrack} instance initialized with all the parameters set
|
||||
* on this <code>Builder</code>.
|
||||
@@ -765,6 +852,25 @@ public class AudioTrack extends PlayerBase
|
||||
.setUsage(AudioAttributes.USAGE_MEDIA)
|
||||
.build();
|
||||
}
|
||||
switch (mPerformanceMode) {
|
||||
case PERFORMANCE_MODE_LOW_LATENCY:
|
||||
mAttributes = new AudioAttributes.Builder(mAttributes)
|
||||
.replaceFlags((mAttributes.getAllFlags()
|
||||
| AudioAttributes.FLAG_LOW_LATENCY)
|
||||
& ~AudioAttributes.FLAG_DEEP_BUFFER)
|
||||
.build();
|
||||
break;
|
||||
case PERFORMANCE_MODE_NONE:
|
||||
break;
|
||||
case PERFORMANCE_MODE_POWER_SAVING:
|
||||
mAttributes = new AudioAttributes.Builder(mAttributes)
|
||||
.replaceFlags((mAttributes.getAllFlags()
|
||||
| AudioAttributes.FLAG_DEEP_BUFFER)
|
||||
& ~AudioAttributes.FLAG_LOW_LATENCY)
|
||||
.build();
|
||||
break;
|
||||
}
|
||||
|
||||
if (mFormat == null) {
|
||||
mFormat = new AudioFormat.Builder()
|
||||
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
|
||||
@@ -1277,6 +1383,27 @@ public class AudioTrack extends PlayerBase
|
||||
return native_get_underrun_count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current performance mode of the {@link AudioTrack}.
|
||||
*
|
||||
* @return one of {@link AudioTrack#PERFORMANCE_MODE_NONE},
|
||||
* {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY},
|
||||
* or {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING}.
|
||||
* Use {@link AudioTrack.Builder#setPerformanceMode}
|
||||
* in the {@link AudioTrack.Builder} to enable a performance mode.
|
||||
* @throws IllegalStateException if track is not initialized.
|
||||
*/
|
||||
public @PerformanceMode int getPerformanceMode() {
|
||||
final int flags = native_get_flags();
|
||||
if ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
|
||||
return PERFORMANCE_MODE_LOW_LATENCY;
|
||||
} else if ((flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
|
||||
return PERFORMANCE_MODE_POWER_SAVING;
|
||||
} else {
|
||||
return PERFORMANCE_MODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output sample rate in Hz for the specified stream type.
|
||||
*/
|
||||
@@ -2855,6 +2982,8 @@ public class AudioTrack extends PlayerBase
|
||||
|
||||
private native final int native_get_underrun_count();
|
||||
|
||||
private native final int native_get_flags();
|
||||
|
||||
// longArray must be a non-null array of length >= 2
|
||||
// [0] is assigned the frame position
|
||||
// [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
|
||||
|
||||
Reference in New Issue
Block a user