Merge "AudioTrack: Enable deep buffer mode from Java"

This commit is contained in:
TreeHugger Robot
2017-01-26 00:22:49 +00:00
committed by Android (Google) Code Review
6 changed files with 188 additions and 4 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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},

View File

@@ -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

View File

@@ -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