1115 lines
57 KiB
C++
1115 lines
57 KiB
C++
/*
|
|
* Copyright (C) 2007 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_AUDIOTRACK_H
|
|
#define ANDROID_AUDIOTRACK_H
|
|
|
|
#include <cutils/sched_policy.h>
|
|
#include <media/AudioSystem.h>
|
|
#include <media/AudioTimestamp.h>
|
|
#include <media/IAudioTrack.h>
|
|
#include <media/AudioResamplerPublic.h>
|
|
#include <media/Modulo.h>
|
|
#include <utils/threads.h>
|
|
|
|
namespace android {
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
struct audio_track_cblk_t;
|
|
class AudioTrackClientProxy;
|
|
class StaticAudioTrackClientProxy;
|
|
struct ExtendedMediaUtils;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class AudioTrack : public RefBase
|
|
{
|
|
public:
|
|
|
|
/* Events used by AudioTrack callback function (callback_t).
|
|
* Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*.
|
|
*/
|
|
enum event_type {
|
|
EVENT_MORE_DATA = 0, // Request to write more data to buffer.
|
|
// This event only occurs for TRANSFER_CALLBACK.
|
|
// If this event is delivered but the callback handler
|
|
// does not want to write more data, the handler must
|
|
// ignore the event by setting frameCount to zero.
|
|
// This might occur, for example, if the application is
|
|
// waiting for source data or is at the end of stream.
|
|
//
|
|
// For data filling, it is preferred that the callback
|
|
// does not block and instead returns a short count on
|
|
// the amount of data actually delivered
|
|
// (or 0, if no data is currently available).
|
|
EVENT_UNDERRUN = 1, // Buffer underrun occurred. This will not occur for
|
|
// static tracks.
|
|
EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from
|
|
// loop start if loop count was not 0 for a static track.
|
|
EVENT_MARKER = 3, // Playback head is at the specified marker position
|
|
// (See setMarkerPosition()).
|
|
EVENT_NEW_POS = 4, // Playback head is at a new position
|
|
// (See setPositionUpdatePeriod()).
|
|
EVENT_BUFFER_END = 5, // Playback has completed for a static track.
|
|
EVENT_NEW_IAUDIOTRACK = 6, // IAudioTrack was re-created, either due to re-routing and
|
|
// voluntary invalidation by mediaserver, or mediaserver crash.
|
|
EVENT_STREAM_END = 7, // Sent after all the buffers queued in AF and HW are played
|
|
// back (after stop is called) for an offloaded track.
|
|
#if 0 // FIXME not yet implemented
|
|
EVENT_NEW_TIMESTAMP = 8, // Delivered periodically and when there's a significant change
|
|
// in the mapping from frame position to presentation time.
|
|
// See AudioTimestamp for the information included with event.
|
|
#endif
|
|
};
|
|
|
|
/* Client should declare a Buffer and pass the address to obtainBuffer()
|
|
* and releaseBuffer(). See also callback_t for EVENT_MORE_DATA.
|
|
*/
|
|
|
|
class Buffer
|
|
{
|
|
public:
|
|
// FIXME use m prefix
|
|
size_t frameCount; // number of sample frames corresponding to size;
|
|
// on input to obtainBuffer() it is the number of frames desired,
|
|
// on output from obtainBuffer() it is the number of available
|
|
// [empty slots for] frames to be filled
|
|
// on input to releaseBuffer() it is currently ignored
|
|
|
|
size_t size; // input/output in bytes == frameCount * frameSize
|
|
// on input to obtainBuffer() it is ignored
|
|
// on output from obtainBuffer() it is the number of available
|
|
// [empty slots for] bytes to be filled,
|
|
// which is frameCount * frameSize
|
|
// on input to releaseBuffer() it is the number of bytes to
|
|
// release
|
|
// FIXME This is redundant with respect to frameCount. Consider
|
|
// removing size and making frameCount the primary field.
|
|
|
|
union {
|
|
void* raw;
|
|
short* i16; // signed 16-bit
|
|
int8_t* i8; // unsigned 8-bit, offset by 0x80
|
|
}; // input to obtainBuffer(): unused, output: pointer to buffer
|
|
};
|
|
|
|
/* As a convenience, if a callback is supplied, a handler thread
|
|
* is automatically created with the appropriate priority. This thread
|
|
* invokes the callback when a new buffer becomes available or various conditions occur.
|
|
* Parameters:
|
|
*
|
|
* event: type of event notified (see enum AudioTrack::event_type).
|
|
* user: Pointer to context for use by the callback receiver.
|
|
* info: Pointer to optional parameter according to event type:
|
|
* - EVENT_MORE_DATA: pointer to AudioTrack::Buffer struct. The callback must not write
|
|
* more bytes than indicated by 'size' field and update 'size' if fewer bytes are
|
|
* written.
|
|
* - EVENT_UNDERRUN: unused.
|
|
* - EVENT_LOOP_END: pointer to an int indicating the number of loops remaining.
|
|
* - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
|
|
* - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
|
|
* - EVENT_BUFFER_END: unused.
|
|
* - EVENT_NEW_IAUDIOTRACK: unused.
|
|
* - EVENT_STREAM_END: unused.
|
|
* - EVENT_NEW_TIMESTAMP: pointer to const AudioTimestamp.
|
|
*/
|
|
|
|
typedef void (*callback_t)(int event, void* user, void *info);
|
|
|
|
/* Returns the minimum frame count required for the successful creation of
|
|
* an AudioTrack object.
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful operation
|
|
* - NO_INIT: audio server or audio hardware not initialized
|
|
* - BAD_VALUE: unsupported configuration
|
|
* frameCount is guaranteed to be non-zero if status is NO_ERROR,
|
|
* and is undefined otherwise.
|
|
* FIXME This API assumes a route, and so should be deprecated.
|
|
*/
|
|
|
|
static status_t getMinFrameCount(size_t* frameCount,
|
|
audio_stream_type_t streamType,
|
|
uint32_t sampleRate);
|
|
|
|
/* How data is transferred to AudioTrack
|
|
*/
|
|
enum transfer_type {
|
|
TRANSFER_DEFAULT, // not specified explicitly; determine from the other parameters
|
|
TRANSFER_CALLBACK, // callback EVENT_MORE_DATA
|
|
TRANSFER_OBTAIN, // call obtainBuffer() and releaseBuffer()
|
|
TRANSFER_SYNC, // synchronous write()
|
|
TRANSFER_SHARED, // shared memory
|
|
};
|
|
|
|
/* Constructs an uninitialized AudioTrack. No connection with
|
|
* AudioFlinger takes place. Use set() after this.
|
|
*/
|
|
AudioTrack();
|
|
|
|
/* Creates an AudioTrack object and registers it with AudioFlinger.
|
|
* Once created, the track needs to be started before it can be used.
|
|
* Unspecified values are set to appropriate default values.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* streamType: Select the type of audio stream this track is attached to
|
|
* (e.g. AUDIO_STREAM_MUSIC).
|
|
* sampleRate: Data source sampling rate in Hz. Zero means to use the sink sample rate.
|
|
* A non-zero value must be specified if AUDIO_OUTPUT_FLAG_DIRECT is set.
|
|
* 0 will not work with current policy implementation for direct output
|
|
* selection where an exact match is needed for sampling rate.
|
|
* format: Audio format. For mixed tracks, any PCM format supported by server is OK.
|
|
* For direct and offloaded tracks, the possible format(s) depends on the
|
|
* output sink.
|
|
* channelMask: Channel mask, such that audio_is_output_channel(channelMask) is true.
|
|
* frameCount: Minimum size of track PCM buffer in frames. This defines the
|
|
* application's contribution to the
|
|
* latency of the track. The actual size selected by the AudioTrack could be
|
|
* larger if the requested size is not compatible with current audio HAL
|
|
* configuration. Zero means to use a default value.
|
|
* flags: See comments on audio_output_flags_t in <system/audio.h>.
|
|
* cbf: Callback function. If not null, this function is called periodically
|
|
* to provide new data in TRANSFER_CALLBACK mode
|
|
* and inform of marker, position updates, etc.
|
|
* user: Context for use by the callback receiver.
|
|
* notificationFrames: The callback function is called each time notificationFrames PCM
|
|
* frames have been consumed from track input buffer by server.
|
|
* Zero means to use a default value, which is typically:
|
|
* - fast tracks: HAL buffer size, even if track frameCount is larger
|
|
* - normal tracks: 1/2 of track frameCount
|
|
* A positive value means that many frames at initial source sample rate.
|
|
* A negative value for this parameter specifies the negative of the
|
|
* requested number of notifications (sub-buffers) in the entire buffer.
|
|
* For fast tracks, the FastMixer will process one sub-buffer at a time.
|
|
* The size of each sub-buffer is determined by the HAL.
|
|
* To get "double buffering", for example, one should pass -2.
|
|
* The minimum number of sub-buffers is 1 (expressed as -1),
|
|
* and the maximum number of sub-buffers is 8 (expressed as -8).
|
|
* Negative is only permitted for fast tracks, and if frameCount is zero.
|
|
* TODO It is ugly to overload a parameter in this way depending on
|
|
* whether it is positive, negative, or zero. Consider splitting apart.
|
|
* sessionId: Specific session ID, or zero to use default.
|
|
* transferType: How data is transferred to AudioTrack.
|
|
* offloadInfo: If not NULL, provides offload parameters for
|
|
* AudioSystem::getOutputForAttr().
|
|
* uid: User ID of the app which initially requested this AudioTrack
|
|
* for power management tracking, or -1 for current user ID.
|
|
* pid: Process ID of the app which initially requested this AudioTrack
|
|
* for power management tracking, or -1 for current process ID.
|
|
* pAttributes: If not NULL, supersedes streamType for use case selection.
|
|
* doNotReconnect: If set to true, AudioTrack won't automatically recreate the IAudioTrack
|
|
binder to AudioFlinger.
|
|
It will return an error instead. The application will recreate
|
|
the track based on offloading or different channel configuration, etc.
|
|
* maxRequiredSpeed: For PCM tracks, this creates an appropriate buffer size that will allow
|
|
* maxRequiredSpeed playback. Values less than 1.0f and greater than
|
|
* AUDIO_TIMESTRETCH_SPEED_MAX will be clamped. For non-PCM tracks
|
|
* and direct or offloaded tracks, this parameter is ignored.
|
|
* threadCanCallJava: Not present in parameter list, and so is fixed at false.
|
|
*/
|
|
|
|
AudioTrack( audio_stream_type_t streamType,
|
|
uint32_t sampleRate,
|
|
audio_format_t format,
|
|
audio_channel_mask_t channelMask,
|
|
size_t frameCount = 0,
|
|
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
|
|
callback_t cbf = NULL,
|
|
void* user = NULL,
|
|
int32_t notificationFrames = 0,
|
|
audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
|
|
transfer_type transferType = TRANSFER_DEFAULT,
|
|
const audio_offload_info_t *offloadInfo = NULL,
|
|
int uid = -1,
|
|
pid_t pid = -1,
|
|
const audio_attributes_t* pAttributes = NULL,
|
|
bool doNotReconnect = false,
|
|
float maxRequiredSpeed = 1.0f);
|
|
|
|
/* Creates an audio track and registers it with AudioFlinger.
|
|
* With this constructor, the track is configured for static buffer mode.
|
|
* Data to be rendered is passed in a shared memory buffer
|
|
* identified by the argument sharedBuffer, which should be non-0.
|
|
* If sharedBuffer is zero, this constructor is equivalent to the previous constructor
|
|
* but without the ability to specify a non-zero value for the frameCount parameter.
|
|
* The memory should be initialized to the desired data before calling start().
|
|
* The write() method is not supported in this case.
|
|
* It is recommended to pass a callback function to be notified of playback end by an
|
|
* EVENT_UNDERRUN event.
|
|
*/
|
|
|
|
AudioTrack( audio_stream_type_t streamType,
|
|
uint32_t sampleRate,
|
|
audio_format_t format,
|
|
audio_channel_mask_t channelMask,
|
|
const sp<IMemory>& sharedBuffer,
|
|
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
|
|
callback_t cbf = NULL,
|
|
void* user = NULL,
|
|
int32_t notificationFrames = 0,
|
|
audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
|
|
transfer_type transferType = TRANSFER_DEFAULT,
|
|
const audio_offload_info_t *offloadInfo = NULL,
|
|
int uid = -1,
|
|
pid_t pid = -1,
|
|
const audio_attributes_t* pAttributes = NULL,
|
|
bool doNotReconnect = false,
|
|
float maxRequiredSpeed = 1.0f);
|
|
|
|
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
|
|
* Also destroys all resources associated with the AudioTrack.
|
|
*/
|
|
protected:
|
|
virtual ~AudioTrack();
|
|
public:
|
|
|
|
/* Initialize an AudioTrack that was created using the AudioTrack() constructor.
|
|
* Don't call set() more than once, or after the AudioTrack() constructors that take parameters.
|
|
* set() is not multi-thread safe.
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful initialization
|
|
* - INVALID_OPERATION: AudioTrack is already initialized
|
|
* - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...)
|
|
* - NO_INIT: audio server or audio hardware not initialized
|
|
* If status is not equal to NO_ERROR, don't call any other APIs on this AudioTrack.
|
|
* If sharedBuffer is non-0, the frameCount parameter is ignored and
|
|
* replaced by the shared buffer's total allocated size in frame units.
|
|
*
|
|
* Parameters not listed in the AudioTrack constructors above:
|
|
*
|
|
* threadCanCallJava: Whether callbacks are made from an attached thread and thus can call JNI.
|
|
*
|
|
* Internal state post condition:
|
|
* (mStreamType == AUDIO_STREAM_DEFAULT) implies this AudioTrack has valid attributes
|
|
*/
|
|
status_t set(audio_stream_type_t streamType,
|
|
uint32_t sampleRate,
|
|
audio_format_t format,
|
|
audio_channel_mask_t channelMask,
|
|
size_t frameCount = 0,
|
|
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
|
|
callback_t cbf = NULL,
|
|
void* user = NULL,
|
|
int32_t notificationFrames = 0,
|
|
const sp<IMemory>& sharedBuffer = 0,
|
|
bool threadCanCallJava = false,
|
|
audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
|
|
transfer_type transferType = TRANSFER_DEFAULT,
|
|
const audio_offload_info_t *offloadInfo = NULL,
|
|
int uid = -1,
|
|
pid_t pid = -1,
|
|
const audio_attributes_t* pAttributes = NULL,
|
|
bool doNotReconnect = false,
|
|
float maxRequiredSpeed = 1.0f);
|
|
|
|
/* Result of constructing the AudioTrack. This must be checked for successful initialization
|
|
* before using any AudioTrack API (except for set()), because using
|
|
* an uninitialized AudioTrack produces undefined results.
|
|
* See set() method above for possible return codes.
|
|
*/
|
|
status_t initCheck() const { return mStatus; }
|
|
|
|
/* Returns this track's estimated latency in milliseconds.
|
|
* This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
|
|
* and audio hardware driver.
|
|
*/
|
|
uint32_t latency() const { return mLatency; }
|
|
|
|
/* Returns the number of application-level buffer underruns
|
|
* since the AudioTrack was created.
|
|
*/
|
|
uint32_t getUnderrunCount() const;
|
|
|
|
/* getters, see constructors and set() */
|
|
|
|
audio_stream_type_t streamType() const;
|
|
audio_format_t format() const { return mFormat; }
|
|
|
|
/* Return frame size in bytes, which for linear PCM is
|
|
* channelCount * (bit depth per channel / 8).
|
|
* channelCount is determined from channelMask, and bit depth comes from format.
|
|
* For non-linear formats, the frame size is typically 1 byte.
|
|
*/
|
|
size_t frameSize() const { return mFrameSize; }
|
|
|
|
uint32_t channelCount() const { return mChannelCount; }
|
|
size_t frameCount() const { return mFrameCount; }
|
|
|
|
// TODO consider notificationFrames() if needed
|
|
|
|
/* Return effective size of audio buffer that an application writes to
|
|
* or a negative error if the track is uninitialized.
|
|
*/
|
|
ssize_t getBufferSizeInFrames();
|
|
|
|
/* Returns the buffer duration in microseconds at current playback rate.
|
|
*/
|
|
status_t getBufferDurationInUs(int64_t *duration);
|
|
|
|
/* Set the effective size of audio buffer that an application writes to.
|
|
* This is used to determine the amount of available room in the buffer,
|
|
* which determines when a write will block.
|
|
* This allows an application to raise and lower the audio latency.
|
|
* The requested size may be adjusted so that it is
|
|
* greater or equal to the absolute minimum and
|
|
* less than or equal to the getBufferCapacityInFrames().
|
|
* It may also be adjusted slightly for internal reasons.
|
|
*
|
|
* Return the final size or a negative error if the track is unitialized
|
|
* or does not support variable sizes.
|
|
*/
|
|
ssize_t setBufferSizeInFrames(size_t size);
|
|
|
|
/* Return the static buffer specified in constructor or set(), or 0 for streaming mode */
|
|
sp<IMemory> sharedBuffer() const { return mSharedBuffer; }
|
|
|
|
/* After it's created the track is not active. Call start() to
|
|
* make it active. If set, the callback will start being called.
|
|
* If the track was previously paused, volume is ramped up over the first mix buffer.
|
|
*/
|
|
status_t start();
|
|
|
|
/* Stop a track.
|
|
* In static buffer mode, the track is stopped immediately.
|
|
* In streaming mode, the callback will cease being called. Note that obtainBuffer() still
|
|
* works and will fill up buffers until the pool is exhausted, and then will return WOULD_BLOCK.
|
|
* In streaming mode the stop does not occur immediately: any data remaining in the buffer
|
|
* is first drained, mixed, and output, and only then is the track marked as stopped.
|
|
*/
|
|
void stop();
|
|
bool stopped() const;
|
|
|
|
/* Flush a stopped or paused track. All previously buffered data is discarded immediately.
|
|
* This has the effect of draining the buffers without mixing or output.
|
|
* Flush is intended for streaming mode, for example before switching to non-contiguous content.
|
|
* This function is a no-op if the track is not stopped or paused, or uses a static buffer.
|
|
*/
|
|
void flush();
|
|
|
|
/* Pause a track. After pause, the callback will cease being called and
|
|
* obtainBuffer returns WOULD_BLOCK. Note that obtainBuffer() still works
|
|
* and will fill up buffers until the pool is exhausted.
|
|
* Volume is ramped down over the next mix buffer following the pause request,
|
|
* and then the track is marked as paused. It can be resumed with ramp up by start().
|
|
*/
|
|
void pause();
|
|
|
|
/* Set volume for this track, mostly used for games' sound effects
|
|
* left and right volumes. Levels must be >= 0.0 and <= 1.0.
|
|
* This is the older API. New applications should use setVolume(float) when possible.
|
|
*/
|
|
status_t setVolume(float left, float right);
|
|
|
|
/* Set volume for all channels. This is the preferred API for new applications,
|
|
* especially for multi-channel content.
|
|
*/
|
|
status_t setVolume(float volume);
|
|
|
|
/* Set the send level for this track. An auxiliary effect should be attached
|
|
* to the track with attachEffect(). Level must be >= 0.0 and <= 1.0.
|
|
*/
|
|
status_t setAuxEffectSendLevel(float level);
|
|
void getAuxEffectSendLevel(float* level) const;
|
|
|
|
/* Set source sample rate for this track in Hz, mostly used for games' sound effects.
|
|
* Zero is not permitted.
|
|
*/
|
|
status_t setSampleRate(uint32_t sampleRate);
|
|
|
|
/* Return current source sample rate in Hz.
|
|
* If specified as zero in constructor or set(), this will be the sink sample rate.
|
|
*/
|
|
uint32_t getSampleRate() const;
|
|
|
|
/* Return the original source sample rate in Hz. This corresponds to the sample rate
|
|
* if playback rate had normal speed and pitch.
|
|
*/
|
|
uint32_t getOriginalSampleRate() const;
|
|
|
|
/* Set source playback rate for timestretch
|
|
* 1.0 is normal speed: < 1.0 is slower, > 1.0 is faster
|
|
* 1.0 is normal pitch: < 1.0 is lower pitch, > 1.0 is higher pitch
|
|
*
|
|
* AUDIO_TIMESTRETCH_SPEED_MIN <= speed <= AUDIO_TIMESTRETCH_SPEED_MAX
|
|
* AUDIO_TIMESTRETCH_PITCH_MIN <= pitch <= AUDIO_TIMESTRETCH_PITCH_MAX
|
|
*
|
|
* Speed increases the playback rate of media, but does not alter pitch.
|
|
* Pitch increases the "tonal frequency" of media, but does not affect the playback rate.
|
|
*/
|
|
status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
|
|
|
|
/* Return current playback rate */
|
|
const AudioPlaybackRate& getPlaybackRate() const;
|
|
|
|
/* Enables looping and sets the start and end points of looping.
|
|
* Only supported for static buffer mode.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* loopStart: loop start in frames relative to start of buffer.
|
|
* loopEnd: loop end in frames relative to start of buffer.
|
|
* loopCount: number of loops to execute. Calling setLoop() with loopCount == 0 cancels any
|
|
* pending or active loop. loopCount == -1 means infinite looping.
|
|
*
|
|
* For proper operation the following condition must be respected:
|
|
* loopCount != 0 implies 0 <= loopStart < loopEnd <= frameCount().
|
|
*
|
|
* If the loop period (loopEnd - loopStart) is too small for the implementation to support,
|
|
* setLoop() will return BAD_VALUE. loopCount must be >= -1.
|
|
*
|
|
*/
|
|
status_t setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount);
|
|
|
|
/* Sets marker position. When playback reaches the number of frames specified, a callback with
|
|
* event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker
|
|
* notification callback. To set a marker at a position which would compute as 0,
|
|
* a workaround is to set the marker at a nearby position such as ~0 or 1.
|
|
* If the AudioTrack has been opened with no callback function associated, the operation will
|
|
* fail.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* marker: marker position expressed in wrapping (overflow) frame units,
|
|
* like the return value of getPosition().
|
|
*
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful operation
|
|
* - INVALID_OPERATION: the AudioTrack has no callback installed.
|
|
*/
|
|
status_t setMarkerPosition(uint32_t marker);
|
|
status_t getMarkerPosition(uint32_t *marker) const;
|
|
|
|
/* Sets position update period. Every time the number of frames specified has been played,
|
|
* a callback with event type EVENT_NEW_POS is called.
|
|
* Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
|
|
* callback.
|
|
* If the AudioTrack has been opened with no callback function associated, the operation will
|
|
* fail.
|
|
* Extremely small values may be rounded up to a value the implementation can support.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* updatePeriod: position update notification period expressed in frames.
|
|
*
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful operation
|
|
* - INVALID_OPERATION: the AudioTrack has no callback installed.
|
|
*/
|
|
status_t setPositionUpdatePeriod(uint32_t updatePeriod);
|
|
status_t getPositionUpdatePeriod(uint32_t *updatePeriod) const;
|
|
|
|
/* Sets playback head position.
|
|
* Only supported for static buffer mode.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* position: New playback head position in frames relative to start of buffer.
|
|
* 0 <= position <= frameCount(). Note that end of buffer is permitted,
|
|
* but will result in an immediate underrun if started.
|
|
*
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful operation
|
|
* - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode.
|
|
* - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack
|
|
* buffer
|
|
*/
|
|
status_t setPosition(uint32_t position);
|
|
|
|
/* Return the total number of frames played since playback start.
|
|
* The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz.
|
|
* It is reset to zero by flush(), reload(), and stop().
|
|
*
|
|
* Parameters:
|
|
*
|
|
* position: Address where to return play head position.
|
|
*
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful operation
|
|
* - BAD_VALUE: position is NULL
|
|
*/
|
|
status_t getPosition(uint32_t *position);
|
|
|
|
/* For static buffer mode only, this returns the current playback position in frames
|
|
* relative to start of buffer. It is analogous to the position units used by
|
|
* setLoop() and setPosition(). After underrun, the position will be at end of buffer.
|
|
*/
|
|
status_t getBufferPosition(uint32_t *position);
|
|
|
|
/* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids
|
|
* rewriting the buffer before restarting playback after a stop.
|
|
* This method must be called with the AudioTrack in paused or stopped state.
|
|
* Not allowed in streaming mode.
|
|
*
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful operation
|
|
* - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode.
|
|
*/
|
|
status_t reload();
|
|
|
|
public:
|
|
/* Returns a handle on the audio output used by this AudioTrack.
|
|
*
|
|
* Parameters:
|
|
* none.
|
|
*
|
|
* Returned value:
|
|
* handle on audio hardware output, or AUDIO_IO_HANDLE_NONE if the
|
|
* track needed to be re-created but that failed
|
|
*/
|
|
audio_io_handle_t getOutput() const;
|
|
|
|
/* Selects the audio device to use for output of this AudioTrack. A value of
|
|
* AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing.
|
|
*
|
|
* Parameters:
|
|
* The device ID of the selected device (as returned by the AudioDevicesManager API).
|
|
*
|
|
* Returned value:
|
|
* - NO_ERROR: successful operation
|
|
* TODO: what else can happen here?
|
|
*/
|
|
status_t setOutputDevice(audio_port_handle_t deviceId);
|
|
|
|
/* Returns the ID of the audio device selected for this AudioTrack.
|
|
* A value of AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing.
|
|
*
|
|
* Parameters:
|
|
* none.
|
|
*/
|
|
audio_port_handle_t getOutputDevice();
|
|
|
|
/* Returns the ID of the audio device actually used by the output to which this AudioTrack is
|
|
* attached.
|
|
* A value of AUDIO_PORT_HANDLE_NONE indicates the audio track is not attached to any output.
|
|
*
|
|
* Parameters:
|
|
* none.
|
|
*/
|
|
audio_port_handle_t getRoutedDeviceId();
|
|
|
|
/* Returns the unique session ID associated with this track.
|
|
*
|
|
* Parameters:
|
|
* none.
|
|
*
|
|
* Returned value:
|
|
* AudioTrack session ID.
|
|
*/
|
|
audio_session_t getSessionId() const { return mSessionId; }
|
|
|
|
/* Attach track auxiliary output to specified effect. Use effectId = 0
|
|
* to detach track from effect.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* effectId: effectId obtained from AudioEffect::id().
|
|
*
|
|
* Returned status (from utils/Errors.h) can be:
|
|
* - NO_ERROR: successful operation
|
|
* - INVALID_OPERATION: the effect is not an auxiliary effect.
|
|
* - BAD_VALUE: The specified effect ID is invalid
|
|
*/
|
|
status_t attachAuxEffect(int effectId);
|
|
|
|
/* Public API for TRANSFER_OBTAIN mode.
|
|
* Obtains a buffer of up to "audioBuffer->frameCount" empty slots for frames.
|
|
* After filling these slots with data, the caller should release them with releaseBuffer().
|
|
* If the track buffer is not full, obtainBuffer() returns as many contiguous
|
|
* [empty slots for] frames as are available immediately.
|
|
*
|
|
* If nonContig is non-NULL, it is an output parameter that will be set to the number of
|
|
* additional non-contiguous frames that are predicted to be available immediately,
|
|
* if the client were to release the first frames and then call obtainBuffer() again.
|
|
* This value is only a prediction, and needs to be confirmed.
|
|
* It will be set to zero for an error return.
|
|
*
|
|
* If the track buffer is full and track is stopped, obtainBuffer() returns WOULD_BLOCK
|
|
* regardless of the value of waitCount.
|
|
* If the track buffer is full and track is not stopped, obtainBuffer() blocks with a
|
|
* maximum timeout based on waitCount; see chart below.
|
|
* Buffers will be returned until the pool
|
|
* is exhausted, at which point obtainBuffer() will either block
|
|
* or return WOULD_BLOCK depending on the value of the "waitCount"
|
|
* parameter.
|
|
*
|
|
* Interpretation of waitCount:
|
|
* +n limits wait time to n * WAIT_PERIOD_MS,
|
|
* -1 causes an (almost) infinite wait time,
|
|
* 0 non-blocking.
|
|
*
|
|
* Buffer fields
|
|
* On entry:
|
|
* frameCount number of [empty slots for] frames requested
|
|
* size ignored
|
|
* raw ignored
|
|
* After error return:
|
|
* frameCount 0
|
|
* size 0
|
|
* raw undefined
|
|
* After successful return:
|
|
* frameCount actual number of [empty slots for] frames available, <= number requested
|
|
* size actual number of bytes available
|
|
* raw pointer to the buffer
|
|
*/
|
|
status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount,
|
|
size_t *nonContig = NULL);
|
|
|
|
private:
|
|
/* If nonContig is non-NULL, it is an output parameter that will be set to the number of
|
|
* additional non-contiguous frames that are predicted to be available immediately,
|
|
* if the client were to release the first frames and then call obtainBuffer() again.
|
|
* This value is only a prediction, and needs to be confirmed.
|
|
* It will be set to zero for an error return.
|
|
* FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),
|
|
* in case the requested amount of frames is in two or more non-contiguous regions.
|
|
* FIXME requested and elapsed are both relative times. Consider changing to absolute time.
|
|
*/
|
|
status_t obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
|
|
struct timespec *elapsed = NULL, size_t *nonContig = NULL);
|
|
public:
|
|
|
|
/* Public API for TRANSFER_OBTAIN mode.
|
|
* Release a filled buffer of frames for AudioFlinger to process.
|
|
*
|
|
* Buffer fields:
|
|
* frameCount currently ignored but recommend to set to actual number of frames filled
|
|
* size actual number of bytes filled, must be multiple of frameSize
|
|
* raw ignored
|
|
*/
|
|
void releaseBuffer(const Buffer* audioBuffer);
|
|
|
|
/* As a convenience we provide a write() interface to the audio buffer.
|
|
* Input parameter 'size' is in byte units.
|
|
* This is implemented on top of obtainBuffer/releaseBuffer. For best
|
|
* performance use callbacks. Returns actual number of bytes written >= 0,
|
|
* or one of the following negative status codes:
|
|
* INVALID_OPERATION AudioTrack is configured for static buffer or streaming mode
|
|
* BAD_VALUE size is invalid
|
|
* WOULD_BLOCK when obtainBuffer() returns same, or
|
|
* AudioTrack was stopped during the write
|
|
* DEAD_OBJECT when AudioFlinger dies or the output device changes and
|
|
* the track cannot be automatically restored.
|
|
* The application needs to recreate the AudioTrack
|
|
* because the audio device changed or AudioFlinger died.
|
|
* This typically occurs for direct or offload tracks
|
|
* or if mDoNotReconnect is true.
|
|
* or any other error code returned by IAudioTrack::start() or restoreTrack_l().
|
|
* Default behavior is to only return when all data has been transferred. Set 'blocking' to
|
|
* false for the method to return immediately without waiting to try multiple times to write
|
|
* the full content of the buffer.
|
|
*/
|
|
ssize_t write(const void* buffer, size_t size, bool blocking = true);
|
|
|
|
/*
|
|
* Dumps the state of an audio track.
|
|
* Not a general-purpose API; intended only for use by media player service to dump its tracks.
|
|
*/
|
|
status_t dump(int fd, const Vector<String16>& args) const;
|
|
|
|
/*
|
|
* Return the total number of frames which AudioFlinger desired but were unavailable,
|
|
* and thus which resulted in an underrun. Reset to zero by stop().
|
|
*/
|
|
uint32_t getUnderrunFrames() const;
|
|
|
|
/* Get the flags */
|
|
audio_output_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; }
|
|
|
|
/* Set parameters - only possible when using direct output */
|
|
status_t setParameters(const String8& keyValuePairs);
|
|
|
|
/* Get parameters */
|
|
String8 getParameters(const String8& keys);
|
|
|
|
/* Poll for a timestamp on demand.
|
|
* Use if EVENT_NEW_TIMESTAMP is not delivered often enough for your needs,
|
|
* or if you need to get the most recent timestamp outside of the event callback handler.
|
|
* Caution: calling this method too often may be inefficient;
|
|
* if you need a high resolution mapping between frame position and presentation time,
|
|
* consider implementing that at application level, based on the low resolution timestamps.
|
|
* Returns NO_ERROR if timestamp is valid.
|
|
* WOULD_BLOCK if called in STOPPED or FLUSHED state, or if called immediately after
|
|
* start/ACTIVE, when the number of frames consumed is less than the
|
|
* overall hardware latency to physical output. In WOULD_BLOCK cases,
|
|
* one might poll again, or use getPosition(), or use 0 position and
|
|
* current time for the timestamp.
|
|
* DEAD_OBJECT if AudioFlinger dies or the output device changes and
|
|
* the track cannot be automatically restored.
|
|
* The application needs to recreate the AudioTrack
|
|
* because the audio device changed or AudioFlinger died.
|
|
* This typically occurs for direct or offload tracks
|
|
* or if mDoNotReconnect is true.
|
|
* INVALID_OPERATION wrong state, or some other error.
|
|
*
|
|
* The timestamp parameter is undefined on return, if status is not NO_ERROR.
|
|
*/
|
|
status_t getTimestamp(AudioTimestamp& timestamp);
|
|
|
|
/* Return the extended timestamp, with additional timebase info and improved drain behavior.
|
|
*
|
|
* This is similar to the AudioTrack.java API:
|
|
* getTimestamp(@NonNull AudioTimestamp timestamp, @AudioTimestamp.Timebase int timebase)
|
|
*
|
|
* Some differences between this method and the getTimestamp(AudioTimestamp& timestamp) method
|
|
*
|
|
* 1. stop() by itself does not reset the frame position.
|
|
* A following start() resets the frame position to 0.
|
|
* 2. flush() by itself does not reset the frame position.
|
|
* The frame position advances by the number of frames flushed,
|
|
* when the first frame after flush reaches the audio sink.
|
|
* 3. BOOTTIME clock offsets are provided to help synchronize with
|
|
* non-audio streams, e.g. sensor data.
|
|
* 4. Position is returned with 64 bits of resolution.
|
|
*
|
|
* Parameters:
|
|
* timestamp: A pointer to the caller allocated ExtendedTimestamp.
|
|
*
|
|
* Returns NO_ERROR on success; timestamp is filled with valid data.
|
|
* BAD_VALUE if timestamp is NULL.
|
|
* WOULD_BLOCK if called immediately after start() when the number
|
|
* of frames consumed is less than the
|
|
* overall hardware latency to physical output. In WOULD_BLOCK cases,
|
|
* one might poll again, or use getPosition(), or use 0 position and
|
|
* current time for the timestamp.
|
|
* If WOULD_BLOCK is returned, the timestamp is still
|
|
* modified with the LOCATION_CLIENT portion filled.
|
|
* DEAD_OBJECT if AudioFlinger dies or the output device changes and
|
|
* the track cannot be automatically restored.
|
|
* The application needs to recreate the AudioTrack
|
|
* because the audio device changed or AudioFlinger died.
|
|
* This typically occurs for direct or offloaded tracks
|
|
* or if mDoNotReconnect is true.
|
|
* INVALID_OPERATION if called on a offloaded or direct track.
|
|
* Use getTimestamp(AudioTimestamp& timestamp) instead.
|
|
*/
|
|
status_t getTimestamp(ExtendedTimestamp *timestamp);
|
|
private:
|
|
status_t getTimestamp_l(ExtendedTimestamp *timestamp);
|
|
public:
|
|
|
|
/* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this
|
|
* AudioTrack is routed is updated.
|
|
* Replaces any previously installed callback.
|
|
* Parameters:
|
|
* callback: The callback interface
|
|
* Returns NO_ERROR if successful.
|
|
* INVALID_OPERATION if the same callback is already installed.
|
|
* NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable
|
|
* BAD_VALUE if the callback is NULL
|
|
*/
|
|
status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
|
|
|
|
/* remove an AudioDeviceCallback.
|
|
* Parameters:
|
|
* callback: The callback interface
|
|
* Returns NO_ERROR if successful.
|
|
* INVALID_OPERATION if the callback is not installed
|
|
* BAD_VALUE if the callback is NULL
|
|
*/
|
|
status_t removeAudioDeviceCallback(
|
|
const sp<AudioSystem::AudioDeviceCallback>& callback);
|
|
|
|
/* Obtain the pending duration in milliseconds for playback of pure PCM
|
|
* (mixable without embedded timing) data remaining in AudioTrack.
|
|
*
|
|
* This is used to estimate the drain time for the client-server buffer
|
|
* so the choice of ExtendedTimestamp::LOCATION_SERVER is default.
|
|
* One may optionally request to find the duration to play through the HAL
|
|
* by specifying a location ExtendedTimestamp::LOCATION_KERNEL; however,
|
|
* INVALID_OPERATION may be returned if the kernel location is unavailable.
|
|
*
|
|
* Returns NO_ERROR if successful.
|
|
* INVALID_OPERATION if ExtendedTimestamp::LOCATION_KERNEL cannot be obtained
|
|
* or the AudioTrack does not contain pure PCM data.
|
|
* BAD_VALUE if msec is nullptr or location is invalid.
|
|
*/
|
|
status_t pendingDuration(int32_t *msec,
|
|
ExtendedTimestamp::Location location = ExtendedTimestamp::LOCATION_SERVER);
|
|
|
|
protected:
|
|
/* copying audio tracks is not allowed */
|
|
AudioTrack(const AudioTrack& other);
|
|
AudioTrack& operator = (const AudioTrack& other);
|
|
|
|
/* a small internal class to handle the callback */
|
|
class AudioTrackThread : public Thread
|
|
{
|
|
public:
|
|
AudioTrackThread(AudioTrack& receiver, bool bCanCallJava = false);
|
|
|
|
// Do not call Thread::requestExitAndWait() without first calling requestExit().
|
|
// Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
|
|
virtual void requestExit();
|
|
|
|
void pause(); // suspend thread from execution at next loop boundary
|
|
void resume(); // allow thread to execute, if not requested to exit
|
|
void wake(); // wake to handle changed notification conditions.
|
|
|
|
private:
|
|
void pauseInternal(nsecs_t ns = 0LL);
|
|
// like pause(), but only used internally within thread
|
|
|
|
friend class AudioTrack;
|
|
virtual bool threadLoop();
|
|
AudioTrack& mReceiver;
|
|
virtual ~AudioTrackThread();
|
|
Mutex mMyLock; // Thread::mLock is private
|
|
Condition mMyCond; // Thread::mThreadExitedCondition is private
|
|
bool mPaused; // whether thread is requested to pause at next loop entry
|
|
bool mPausedInt; // whether thread internally requests pause
|
|
nsecs_t mPausedNs; // if mPausedInt then associated timeout, otherwise ignored
|
|
bool mIgnoreNextPausedInt; // skip any internal pause and go immediately
|
|
// to processAudioBuffer() as state may have changed
|
|
// since pause time calculated.
|
|
};
|
|
|
|
// body of AudioTrackThread::threadLoop()
|
|
// returns the maximum amount of time before we would like to run again, where:
|
|
// 0 immediately
|
|
// > 0 no later than this many nanoseconds from now
|
|
// NS_WHENEVER still active but no particular deadline
|
|
// NS_INACTIVE inactive so don't run again until re-started
|
|
// NS_NEVER never again
|
|
static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3;
|
|
nsecs_t processAudioBuffer();
|
|
|
|
// caller must hold lock on mLock for all _l methods
|
|
|
|
status_t createTrack_l();
|
|
|
|
// can only be called when mState != STATE_ACTIVE
|
|
void flush_l();
|
|
|
|
void setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount);
|
|
|
|
// FIXME enum is faster than strcmp() for parameter 'from'
|
|
status_t restoreTrack_l(const char *from);
|
|
|
|
uint32_t getUnderrunCount_l() const;
|
|
|
|
bool isOffloaded() const;
|
|
bool isDirect() const;
|
|
bool isOffloadedOrDirect() const;
|
|
|
|
bool isOffloaded_l() const
|
|
{ return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; }
|
|
|
|
bool isOffloadedOrDirect_l() const
|
|
{ return (mFlags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|
|
|
AUDIO_OUTPUT_FLAG_DIRECT)) != 0; }
|
|
|
|
bool isDirect_l() const
|
|
{ return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
|
|
|
|
// pure pcm data is mixable (which excludes HW_AV_SYNC, with embedded timing)
|
|
bool isPurePcmData_l() const
|
|
{ return audio_is_linear_pcm(mFormat)
|
|
&& (mAttributes.flags & AUDIO_FLAG_HW_AV_SYNC) == 0; }
|
|
|
|
// increment mPosition by the delta of mServer, and return new value of mPosition
|
|
Modulo<uint32_t> updateAndGetPosition_l();
|
|
|
|
// check sample rate and speed is compatible with AudioTrack
|
|
bool isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const;
|
|
|
|
void restartIfDisabled();
|
|
|
|
// Next 4 fields may be changed if IAudioTrack is re-created, but always != 0
|
|
sp<IAudioTrack> mAudioTrack;
|
|
sp<IMemory> mCblkMemory;
|
|
audio_track_cblk_t* mCblk; // re-load after mLock.unlock()
|
|
audio_io_handle_t mOutput; // returned by AudioSystem::getOutput()
|
|
|
|
sp<AudioTrackThread> mAudioTrackThread;
|
|
bool mThreadCanCallJava;
|
|
|
|
float mVolume[2];
|
|
float mSendLevel;
|
|
mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it
|
|
uint32_t mOriginalSampleRate;
|
|
AudioPlaybackRate mPlaybackRate;
|
|
float mMaxRequiredSpeed; // use PCM buffer size to allow this speed
|
|
|
|
// Corresponds to current IAudioTrack, value is reported back by AudioFlinger to the client.
|
|
// This allocated buffer size is maintained by the proxy.
|
|
size_t mFrameCount; // maximum size of buffer
|
|
|
|
size_t mReqFrameCount; // frame count to request the first or next time
|
|
// a new IAudioTrack is needed, non-decreasing
|
|
|
|
// The following AudioFlinger server-side values are cached in createAudioTrack_l().
|
|
// These values can be used for informational purposes until the track is invalidated,
|
|
// whereupon restoreTrack_l() calls createTrack_l() to update the values.
|
|
uint32_t mAfLatency; // AudioFlinger latency in ms
|
|
size_t mAfFrameCount; // AudioFlinger frame count
|
|
uint32_t mAfSampleRate; // AudioFlinger sample rate
|
|
|
|
// constant after constructor or set()
|
|
audio_format_t mFormat; // as requested by client, not forced to 16-bit
|
|
audio_stream_type_t mStreamType; // mStreamType == AUDIO_STREAM_DEFAULT implies
|
|
// this AudioTrack has valid attributes
|
|
uint32_t mChannelCount;
|
|
audio_channel_mask_t mChannelMask;
|
|
sp<IMemory> mSharedBuffer;
|
|
transfer_type mTransfer;
|
|
audio_offload_info_t mOffloadInfoCopy;
|
|
const audio_offload_info_t* mOffloadInfo;
|
|
audio_attributes_t mAttributes;
|
|
|
|
size_t mFrameSize; // frame size in bytes
|
|
|
|
status_t mStatus;
|
|
|
|
// can change dynamically when IAudioTrack invalidated
|
|
uint32_t mLatency; // in ms
|
|
|
|
// Indicates the current track state. Protected by mLock.
|
|
enum State {
|
|
STATE_ACTIVE,
|
|
STATE_STOPPED,
|
|
STATE_PAUSED,
|
|
STATE_PAUSED_STOPPING,
|
|
STATE_FLUSHED,
|
|
STATE_STOPPING,
|
|
} mState;
|
|
|
|
// for client callback handler
|
|
callback_t mCbf; // callback handler for events, or NULL
|
|
void* mUserData;
|
|
|
|
// for notification APIs
|
|
|
|
// next 2 fields are const after constructor or set()
|
|
uint32_t mNotificationFramesReq; // requested number of frames between each
|
|
// notification callback,
|
|
// at initial source sample rate
|
|
uint32_t mNotificationsPerBufferReq;
|
|
// requested number of notifications per buffer,
|
|
// currently only used for fast tracks with
|
|
// default track buffer size
|
|
|
|
uint32_t mNotificationFramesAct; // actual number of frames between each
|
|
// notification callback,
|
|
// at initial source sample rate
|
|
bool mRefreshRemaining; // processAudioBuffer() should refresh
|
|
// mRemainingFrames and mRetryOnPartialBuffer
|
|
|
|
// used for static track cbf and restoration
|
|
int32_t mLoopCount; // last setLoop loopCount; zero means disabled
|
|
uint32_t mLoopStart; // last setLoop loopStart
|
|
uint32_t mLoopEnd; // last setLoop loopEnd
|
|
int32_t mLoopCountNotified; // the last loopCount notified by callback.
|
|
// mLoopCountNotified counts down, matching
|
|
// the remaining loop count for static track
|
|
// playback.
|
|
|
|
// These are private to processAudioBuffer(), and are not protected by a lock
|
|
uint32_t mRemainingFrames; // number of frames to request in obtainBuffer()
|
|
bool mRetryOnPartialBuffer; // sleep and retry after partial obtainBuffer()
|
|
uint32_t mObservedSequence; // last observed value of mSequence
|
|
|
|
Modulo<uint32_t> mMarkerPosition; // in wrapping (overflow) frame units
|
|
bool mMarkerReached;
|
|
Modulo<uint32_t> mNewPosition; // in frames
|
|
uint32_t mUpdatePeriod; // in frames, zero means no EVENT_NEW_POS
|
|
|
|
Modulo<uint32_t> mServer; // in frames, last known mProxy->getPosition()
|
|
// which is count of frames consumed by server,
|
|
// reset by new IAudioTrack,
|
|
// whether it is reset by stop() is TBD
|
|
Modulo<uint32_t> mPosition; // in frames, like mServer except continues
|
|
// monotonically after new IAudioTrack,
|
|
// and could be easily widened to uint64_t
|
|
Modulo<uint32_t> mReleased; // count of frames released to server
|
|
// but not necessarily consumed by server,
|
|
// reset by stop() but continues monotonically
|
|
// after new IAudioTrack to restore mPosition,
|
|
// and could be easily widened to uint64_t
|
|
int64_t mStartUs; // the start time after flush or stop.
|
|
// only used for offloaded and direct tracks.
|
|
|
|
bool mPreviousTimestampValid;// true if mPreviousTimestamp is valid
|
|
bool mTimestampStartupGlitchReported; // reduce log spam
|
|
bool mRetrogradeMotionReported; // reduce log spam
|
|
AudioTimestamp mPreviousTimestamp; // used to detect retrograde motion
|
|
ExtendedTimestamp::Location mPreviousLocation; // location used for previous timestamp
|
|
|
|
uint32_t mUnderrunCountOffset; // updated when restoring tracks
|
|
|
|
int64_t mFramesWritten; // total frames written. reset to zero after
|
|
// the start() following stop(). It is not
|
|
// changed after restoring the track or
|
|
// after flush.
|
|
int64_t mFramesWrittenServerOffset; // An offset to server frames due to
|
|
// restoring AudioTrack, or stop/start.
|
|
|
|
audio_output_flags_t mFlags; // same as mOrigFlags, except for bits that may
|
|
// be denied by client or server, such as
|
|
// AUDIO_OUTPUT_FLAG_FAST. mLock must be
|
|
// held to read or write those bits reliably.
|
|
audio_output_flags_t mOrigFlags; // as specified in constructor or set(), const
|
|
|
|
bool mDoNotReconnect;
|
|
|
|
audio_session_t mSessionId;
|
|
int mAuxEffectId;
|
|
|
|
mutable Mutex mLock;
|
|
|
|
int mPreviousPriority; // before start()
|
|
SchedPolicy mPreviousSchedulingGroup;
|
|
bool mAwaitBoost; // thread should wait for priority boost before running
|
|
|
|
// The proxy should only be referenced while a lock is held because the proxy isn't
|
|
// multi-thread safe, especially the SingleStateQueue part of the proxy.
|
|
// An exception is that a blocking ClientProxy::obtainBuffer() may be called without a lock,
|
|
// provided that the caller also holds an extra reference to the proxy and shared memory to keep
|
|
// them around in case they are replaced during the obtainBuffer().
|
|
sp<StaticAudioTrackClientProxy> mStaticProxy; // for type safety only
|
|
sp<AudioTrackClientProxy> mProxy; // primary owner of the memory
|
|
|
|
bool mInUnderrun; // whether track is currently in underrun state
|
|
uint32_t mPausedPosition;
|
|
|
|
// For Device Selection API
|
|
// a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
|
|
audio_port_handle_t mSelectedDeviceId;
|
|
bool mTrackOffloaded;
|
|
bool mPlaybackRateSet;
|
|
|
|
private:
|
|
class DeathNotifier : public IBinder::DeathRecipient {
|
|
public:
|
|
DeathNotifier(AudioTrack* audioTrack) : mAudioTrack(audioTrack) { }
|
|
protected:
|
|
virtual void binderDied(const wp<IBinder>& who);
|
|
private:
|
|
const wp<AudioTrack> mAudioTrack;
|
|
};
|
|
|
|
sp<DeathNotifier> mDeathNotifier;
|
|
uint32_t mSequence; // incremented for each new IAudioTrack attempt
|
|
int mClientUid;
|
|
pid_t mClientPid;
|
|
|
|
sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
|
|
friend struct ExtendedMediaUtils;
|
|
};
|
|
|
|
}; // namespace android
|
|
|
|
#endif // ANDROID_AUDIOTRACK_H
|