| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2007 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #ifndef ANDROID_AUDIOTRACK_H | 
|  | 18 | #define ANDROID_AUDIOTRACK_H | 
|  | 19 |  | 
| Glenn Kasten | a636433 | 2012-04-19 09:35:04 -0700 | [diff] [blame] | 20 | #include <cutils/sched_policy.h> | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 21 | #include <media/AudioSystem.h> | 
| Glenn Kasten | ce70374 | 2013-07-19 16:33:58 -0700 | [diff] [blame] | 22 | #include <media/AudioTimestamp.h> | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 23 | #include <media/IAudioTrack.h> | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 24 | #include <utils/threads.h> | 
|  | 25 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 26 | namespace android { | 
|  | 27 |  | 
|  | 28 | // ---------------------------------------------------------------------------- | 
|  | 29 |  | 
| Glenn Kasten | 01d3acb | 2014-02-06 08:24:07 -0800 | [diff] [blame] | 30 | struct audio_track_cblk_t; | 
| Glenn Kasten | e3aa659 | 2012-12-04 12:22:46 -0800 | [diff] [blame] | 31 | class AudioTrackClientProxy; | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 32 | class StaticAudioTrackClientProxy; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 33 |  | 
|  | 34 | // ---------------------------------------------------------------------------- | 
|  | 35 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 36 | class AudioTrack : public RefBase | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 37 | { | 
|  | 38 | public: | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 39 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 40 | /* Events used by AudioTrack callback function (callback_t). | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 41 | * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 42 | */ | 
|  | 43 | enum event_type { | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 44 | EVENT_MORE_DATA = 0,        // Request to write more data to buffer. | 
|  | 45 | // If this event is delivered but the callback handler | 
|  | 46 | // does not want to write more data, the handler must explicitly | 
|  | 47 | // ignore the event by setting frameCount to zero. | 
|  | 48 | EVENT_UNDERRUN = 1,         // Buffer underrun occurred. | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 49 | EVENT_LOOP_END = 2,         // Sample loop end was reached; playback restarted from | 
|  | 50 | // loop start if loop count was not 0. | 
|  | 51 | EVENT_MARKER = 3,           // Playback head is at the specified marker position | 
|  | 52 | // (See setMarkerPosition()). | 
|  | 53 | EVENT_NEW_POS = 4,          // Playback head is at a new position | 
|  | 54 | // (See setPositionUpdatePeriod()). | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 55 | EVENT_BUFFER_END = 5,       // Playback head is at the end of the buffer. | 
|  | 56 | // Not currently used by android.media.AudioTrack. | 
|  | 57 | EVENT_NEW_IAUDIOTRACK = 6,  // IAudioTrack was re-created, either due to re-routing and | 
|  | 58 | // voluntary invalidation by mediaserver, or mediaserver crash. | 
| Richard Fitzgerald | ad3af33 | 2013-03-25 16:54:37 +0000 | [diff] [blame] | 59 | EVENT_STREAM_END = 7,       // Sent after all the buffers queued in AF and HW are played | 
|  | 60 | // back (after stop is called) | 
| Glenn Kasten | ce70374 | 2013-07-19 16:33:58 -0700 | [diff] [blame] | 61 | EVENT_NEW_TIMESTAMP = 8,    // Delivered periodically and when there's a significant change | 
|  | 62 | // in the mapping from frame position to presentation time. | 
|  | 63 | // See AudioTimestamp for the information included with event. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 64 | }; | 
|  | 65 |  | 
| Glenn Kasten | 3f02be2 | 2015-03-09 11:59:04 -0700 | [diff] [blame^] | 66 | /* Client should declare a Buffer and pass the address to obtainBuffer() | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 67 | * and releaseBuffer().  See also callback_t for EVENT_MORE_DATA. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 68 | */ | 
|  | 69 |  | 
|  | 70 | class Buffer | 
|  | 71 | { | 
|  | 72 | public: | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 73 | // FIXME use m prefix | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 74 | size_t      frameCount;   // number of sample frames corresponding to size; | 
| Glenn Kasten | 3f02be2 | 2015-03-09 11:59:04 -0700 | [diff] [blame^] | 75 | // on input to obtainBuffer() it is the number of frames desired, | 
|  | 76 | // on output from obtainBuffer() it is the number of available | 
|  | 77 | //    [empty slots for] frames to be filled | 
|  | 78 | // on input to releaseBuffer() it is currently ignored | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 79 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 80 | size_t      size;         // input/output in bytes == frameCount * frameSize | 
| Glenn Kasten | 3f02be2 | 2015-03-09 11:59:04 -0700 | [diff] [blame^] | 81 | // on input to obtainBuffer() it is ignored | 
|  | 82 | // on output from obtainBuffer() it is the number of available | 
|  | 83 | //    [empty slots for] bytes to be filled, | 
|  | 84 | //    which is frameCount * frameSize | 
|  | 85 | // on input to releaseBuffer() it is the number of bytes to | 
|  | 86 | //    release | 
|  | 87 | // FIXME This is redundant with respect to frameCount.  Consider | 
|  | 88 | //    removing size and making frameCount the primary field. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 89 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 90 | union { | 
|  | 91 | void*       raw; | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 92 | short*      i16;      // signed 16-bit | 
|  | 93 | int8_t*     i8;       // unsigned 8-bit, offset by 0x80 | 
| Glenn Kasten | 2301acc | 2014-01-17 10:21:00 -0800 | [diff] [blame] | 94 | };                        // input: unused, output: pointer to buffer | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 95 | }; | 
|  | 96 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 97 | /* As a convenience, if a callback is supplied, a handler thread | 
|  | 98 | * is automatically created with the appropriate priority. This thread | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 99 | * invokes the callback when a new buffer becomes available or various conditions occur. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 100 | * Parameters: | 
|  | 101 | * | 
|  | 102 | * event:   type of event notified (see enum AudioTrack::event_type). | 
|  | 103 | * user:    Pointer to context for use by the callback receiver. | 
|  | 104 | * info:    Pointer to optional parameter according to event type: | 
|  | 105 | *          - EVENT_MORE_DATA: pointer to AudioTrack::Buffer struct. The callback must not write | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 106 | *            more bytes than indicated by 'size' field and update 'size' if fewer bytes are | 
|  | 107 | *            written. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 108 | *          - EVENT_UNDERRUN: unused. | 
|  | 109 | *          - EVENT_LOOP_END: pointer to an int indicating the number of loops remaining. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 110 | *          - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames. | 
|  | 111 | *          - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 112 | *          - EVENT_BUFFER_END: unused. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 113 | *          - EVENT_NEW_IAUDIOTRACK: unused. | 
| Glenn Kasten | ce70374 | 2013-07-19 16:33:58 -0700 | [diff] [blame] | 114 | *          - EVENT_STREAM_END: unused. | 
|  | 115 | *          - EVENT_NEW_TIMESTAMP: pointer to const AudioTimestamp. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 116 | */ | 
|  | 117 |  | 
| Glenn Kasten | d217a8c | 2011-06-01 15:20:35 -0700 | [diff] [blame] | 118 | typedef void (*callback_t)(int event, void* user, void *info); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 119 |  | 
| Chia-chi Yeh | 33005a9 | 2010-06-16 06:33:13 +0800 | [diff] [blame] | 120 | /* Returns the minimum frame count required for the successful creation of | 
|  | 121 | * an AudioTrack object. | 
|  | 122 | * Returned status (from utils/Errors.h) can be: | 
|  | 123 | *  - NO_ERROR: successful operation | 
|  | 124 | *  - NO_INIT: audio server or audio hardware not initialized | 
| Glenn Kasten | 6ca126d | 2013-07-31 12:25:00 -0700 | [diff] [blame] | 125 | *  - BAD_VALUE: unsupported configuration | 
| Glenn Kasten | 66a0467 | 2014-01-08 08:53:44 -0800 | [diff] [blame] | 126 | * frameCount is guaranteed to be non-zero if status is NO_ERROR, | 
|  | 127 | * and is undefined otherwise. | 
| Chia-chi Yeh | 33005a9 | 2010-06-16 06:33:13 +0800 | [diff] [blame] | 128 | */ | 
|  | 129 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 130 | static status_t getMinFrameCount(size_t* frameCount, | 
|  | 131 | audio_stream_type_t streamType, | 
|  | 132 | uint32_t sampleRate); | 
|  | 133 |  | 
|  | 134 | /* How data is transferred to AudioTrack | 
|  | 135 | */ | 
|  | 136 | enum transfer_type { | 
|  | 137 | TRANSFER_DEFAULT,   // not specified explicitly; determine from the other parameters | 
|  | 138 | TRANSFER_CALLBACK,  // callback EVENT_MORE_DATA | 
|  | 139 | TRANSFER_OBTAIN,    // FIXME deprecated: call obtainBuffer() and releaseBuffer() | 
|  | 140 | TRANSFER_SYNC,      // synchronous write() | 
|  | 141 | TRANSFER_SHARED,    // shared memory | 
|  | 142 | }; | 
| Chia-chi Yeh | 33005a9 | 2010-06-16 06:33:13 +0800 | [diff] [blame] | 143 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 144 | /* Constructs an uninitialized AudioTrack. No connection with | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 145 | * AudioFlinger takes place.  Use set() after this. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 146 | */ | 
|  | 147 | AudioTrack(); | 
|  | 148 |  | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 149 | /* Creates an AudioTrack object and registers it with AudioFlinger. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 150 | * Once created, the track needs to be started before it can be used. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 151 | * Unspecified values are set to appropriate default values. | 
|  | 152 | * With this constructor, the track is configured for streaming mode. | 
|  | 153 | * Data to be rendered is supplied by write() or by the callback EVENT_MORE_DATA. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 154 | * Intermixing a combination of write() and non-ignored EVENT_MORE_DATA is not allowed. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 155 | * | 
|  | 156 | * Parameters: | 
|  | 157 | * | 
|  | 158 | * streamType:         Select the type of audio stream this track is attached to | 
| Dima Zavin | fce7a47 | 2011-04-19 22:30:36 -0700 | [diff] [blame] | 159 | *                     (e.g. AUDIO_STREAM_MUSIC). | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 160 | * sampleRate:         Data source sampling rate in Hz. | 
| Andy Hung | abdb990 | 2015-01-12 15:08:22 -0800 | [diff] [blame] | 161 | * format:             Audio format. For mixed tracks, any PCM format supported by server is OK. | 
|  | 162 | *                     For direct and offloaded tracks, the possible format(s) depends on the | 
|  | 163 | *                     output sink. | 
| Glenn Kasten | 2b2165c | 2014-01-13 08:53:36 -0800 | [diff] [blame] | 164 | * channelMask:        Channel mask, such that audio_is_output_channel(channelMask) is true. | 
| Eric Laurent | d8d6185 | 2012-03-05 17:06:40 -0800 | [diff] [blame] | 165 | * frameCount:         Minimum size of track PCM buffer in frames. This defines the | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 166 | *                     application's contribution to the | 
| Eric Laurent | d8d6185 | 2012-03-05 17:06:40 -0800 | [diff] [blame] | 167 | *                     latency of the track. The actual size selected by the AudioTrack could be | 
|  | 168 | *                     larger if the requested size is not compatible with current audio HAL | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 169 | *                     configuration.  Zero means to use a default value. | 
| Eric Laurent | 0ca3cf9 | 2012-04-18 09:24:29 -0700 | [diff] [blame] | 170 | * flags:              See comments on audio_output_flags_t in <system/audio.h>. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 171 | * cbf:                Callback function. If not null, this function is called periodically | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 172 | *                     to provide new data and inform of marker, position updates, etc. | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 173 | * user:               Context for use by the callback receiver. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 174 | * notificationFrames: The callback function is called each time notificationFrames PCM | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 175 | *                     frames have been consumed from track input buffer. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 176 | *                     This is expressed in units of frames at the initial source sample rate. | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 177 | * sessionId:          Specific session ID, or zero to use default. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 178 | * transferType:       How data is transferred to AudioTrack. | 
|  | 179 | * threadCanCallJava:  Not present in parameter list, and so is fixed at false. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 180 | */ | 
|  | 181 |  | 
| Glenn Kasten | fff6d71 | 2012-01-12 16:38:12 -0800 | [diff] [blame] | 182 | AudioTrack( audio_stream_type_t streamType, | 
| Glenn Kasten | 7437322 | 2013-08-02 15:51:35 -0700 | [diff] [blame] | 183 | uint32_t sampleRate, | 
|  | 184 | audio_format_t format, | 
|  | 185 | audio_channel_mask_t, | 
| Glenn Kasten | bce50bf | 2014-02-27 15:29:51 -0800 | [diff] [blame] | 186 | size_t frameCount    = 0, | 
| Eric Laurent | 0ca3cf9 | 2012-04-18 09:24:29 -0700 | [diff] [blame] | 187 | audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, | 
| Glenn Kasten | a0d6833 | 2012-01-27 16:47:15 -0800 | [diff] [blame] | 188 | callback_t cbf       = NULL, | 
|  | 189 | void* user           = NULL, | 
| Glenn Kasten | 838b3d8 | 2014-02-27 15:30:41 -0800 | [diff] [blame] | 190 | uint32_t notificationFrames = 0, | 
| Glenn Kasten | aea7ea0 | 2013-06-26 09:25:47 -0700 | [diff] [blame] | 191 | int sessionId        = AUDIO_SESSION_ALLOCATE, | 
| Richard Fitzgerald | ad3af33 | 2013-03-25 16:54:37 +0000 | [diff] [blame] | 192 | transfer_type transferType = TRANSFER_DEFAULT, | 
| Marco Nelissen | 462fd2f | 2013-01-14 14:12:05 -0800 | [diff] [blame] | 193 | const audio_offload_info_t *offloadInfo = NULL, | 
| Marco Nelissen | d457c97 | 2014-02-11 08:47:07 -0800 | [diff] [blame] | 194 | int uid = -1, | 
| Jean-Michel Trivi | d9d7fa0 | 2014-06-24 08:01:46 -0700 | [diff] [blame] | 195 | pid_t pid = -1, | 
|  | 196 | const audio_attributes_t* pAttributes = NULL); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 197 |  | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 198 | /* Creates an audio track and registers it with AudioFlinger. | 
|  | 199 | * With this constructor, the track is configured for static buffer mode. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 200 | * Data to be rendered is passed in a shared memory buffer | 
|  | 201 | * identified by the argument sharedBuffer, which must be non-0. | 
|  | 202 | * The memory should be initialized to the desired data before calling start(). | 
| Glenn Kasten | 4bae364 | 2012-11-30 13:41:12 -0800 | [diff] [blame] | 203 | * The write() method is not supported in this case. | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 204 | * It is recommended to pass a callback function to be notified of playback end by an | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 205 | * EVENT_UNDERRUN event. | 
|  | 206 | */ | 
|  | 207 |  | 
| Glenn Kasten | fff6d71 | 2012-01-12 16:38:12 -0800 | [diff] [blame] | 208 | AudioTrack( audio_stream_type_t streamType, | 
| Glenn Kasten | 7437322 | 2013-08-02 15:51:35 -0700 | [diff] [blame] | 209 | uint32_t sampleRate, | 
|  | 210 | audio_format_t format, | 
|  | 211 | audio_channel_mask_t channelMask, | 
|  | 212 | const sp<IMemory>& sharedBuffer, | 
| Eric Laurent | 0ca3cf9 | 2012-04-18 09:24:29 -0700 | [diff] [blame] | 213 | audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, | 
| Glenn Kasten | a0d6833 | 2012-01-27 16:47:15 -0800 | [diff] [blame] | 214 | callback_t cbf      = NULL, | 
|  | 215 | void* user          = NULL, | 
| Glenn Kasten | 838b3d8 | 2014-02-27 15:30:41 -0800 | [diff] [blame] | 216 | uint32_t notificationFrames = 0, | 
| Glenn Kasten | aea7ea0 | 2013-06-26 09:25:47 -0700 | [diff] [blame] | 217 | int sessionId       = AUDIO_SESSION_ALLOCATE, | 
| Richard Fitzgerald | ad3af33 | 2013-03-25 16:54:37 +0000 | [diff] [blame] | 218 | transfer_type transferType = TRANSFER_DEFAULT, | 
| Marco Nelissen | 462fd2f | 2013-01-14 14:12:05 -0800 | [diff] [blame] | 219 | const audio_offload_info_t *offloadInfo = NULL, | 
| Marco Nelissen | d457c97 | 2014-02-11 08:47:07 -0800 | [diff] [blame] | 220 | int uid = -1, | 
| Jean-Michel Trivi | d9d7fa0 | 2014-06-24 08:01:46 -0700 | [diff] [blame] | 221 | pid_t pid = -1, | 
|  | 222 | const audio_attributes_t* pAttributes = NULL); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 223 |  | 
|  | 224 | /* Terminates the AudioTrack and unregisters it from AudioFlinger. | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 225 | * Also destroys all resources associated with the AudioTrack. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 226 | */ | 
| Glenn Kasten | 2799d74 | 2013-05-30 14:33:29 -0700 | [diff] [blame] | 227 | protected: | 
|  | 228 | virtual ~AudioTrack(); | 
|  | 229 | public: | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 230 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 231 | /* Initialize an AudioTrack that was created using the AudioTrack() constructor. | 
|  | 232 | * Don't call set() more than once, or after the AudioTrack() constructors that take parameters. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 233 | * Returned status (from utils/Errors.h) can be: | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 234 | *  - NO_ERROR: successful initialization | 
|  | 235 | *  - INVALID_OPERATION: AudioTrack is already initialized | 
| Glenn Kasten | 28b76b3 | 2012-07-03 17:24:41 -0700 | [diff] [blame] | 236 | *  - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...) | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 237 | *  - NO_INIT: audio server or audio hardware not initialized | 
| Glenn Kasten | 53cec22 | 2013-08-29 09:01:02 -0700 | [diff] [blame] | 238 | * If status is not equal to NO_ERROR, don't call any other APIs on this AudioTrack. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 239 | * If sharedBuffer is non-0, the frameCount parameter is ignored and | 
|  | 240 | * replaced by the shared buffer's total allocated size in frame units. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 241 | * | 
|  | 242 | * Parameters not listed in the AudioTrack constructors above: | 
|  | 243 | * | 
|  | 244 | * threadCanCallJava:  Whether callbacks are made from an attached thread and thus can call JNI. | 
| Eric Laurent | e83b55d | 2014-11-14 10:06:21 -0800 | [diff] [blame] | 245 | * | 
|  | 246 | * Internal state post condition: | 
|  | 247 | *      (mStreamType == AUDIO_STREAM_DEFAULT) implies this AudioTrack has valid attributes | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 248 | */ | 
| Glenn Kasten | 7437322 | 2013-08-02 15:51:35 -0700 | [diff] [blame] | 249 | status_t    set(audio_stream_type_t streamType, | 
|  | 250 | uint32_t sampleRate, | 
|  | 251 | audio_format_t format, | 
|  | 252 | audio_channel_mask_t channelMask, | 
| Glenn Kasten | bce50bf | 2014-02-27 15:29:51 -0800 | [diff] [blame] | 253 | size_t frameCount   = 0, | 
| Eric Laurent | 0ca3cf9 | 2012-04-18 09:24:29 -0700 | [diff] [blame] | 254 | audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, | 
| Glenn Kasten | a0d6833 | 2012-01-27 16:47:15 -0800 | [diff] [blame] | 255 | callback_t cbf      = NULL, | 
|  | 256 | void* user          = NULL, | 
| Glenn Kasten | 838b3d8 | 2014-02-27 15:30:41 -0800 | [diff] [blame] | 257 | uint32_t notificationFrames = 0, | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 258 | const sp<IMemory>& sharedBuffer = 0, | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 259 | bool threadCanCallJava = false, | 
| Glenn Kasten | aea7ea0 | 2013-06-26 09:25:47 -0700 | [diff] [blame] | 260 | int sessionId       = AUDIO_SESSION_ALLOCATE, | 
| Richard Fitzgerald | ad3af33 | 2013-03-25 16:54:37 +0000 | [diff] [blame] | 261 | transfer_type transferType = TRANSFER_DEFAULT, | 
| Marco Nelissen | 462fd2f | 2013-01-14 14:12:05 -0800 | [diff] [blame] | 262 | const audio_offload_info_t *offloadInfo = NULL, | 
| Marco Nelissen | d457c97 | 2014-02-11 08:47:07 -0800 | [diff] [blame] | 263 | int uid = -1, | 
| Jean-Michel Trivi | faabb51 | 2014-06-11 16:55:06 -0700 | [diff] [blame] | 264 | pid_t pid = -1, | 
| Jean-Michel Trivi | d9d7fa0 | 2014-06-24 08:01:46 -0700 | [diff] [blame] | 265 | const audio_attributes_t* pAttributes = NULL); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 266 |  | 
| Glenn Kasten | 53cec22 | 2013-08-29 09:01:02 -0700 | [diff] [blame] | 267 | /* Result of constructing the AudioTrack. This must be checked for successful initialization | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 268 | * before using any AudioTrack API (except for set()), because using | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 269 | * an uninitialized AudioTrack produces undefined results. | 
|  | 270 | * See set() method above for possible return codes. | 
|  | 271 | */ | 
| Glenn Kasten | 01437b7 | 2012-11-29 07:32:49 -0800 | [diff] [blame] | 272 | status_t    initCheck() const   { return mStatus; } | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 273 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 274 | /* Returns this track's estimated latency in milliseconds. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 275 | * This includes the latency due to AudioTrack buffer size, AudioMixer (if any) | 
|  | 276 | * and audio hardware driver. | 
|  | 277 | */ | 
| Glenn Kasten | c9b2e20 | 2013-02-26 11:32:32 -0800 | [diff] [blame] | 278 | uint32_t    latency() const     { return mLatency; } | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 279 |  | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 280 | /* getters, see constructors and set() */ | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 281 |  | 
| Eric Laurent | e83b55d | 2014-11-14 10:06:21 -0800 | [diff] [blame] | 282 | audio_stream_type_t streamType() const; | 
| Glenn Kasten | 01437b7 | 2012-11-29 07:32:49 -0800 | [diff] [blame] | 283 | audio_format_t format() const   { return mFormat; } | 
| Glenn Kasten | b998065 | 2012-01-11 09:48:27 -0800 | [diff] [blame] | 284 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 285 | /* Return frame size in bytes, which for linear PCM is | 
|  | 286 | * channelCount * (bit depth per channel / 8). | 
| Glenn Kasten | b998065 | 2012-01-11 09:48:27 -0800 | [diff] [blame] | 287 | * channelCount is determined from channelMask, and bit depth comes from format. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 288 | * For non-linear formats, the frame size is typically 1 byte. | 
| Glenn Kasten | b998065 | 2012-01-11 09:48:27 -0800 | [diff] [blame] | 289 | */ | 
| Glenn Kasten | 01437b7 | 2012-11-29 07:32:49 -0800 | [diff] [blame] | 290 | size_t      frameSize() const   { return mFrameSize; } | 
|  | 291 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 292 | uint32_t    channelCount() const { return mChannelCount; } | 
| Glenn Kasten | bce50bf | 2014-02-27 15:29:51 -0800 | [diff] [blame] | 293 | size_t      frameCount() const  { return mFrameCount; } | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 294 |  | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 295 | /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */ | 
| Glenn Kasten | 01437b7 | 2012-11-29 07:32:49 -0800 | [diff] [blame] | 296 | sp<IMemory> sharedBuffer() const { return mSharedBuffer; } | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 297 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 298 | /* After it's created the track is not active. Call start() to | 
|  | 299 | * make it active. If set, the callback will start being called. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 300 | * If the track was previously paused, volume is ramped up over the first mix buffer. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 301 | */ | 
| Richard Fitzgerald | b1a270d | 2013-05-14 12:12:21 +0100 | [diff] [blame] | 302 | status_t        start(); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 303 |  | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 304 | /* Stop a track. | 
|  | 305 | * In static buffer mode, the track is stopped immediately. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 306 | * In streaming mode, the callback will cease being called.  Note that obtainBuffer() still | 
|  | 307 | * works and will fill up buffers until the pool is exhausted, and then will return WOULD_BLOCK. | 
|  | 308 | * In streaming mode the stop does not occur immediately: any data remaining in the buffer | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 309 | * is first drained, mixed, and output, and only then is the track marked as stopped. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 310 | */ | 
|  | 311 | void        stop(); | 
|  | 312 | bool        stopped() const; | 
|  | 313 |  | 
| Glenn Kasten | 4bae364 | 2012-11-30 13:41:12 -0800 | [diff] [blame] | 314 | /* Flush a stopped or paused track. All previously buffered data is discarded immediately. | 
|  | 315 | * This has the effect of draining the buffers without mixing or output. | 
|  | 316 | * Flush is intended for streaming mode, for example before switching to non-contiguous content. | 
|  | 317 | * This function is a no-op if the track is not stopped or paused, or uses a static buffer. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 318 | */ | 
|  | 319 | void        flush(); | 
|  | 320 |  | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 321 | /* Pause a track. After pause, the callback will cease being called and | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 322 | * obtainBuffer returns WOULD_BLOCK. Note that obtainBuffer() still works | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 323 | * and will fill up buffers until the pool is exhausted. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 324 | * Volume is ramped down over the next mix buffer following the pause request, | 
|  | 325 | * and then the track is marked as paused.  It can be resumed with ramp up by start(). | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 326 | */ | 
|  | 327 | void        pause(); | 
|  | 328 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 329 | /* Set volume for this track, mostly used for games' sound effects | 
|  | 330 | * left and right volumes. Levels must be >= 0.0 and <= 1.0. | 
| Glenn Kasten | b1c0993 | 2012-02-27 16:21:04 -0800 | [diff] [blame] | 331 | * This is the older API.  New applications should use setVolume(float) when possible. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 332 | */ | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 333 | status_t    setVolume(float left, float right); | 
| Glenn Kasten | b1c0993 | 2012-02-27 16:21:04 -0800 | [diff] [blame] | 334 |  | 
|  | 335 | /* Set volume for all channels.  This is the preferred API for new applications, | 
|  | 336 | * especially for multi-channel content. | 
|  | 337 | */ | 
|  | 338 | status_t    setVolume(float volume); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 339 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 340 | /* Set the send level for this track. An auxiliary effect should be attached | 
|  | 341 | * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0. | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 342 | */ | 
| Eric Laurent | 2beeb50 | 2010-07-16 07:43:46 -0700 | [diff] [blame] | 343 | status_t    setAuxEffectSendLevel(float level); | 
| Glenn Kasten | a5224f3 | 2012-01-04 12:41:44 -0800 | [diff] [blame] | 344 | void        getAuxEffectSendLevel(float* level) const; | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 345 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 346 | /* Set source sample rate for this track in Hz, mostly used for games' sound effects | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 347 | */ | 
| Glenn Kasten | 3b16c76 | 2012-11-14 08:44:39 -0800 | [diff] [blame] | 348 | status_t    setSampleRate(uint32_t sampleRate); | 
|  | 349 |  | 
| Glenn Kasten | 2b2165c | 2014-01-13 08:53:36 -0800 | [diff] [blame] | 350 | /* Return current source sample rate in Hz */ | 
| Glenn Kasten | a5224f3 | 2012-01-04 12:41:44 -0800 | [diff] [blame] | 351 | uint32_t    getSampleRate() const; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 352 |  | 
|  | 353 | /* Enables looping and sets the start and end points of looping. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 354 | * Only supported for static buffer mode. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 355 | * | 
|  | 356 | * Parameters: | 
|  | 357 | * | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 358 | * loopStart:   loop start in frames relative to start of buffer. | 
|  | 359 | * loopEnd:     loop end in frames relative to start of buffer. | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 360 | * loopCount:   number of loops to execute. Calling setLoop() with loopCount == 0 cancels any | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 361 | *              pending or active loop. loopCount == -1 means infinite looping. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 362 | * | 
|  | 363 | * For proper operation the following condition must be respected: | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 364 | *      loopCount != 0 implies 0 <= loopStart < loopEnd <= frameCount(). | 
|  | 365 | * | 
|  | 366 | * If the loop period (loopEnd - loopStart) is too small for the implementation to support, | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 367 | * setLoop() will return BAD_VALUE.  loopCount must be >= -1. | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 368 | * | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 369 | */ | 
|  | 370 | status_t    setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 371 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 372 | /* Sets marker position. When playback reaches the number of frames specified, a callback with | 
|  | 373 | * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 374 | * notification callback.  To set a marker at a position which would compute as 0, | 
| Glenn Kasten | 2b2165c | 2014-01-13 08:53:36 -0800 | [diff] [blame] | 375 | * a workaround is to set the marker at a nearby position such as ~0 or 1. | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 376 | * If the AudioTrack has been opened with no callback function associated, the operation will | 
|  | 377 | * fail. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 378 | * | 
|  | 379 | * Parameters: | 
|  | 380 | * | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 381 | * marker:   marker position expressed in wrapping (overflow) frame units, | 
|  | 382 | *           like the return value of getPosition(). | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 383 | * | 
|  | 384 | * Returned status (from utils/Errors.h) can be: | 
|  | 385 | *  - NO_ERROR: successful operation | 
|  | 386 | *  - INVALID_OPERATION: the AudioTrack has no callback installed. | 
|  | 387 | */ | 
|  | 388 | status_t    setMarkerPosition(uint32_t marker); | 
| Glenn Kasten | a5224f3 | 2012-01-04 12:41:44 -0800 | [diff] [blame] | 389 | status_t    getMarkerPosition(uint32_t *marker) const; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 390 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 391 | /* Sets position update period. Every time the number of frames specified has been played, | 
|  | 392 | * a callback with event type EVENT_NEW_POS is called. | 
|  | 393 | * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification | 
|  | 394 | * callback. | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 395 | * If the AudioTrack has been opened with no callback function associated, the operation will | 
|  | 396 | * fail. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 397 | * Extremely small values may be rounded up to a value the implementation can support. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 398 | * | 
|  | 399 | * Parameters: | 
|  | 400 | * | 
|  | 401 | * updatePeriod:  position update notification period expressed in frames. | 
|  | 402 | * | 
|  | 403 | * Returned status (from utils/Errors.h) can be: | 
|  | 404 | *  - NO_ERROR: successful operation | 
|  | 405 | *  - INVALID_OPERATION: the AudioTrack has no callback installed. | 
|  | 406 | */ | 
|  | 407 | status_t    setPositionUpdatePeriod(uint32_t updatePeriod); | 
| Glenn Kasten | a5224f3 | 2012-01-04 12:41:44 -0800 | [diff] [blame] | 408 | status_t    getPositionUpdatePeriod(uint32_t *updatePeriod) const; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 409 |  | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 410 | /* Sets playback head position. | 
|  | 411 | * Only supported for static buffer mode. | 
|  | 412 | * | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 413 | * Parameters: | 
|  | 414 | * | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 415 | * position:  New playback head position in frames relative to start of buffer. | 
|  | 416 | *            0 <= position <= frameCount().  Note that end of buffer is permitted, | 
|  | 417 | *            but will result in an immediate underrun if started. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 418 | * | 
|  | 419 | * Returned status (from utils/Errors.h) can be: | 
|  | 420 | *  - NO_ERROR: successful operation | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 421 | *  - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode. | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 422 | *  - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack | 
|  | 423 | *               buffer | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 424 | */ | 
|  | 425 | status_t    setPosition(uint32_t position); | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 426 |  | 
|  | 427 | /* Return the total number of frames played since playback start. | 
|  | 428 | * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz. | 
|  | 429 | * It is reset to zero by flush(), reload(), and stop(). | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 430 | * | 
|  | 431 | * Parameters: | 
|  | 432 | * | 
|  | 433 | *  position:  Address where to return play head position. | 
|  | 434 | * | 
|  | 435 | * Returned status (from utils/Errors.h) can be: | 
|  | 436 | *  - NO_ERROR: successful operation | 
|  | 437 | *  - BAD_VALUE:  position is NULL | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 438 | */ | 
| Glenn Kasten | 200092b | 2014-08-15 15:13:30 -0700 | [diff] [blame] | 439 | status_t    getPosition(uint32_t *position); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 440 |  | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 441 | /* For static buffer mode only, this returns the current playback position in frames | 
| Glenn Kasten | 02de892 | 2013-07-31 12:30:12 -0700 | [diff] [blame] | 442 | * relative to start of buffer.  It is analogous to the position units used by | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 443 | * setLoop() and setPosition().  After underrun, the position will be at end of buffer. | 
|  | 444 | */ | 
|  | 445 | status_t    getBufferPosition(uint32_t *position); | 
| Glenn Kasten | 9c6745f | 2012-11-30 13:35:29 -0800 | [diff] [blame] | 446 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 447 | /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 448 | * rewriting the buffer before restarting playback after a stop. | 
|  | 449 | * This method must be called with the AudioTrack in paused or stopped state. | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 450 | * Not allowed in streaming mode. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 451 | * | 
|  | 452 | * Returned status (from utils/Errors.h) can be: | 
|  | 453 | *  - NO_ERROR: successful operation | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 454 | *  - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 455 | */ | 
|  | 456 | status_t    reload(); | 
|  | 457 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 458 | /* Returns a handle on the audio output used by this AudioTrack. | 
| Eric Laurent | c2f1f07 | 2009-07-17 12:17:14 -0700 | [diff] [blame] | 459 | * | 
|  | 460 | * Parameters: | 
|  | 461 | *  none. | 
|  | 462 | * | 
|  | 463 | * Returned value: | 
| Glenn Kasten | 142f519 | 2014-03-25 17:44:59 -0700 | [diff] [blame] | 464 | *  handle on audio hardware output, or AUDIO_IO_HANDLE_NONE if the | 
|  | 465 | *  track needed to be re-created but that failed | 
| Eric Laurent | c2f1f07 | 2009-07-17 12:17:14 -0700 | [diff] [blame] | 466 | */ | 
| Glenn Kasten | 38e905b | 2014-01-13 10:21:48 -0800 | [diff] [blame] | 467 | audio_io_handle_t    getOutput() const; | 
| Eric Laurent | c2f1f07 | 2009-07-17 12:17:14 -0700 | [diff] [blame] | 468 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 469 | /* Returns the unique session ID associated with this track. | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 470 | * | 
|  | 471 | * Parameters: | 
|  | 472 | *  none. | 
|  | 473 | * | 
|  | 474 | * Returned value: | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 475 | *  AudioTrack session ID. | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 476 | */ | 
| Glenn Kasten | 01437b7 | 2012-11-29 07:32:49 -0800 | [diff] [blame] | 477 | int    getSessionId() const { return mSessionId; } | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 478 |  | 
| Glenn Kasten | 362c4e6 | 2011-12-14 10:28:06 -0800 | [diff] [blame] | 479 | /* Attach track auxiliary output to specified effect. Use effectId = 0 | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 480 | * to detach track from effect. | 
|  | 481 | * | 
|  | 482 | * Parameters: | 
|  | 483 | * | 
|  | 484 | * effectId:  effectId obtained from AudioEffect::id(). | 
|  | 485 | * | 
|  | 486 | * Returned status (from utils/Errors.h) can be: | 
|  | 487 | *  - NO_ERROR: successful operation | 
|  | 488 | *  - INVALID_OPERATION: the effect is not an auxiliary effect. | 
|  | 489 | *  - BAD_VALUE: The specified effect ID is invalid | 
|  | 490 | */ | 
|  | 491 | status_t    attachAuxEffect(int effectId); | 
|  | 492 |  | 
| Glenn Kasten | 3f02be2 | 2015-03-09 11:59:04 -0700 | [diff] [blame^] | 493 | /* Public API for TRANSFER_OBTAIN mode. | 
|  | 494 | * Obtains a buffer of up to "audioBuffer->frameCount" empty slots for frames. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 495 | * After filling these slots with data, the caller should release them with releaseBuffer(). | 
|  | 496 | * If the track buffer is not full, obtainBuffer() returns as many contiguous | 
|  | 497 | * [empty slots for] frames as are available immediately. | 
|  | 498 | * If the track buffer is full and track is stopped, obtainBuffer() returns WOULD_BLOCK | 
|  | 499 | * regardless of the value of waitCount. | 
|  | 500 | * If the track buffer is full and track is not stopped, obtainBuffer() blocks with a | 
|  | 501 | * maximum timeout based on waitCount; see chart below. | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 502 | * Buffers will be returned until the pool | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 503 | * is exhausted, at which point obtainBuffer() will either block | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 504 | * or return WOULD_BLOCK depending on the value of the "waitCount" | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 505 | * parameter. | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 506 | * | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 507 | * obtainBuffer() and releaseBuffer() are deprecated for direct use by applications, | 
|  | 508 | * which should use write() or callback EVENT_MORE_DATA instead. | 
|  | 509 | * | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 510 | * Interpretation of waitCount: | 
|  | 511 | *  +n  limits wait time to n * WAIT_PERIOD_MS, | 
|  | 512 | *  -1  causes an (almost) infinite wait time, | 
|  | 513 | *   0  non-blocking. | 
| Glenn Kasten | 05d4999 | 2012-11-06 14:25:20 -0800 | [diff] [blame] | 514 | * | 
|  | 515 | * Buffer fields | 
|  | 516 | * On entry: | 
| Glenn Kasten | 3f02be2 | 2015-03-09 11:59:04 -0700 | [diff] [blame^] | 517 | *  frameCount  number of [empty slots for] frames requested | 
|  | 518 | *  size        ignored | 
|  | 519 | *  raw         ignored | 
| Glenn Kasten | 05d4999 | 2012-11-06 14:25:20 -0800 | [diff] [blame] | 520 | * After error return: | 
|  | 521 | *  frameCount  0 | 
|  | 522 | *  size        0 | 
| Glenn Kasten | 22eb4e2 | 2012-11-07 14:03:00 -0800 | [diff] [blame] | 523 | *  raw         undefined | 
| Glenn Kasten | 05d4999 | 2012-11-06 14:25:20 -0800 | [diff] [blame] | 524 | * After successful return: | 
| Glenn Kasten | 3f02be2 | 2015-03-09 11:59:04 -0700 | [diff] [blame^] | 525 | *  frameCount  actual number of [empty slots for] frames available, <= number requested | 
| Glenn Kasten | 05d4999 | 2012-11-06 14:25:20 -0800 | [diff] [blame] | 526 | *  size        actual number of bytes available | 
|  | 527 | *  raw         pointer to the buffer | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 528 | */ | 
|  | 529 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 530 | /* FIXME Deprecated public API for TRANSFER_OBTAIN mode */ | 
|  | 531 | status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount) | 
|  | 532 | __attribute__((__deprecated__)); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 533 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 534 | private: | 
| Glenn Kasten | 02de892 | 2013-07-31 12:30:12 -0700 | [diff] [blame] | 535 | /* If nonContig is non-NULL, it is an output parameter that will be set to the number of | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 536 | * additional non-contiguous frames that are available immediately. | 
|  | 537 | * FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(), | 
|  | 538 | * in case the requested amount of frames is in two or more non-contiguous regions. | 
|  | 539 | * FIXME requested and elapsed are both relative times.  Consider changing to absolute time. | 
|  | 540 | */ | 
|  | 541 | status_t    obtainBuffer(Buffer* audioBuffer, const struct timespec *requested, | 
|  | 542 | struct timespec *elapsed = NULL, size_t *nonContig = NULL); | 
|  | 543 | public: | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 544 |  | 
| Glenn Kasten | 3f02be2 | 2015-03-09 11:59:04 -0700 | [diff] [blame^] | 545 | /* Public API for TRANSFER_OBTAIN mode. | 
|  | 546 | * Release a filled buffer of frames for AudioFlinger to process. | 
|  | 547 | * | 
|  | 548 | * Buffer fields: | 
|  | 549 | *  frameCount  currently ignored but recommend to set to actual number of frames filled | 
|  | 550 | *  size        actual number of bytes filled, must be multiple of frameSize | 
|  | 551 | *  raw         ignored | 
|  | 552 | * | 
|  | 553 | */ | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 554 | // FIXME make private when obtainBuffer() for TRANSFER_OBTAIN is removed | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 555 | void        releaseBuffer(Buffer* audioBuffer); | 
|  | 556 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 557 | /* As a convenience we provide a write() interface to the audio buffer. | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 558 | * Input parameter 'size' is in byte units. | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 559 | * This is implemented on top of obtainBuffer/releaseBuffer. For best | 
|  | 560 | * performance use callbacks. Returns actual number of bytes written >= 0, | 
|  | 561 | * or one of the following negative status codes: | 
| Glenn Kasten | 02de892 | 2013-07-31 12:30:12 -0700 | [diff] [blame] | 562 | *      INVALID_OPERATION   AudioTrack is configured for static buffer or streaming mode | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 563 | *      BAD_VALUE           size is invalid | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 564 | *      WOULD_BLOCK         when obtainBuffer() returns same, or | 
|  | 565 | *                          AudioTrack was stopped during the write | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 566 | *      or any other error code returned by IAudioTrack::start() or restoreTrack_l(). | 
| Jean-Michel Trivi | 720ad9d | 2014-02-04 11:00:59 -0800 | [diff] [blame] | 567 | * Default behavior is to only return until all data has been transferred. Set 'blocking' to | 
|  | 568 | * false for the method to return immediately without waiting to try multiple times to write | 
|  | 569 | * the full content of the buffer. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 570 | */ | 
| Jean-Michel Trivi | 720ad9d | 2014-02-04 11:00:59 -0800 | [diff] [blame] | 571 | ssize_t     write(const void* buffer, size_t size, bool blocking = true); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 572 |  | 
|  | 573 | /* | 
|  | 574 | * Dumps the state of an audio track. | 
|  | 575 | */ | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 576 | status_t    dump(int fd, const Vector<String16>& args) const; | 
|  | 577 |  | 
|  | 578 | /* | 
|  | 579 | * Return the total number of frames which AudioFlinger desired but were unavailable, | 
|  | 580 | * and thus which resulted in an underrun.  Reset to zero by stop(). | 
|  | 581 | */ | 
|  | 582 | uint32_t    getUnderrunFrames() const; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 583 |  | 
| Richard Fitzgerald | ad3af33 | 2013-03-25 16:54:37 +0000 | [diff] [blame] | 584 | /* Get the flags */ | 
| Glenn Kasten | 23a7545 | 2014-01-13 10:37:17 -0800 | [diff] [blame] | 585 | audio_output_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; } | 
| Richard Fitzgerald | ad3af33 | 2013-03-25 16:54:37 +0000 | [diff] [blame] | 586 |  | 
|  | 587 | /* Set parameters - only possible when using direct output */ | 
|  | 588 | status_t    setParameters(const String8& keyValuePairs); | 
|  | 589 |  | 
|  | 590 | /* Get parameters */ | 
|  | 591 | String8     getParameters(const String8& keys); | 
|  | 592 |  | 
| Glenn Kasten | ce70374 | 2013-07-19 16:33:58 -0700 | [diff] [blame] | 593 | /* Poll for a timestamp on demand. | 
|  | 594 | * Use if EVENT_NEW_TIMESTAMP is not delivered often enough for your needs, | 
|  | 595 | * or if you need to get the most recent timestamp outside of the event callback handler. | 
|  | 596 | * Caution: calling this method too often may be inefficient; | 
|  | 597 | * if you need a high resolution mapping between frame position and presentation time, | 
|  | 598 | * consider implementing that at application level, based on the low resolution timestamps. | 
| Andy Hung | 7f1bc8a | 2014-09-12 14:43:11 -0700 | [diff] [blame] | 599 | * Returns NO_ERROR    if timestamp is valid. | 
|  | 600 | *         WOULD_BLOCK if called in STOPPED or FLUSHED state, or if called immediately after | 
|  | 601 | *                     start/ACTIVE, when the number of frames consumed is less than the | 
|  | 602 | *                     overall hardware latency to physical output. In WOULD_BLOCK cases, | 
|  | 603 | *                     one might poll again, or use getPosition(), or use 0 position and | 
|  | 604 | *                     current time for the timestamp. | 
|  | 605 | *         INVALID_OPERATION  if called on a FastTrack, wrong state, or some other error. | 
|  | 606 | * | 
| Glenn Kasten | 200092b | 2014-08-15 15:13:30 -0700 | [diff] [blame] | 607 | * The timestamp parameter is undefined on return, if status is not NO_ERROR. | 
| Glenn Kasten | ce70374 | 2013-07-19 16:33:58 -0700 | [diff] [blame] | 608 | */ | 
|  | 609 | status_t    getTimestamp(AudioTimestamp& timestamp); | 
|  | 610 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 611 | protected: | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 612 | /* copying audio tracks is not allowed */ | 
|  | 613 | AudioTrack(const AudioTrack& other); | 
|  | 614 | AudioTrack& operator = (const AudioTrack& other); | 
|  | 615 |  | 
| Jean-Michel Trivi | faabb51 | 2014-06-11 16:55:06 -0700 | [diff] [blame] | 616 | void        setAttributesFromStreamType(audio_stream_type_t streamType); | 
| Jean-Michel Trivi | faabb51 | 2014-06-11 16:55:06 -0700 | [diff] [blame] | 617 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 618 | /* a small internal class to handle the callback */ | 
|  | 619 | class AudioTrackThread : public Thread | 
|  | 620 | { | 
|  | 621 | public: | 
|  | 622 | AudioTrackThread(AudioTrack& receiver, bool bCanCallJava = false); | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 623 |  | 
|  | 624 | // Do not call Thread::requestExitAndWait() without first calling requestExit(). | 
|  | 625 | // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough. | 
|  | 626 | virtual void        requestExit(); | 
|  | 627 |  | 
|  | 628 | void        pause();    // suspend thread from execution at next loop boundary | 
|  | 629 | void        resume();   // allow thread to execute, if not requested to exit | 
| Andy Hung | 3c09c78 | 2014-12-29 18:39:32 -0800 | [diff] [blame] | 630 | void        wake();     // wake to handle changed notification conditions. | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 631 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 632 | private: | 
| Glenn Kasten | 5a6cd22 | 2013-09-20 09:20:45 -0700 | [diff] [blame] | 633 | void        pauseInternal(nsecs_t ns = 0LL); | 
|  | 634 | // like pause(), but only used internally within thread | 
|  | 635 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 636 | friend class AudioTrack; | 
|  | 637 | virtual bool        threadLoop(); | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 638 | AudioTrack&         mReceiver; | 
|  | 639 | virtual ~AudioTrackThread(); | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 640 | Mutex               mMyLock;    // Thread::mLock is private | 
|  | 641 | Condition           mMyCond;    // Thread::mThreadExitedCondition is private | 
| Glenn Kasten | 5a6cd22 | 2013-09-20 09:20:45 -0700 | [diff] [blame] | 642 | bool                mPaused;    // whether thread is requested to pause at next loop entry | 
|  | 643 | bool                mPausedInt; // whether thread internally requests pause | 
|  | 644 | nsecs_t             mPausedNs;  // if mPausedInt then associated timeout, otherwise ignored | 
| Andy Hung | 3c09c78 | 2014-12-29 18:39:32 -0800 | [diff] [blame] | 645 | bool                mIgnoreNextPausedInt;   // skip any internal pause and go immediately | 
|  | 646 | // to processAudioBuffer() as state may have changed | 
|  | 647 | // since pause time calculated. | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 648 | }; | 
|  | 649 |  | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 650 | // body of AudioTrackThread::threadLoop() | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 651 | // returns the maximum amount of time before we would like to run again, where: | 
|  | 652 | //      0           immediately | 
|  | 653 | //      > 0         no later than this many nanoseconds from now | 
|  | 654 | //      NS_WHENEVER still active but no particular deadline | 
|  | 655 | //      NS_INACTIVE inactive so don't run again until re-started | 
|  | 656 | //      NS_NEVER    never again | 
|  | 657 | static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3; | 
| Glenn Kasten | 7c7be1e | 2013-12-19 16:34:04 -0800 | [diff] [blame] | 658 | nsecs_t processAudioBuffer(); | 
| Glenn Kasten | ea7939a | 2012-03-14 12:56:26 -0700 | [diff] [blame] | 659 |  | 
| Glenn Kasten | 23a7545 | 2014-01-13 10:37:17 -0800 | [diff] [blame] | 660 | bool     isOffloaded() const; | 
| Eric Laurent | ab5cdba | 2014-06-09 17:22:27 -0700 | [diff] [blame] | 661 | bool     isDirect() const; | 
|  | 662 | bool     isOffloadedOrDirect() const; | 
| Glenn Kasten | 23a7545 | 2014-01-13 10:37:17 -0800 | [diff] [blame] | 663 |  | 
| Glenn Kasten | d5ed6e8 | 2012-11-02 13:05:14 -0700 | [diff] [blame] | 664 | // caller must hold lock on mLock for all _l methods | 
| Richard Fitzgerald | ad3af33 | 2013-03-25 16:54:37 +0000 | [diff] [blame] | 665 |  | 
| Glenn Kasten | 200092b | 2014-08-15 15:13:30 -0700 | [diff] [blame] | 666 | status_t createTrack_l(); | 
| Glenn Kasten | 4bae364 | 2012-11-30 13:41:12 -0800 | [diff] [blame] | 667 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 668 | // can only be called when mState != STATE_ACTIVE | 
| Eric Laurent | 1703cdf | 2011-03-07 14:52:59 -0800 | [diff] [blame] | 669 | void flush_l(); | 
| Glenn Kasten | 4bae364 | 2012-11-30 13:41:12 -0800 | [diff] [blame] | 670 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 671 | void setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount); | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 672 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 673 | // FIXME enum is faster than strcmp() for parameter 'from' | 
|  | 674 | status_t restoreTrack_l(const char *from); | 
|  | 675 |  | 
| Glenn Kasten | 23a7545 | 2014-01-13 10:37:17 -0800 | [diff] [blame] | 676 | bool     isOffloaded_l() const | 
| Richard Fitzgerald | b1a270d | 2013-05-14 12:12:21 +0100 | [diff] [blame] | 677 | { return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; } | 
|  | 678 |  | 
| Eric Laurent | ab5cdba | 2014-06-09 17:22:27 -0700 | [diff] [blame] | 679 | bool     isOffloadedOrDirect_l() const | 
|  | 680 | { return (mFlags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD| | 
|  | 681 | AUDIO_OUTPUT_FLAG_DIRECT)) != 0; } | 
|  | 682 |  | 
|  | 683 | bool     isDirect_l() const | 
|  | 684 | { return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; } | 
|  | 685 |  | 
| Glenn Kasten | 200092b | 2014-08-15 15:13:30 -0700 | [diff] [blame] | 686 | // increment mPosition by the delta of mServer, and return new value of mPosition | 
|  | 687 | uint32_t updateAndGetPosition_l(); | 
|  | 688 |  | 
| Glenn Kasten | 38e905b | 2014-01-13 10:21:48 -0800 | [diff] [blame] | 689 | // Next 4 fields may be changed if IAudioTrack is re-created, but always != 0 | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 690 | sp<IAudioTrack>         mAudioTrack; | 
|  | 691 | sp<IMemory>             mCblkMemory; | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 692 | audio_track_cblk_t*     mCblk;                  // re-load after mLock.unlock() | 
| Glenn Kasten | 38e905b | 2014-01-13 10:21:48 -0800 | [diff] [blame] | 693 | audio_io_handle_t       mOutput;                // returned by AudioSystem::getOutput() | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 694 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 695 | sp<AudioTrackThread>    mAudioTrackThread; | 
| Glenn Kasten | b5ccb2d | 2014-01-13 14:42:43 -0800 | [diff] [blame] | 696 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 697 | float                   mVolume[2]; | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 698 | float                   mSendLevel; | 
| Glenn Kasten | b187de1 | 2014-12-30 08:18:15 -0800 | [diff] [blame] | 699 | mutable uint32_t        mSampleRate;            // mutable because getSampleRate() can update it | 
| Glenn Kasten | 396fabd | 2014-01-08 08:54:23 -0800 | [diff] [blame] | 700 | size_t                  mFrameCount;            // corresponds to current IAudioTrack, value is | 
|  | 701 | // reported back by AudioFlinger to the client | 
|  | 702 | size_t                  mReqFrameCount;         // frame count to request the first or next time | 
|  | 703 | // a new IAudioTrack is needed, non-decreasing | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 704 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 705 | // constant after constructor or set() | 
| Glenn Kasten | 60a8392 | 2012-06-21 12:56:37 -0700 | [diff] [blame] | 706 | audio_format_t          mFormat;                // as requested by client, not forced to 16-bit | 
| Eric Laurent | e83b55d | 2014-11-14 10:06:21 -0800 | [diff] [blame] | 707 | audio_stream_type_t     mStreamType;            // mStreamType == AUDIO_STREAM_DEFAULT implies | 
|  | 708 | // this AudioTrack has valid attributes | 
| Glenn Kasten | e4756fe | 2012-11-29 13:38:14 -0800 | [diff] [blame] | 709 | uint32_t                mChannelCount; | 
| Glenn Kasten | 28b76b3 | 2012-07-03 17:24:41 -0700 | [diff] [blame] | 710 | audio_channel_mask_t    mChannelMask; | 
| Glenn Kasten | dd5f4c8 | 2014-01-13 10:26:32 -0800 | [diff] [blame] | 711 | sp<IMemory>             mSharedBuffer; | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 712 | transfer_type           mTransfer; | 
| Glenn Kasten | b5ccb2d | 2014-01-13 14:42:43 -0800 | [diff] [blame] | 713 | audio_offload_info_t    mOffloadInfoCopy; | 
|  | 714 | const audio_offload_info_t* mOffloadInfo; | 
| Jean-Michel Trivi | faabb51 | 2014-06-11 16:55:06 -0700 | [diff] [blame] | 715 | audio_attributes_t      mAttributes; | 
| Glenn Kasten | 83a0382 | 2012-11-12 07:58:20 -0800 | [diff] [blame] | 716 |  | 
| Andy Hung | abdb990 | 2015-01-12 15:08:22 -0800 | [diff] [blame] | 717 | size_t                  mFrameSize;             // frame size in bytes | 
| Glenn Kasten | 83a0382 | 2012-11-12 07:58:20 -0800 | [diff] [blame] | 718 |  | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 719 | status_t                mStatus; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 720 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 721 | // can change dynamically when IAudioTrack invalidated | 
|  | 722 | uint32_t                mLatency;               // in ms | 
|  | 723 |  | 
|  | 724 | // Indicates the current track state.  Protected by mLock. | 
|  | 725 | enum State { | 
|  | 726 | STATE_ACTIVE, | 
|  | 727 | STATE_STOPPED, | 
|  | 728 | STATE_PAUSED, | 
| Richard Fitzgerald | b1a270d | 2013-05-14 12:12:21 +0100 | [diff] [blame] | 729 | STATE_PAUSED_STOPPING, | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 730 | STATE_FLUSHED, | 
| Richard Fitzgerald | b1a270d | 2013-05-14 12:12:21 +0100 | [diff] [blame] | 731 | STATE_STOPPING, | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 732 | }                       mState; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 733 |  | 
| Glenn Kasten | 6ca126d | 2013-07-31 12:25:00 -0700 | [diff] [blame] | 734 | // for client callback handler | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 735 | callback_t              mCbf;                   // callback handler for events, or NULL | 
| Glenn Kasten | 6ca126d | 2013-07-31 12:25:00 -0700 | [diff] [blame] | 736 | void*                   mUserData; | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 737 |  | 
|  | 738 | // for notification APIs | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 739 | uint32_t                mNotificationFramesReq; // requested number of frames between each | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 740 | // notification callback, | 
|  | 741 | // at initial source sample rate | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 742 | uint32_t                mNotificationFramesAct; // actual number of frames between each | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 743 | // notification callback, | 
|  | 744 | // at initial source sample rate | 
| Glenn Kasten | 2fc1473 | 2013-08-05 14:58:14 -0700 | [diff] [blame] | 745 | bool                    mRefreshRemaining;      // processAudioBuffer() should refresh | 
|  | 746 | // mRemainingFrames and mRetryOnPartialBuffer | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 747 |  | 
| Andy Hung | 4ede21d | 2014-12-12 15:37:34 -0800 | [diff] [blame] | 748 | // used for static track cbf and restoration | 
|  | 749 | int32_t                 mLoopCount;             // last setLoop loopCount; zero means disabled | 
|  | 750 | uint32_t                mLoopStart;             // last setLoop loopStart | 
|  | 751 | uint32_t                mLoopEnd;               // last setLoop loopEnd | 
| Andy Hung | 53c3b5f | 2014-12-15 16:42:05 -0800 | [diff] [blame] | 752 | int32_t                 mLoopCountNotified;     // the last loopCount notified by callback. | 
|  | 753 | // mLoopCountNotified counts down, matching | 
|  | 754 | // the remaining loop count for static track | 
|  | 755 | // playback. | 
| Andy Hung | 4ede21d | 2014-12-12 15:37:34 -0800 | [diff] [blame] | 756 |  | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 757 | // These are private to processAudioBuffer(), and are not protected by a lock | 
|  | 758 | uint32_t                mRemainingFrames;       // number of frames to request in obtainBuffer() | 
|  | 759 | bool                    mRetryOnPartialBuffer;  // sleep and retry after partial obtainBuffer() | 
| Richard Fitzgerald | b1a270d | 2013-05-14 12:12:21 +0100 | [diff] [blame] | 760 | uint32_t                mObservedSequence;      // last observed value of mSequence | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 761 |  | 
| Glenn Kasten | 083d1c1 | 2012-11-30 15:00:36 -0800 | [diff] [blame] | 762 | uint32_t                mMarkerPosition;        // in wrapping (overflow) frame units | 
| Jean-Michel Trivi | 2c22aeb | 2009-03-24 18:11:07 -0700 | [diff] [blame] | 763 | bool                    mMarkerReached; | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 764 | uint32_t                mNewPosition;           // in frames | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 765 | uint32_t                mUpdatePeriod;          // in frames, zero means no EVENT_NEW_POS | 
| Glenn Kasten | 200092b | 2014-08-15 15:13:30 -0700 | [diff] [blame] | 766 | uint32_t                mServer;                // in frames, last known mProxy->getPosition() | 
|  | 767 | // which is count of frames consumed by server, | 
|  | 768 | // reset by new IAudioTrack, | 
|  | 769 | // whether it is reset by stop() is TBD | 
|  | 770 | uint32_t                mPosition;              // in frames, like mServer except continues | 
|  | 771 | // monotonically after new IAudioTrack, | 
|  | 772 | // and could be easily widened to uint64_t | 
|  | 773 | uint32_t                mReleased;              // in frames, count of frames released to server | 
|  | 774 | // but not necessarily consumed by server, | 
|  | 775 | // reset by stop() but continues monotonically | 
|  | 776 | // after new IAudioTrack to restore mPosition, | 
|  | 777 | // and could be easily widened to uint64_t | 
| Andy Hung | 7f1bc8a | 2014-09-12 14:43:11 -0700 | [diff] [blame] | 778 | int64_t                 mStartUs;               // the start time after flush or stop. | 
|  | 779 | // only used for offloaded and direct tracks. | 
| Glenn Kasten | ad2f6db | 2012-11-01 15:45:06 -0700 | [diff] [blame] | 780 |  | 
| Eric Laurent | 0ca3cf9 | 2012-04-18 09:24:29 -0700 | [diff] [blame] | 781 | audio_output_flags_t    mFlags; | 
| Glenn Kasten | 23a7545 | 2014-01-13 10:37:17 -0800 | [diff] [blame] | 782 | // const after set(), except for bits AUDIO_OUTPUT_FLAG_FAST and AUDIO_OUTPUT_FLAG_OFFLOAD. | 
|  | 783 | // mLock must be held to read or write those bits reliably. | 
|  | 784 |  | 
| Eric Laurent | be916aa | 2010-06-01 23:49:17 -0700 | [diff] [blame] | 785 | int                     mSessionId; | 
| Eric Laurent | 2beeb50 | 2010-07-16 07:43:46 -0700 | [diff] [blame] | 786 | int                     mAuxEffectId; | 
| Glenn Kasten | d5ed6e8 | 2012-11-02 13:05:14 -0700 | [diff] [blame] | 787 |  | 
| Glenn Kasten | 9a2aaf9 | 2012-01-03 09:42:47 -0800 | [diff] [blame] | 788 | mutable Mutex           mLock; | 
| Glenn Kasten | d5ed6e8 | 2012-11-02 13:05:14 -0700 | [diff] [blame] | 789 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 790 | bool                    mIsTimed; | 
| Glenn Kasten | 8791351 | 2011-06-22 16:15:25 -0700 | [diff] [blame] | 791 | int                     mPreviousPriority;          // before start() | 
| Glenn Kasten | a636433 | 2012-04-19 09:35:04 -0700 | [diff] [blame] | 792 | SchedPolicy             mPreviousSchedulingGroup; | 
| Glenn Kasten | a07f17c | 2013-04-23 12:39:37 -0700 | [diff] [blame] | 793 | bool                    mAwaitBoost;    // thread should wait for priority boost before running | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 794 |  | 
|  | 795 | // The proxy should only be referenced while a lock is held because the proxy isn't | 
|  | 796 | // multi-thread safe, especially the SingleStateQueue part of the proxy. | 
|  | 797 | // An exception is that a blocking ClientProxy::obtainBuffer() may be called without a lock, | 
|  | 798 | // provided that the caller also holds an extra reference to the proxy and shared memory to keep | 
|  | 799 | // them around in case they are replaced during the obtainBuffer(). | 
|  | 800 | sp<StaticAudioTrackClientProxy> mStaticProxy;   // for type safety only | 
|  | 801 | sp<AudioTrackClientProxy>       mProxy;         // primary owner of the memory | 
|  | 802 |  | 
|  | 803 | bool                    mInUnderrun;            // whether track is currently in underrun state | 
| Haynes Mathew George | 7064fd2 | 2014-01-08 13:59:53 -0800 | [diff] [blame] | 804 | uint32_t                mPausedPosition; | 
| Glenn Kasten | 9f80dd2 | 2012-12-18 15:57:32 -0800 | [diff] [blame] | 805 |  | 
|  | 806 | private: | 
|  | 807 | class DeathNotifier : public IBinder::DeathRecipient { | 
|  | 808 | public: | 
|  | 809 | DeathNotifier(AudioTrack* audioTrack) : mAudioTrack(audioTrack) { } | 
|  | 810 | protected: | 
|  | 811 | virtual void        binderDied(const wp<IBinder>& who); | 
|  | 812 | private: | 
|  | 813 | const wp<AudioTrack> mAudioTrack; | 
|  | 814 | }; | 
|  | 815 |  | 
|  | 816 | sp<DeathNotifier>       mDeathNotifier; | 
|  | 817 | uint32_t                mSequence;              // incremented for each new IAudioTrack attempt | 
| Marco Nelissen | 462fd2f | 2013-01-14 14:12:05 -0800 | [diff] [blame] | 818 | int                     mClientUid; | 
| Marco Nelissen | d457c97 | 2014-02-11 08:47:07 -0800 | [diff] [blame] | 819 | pid_t                   mClientPid; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 820 | }; | 
|  | 821 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 822 | class TimedAudioTrack : public AudioTrack | 
|  | 823 | { | 
|  | 824 | public: | 
|  | 825 | TimedAudioTrack(); | 
|  | 826 |  | 
|  | 827 | /* allocate a shared memory buffer that can be passed to queueTimedBuffer */ | 
|  | 828 | status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer); | 
|  | 829 |  | 
|  | 830 | /* queue a buffer obtained via allocateTimedBuffer for playback at the | 
| Glenn Kasten | c3ae93f | 2012-07-30 10:59:30 -0700 | [diff] [blame] | 831 | given timestamp.  PTS units are microseconds on the media time timeline. | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 832 | The media time transform (set with setMediaTimeTransform) set by the | 
|  | 833 | audio producer will handle converting from media time to local time | 
|  | 834 | (perhaps going through the common time timeline in the case of | 
|  | 835 | synchronized multiroom audio case) */ | 
|  | 836 | status_t queueTimedBuffer(const sp<IMemory>& buffer, int64_t pts); | 
|  | 837 |  | 
|  | 838 | /* define a transform between media time and either common time or | 
|  | 839 | local time */ | 
|  | 840 | enum TargetTimeline {LOCAL_TIME, COMMON_TIME}; | 
|  | 841 | status_t setMediaTimeTransform(const LinearTransform& xform, | 
|  | 842 | TargetTimeline target); | 
|  | 843 | }; | 
| The Android Open Source Project | 89fa4ad | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 844 |  | 
|  | 845 | }; // namespace android | 
|  | 846 |  | 
|  | 847 | #endif // ANDROID_AUDIOTRACK_H |