/*
 * 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;

// ----------------------------------------------------------------------------

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();

    /* 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
     */
private:
            audio_io_handle_t    getOutput() const;
public:

    /* 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;

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

}; // namespace android

#endif // ANDROID_AUDIOTRACK_H
