public final class AudioTrack
extends java.lang.Object
AudioTrack
and handles
playback position smoothing, non-blocking writes and reconfiguration.
Before starting playback, specify the input audio format by calling one of the configure(java.lang.String, int, int, int)
methods and initialize()
the instance, optionally specifying an audio session.
Call handleBuffer(ByteBuffer, int, int, long)
to write data to play back, and
handleDiscontinuity()
when a buffer is skipped. Call play()
to start playing
back written data.
Call configure(java.lang.String, int, int, int)
again whenever the input format changes. If isInitialized()
returns false after calling configure(java.lang.String, int, int, int)
, it is necessary to re-initialize()
the
instance before writing more data.
The underlying framework audio track is created by initialize()
and released
asynchronously by reset()
(and configure(java.lang.String, int, int, int)
, unless the format is unchanged).
Reinitialization blocks until releasing the old audio track completes. It is safe to
re-initialize()
the instance after calling reset()
, without reconfiguration.
Call release()
when the instance will no longer be used.
Modifier and Type | Class and Description |
---|---|
static class |
AudioTrack.InitializationException
Thrown when a failure occurs instantiating an
AudioTrack . |
static class |
AudioTrack.InvalidAudioTrackTimestampException
Thrown when
AudioTrack.getTimestamp(android.media.AudioTimestamp) returns a spurious timestamp, if
AudioTrack#failOnSpuriousAudioTimestamp is set. |
static class |
AudioTrack.WriteException
Thrown when a failure occurs writing to an
AudioTrack . |
Modifier and Type | Field and Description |
---|---|
static long |
CURRENT_POSITION_NOT_SET
Returned by
getCurrentPositionUs(boolean) when the position is not set. |
static boolean |
enablePreV21AudioSessionWorkaround
Whether to enable a workaround for an issue where an audio effect does not keep its session
active across releasing/initializing a new audio track, on platform API version < 21.
|
static boolean |
failOnSpuriousAudioTimestamp
Whether to throw an
AudioTrack.InvalidAudioTrackTimestampException when a spurious timestamp is
reported from AudioTrack.getTimestamp(android.media.AudioTimestamp) . |
static int |
RESULT_BUFFER_CONSUMED
Returned in the result of
handleBuffer(java.nio.ByteBuffer, int, int, long) if the buffer can be released. |
static int |
RESULT_POSITION_DISCONTINUITY
Returned in the result of
handleBuffer(java.nio.ByteBuffer, int, int, long) if the buffer was discontinuous. |
static int |
SESSION_ID_NOT_SET
Represents an unset
AudioTrack session identifier. |
Constructor and Description |
---|
AudioTrack()
Creates an audio track with default audio capabilities (no encoded audio passthrough support).
|
AudioTrack(AudioCapabilities audioCapabilities,
int streamType)
Creates an audio track using the specified audio capabilities and stream type.
|
Modifier and Type | Method and Description |
---|---|
void |
configure(java.lang.String mimeType,
int channelCount,
int sampleRate,
int pcmEncoding)
Configures (or reconfigures) the audio track, inferring a suitable buffer size automatically.
|
void |
configure(java.lang.String mimeType,
int channelCount,
int sampleRate,
int pcmEncoding,
int specifiedBufferSize)
Configures (or reconfigures) the audio track.
|
int |
getBufferSize()
Returns the size of this
AudioTrack 's buffer in bytes. |
long |
getBufferSizeUs()
Returns the size of the buffer in microseconds for PCM
AudioTrack s, or
C.UNKNOWN_TIME_US for passthrough AudioTrack s. |
long |
getCurrentPositionUs(boolean sourceEnded)
Returns the playback position in the stream starting at zero, in microseconds, or
CURRENT_POSITION_NOT_SET if it is not yet available. |
int |
handleBuffer(java.nio.ByteBuffer buffer,
int offset,
int size,
long presentationTimeUs)
Attempts to write
size bytes from buffer at offset to the audio track. |
void |
handleDiscontinuity()
Signals to the audio track that the next buffer is discontinuous with the previous buffer.
|
void |
handleEndOfStream()
Ensures that the last data passed to
handleBuffer(ByteBuffer, int, int, long) is
played out in full. |
boolean |
hasPendingData()
Returns whether the audio track has more data pending that will be played back.
|
int |
initialize()
Initializes the audio track for writing new buffers using
handleBuffer(java.nio.ByteBuffer, int, int, long) . |
int |
initialize(int sessionId)
Initializes the audio track for writing new buffers using
handleBuffer(java.nio.ByteBuffer, int, int, long) . |
boolean |
isInitialized()
Returns whether the audio track has been successfully initialized via
initialize() and
not yet reset() . |
boolean |
isPassthroughSupported(java.lang.String mimeType)
Returns whether it is possible to play back input audio in the specified format using encoded
audio passthrough.
|
void |
pause()
Pauses playback.
|
void |
play()
Starts or resumes playing audio if the audio track has been initialized.
|
void |
release()
Releases all resources associated with this instance.
|
void |
reset()
Releases the underlying audio track asynchronously.
|
void |
setPlaybackParams(android.media.PlaybackParams playbackParams)
Sets the playback parameters.
|
void |
setVolume(float volume)
Sets the playback volume.
|
public static final int RESULT_POSITION_DISCONTINUITY
handleBuffer(java.nio.ByteBuffer, int, int, long)
if the buffer was discontinuous.public static final int RESULT_BUFFER_CONSUMED
handleBuffer(java.nio.ByteBuffer, int, int, long)
if the buffer can be released.public static final int SESSION_ID_NOT_SET
AudioTrack
session identifier.public static final long CURRENT_POSITION_NOT_SET
getCurrentPositionUs(boolean)
when the position is not set.public static boolean enablePreV21AudioSessionWorkaround
The flag must be set before creating a player.
public static boolean failOnSpuriousAudioTimestamp
AudioTrack.InvalidAudioTrackTimestampException
when a spurious timestamp is
reported from AudioTrack.getTimestamp(android.media.AudioTimestamp)
.
The flag must be set before creating a player. Should be set to true
for testing and
debugging purposes only.
public AudioTrack()
public AudioTrack(AudioCapabilities audioCapabilities, int streamType)
audioCapabilities
- The current audio playback capabilities.streamType
- The type of audio stream for the underlying AudioTrack
.public boolean isPassthroughSupported(java.lang.String mimeType)
public boolean isInitialized()
initialize()
and
not yet reset()
.public long getCurrentPositionUs(boolean sourceEnded)
CURRENT_POSITION_NOT_SET
if it is not yet available.
If the device supports it, the method uses the playback timestamp from
AudioTrack.getTimestamp(android.media.AudioTimestamp)
. Otherwise, it derives a smoothed position by
sampling the AudioTrack
's frame position.
sourceEnded
- Specify true
if no more input buffers will be provided.public void configure(java.lang.String mimeType, int channelCount, int sampleRate, int pcmEncoding)
mimeType
- The mime type.channelCount
- The number of channels.sampleRate
- The sample rate in Hz.pcmEncoding
- For PCM formats, the encoding used. One of C.ENCODING_PCM_16BIT
,
C.ENCODING_PCM_16BIT
, C.ENCODING_PCM_24BIT
and
C.ENCODING_PCM_32BIT
.public void configure(java.lang.String mimeType, int channelCount, int sampleRate, int pcmEncoding, int specifiedBufferSize)
mimeType
- The mime type.channelCount
- The number of channels.sampleRate
- The sample rate in Hz.pcmEncoding
- For PCM formats, the encoding used. One of C.ENCODING_PCM_16BIT
,
C.ENCODING_PCM_16BIT
, C.ENCODING_PCM_24BIT
and
C.ENCODING_PCM_32BIT
.specifiedBufferSize
- A specific size for the playback buffer in bytes, or 0 to infer a
suitable buffer size automatically.public int initialize() throws AudioTrack.InitializationException
handleBuffer(java.nio.ByteBuffer, int, int, long)
.AudioTrack.InitializationException
public int initialize(int sessionId) throws AudioTrack.InitializationException
handleBuffer(java.nio.ByteBuffer, int, int, long)
.sessionId
- Audio track session identifier to re-use, or SESSION_ID_NOT_SET
to
create a new one.AudioTrack.InitializationException
public int getBufferSize()
AudioTrack
's buffer in bytes.
The value returned from this method may change as a result of calling one of the
configure(java.lang.String, int, int, int)
methods.
public long getBufferSizeUs()
AudioTrack
s, or
C.UNKNOWN_TIME_US
for passthrough AudioTrack
s.
The value returned from this method may change as a result of calling one of the
configure(java.lang.String, int, int, int)
methods.
AudioTrack
s, or
C.UNKNOWN_TIME_US
for passthrough AudioTrack
s.public void play()
public void handleDiscontinuity()
public int handleBuffer(java.nio.ByteBuffer buffer, int offset, int size, long presentationTimeUs) throws AudioTrack.WriteException
size
bytes from buffer
at offset
to the audio track.
Returns a bit field containing RESULT_BUFFER_CONSUMED
if the buffer can be released
(due to having been written), and RESULT_POSITION_DISCONTINUITY
if the buffer was
discontinuous with previously written data.buffer
- The buffer containing audio data to play back.offset
- The offset in the buffer from which to consume data.size
- The number of bytes to consume from buffer
.presentationTimeUs
- Presentation timestamp of the next buffer in microseconds.RESULT_BUFFER_CONSUMED
if the buffer can be released, and
RESULT_POSITION_DISCONTINUITY
if the buffer was not contiguous with previously
written data.AudioTrack.WriteException
- If an error occurs writing the audio data.public void handleEndOfStream()
handleBuffer(ByteBuffer, int, int, long)
is
played out in full.public boolean hasPendingData()
public void setPlaybackParams(android.media.PlaybackParams playbackParams)
java.lang.UnsupportedOperationException
- if the Playback Parameters are not supported. That is,
SDK_INT < 23.public void setVolume(float volume)
public void pause()
public void reset()
initialize()
will block
until the audio track has been released, so it is safe to initialize immediately after
resetting. The audio session may remain active until the instance is release()
d.public void release()