| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1 | /* | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 2 | ** | 
 | 3 | ** Copyright 2007, The Android Open Source Project | 
 | 4 | ** | 
 | 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 6 | ** you may not use this file except in compliance with the License. | 
 | 7 | ** You may obtain a copy of the License at | 
 | 8 | ** | 
 | 9 | **     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 10 | ** | 
 | 11 | ** Unless required by applicable law or agreed to in writing, software | 
 | 12 | ** distributed under the License is distributed on an "AS IS" BASIS, | 
 | 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 14 | ** See the License for the specific language governing permissions and | 
 | 15 | ** limitations under the License. | 
 | 16 | */ | 
 | 17 |  | 
 | 18 | #ifndef ANDROID_AUDIO_FLINGER_H | 
 | 19 | #define ANDROID_AUDIO_FLINGER_H | 
 | 20 |  | 
 | 21 | #include <stdint.h> | 
 | 22 | #include <sys/types.h> | 
 | 23 | #include <limits.h> | 
 | 24 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 25 | #include <common_time/cc_helper.h> | 
 | 26 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 27 | #include <media/IAudioFlinger.h> | 
 | 28 | #include <media/IAudioFlingerClient.h> | 
 | 29 | #include <media/IAudioTrack.h> | 
 | 30 | #include <media/IAudioRecord.h> | 
| Glenn Kasten | 335787f | 2012-01-20 17:00:00 -0800 | [diff] [blame] | 31 | #include <media/AudioSystem.h> | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 32 | #include <media/AudioTrack.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 33 |  | 
 | 34 | #include <utils/Atomic.h> | 
 | 35 | #include <utils/Errors.h> | 
 | 36 | #include <utils/threads.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 37 | #include <utils/SortedVector.h> | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 38 | #include <utils/TypeHelpers.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 39 | #include <utils/Vector.h> | 
 | 40 |  | 
| Mathias Agopian | 5462fc9 | 2010-07-14 18:41:18 -0700 | [diff] [blame] | 41 | #include <binder/BinderService.h> | 
 | 42 | #include <binder/MemoryDealer.h> | 
 | 43 |  | 
| Dima Zavin | 6476024 | 2011-05-11 14:15:23 -0700 | [diff] [blame] | 44 | #include <system/audio.h> | 
| Dima Zavin | 7394a4f | 2011-06-13 18:16:26 -0700 | [diff] [blame] | 45 | #include <hardware/audio.h> | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 46 | #include <hardware/audio_policy.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 47 |  | 
 | 48 | #include "AudioBufferProvider.h" | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 49 | #include "ExtendedAudioBufferProvider.h" | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 50 | #include "FastMixer.h" | 
 | 51 | #include "NBAIO.h" | 
| Glenn Kasten | c15d665 | 2012-05-30 14:52:57 -0700 | [diff] [blame] | 52 | #include "AudioWatchdog.h" | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 53 |  | 
| Eric Laurent | feb0db6 | 2011-07-22 09:04:31 -0700 | [diff] [blame] | 54 | #include <powermanager/IPowerManager.h> | 
 | 55 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 56 | namespace android { | 
 | 57 |  | 
 | 58 | class audio_track_cblk_t; | 
 | 59 | class effect_param_cblk_t; | 
 | 60 | class AudioMixer; | 
 | 61 | class AudioBuffer; | 
 | 62 | class AudioResampler; | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 63 | class FastMixer; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 64 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 65 | // ---------------------------------------------------------------------------- | 
 | 66 |  | 
| Glenn Kasten | 53d76db | 2012-03-08 12:32:47 -0800 | [diff] [blame] | 67 | // AudioFlinger has a hard-coded upper limit of 2 channels for capture and playback. | 
 | 68 | // There is support for > 2 channel tracks down-mixed to 2 channel output via a down-mix effect. | 
 | 69 | // Adding full support for > 2 channel capture or playback would require more than simply changing | 
 | 70 | // this #define.  There is an independent hard-coded upper limit in AudioMixer; | 
 | 71 | // removing that AudioMixer limit would be necessary but insufficient to support > 2 channels. | 
 | 72 | // The macro FCC_2 highlights some (but not all) places where there is are 2-channel assumptions. | 
 | 73 | // Search also for "2", "left", "right", "[0]", "[1]", ">> 16", "<< 16", etc. | 
 | 74 | #define FCC_2 2     // FCC_2 = Fixed Channel Count 2 | 
 | 75 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 76 | static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 77 |  | 
| Mathias Agopian | 5462fc9 | 2010-07-14 18:41:18 -0700 | [diff] [blame] | 78 | class AudioFlinger : | 
 | 79 |     public BinderService<AudioFlinger>, | 
 | 80 |     public BnAudioFlinger | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 81 | { | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 82 |     friend class BinderService<AudioFlinger>;   // for AudioFlinger() | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 83 | public: | 
| Glenn Kasten | 54c3b66 | 2012-01-06 07:46:30 -0800 | [diff] [blame] | 84 |     static const char* getServiceName() { return "media.audio_flinger"; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 85 |  | 
 | 86 |     virtual     status_t    dump(int fd, const Vector<String16>& args); | 
 | 87 |  | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 88 |     // IAudioFlinger interface, in binder opcode order | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 89 |     virtual sp<IAudioTrack> createTrack( | 
 | 90 |                                 pid_t pid, | 
| Glenn Kasten | fff6d71 | 2012-01-12 16:38:12 -0800 | [diff] [blame] | 91 |                                 audio_stream_type_t streamType, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 92 |                                 uint32_t sampleRate, | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 93 |                                 audio_format_t format, | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 94 |                                 uint32_t channelMask, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 95 |                                 int frameCount, | 
| Glenn Kasten | a075db4 | 2012-03-06 11:22:44 -0800 | [diff] [blame] | 96 |                                 IAudioFlinger::track_flags_t flags, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 97 |                                 const sp<IMemory>& sharedBuffer, | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 98 |                                 audio_io_handle_t output, | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 99 |                                 pid_t tid, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 100 |                                 int *sessionId, | 
 | 101 |                                 status_t *status); | 
 | 102 |  | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 103 |     virtual sp<IAudioRecord> openRecord( | 
 | 104 |                                 pid_t pid, | 
 | 105 |                                 audio_io_handle_t input, | 
 | 106 |                                 uint32_t sampleRate, | 
 | 107 |                                 audio_format_t format, | 
 | 108 |                                 uint32_t channelMask, | 
 | 109 |                                 int frameCount, | 
| Glenn Kasten | a075db4 | 2012-03-06 11:22:44 -0800 | [diff] [blame] | 110 |                                 IAudioFlinger::track_flags_t flags, | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 111 |                                 int *sessionId, | 
 | 112 |                                 status_t *status); | 
 | 113 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 114 |     virtual     uint32_t    sampleRate(audio_io_handle_t output) const; | 
 | 115 |     virtual     int         channelCount(audio_io_handle_t output) const; | 
 | 116 |     virtual     audio_format_t format(audio_io_handle_t output) const; | 
 | 117 |     virtual     size_t      frameCount(audio_io_handle_t output) const; | 
 | 118 |     virtual     uint32_t    latency(audio_io_handle_t output) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 119 |  | 
 | 120 |     virtual     status_t    setMasterVolume(float value); | 
 | 121 |     virtual     status_t    setMasterMute(bool muted); | 
 | 122 |  | 
 | 123 |     virtual     float       masterVolume() const; | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 124 |     virtual     float       masterVolumeSW() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 125 |     virtual     bool        masterMute() const; | 
 | 126 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 127 |     virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value, | 
 | 128 |                                             audio_io_handle_t output); | 
| Glenn Kasten | fff6d71 | 2012-01-12 16:38:12 -0800 | [diff] [blame] | 129 |     virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 130 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 131 |     virtual     float       streamVolume(audio_stream_type_t stream, | 
 | 132 |                                          audio_io_handle_t output) const; | 
| Glenn Kasten | fff6d71 | 2012-01-12 16:38:12 -0800 | [diff] [blame] | 133 |     virtual     bool        streamMute(audio_stream_type_t stream) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 134 |  | 
| Glenn Kasten | f78aee7 | 2012-01-04 11:00:47 -0800 | [diff] [blame] | 135 |     virtual     status_t    setMode(audio_mode_t mode); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 136 |  | 
 | 137 |     virtual     status_t    setMicMute(bool state); | 
 | 138 |     virtual     bool        getMicMute() const; | 
 | 139 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 140 |     virtual     status_t    setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs); | 
 | 141 |     virtual     String8     getParameters(audio_io_handle_t ioHandle, const String8& keys) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 142 |  | 
 | 143 |     virtual     void        registerClient(const sp<IAudioFlingerClient>& client); | 
 | 144 |  | 
| Glenn Kasten | f587ba5 | 2012-01-26 16:25:10 -0800 | [diff] [blame] | 145 |     virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 146 |  | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 147 |     virtual audio_io_handle_t openOutput(audio_module_handle_t module, | 
 | 148 |                                          audio_devices_t *pDevices, | 
 | 149 |                                          uint32_t *pSamplingRate, | 
 | 150 |                                          audio_format_t *pFormat, | 
 | 151 |                                          audio_channel_mask_t *pChannelMask, | 
 | 152 |                                          uint32_t *pLatencyMs, | 
| Eric Laurent | 0ca3cf9 | 2012-04-18 09:24:29 -0700 | [diff] [blame] | 153 |                                          audio_output_flags_t flags); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 154 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 155 |     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, | 
 | 156 |                                                   audio_io_handle_t output2); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 157 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 158 |     virtual status_t closeOutput(audio_io_handle_t output); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 159 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 160 |     virtual status_t suspendOutput(audio_io_handle_t output); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 161 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 162 |     virtual status_t restoreOutput(audio_io_handle_t output); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 163 |  | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 164 |     virtual audio_io_handle_t openInput(audio_module_handle_t module, | 
 | 165 |                                         audio_devices_t *pDevices, | 
 | 166 |                                         uint32_t *pSamplingRate, | 
 | 167 |                                         audio_format_t *pFormat, | 
 | 168 |                                         audio_channel_mask_t *pChannelMask); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 169 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 170 |     virtual status_t closeInput(audio_io_handle_t input); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 171 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 172 |     virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 173 |  | 
 | 174 |     virtual status_t setVoiceVolume(float volume); | 
 | 175 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 176 |     virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, | 
 | 177 |                                        audio_io_handle_t output) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 178 |  | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 179 |     virtual     unsigned int  getInputFramesLost(audio_io_handle_t ioHandle) const; | 
 | 180 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 181 |     virtual int newAudioSessionId(); | 
 | 182 |  | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 183 |     virtual void acquireAudioSessionId(int audioSession); | 
 | 184 |  | 
 | 185 |     virtual void releaseAudioSessionId(int audioSession); | 
 | 186 |  | 
| Glenn Kasten | f587ba5 | 2012-01-26 16:25:10 -0800 | [diff] [blame] | 187 |     virtual status_t queryNumberEffects(uint32_t *numEffects) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 188 |  | 
| Glenn Kasten | f587ba5 | 2012-01-26 16:25:10 -0800 | [diff] [blame] | 189 |     virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 190 |  | 
| Glenn Kasten | 5e92a78 | 2012-01-30 07:40:52 -0800 | [diff] [blame] | 191 |     virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid, | 
| Glenn Kasten | f587ba5 | 2012-01-26 16:25:10 -0800 | [diff] [blame] | 192 |                                          effect_descriptor_t *descriptor) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 193 |  | 
 | 194 |     virtual sp<IEffect> createEffect(pid_t pid, | 
 | 195 |                         effect_descriptor_t *pDesc, | 
 | 196 |                         const sp<IEffectClient>& effectClient, | 
 | 197 |                         int32_t priority, | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 198 |                         audio_io_handle_t io, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 199 |                         int sessionId, | 
 | 200 |                         status_t *status, | 
 | 201 |                         int *id, | 
 | 202 |                         int *enabled); | 
 | 203 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 204 |     virtual status_t moveEffects(int sessionId, audio_io_handle_t srcOutput, | 
 | 205 |                         audio_io_handle_t dstOutput); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 206 |  | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 207 |     virtual audio_module_handle_t loadHwModule(const char *name); | 
 | 208 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 209 |     virtual     status_t    onTransact( | 
 | 210 |                                 uint32_t code, | 
 | 211 |                                 const Parcel& data, | 
 | 212 |                                 Parcel* reply, | 
 | 213 |                                 uint32_t flags); | 
 | 214 |  | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 215 |     // end of IAudioFlinger interface | 
 | 216 |  | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 217 |     class SyncEvent; | 
 | 218 |  | 
 | 219 |     typedef void (*sync_event_callback_t)(const wp<SyncEvent>& event) ; | 
 | 220 |  | 
 | 221 |     class SyncEvent : public RefBase { | 
 | 222 |     public: | 
 | 223 |         SyncEvent(AudioSystem::sync_event_t type, | 
 | 224 |                   int triggerSession, | 
 | 225 |                   int listenerSession, | 
 | 226 |                   sync_event_callback_t callBack, | 
 | 227 |                   void *cookie) | 
 | 228 |         : mType(type), mTriggerSession(triggerSession), mListenerSession(listenerSession), | 
 | 229 |           mCallback(callBack), mCookie(cookie) | 
 | 230 |         {} | 
 | 231 |  | 
 | 232 |         virtual ~SyncEvent() {} | 
 | 233 |  | 
 | 234 |         void trigger() { Mutex::Autolock _l(mLock); if (mCallback) mCallback(this); } | 
| Eric Laurent | 2986460 | 2012-05-08 18:57:51 -0700 | [diff] [blame] | 235 |         bool isCancelled() { Mutex::Autolock _l(mLock); return (mCallback == NULL); } | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 236 |         void cancel() {Mutex::Autolock _l(mLock); mCallback = NULL; } | 
 | 237 |         AudioSystem::sync_event_t type() const { return mType; } | 
 | 238 |         int triggerSession() const { return mTriggerSession; } | 
 | 239 |         int listenerSession() const { return mListenerSession; } | 
 | 240 |         void *cookie() const { return mCookie; } | 
 | 241 |  | 
 | 242 |     private: | 
 | 243 |           const AudioSystem::sync_event_t mType; | 
 | 244 |           const int mTriggerSession; | 
 | 245 |           const int mListenerSession; | 
 | 246 |           sync_event_callback_t mCallback; | 
 | 247 |           void * const mCookie; | 
 | 248 |           Mutex mLock; | 
 | 249 |     }; | 
 | 250 |  | 
 | 251 |     sp<SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, | 
 | 252 |                                         int triggerSession, | 
 | 253 |                                         int listenerSession, | 
 | 254 |                                         sync_event_callback_t callBack, | 
 | 255 |                                         void *cookie); | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 256 | private: | 
| Glenn Kasten | f78aee7 | 2012-01-04 11:00:47 -0800 | [diff] [blame] | 257 |                audio_mode_t getMode() const { return mMode; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 258 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 259 |                 bool        btNrecIsOff() const { return mBtNrecIsOff; } | 
| Eric Laurent | 59bd0da | 2011-08-01 09:52:20 -0700 | [diff] [blame] | 260 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 261 |                             AudioFlinger(); | 
 | 262 |     virtual                 ~AudioFlinger(); | 
 | 263 |  | 
| Glenn Kasten | 2b213bc | 2012-02-02 14:05:20 -0800 | [diff] [blame] | 264 |     // call in any IAudioFlinger method that accesses mPrimaryHardwareDev | 
 | 265 |     status_t                initCheck() const { return mPrimaryHardwareDev == NULL ? NO_INIT : NO_ERROR; } | 
 | 266 |  | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 267 |     // RefBase | 
| Dima Zavin | 5a61d2f | 2011-04-19 19:04:32 -0700 | [diff] [blame] | 268 |     virtual     void        onFirstRef(); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 269 |  | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 270 |     audio_hw_device_t*      findSuitableHwDev_l(audio_module_handle_t module, uint32_t devices); | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 271 |     void                    purgeStaleEffects_l(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 272 |  | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 273 |     // standby delay for MIXER and DUPLICATING playback threads is read from property | 
 | 274 |     // ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 275 |     static nsecs_t          mStandbyTimeInNsecs; | 
 | 276 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 277 |     // Internal dump utilites. | 
 | 278 |     status_t dumpPermissionDenial(int fd, const Vector<String16>& args); | 
 | 279 |     status_t dumpClients(int fd, const Vector<String16>& args); | 
 | 280 |     status_t dumpInternals(int fd, const Vector<String16>& args); | 
 | 281 |  | 
 | 282 |     // --- Client --- | 
 | 283 |     class Client : public RefBase { | 
 | 284 |     public: | 
 | 285 |                             Client(const sp<AudioFlinger>& audioFlinger, pid_t pid); | 
 | 286 |         virtual             ~Client(); | 
| Glenn Kasten | 435dbe6 | 2012-01-30 10:15:48 -0800 | [diff] [blame] | 287 |         sp<MemoryDealer>    heap() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 288 |         pid_t               pid() const { return mPid; } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 289 |         sp<AudioFlinger>    audioFlinger() const { return mAudioFlinger; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 290 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 291 |         bool reserveTimedTrack(); | 
 | 292 |         void releaseTimedTrack(); | 
 | 293 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 294 |     private: | 
 | 295 |                             Client(const Client&); | 
 | 296 |                             Client& operator = (const Client&); | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 297 |         const sp<AudioFlinger> mAudioFlinger; | 
 | 298 |         const sp<MemoryDealer> mMemoryDealer; | 
 | 299 |         const pid_t         mPid; | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 300 |  | 
 | 301 |         Mutex               mTimedTrackLock; | 
 | 302 |         int                 mTimedTrackCount; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 303 |     }; | 
 | 304 |  | 
 | 305 |     // --- Notification Client --- | 
 | 306 |     class NotificationClient : public IBinder::DeathRecipient { | 
 | 307 |     public: | 
 | 308 |                             NotificationClient(const sp<AudioFlinger>& audioFlinger, | 
 | 309 |                                                 const sp<IAudioFlingerClient>& client, | 
 | 310 |                                                 pid_t pid); | 
 | 311 |         virtual             ~NotificationClient(); | 
 | 312 |  | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 313 |                 sp<IAudioFlingerClient> audioFlingerClient() const { return mAudioFlingerClient; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 314 |  | 
 | 315 |                 // IBinder::DeathRecipient | 
 | 316 |                 virtual     void        binderDied(const wp<IBinder>& who); | 
 | 317 |  | 
 | 318 |     private: | 
 | 319 |                             NotificationClient(const NotificationClient&); | 
 | 320 |                             NotificationClient& operator = (const NotificationClient&); | 
 | 321 |  | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 322 |         const sp<AudioFlinger>  mAudioFlinger; | 
 | 323 |         const pid_t             mPid; | 
 | 324 |         const sp<IAudioFlingerClient> mAudioFlingerClient; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 325 |     }; | 
 | 326 |  | 
 | 327 |     class TrackHandle; | 
 | 328 |     class RecordHandle; | 
 | 329 |     class RecordThread; | 
 | 330 |     class PlaybackThread; | 
 | 331 |     class MixerThread; | 
 | 332 |     class DirectOutputThread; | 
 | 333 |     class DuplicatingThread; | 
 | 334 |     class Track; | 
 | 335 |     class RecordTrack; | 
 | 336 |     class EffectModule; | 
 | 337 |     class EffectHandle; | 
 | 338 |     class EffectChain; | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 339 |     struct AudioStreamOut; | 
 | 340 |     struct AudioStreamIn; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 341 |  | 
 | 342 |     class ThreadBase : public Thread { | 
 | 343 |     public: | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 344 |  | 
| Glenn Kasten | 23bb8be | 2012-01-26 10:38:26 -0800 | [diff] [blame] | 345 |         enum type_t { | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 346 |             MIXER,              // Thread class is MixerThread | 
 | 347 |             DIRECT,             // Thread class is DirectOutputThread | 
 | 348 |             DUPLICATING,        // Thread class is DuplicatingThread | 
 | 349 |             RECORD              // Thread class is RecordThread | 
 | 350 |         }; | 
 | 351 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 352 |         ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, uint32_t device, type_t type); | 
| Glenn Kasten | 23bb8be | 2012-01-26 10:38:26 -0800 | [diff] [blame] | 353 |         virtual             ~ThreadBase(); | 
 | 354 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 355 |         status_t dumpBase(int fd, const Vector<String16>& args); | 
| Eric Laurent | 1d2bff0 | 2011-07-24 17:49:51 -0700 | [diff] [blame] | 356 |         status_t dumpEffectChains(int fd, const Vector<String16>& args); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 357 |  | 
| Eric Laurent | feb0db6 | 2011-07-22 09:04:31 -0700 | [diff] [blame] | 358 |         void clearPowerManager(); | 
 | 359 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 360 |         // base for record and playback | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 361 |         class TrackBase : public ExtendedAudioBufferProvider, public RefBase { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 362 |  | 
 | 363 |         public: | 
 | 364 |             enum track_state { | 
 | 365 |                 IDLE, | 
 | 366 |                 TERMINATED, | 
| Eric Laurent | 2986460 | 2012-05-08 18:57:51 -0700 | [diff] [blame] | 367 |                 FLUSHED, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 368 |                 STOPPED, | 
| Glenn Kasten | d08f48c | 2012-05-01 18:14:02 -0700 | [diff] [blame] | 369 |                 // next 2 states are currently used for fast tracks only | 
 | 370 |                 STOPPING_1,     // waiting for first underrun | 
 | 371 |                 STOPPING_2,     // waiting for presentation complete | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 372 |                 RESUMING, | 
 | 373 |                 ACTIVE, | 
 | 374 |                 PAUSING, | 
 | 375 |                 PAUSED | 
 | 376 |             }; | 
 | 377 |  | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 378 |                                 TrackBase(ThreadBase *thread, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 379 |                                         const sp<Client>& client, | 
 | 380 |                                         uint32_t sampleRate, | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 381 |                                         audio_format_t format, | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 382 |                                         uint32_t channelMask, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 383 |                                         int frameCount, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 384 |                                         const sp<IMemory>& sharedBuffer, | 
 | 385 |                                         int sessionId); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 386 |             virtual             ~TrackBase(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 387 |  | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 388 |             virtual status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE, | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 389 |                                      int triggerSession = 0) = 0; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 390 |             virtual void        stop() = 0; | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 391 |                     sp<IMemory> getCblk() const { return mCblkMemory; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 392 |                     audio_track_cblk_t* cblk() const { return mCblk; } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 393 |                     int         sessionId() const { return mSessionId; } | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 394 |             virtual status_t    setSyncEvent(const sp<SyncEvent>& event); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 395 |  | 
 | 396 |         protected: | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 397 |                                 TrackBase(const TrackBase&); | 
 | 398 |                                 TrackBase& operator = (const TrackBase&); | 
 | 399 |  | 
| Glenn Kasten | 01c4ebf | 2012-02-22 10:47:35 -0800 | [diff] [blame] | 400 |             // AudioBufferProvider interface | 
 | 401 |             virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts) = 0; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 402 |             virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer); | 
 | 403 |  | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 404 |             // ExtendedAudioBufferProvider interface is only needed for Track, | 
 | 405 |             // but putting it in TrackBase avoids the complexity of virtual inheritance | 
 | 406 |             virtual size_t  framesReady() const { return SIZE_MAX; } | 
 | 407 |  | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 408 |             audio_format_t format() const { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 409 |                 return mFormat; | 
 | 410 |             } | 
 | 411 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 412 |             int channelCount() const { return mChannelCount; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 413 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 414 |             uint32_t channelMask() const { return mChannelMask; } | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 415 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 416 |             int sampleRate() const; // FIXME inline after cblk sr moved | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 417 |  | 
 | 418 |             void* getBuffer(uint32_t offset, uint32_t frames) const; | 
 | 419 |  | 
 | 420 |             bool isStopped() const { | 
| Eric Laurent | 2986460 | 2012-05-08 18:57:51 -0700 | [diff] [blame] | 421 |                 return (mState == STOPPED || mState == FLUSHED); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 422 |             } | 
 | 423 |  | 
| Glenn Kasten | d08f48c | 2012-05-01 18:14:02 -0700 | [diff] [blame] | 424 |             // for fast tracks only | 
 | 425 |             bool isStopping() const { | 
 | 426 |                 return mState == STOPPING_1 || mState == STOPPING_2; | 
 | 427 |             } | 
 | 428 |             bool isStopping_1() const { | 
 | 429 |                 return mState == STOPPING_1; | 
 | 430 |             } | 
 | 431 |             bool isStopping_2() const { | 
 | 432 |                 return mState == STOPPING_2; | 
 | 433 |             } | 
 | 434 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 435 |             bool isTerminated() const { | 
 | 436 |                 return mState == TERMINATED; | 
 | 437 |             } | 
 | 438 |  | 
 | 439 |             bool step(); | 
 | 440 |             void reset(); | 
 | 441 |  | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 442 |             const wp<ThreadBase> mThread; | 
 | 443 |             /*const*/ sp<Client> mClient;   // see explanation at ~TrackBase() why not const | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 444 |             sp<IMemory>         mCblkMemory; | 
 | 445 |             audio_track_cblk_t* mCblk; | 
 | 446 |             void*               mBuffer; | 
 | 447 |             void*               mBufferEnd; | 
 | 448 |             uint32_t            mFrameCount; | 
 | 449 |             // we don't really need a lock for these | 
| Glenn Kasten | b853e98 | 2012-01-26 13:39:18 -0800 | [diff] [blame] | 450 |             track_state         mState; | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 451 |             const uint32_t      mSampleRate;    // initial sample rate only; for tracks which | 
 | 452 |                                 // support dynamic rates, the current value is in control block | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 453 |             const audio_format_t mFormat; | 
| Glenn Kasten | 5cf034d | 2012-02-21 10:35:56 -0800 | [diff] [blame] | 454 |             bool                mStepServerFailed; | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 455 |             const int           mSessionId; | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 456 |             uint8_t             mChannelCount; | 
 | 457 |             uint32_t            mChannelMask; | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 458 |             Vector < sp<SyncEvent> >mSyncEvents; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 459 |         }; | 
 | 460 |  | 
 | 461 |         class ConfigEvent { | 
 | 462 |         public: | 
 | 463 |             ConfigEvent() : mEvent(0), mParam(0) {} | 
 | 464 |  | 
 | 465 |             int mEvent; | 
 | 466 |             int mParam; | 
 | 467 |         }; | 
 | 468 |  | 
| Eric Laurent | feb0db6 | 2011-07-22 09:04:31 -0700 | [diff] [blame] | 469 |         class PMDeathRecipient : public IBinder::DeathRecipient { | 
 | 470 |         public: | 
 | 471 |                         PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {} | 
 | 472 |             virtual     ~PMDeathRecipient() {} | 
 | 473 |  | 
 | 474 |             // IBinder::DeathRecipient | 
 | 475 |             virtual     void        binderDied(const wp<IBinder>& who); | 
 | 476 |  | 
 | 477 |         private: | 
 | 478 |                         PMDeathRecipient(const PMDeathRecipient&); | 
 | 479 |                         PMDeathRecipient& operator = (const PMDeathRecipient&); | 
 | 480 |  | 
 | 481 |             wp<ThreadBase> mThread; | 
 | 482 |         }; | 
 | 483 |  | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 484 |         virtual     status_t    initCheck() const = 0; | 
| Glenn Kasten | 23bb8be | 2012-01-26 10:38:26 -0800 | [diff] [blame] | 485 |                     type_t      type() const { return mType; } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 486 |                     uint32_t    sampleRate() const { return mSampleRate; } | 
 | 487 |                     int         channelCount() const { return mChannelCount; } | 
 | 488 |                     audio_format_t format() const { return mFormat; } | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 489 |                     // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects, | 
 | 490 |                     // and returns the normal mix buffer's frame count.  No API for HAL frame count. | 
 | 491 |                     size_t      frameCount() const { return mNormalFrameCount; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 492 |                     void        wakeUp()    { mWaitWorkCV.broadcast(); } | 
| Glenn Kasten | b28686f | 2012-01-06 08:39:38 -0800 | [diff] [blame] | 493 |         // Should be "virtual status_t requestExitAndWait()" and override same | 
 | 494 |         // method in Thread, but Thread::requestExitAndWait() is not yet virtual. | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 495 |                     void        exit(); | 
 | 496 |         virtual     bool        checkForNewParameters_l() = 0; | 
 | 497 |         virtual     status_t    setParameters(const String8& keyValuePairs); | 
 | 498 |         virtual     String8     getParameters(const String8& keys) = 0; | 
 | 499 |         virtual     void        audioConfigChanged_l(int event, int param = 0) = 0; | 
 | 500 |                     void        sendConfigEvent(int event, int param = 0); | 
 | 501 |                     void        sendConfigEvent_l(int event, int param = 0); | 
 | 502 |                     void        processConfigEvents(); | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 503 |                     audio_io_handle_t id() const { return mId;} | 
| Glenn Kasten | 02fe1bf | 2012-02-24 15:42:17 -0800 | [diff] [blame] | 504 |                     bool        standby() const { return mStandby; } | 
 | 505 |                     uint32_t    device() const { return mDevice; } | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 506 |         virtual     audio_stream_t* stream() const = 0; | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 507 |  | 
 | 508 |                     sp<EffectHandle> createEffect_l( | 
 | 509 |                                         const sp<AudioFlinger::Client>& client, | 
 | 510 |                                         const sp<IEffectClient>& effectClient, | 
 | 511 |                                         int32_t priority, | 
 | 512 |                                         int sessionId, | 
 | 513 |                                         effect_descriptor_t *desc, | 
 | 514 |                                         int *enabled, | 
 | 515 |                                         status_t *status); | 
 | 516 |                     void disconnectEffect(const sp< EffectModule>& effect, | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 517 |                                           const wp<EffectHandle>& handle, | 
| Glenn Kasten | 58123c3 | 2012-02-03 10:32:24 -0800 | [diff] [blame] | 518 |                                           bool unpinIfLast); | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 519 |  | 
 | 520 |                     // return values for hasAudioSession (bit field) | 
 | 521 |                     enum effect_state { | 
 | 522 |                         EFFECT_SESSION = 0x1,   // the audio session corresponds to at least one | 
 | 523 |                                                 // effect | 
 | 524 |                         TRACK_SESSION = 0x2     // the audio session corresponds to at least one | 
 | 525 |                                                 // track | 
 | 526 |                     }; | 
 | 527 |  | 
 | 528 |                     // get effect chain corresponding to session Id. | 
 | 529 |                     sp<EffectChain> getEffectChain(int sessionId); | 
 | 530 |                     // same as getEffectChain() but must be called with ThreadBase mutex locked | 
 | 531 |                     sp<EffectChain> getEffectChain_l(int sessionId); | 
 | 532 |                     // add an effect chain to the chain list (mEffectChains) | 
 | 533 |         virtual     status_t addEffectChain_l(const sp<EffectChain>& chain) = 0; | 
 | 534 |                     // remove an effect chain from the chain list (mEffectChains) | 
 | 535 |         virtual     size_t removeEffectChain_l(const sp<EffectChain>& chain) = 0; | 
| Glenn Kasten | d805b71 | 2012-02-24 15:42:48 -0800 | [diff] [blame] | 536 |                     // lock all effect chains Mutexes. Must be called before releasing the | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 537 |                     // ThreadBase mutex before processing the mixer and effects. This guarantees the | 
 | 538 |                     // integrity of the chains during the process. | 
| Glenn Kasten | d805b71 | 2012-02-24 15:42:48 -0800 | [diff] [blame] | 539 |                     // Also sets the parameter 'effectChains' to current value of mEffectChains. | 
| Glenn Kasten | e53b9ea | 2012-03-12 16:29:55 -0700 | [diff] [blame] | 540 |                     void lockEffectChains_l(Vector< sp<EffectChain> >& effectChains); | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 541 |                     // unlock effect chains after process | 
| Glenn Kasten | e53b9ea | 2012-03-12 16:29:55 -0700 | [diff] [blame] | 542 |                     void unlockEffectChains(const Vector< sp<EffectChain> >& effectChains); | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 543 |                     // set audio mode to all effect chains | 
| Glenn Kasten | f78aee7 | 2012-01-04 11:00:47 -0800 | [diff] [blame] | 544 |                     void setMode(audio_mode_t mode); | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 545 |                     // get effect module with corresponding ID on specified audio session | 
 | 546 |                     sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId); | 
 | 547 |                     // add and effect module. Also creates the effect chain is none exists for | 
 | 548 |                     // the effects audio session | 
 | 549 |                     status_t addEffect_l(const sp< EffectModule>& effect); | 
 | 550 |                     // remove and effect module. Also removes the effect chain is this was the last | 
 | 551 |                     // effect | 
 | 552 |                     void removeEffect_l(const sp< EffectModule>& effect); | 
 | 553 |                     // detach all tracks connected to an auxiliary effect | 
 | 554 |         virtual     void detachAuxEffect_l(int effectId) {} | 
 | 555 |                     // returns either EFFECT_SESSION if effects on this audio session exist in one | 
 | 556 |                     // chain, or TRACK_SESSION if tracks on this audio session exist, or both | 
 | 557 |                     virtual uint32_t hasAudioSession(int sessionId) = 0; | 
 | 558 |                     // the value returned by default implementation is not important as the | 
 | 559 |                     // strategy is only meaningful for PlaybackThread which implements this method | 
 | 560 |                     virtual uint32_t getStrategyForSession_l(int sessionId) { return 0; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 561 |  | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 562 |                     // suspend or restore effect according to the type of effect passed. a NULL | 
 | 563 |                     // type pointer means suspend all effects in the session | 
 | 564 |                     void setEffectSuspended(const effect_uuid_t *type, | 
 | 565 |                                             bool suspend, | 
 | 566 |                                             int sessionId = AUDIO_SESSION_OUTPUT_MIX); | 
 | 567 |                     // check if some effects must be suspended/restored when an effect is enabled | 
 | 568 |                     // or disabled | 
| Eric Laurent | a85a74a | 2011-10-19 11:44:54 -0700 | [diff] [blame] | 569 |                     void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 570 |                                                      bool enabled, | 
 | 571 |                                                      int sessionId = AUDIO_SESSION_OUTPUT_MIX); | 
| Eric Laurent | a85a74a | 2011-10-19 11:44:54 -0700 | [diff] [blame] | 572 |                     void checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect, | 
 | 573 |                                                        bool enabled, | 
 | 574 |                                                        int sessionId = AUDIO_SESSION_OUTPUT_MIX); | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 575 |  | 
 | 576 |                     virtual status_t    setSyncEvent(const sp<SyncEvent>& event) = 0; | 
 | 577 |                     virtual bool        isValidSyncEvent(const sp<SyncEvent>& event) = 0; | 
 | 578 |  | 
 | 579 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 580 |         mutable     Mutex                   mLock; | 
 | 581 |  | 
 | 582 |     protected: | 
 | 583 |  | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 584 |                     // entry describing an effect being suspended in mSuspendedSessions keyed vector | 
 | 585 |                     class SuspendedSessionDesc : public RefBase { | 
 | 586 |                     public: | 
 | 587 |                         SuspendedSessionDesc() : mRefCount(0) {} | 
 | 588 |  | 
 | 589 |                         int mRefCount;          // number of active suspend requests | 
 | 590 |                         effect_uuid_t mType;    // effect type UUID | 
 | 591 |                     }; | 
 | 592 |  | 
| Eric Laurent | feb0db6 | 2011-07-22 09:04:31 -0700 | [diff] [blame] | 593 |                     void        acquireWakeLock(); | 
 | 594 |                     void        acquireWakeLock_l(); | 
 | 595 |                     void        releaseWakeLock(); | 
 | 596 |                     void        releaseWakeLock_l(); | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 597 |                     void setEffectSuspended_l(const effect_uuid_t *type, | 
 | 598 |                                               bool suspend, | 
 | 599 |                                               int sessionId = AUDIO_SESSION_OUTPUT_MIX); | 
 | 600 |                     // updated mSuspendedSessions when an effect suspended or restored | 
 | 601 |                     void        updateSuspendedSessions_l(const effect_uuid_t *type, | 
 | 602 |                                                           bool suspend, | 
 | 603 |                                                           int sessionId); | 
 | 604 |                     // check if some effects must be suspended when an effect chain is added | 
 | 605 |                     void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain); | 
| Eric Laurent | feb0db6 | 2011-07-22 09:04:31 -0700 | [diff] [blame] | 606 |  | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 607 |         friend class AudioFlinger;      // for mEffectChains | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 608 |  | 
| Glenn Kasten | 23bb8be | 2012-01-26 10:38:26 -0800 | [diff] [blame] | 609 |                     const type_t            mType; | 
| Glenn Kasten | cbc52bf | 2012-03-01 09:21:37 -0800 | [diff] [blame] | 610 |  | 
 | 611 |                     // Used by parameters, config events, addTrack_l, exit | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 612 |                     Condition               mWaitWorkCV; | 
| Glenn Kasten | cbc52bf | 2012-03-01 09:21:37 -0800 | [diff] [blame] | 613 |  | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 614 |                     const sp<AudioFlinger>  mAudioFlinger; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 615 |                     uint32_t                mSampleRate; | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 616 |                     size_t                  mFrameCount;       // output HAL, direct output, record | 
 | 617 |                     size_t                  mNormalFrameCount; // normal mixer and effects | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 618 |                     uint32_t                mChannelMask; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 619 |                     uint16_t                mChannelCount; | 
| Glenn Kasten | b998065 | 2012-01-11 09:48:27 -0800 | [diff] [blame] | 620 |                     size_t                  mFrameSize; | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 621 |                     audio_format_t          mFormat; | 
| Glenn Kasten | cbc52bf | 2012-03-01 09:21:37 -0800 | [diff] [blame] | 622 |  | 
 | 623 |                     // Parameter sequence by client: binder thread calling setParameters(): | 
 | 624 |                     //  1. Lock mLock | 
 | 625 |                     //  2. Append to mNewParameters | 
 | 626 |                     //  3. mWaitWorkCV.signal | 
 | 627 |                     //  4. mParamCond.waitRelative with timeout | 
 | 628 |                     //  5. read mParamStatus | 
 | 629 |                     //  6. mWaitWorkCV.signal | 
 | 630 |                     //  7. Unlock | 
 | 631 |                     // | 
 | 632 |                     // Parameter sequence by server: threadLoop calling checkForNewParameters_l(): | 
 | 633 |                     // 1. Lock mLock | 
 | 634 |                     // 2. If there is an entry in mNewParameters proceed ... | 
 | 635 |                     // 2. Read first entry in mNewParameters | 
 | 636 |                     // 3. Process | 
 | 637 |                     // 4. Remove first entry from mNewParameters | 
 | 638 |                     // 5. Set mParamStatus | 
 | 639 |                     // 6. mParamCond.signal | 
 | 640 |                     // 7. mWaitWorkCV.wait with timeout (this is to avoid overwriting mParamStatus) | 
 | 641 |                     // 8. Unlock | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 642 |                     Condition               mParamCond; | 
 | 643 |                     Vector<String8>         mNewParameters; | 
 | 644 |                     status_t                mParamStatus; | 
| Glenn Kasten | cbc52bf | 2012-03-01 09:21:37 -0800 | [diff] [blame] | 645 |  | 
| Glenn Kasten | f3990f2 | 2011-12-13 11:50:00 -0800 | [diff] [blame] | 646 |                     Vector<ConfigEvent>     mConfigEvents; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 647 |                     bool                    mStandby; | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 648 |                     const audio_io_handle_t mId; | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 649 |                     Vector< sp<EffectChain> > mEffectChains; | 
 | 650 |                     uint32_t                mDevice;    // output device for PlaybackThread | 
 | 651 |                                                         // input + output devices for RecordThread | 
| Glenn Kasten | 480b468 | 2012-02-28 12:30:08 -0800 | [diff] [blame] | 652 |                     static const int        kNameLength = 16;   // prctl(PR_SET_NAME) limit | 
| Eric Laurent | feb0db6 | 2011-07-22 09:04:31 -0700 | [diff] [blame] | 653 |                     char                    mName[kNameLength]; | 
 | 654 |                     sp<IPowerManager>       mPowerManager; | 
 | 655 |                     sp<IBinder>             mWakeLockToken; | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 656 |                     const sp<PMDeathRecipient> mDeathRecipient; | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 657 |                     // list of suspended effects per session and per type. The first vector is | 
 | 658 |                     // keyed by session ID, the second by type UUID timeLow field | 
 | 659 |                     KeyedVector< int, KeyedVector< int, sp<SuspendedSessionDesc> > >  mSuspendedSessions; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 660 |     }; | 
 | 661 |  | 
| Glenn Kasten | b7bf796 | 2012-02-08 12:36:25 -0800 | [diff] [blame] | 662 |     struct  stream_type_t { | 
 | 663 |         stream_type_t() | 
 | 664 |             :   volume(1.0f), | 
| Eric Laurent | 1a9ed11 | 2012-03-20 18:36:01 -0700 | [diff] [blame] | 665 |                 mute(false) | 
| Glenn Kasten | b7bf796 | 2012-02-08 12:36:25 -0800 | [diff] [blame] | 666 |         { | 
 | 667 |         } | 
 | 668 |         float       volume; | 
 | 669 |         bool        mute; | 
| Glenn Kasten | b7bf796 | 2012-02-08 12:36:25 -0800 | [diff] [blame] | 670 |     }; | 
 | 671 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 672 |     // --- PlaybackThread --- | 
 | 673 |     class PlaybackThread : public ThreadBase { | 
 | 674 |     public: | 
 | 675 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 676 |         enum mixer_state { | 
| Glenn Kasten | d805b71 | 2012-02-24 15:42:48 -0800 | [diff] [blame] | 677 |             MIXER_IDLE,             // no active tracks | 
 | 678 |             MIXER_TRACKS_ENABLED,   // at least one active track, but no track has any data ready | 
 | 679 |             MIXER_TRACKS_READY      // at least one active track, and at least one track has data | 
 | 680 |             // standby mode does not have an enum value | 
 | 681 |             // suspend by audio policy manager is orthogonal to mixer state | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 682 |         }; | 
 | 683 |  | 
 | 684 |         // playback track | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 685 |         class Track : public TrackBase, public VolumeProvider { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 686 |         public: | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 687 |                                 Track(  PlaybackThread *thread, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 688 |                                         const sp<Client>& client, | 
| Glenn Kasten | fff6d71 | 2012-01-12 16:38:12 -0800 | [diff] [blame] | 689 |                                         audio_stream_type_t streamType, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 690 |                                         uint32_t sampleRate, | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 691 |                                         audio_format_t format, | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 692 |                                         uint32_t channelMask, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 693 |                                         int frameCount, | 
 | 694 |                                         const sp<IMemory>& sharedBuffer, | 
| Glenn Kasten | 73d2275 | 2012-03-19 13:38:30 -0700 | [diff] [blame] | 695 |                                         int sessionId, | 
 | 696 |                                         IAudioFlinger::track_flags_t flags); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 697 |             virtual             ~Track(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 698 |  | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 699 |             static  void        appendDumpHeader(String8& result); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 700 |                     void        dump(char* buffer, size_t size); | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 701 |             virtual status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE, | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 702 |                                      int triggerSession = 0); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 703 |             virtual void        stop(); | 
 | 704 |                     void        pause(); | 
 | 705 |  | 
 | 706 |                     void        flush(); | 
 | 707 |                     void        destroy(); | 
 | 708 |                     void        mute(bool); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 709 |                     int name() const { | 
 | 710 |                         return mName; | 
 | 711 |                     } | 
 | 712 |  | 
| Glenn Kasten | 02bbd20 | 2012-02-08 12:35:35 -0800 | [diff] [blame] | 713 |                     audio_stream_type_t streamType() const { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 714 |                         return mStreamType; | 
 | 715 |                     } | 
 | 716 |                     status_t    attachAuxEffect(int EffectId); | 
 | 717 |                     void        setAuxBuffer(int EffectId, int32_t *buffer); | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 718 |                     int32_t     *auxBuffer() const { return mAuxBuffer; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 719 |                     void        setMainBuffer(int16_t *buffer) { mMainBuffer = buffer; } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 720 |                     int16_t     *mainBuffer() const { return mMainBuffer; } | 
 | 721 |                     int         auxEffectId() const { return mAuxEffectId; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 722 |  | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 723 |         // implement FastMixerState::VolumeProvider interface | 
 | 724 |             virtual uint32_t    getVolumeLR(); | 
| Eric Laurent | 2986460 | 2012-05-08 18:57:51 -0700 | [diff] [blame] | 725 |             virtual status_t    setSyncEvent(const sp<SyncEvent>& event); | 
| Glenn Kasten | 73d2275 | 2012-03-19 13:38:30 -0700 | [diff] [blame] | 726 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 727 |         protected: | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 728 |             // for numerous | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 729 |             friend class PlaybackThread; | 
 | 730 |             friend class MixerThread; | 
 | 731 |             friend class DirectOutputThread; | 
 | 732 |  | 
 | 733 |                                 Track(const Track&); | 
 | 734 |                                 Track& operator = (const Track&); | 
 | 735 |  | 
| Glenn Kasten | 01c4ebf | 2012-02-22 10:47:35 -0800 | [diff] [blame] | 736 |             // AudioBufferProvider interface | 
 | 737 |             virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS); | 
 | 738 |             // releaseBuffer() not overridden | 
 | 739 |  | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 740 |             virtual size_t framesReady() const; | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 741 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 742 |             bool isMuted() const { return mMute; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 743 |             bool isPausing() const { | 
 | 744 |                 return mState == PAUSING; | 
 | 745 |             } | 
 | 746 |             bool isPaused() const { | 
 | 747 |                 return mState == PAUSED; | 
 | 748 |             } | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 749 |             bool isResuming() const { | 
 | 750 |                 return mState == RESUMING; | 
 | 751 |             } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 752 |             bool isReady() const; | 
 | 753 |             void setPaused() { mState = PAUSED; } | 
 | 754 |             void reset(); | 
 | 755 |  | 
 | 756 |             bool isOutputTrack() const { | 
| Dima Zavin | fce7a47 | 2011-04-19 22:30:36 -0700 | [diff] [blame] | 757 |                 return (mStreamType == AUDIO_STREAM_CNT); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 758 |             } | 
 | 759 |  | 
| Eric Laurent | 83faee0 | 2012-04-27 18:24:29 -0700 | [diff] [blame] | 760 |             sp<IMemory> sharedBuffer() const { return mSharedBuffer; } | 
 | 761 |  | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 762 |             bool presentationComplete(size_t framesWritten, size_t audioHalFrames); | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 763 |  | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 764 |         public: | 
| Eric Laurent | 2986460 | 2012-05-08 18:57:51 -0700 | [diff] [blame] | 765 |             void triggerEvents(AudioSystem::sync_event_t type); | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 766 |             virtual bool isTimedTrack() const { return false; } | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 767 |             bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; } | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 768 |         protected: | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 769 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 770 |             // we don't really need a lock for these | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 771 |             volatile bool       mMute; | 
 | 772 |             // FILLED state is used for suppressing volume ramp at begin of playing | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 773 |             enum {FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE}; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 774 |             mutable uint8_t     mFillingUpStatus; | 
 | 775 |             int8_t              mRetryCount; | 
| Glenn Kasten | f995901 | 2012-03-19 11:14:37 -0700 | [diff] [blame] | 776 |             const sp<IMemory>   mSharedBuffer; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 777 |             bool                mResetDone; | 
| Glenn Kasten | f995901 | 2012-03-19 11:14:37 -0700 | [diff] [blame] | 778 |             const audio_stream_type_t mStreamType; | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 779 |             int                 mName;      // track name on the normal mixer, | 
 | 780 |                                             // allocated statically at track creation time, | 
 | 781 |                                             // and is even allocated (though unused) for fast tracks | 
| Glenn Kasten | 893a054 | 2012-05-30 10:32:06 -0700 | [diff] [blame] | 782 |                                             // FIXME don't allocate track name for fast tracks | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 783 |             int16_t             *mMainBuffer; | 
 | 784 |             int32_t             *mAuxBuffer; | 
 | 785 |             int                 mAuxEffectId; | 
| Eric Laurent | 8f45bd7 | 2010-08-31 13:50:07 -0700 | [diff] [blame] | 786 |             bool                mHasVolumeController; | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 787 |             size_t              mPresentationCompleteFrames; // number of frames written to the audio HAL | 
 | 788 |                                                        // when this track will be fully rendered | 
| Glenn Kasten | 73d2275 | 2012-03-19 13:38:30 -0700 | [diff] [blame] | 789 |         private: | 
 | 790 |             IAudioFlinger::track_flags_t mFlags; | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 791 |  | 
 | 792 |             // The following fields are only for fast tracks, and should be in a subclass | 
 | 793 |             int                 mFastIndex; // index within FastMixerState::mFastTracks[]; | 
| Glenn Kasten | 893a054 | 2012-05-30 10:32:06 -0700 | [diff] [blame] | 794 |                                             // either mFastIndex == -1 if not isFastTrack() | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 795 |                                             // or 0 < mFastIndex < FastMixerState::kMaxFast because | 
 | 796 |                                             // index 0 is reserved for normal mixer's submix; | 
 | 797 |                                             // index is allocated statically at track creation time | 
 | 798 |                                             // but the slot is only used if track is active | 
| Glenn Kasten | 09474df | 2012-05-10 14:48:07 -0700 | [diff] [blame] | 799 |             FastTrackUnderruns  mObservedUnderruns; // Most recently observed value of | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 800 |                                             // mFastMixerDumpState.mTracks[mFastIndex].mUnderruns | 
 | 801 |             uint32_t            mUnderrunCount; // Counter of total number of underruns, never reset | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 802 |             volatile float      mCachedVolume;  // combined master volume and stream type volume; | 
 | 803 |                                                 // 'volatile' means accessed without lock or | 
 | 804 |                                                 // barrier, but is read/written atomically | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 805 |         };  // end of Track | 
 | 806 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 807 |         class TimedTrack : public Track { | 
 | 808 |           public: | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 809 |             static sp<TimedTrack> create(PlaybackThread *thread, | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 810 |                                          const sp<Client>& client, | 
 | 811 |                                          audio_stream_type_t streamType, | 
 | 812 |                                          uint32_t sampleRate, | 
 | 813 |                                          audio_format_t format, | 
 | 814 |                                          uint32_t channelMask, | 
 | 815 |                                          int frameCount, | 
 | 816 |                                          const sp<IMemory>& sharedBuffer, | 
 | 817 |                                          int sessionId); | 
 | 818 |             ~TimedTrack(); | 
 | 819 |  | 
 | 820 |             class TimedBuffer { | 
 | 821 |               public: | 
 | 822 |                 TimedBuffer(); | 
 | 823 |                 TimedBuffer(const sp<IMemory>& buffer, int64_t pts); | 
 | 824 |                 const sp<IMemory>& buffer() const { return mBuffer; } | 
 | 825 |                 int64_t pts() const { return mPTS; } | 
| John Grossman | 1c34519 | 2012-03-27 14:00:17 -0700 | [diff] [blame] | 826 |                 uint32_t position() const { return mPosition; } | 
 | 827 |                 void setPosition(uint32_t pos) { mPosition = pos; } | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 828 |               private: | 
 | 829 |                 sp<IMemory> mBuffer; | 
| John Grossman | 1c34519 | 2012-03-27 14:00:17 -0700 | [diff] [blame] | 830 |                 int64_t     mPTS; | 
 | 831 |                 uint32_t    mPosition; | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 832 |             }; | 
 | 833 |  | 
| John Grossman | 1c34519 | 2012-03-27 14:00:17 -0700 | [diff] [blame] | 834 |             // Mixer facing methods. | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 835 |             virtual bool isTimedTrack() const { return true; } | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 836 |             virtual size_t framesReady() const; | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 837 |  | 
| Glenn Kasten | 01c4ebf | 2012-02-22 10:47:35 -0800 | [diff] [blame] | 838 |             // AudioBufferProvider interface | 
| John Grossman | 1c34519 | 2012-03-27 14:00:17 -0700 | [diff] [blame] | 839 |             virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, | 
 | 840 |                                            int64_t pts); | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 841 |             virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer); | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 842 |  | 
| John Grossman | 1c34519 | 2012-03-27 14:00:17 -0700 | [diff] [blame] | 843 |             // Client/App facing methods. | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 844 |             status_t    allocateTimedBuffer(size_t size, | 
 | 845 |                                             sp<IMemory>* buffer); | 
 | 846 |             status_t    queueTimedBuffer(const sp<IMemory>& buffer, | 
 | 847 |                                          int64_t pts); | 
 | 848 |             status_t    setMediaTimeTransform(const LinearTransform& xform, | 
 | 849 |                                               TimedAudioTrack::TargetTimeline target); | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 850 |  | 
 | 851 |           private: | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 852 |             TimedTrack(PlaybackThread *thread, | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 853 |                        const sp<Client>& client, | 
 | 854 |                        audio_stream_type_t streamType, | 
 | 855 |                        uint32_t sampleRate, | 
 | 856 |                        audio_format_t format, | 
 | 857 |                        uint32_t channelMask, | 
 | 858 |                        int frameCount, | 
 | 859 |                        const sp<IMemory>& sharedBuffer, | 
 | 860 |                        int sessionId); | 
 | 861 |  | 
| John Grossman | 1c34519 | 2012-03-27 14:00:17 -0700 | [diff] [blame] | 862 |             void timedYieldSamples_l(AudioBufferProvider::Buffer* buffer); | 
 | 863 |             void timedYieldSilence_l(uint32_t numFrames, | 
 | 864 |                                      AudioBufferProvider::Buffer* buffer); | 
 | 865 |             void trimTimedBufferQueue_l(); | 
 | 866 |             void trimTimedBufferQueueHead_l(const char* logTag); | 
 | 867 |             void updateFramesPendingAfterTrim_l(const TimedBuffer& buf, | 
 | 868 |                                                 const char* logTag); | 
 | 869 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 870 |             uint64_t            mLocalTimeFreq; | 
 | 871 |             LinearTransform     mLocalTimeToSampleTransform; | 
| John Grossman | 9fbdee1 | 2012-03-26 17:51:46 -0700 | [diff] [blame] | 872 |             LinearTransform     mMediaTimeToSampleTransform; | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 873 |             sp<MemoryDealer>    mTimedMemoryDealer; | 
| John Grossman | 9fbdee1 | 2012-03-26 17:51:46 -0700 | [diff] [blame] | 874 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 875 |             Vector<TimedBuffer> mTimedBufferQueue; | 
| John Grossman | 9fbdee1 | 2012-03-26 17:51:46 -0700 | [diff] [blame] | 876 |             bool                mQueueHeadInFlight; | 
 | 877 |             bool                mTrimQueueHeadOnRelease; | 
| John Grossman | 1c34519 | 2012-03-27 14:00:17 -0700 | [diff] [blame] | 878 |             uint32_t            mFramesPendingInQueue; | 
| John Grossman | 9fbdee1 | 2012-03-26 17:51:46 -0700 | [diff] [blame] | 879 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 880 |             uint8_t*            mTimedSilenceBuffer; | 
 | 881 |             uint32_t            mTimedSilenceBufferSize; | 
 | 882 |             mutable Mutex       mTimedBufferQueueLock; | 
 | 883 |             bool                mTimedAudioOutputOnTime; | 
 | 884 |             CCHelper            mCCHelper; | 
 | 885 |  | 
 | 886 |             Mutex               mMediaTimeTransformLock; | 
 | 887 |             LinearTransform     mMediaTimeTransform; | 
 | 888 |             bool                mMediaTimeTransformValid; | 
 | 889 |             TimedAudioTrack::TargetTimeline mMediaTimeTransformTarget; | 
 | 890 |         }; | 
 | 891 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 892 |  | 
 | 893 |         // playback track | 
 | 894 |         class OutputTrack : public Track { | 
 | 895 |         public: | 
 | 896 |  | 
 | 897 |             class Buffer: public AudioBufferProvider::Buffer { | 
 | 898 |             public: | 
 | 899 |                 int16_t *mBuffer; | 
 | 900 |             }; | 
 | 901 |  | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 902 |                                 OutputTrack(PlaybackThread *thread, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 903 |                                         DuplicatingThread *sourceThread, | 
 | 904 |                                         uint32_t sampleRate, | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 905 |                                         audio_format_t format, | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 906 |                                         uint32_t channelMask, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 907 |                                         int frameCount); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 908 |             virtual             ~OutputTrack(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 909 |  | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 910 |             virtual status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE, | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 911 |                                      int triggerSession = 0); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 912 |             virtual void        stop(); | 
 | 913 |                     bool        write(int16_t* data, uint32_t frames); | 
| Glenn Kasten | a111792 | 2012-01-26 10:53:32 -0800 | [diff] [blame] | 914 |                     bool        bufferQueueEmpty() const { return mBufferQueue.size() == 0; } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 915 |                     bool        isActive() const { return mActive; } | 
 | 916 |             const wp<ThreadBase>& thread() const { return mThread; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 917 |  | 
 | 918 |         private: | 
 | 919 |  | 
| Glenn Kasten | 335787f | 2012-01-20 17:00:00 -0800 | [diff] [blame] | 920 |             enum { | 
 | 921 |                 NO_MORE_BUFFERS = 0x80000001,   // same in AudioTrack.h, ok to be different value | 
 | 922 |             }; | 
 | 923 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 924 |             status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs); | 
 | 925 |             void                clearBufferQueue(); | 
 | 926 |  | 
 | 927 |             // Maximum number of pending buffers allocated by OutputTrack::write() | 
 | 928 |             static const uint8_t kMaxOverFlowBuffers = 10; | 
 | 929 |  | 
 | 930 |             Vector < Buffer* >          mBufferQueue; | 
 | 931 |             AudioBufferProvider::Buffer mOutBuffer; | 
 | 932 |             bool                        mActive; | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 933 |             DuplicatingThread* const mSourceThread; // for waitTimeMs() in write() | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 934 |         };  // end of OutputTrack | 
 | 935 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 936 |         PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, | 
 | 937 |                         audio_io_handle_t id, uint32_t device, type_t type); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 938 |         virtual             ~PlaybackThread(); | 
 | 939 |  | 
| Glenn Kasten | 688aac7 | 2012-03-09 10:30:26 -0800 | [diff] [blame] | 940 |                     status_t    dump(int fd, const Vector<String16>& args); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 941 |  | 
 | 942 |         // Thread virtuals | 
 | 943 |         virtual     status_t    readyToRun(); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 944 |         virtual     bool        threadLoop(); | 
 | 945 |  | 
 | 946 |         // RefBase | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 947 |         virtual     void        onFirstRef(); | 
 | 948 |  | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 949 | protected: | 
 | 950 |         // Code snippets that were lifted up out of threadLoop() | 
 | 951 |         virtual     void        threadLoop_mix() = 0; | 
 | 952 |         virtual     void        threadLoop_sleepTime() = 0; | 
 | 953 |         virtual     void        threadLoop_write(); | 
 | 954 |         virtual     void        threadLoop_standby(); | 
| Eric Laurent | 44a957f | 2012-05-15 15:26:05 -0700 | [diff] [blame] | 955 |         virtual     void        threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 956 |  | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 957 |                     // prepareTracks_l reads and writes mActiveTracks, and returns | 
 | 958 |                     // the pending set of tracks to remove via Vector 'tracksToRemove'.  The caller | 
 | 959 |                     // is responsible for clearing or destroying this Vector later on, when it | 
| Glenn Kasten | 1465f0c | 2012-03-06 11:23:32 -0800 | [diff] [blame] | 960 |                     // is safe to do so. That will drop the final ref count and destroy the tracks. | 
 | 961 |         virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove) = 0; | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 962 |  | 
 | 963 | public: | 
 | 964 |  | 
| Glenn Kasten | e0feee3 | 2011-12-13 11:53:26 -0800 | [diff] [blame] | 965 |         virtual     status_t    initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; } | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 966 |  | 
| Glenn Kasten | 688aac7 | 2012-03-09 10:30:26 -0800 | [diff] [blame] | 967 |                     // return estimated latency in milliseconds, as reported by HAL | 
 | 968 |                     uint32_t    latency() const; | 
| Marco Nelissen | f06c2ed | 2012-06-06 09:52:31 -0700 | [diff] [blame] | 969 |                     // same, but lock must already be held | 
 | 970 |                     uint32_t    latency_l() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 971 |  | 
| Glenn Kasten | 6637baa | 2012-01-09 09:40:36 -0800 | [diff] [blame] | 972 |                     void        setMasterVolume(float value); | 
 | 973 |                     void        setMasterMute(bool muted); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 974 |  | 
| Glenn Kasten | 6637baa | 2012-01-09 09:40:36 -0800 | [diff] [blame] | 975 |                     void        setStreamVolume(audio_stream_type_t stream, float value); | 
 | 976 |                     void        setStreamMute(audio_stream_type_t stream, bool muted); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 977 |  | 
| Glenn Kasten | 6637baa | 2012-01-09 09:40:36 -0800 | [diff] [blame] | 978 |                     float       streamVolume(audio_stream_type_t stream) const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 979 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 980 |                     sp<Track>   createTrack_l( | 
 | 981 |                                     const sp<AudioFlinger::Client>& client, | 
| Glenn Kasten | fff6d71 | 2012-01-12 16:38:12 -0800 | [diff] [blame] | 982 |                                     audio_stream_type_t streamType, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 983 |                                     uint32_t sampleRate, | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 984 |                                     audio_format_t format, | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 985 |                                     uint32_t channelMask, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 986 |                                     int frameCount, | 
 | 987 |                                     const sp<IMemory>& sharedBuffer, | 
 | 988 |                                     int sessionId, | 
| Glenn Kasten | 73d2275 | 2012-03-19 13:38:30 -0700 | [diff] [blame] | 989 |                                     IAudioFlinger::track_flags_t flags, | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 990 |                                     pid_t tid, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 991 |                                     status_t *status); | 
 | 992 |  | 
| Glenn Kasten | aed850d | 2012-01-26 09:46:34 -0800 | [diff] [blame] | 993 |                     AudioStreamOut* getOutput() const; | 
| Eric Laurent | b8ba0a9 | 2011-08-07 16:32:26 -0700 | [diff] [blame] | 994 |                     AudioStreamOut* clearOutput(); | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 995 |                     virtual audio_stream_t* stream() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 996 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 997 |                     void        suspend() { mSuspended++; } | 
| Glenn Kasten | c455fe9 | 2012-02-29 07:07:30 -0800 | [diff] [blame] | 998 |                     void        restore() { if (mSuspended > 0) mSuspended--; } | 
 | 999 |                     bool        isSuspended() const { return (mSuspended > 0); } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1000 |         virtual     String8     getParameters(const String8& keys); | 
 | 1001 |         virtual     void        audioConfigChanged_l(int event, int param = 0); | 
| Glenn Kasten | 688aac7 | 2012-03-09 10:30:26 -0800 | [diff] [blame] | 1002 |                     status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1003 |                     int16_t     *mixBuffer() const { return mMixBuffer; }; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1004 |  | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1005 |         virtual     void detachAuxEffect_l(int effectId); | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1006 |                     status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track, | 
 | 1007 |                             int EffectId); | 
 | 1008 |                     status_t attachAuxEffect_l(const sp<AudioFlinger::PlaybackThread::Track> track, | 
 | 1009 |                             int EffectId); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1010 |  | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1011 |                     virtual status_t addEffectChain_l(const sp<EffectChain>& chain); | 
 | 1012 |                     virtual size_t removeEffectChain_l(const sp<EffectChain>& chain); | 
 | 1013 |                     virtual uint32_t hasAudioSession(int sessionId); | 
 | 1014 |                     virtual uint32_t getStrategyForSession_l(int sessionId); | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1015 |  | 
| Eric Laurent | 9f6530f | 2011-08-30 10:18:54 -0700 | [diff] [blame] | 1016 |  | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1017 |                     virtual status_t setSyncEvent(const sp<SyncEvent>& event); | 
 | 1018 |                     virtual bool     isValidSyncEvent(const sp<SyncEvent>& event); | 
| Eric Laurent | 2216785 | 2012-06-20 12:26:32 -0700 | [diff] [blame^] | 1019 |                             void     invalidateTracks(audio_stream_type_t streamType); | 
 | 1020 |  | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1021 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1022 |     protected: | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1023 |         int16_t*                        mMixBuffer; | 
| Glenn Kasten | c455fe9 | 2012-02-29 07:07:30 -0800 | [diff] [blame] | 1024 |         uint32_t                        mSuspended;     // suspend count, > 0 means suspended | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1025 |         int                             mBytesWritten; | 
| Glenn Kasten | 9806710 | 2011-12-13 11:47:54 -0800 | [diff] [blame] | 1026 |     private: | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1027 |         // mMasterMute is in both PlaybackThread and in AudioFlinger.  When a | 
 | 1028 |         // PlaybackThread needs to find out if master-muted, it checks it's local | 
 | 1029 |         // copy rather than the one in AudioFlinger.  This optimization saves a lock. | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1030 |         bool                            mMasterMute; | 
| Glenn Kasten | 6637baa | 2012-01-09 09:40:36 -0800 | [diff] [blame] | 1031 |                     void        setMasterMute_l(bool muted) { mMasterMute = muted; } | 
| Glenn Kasten | 9806710 | 2011-12-13 11:47:54 -0800 | [diff] [blame] | 1032 |     protected: | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 1033 |         SortedVector< wp<Track> >       mActiveTracks;  // FIXME check if this could be sp<> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1034 |  | 
| Jean-Michel Trivi | 7d5b262 | 2012-04-04 18:54:36 -0700 | [diff] [blame] | 1035 |         // Allocate a track name for a given channel mask. | 
 | 1036 |         //   Returns name >= 0 if successful, -1 on failure. | 
 | 1037 |         virtual int             getTrackName_l(audio_channel_mask_t channelMask) = 0; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1038 |         virtual void            deleteTrackName_l(int name) = 0; | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 1039 |  | 
 | 1040 |         // Time to sleep between cycles when: | 
 | 1041 |         virtual uint32_t        activeSleepTimeUs() const;      // mixer state MIXER_TRACKS_ENABLED | 
 | 1042 |         virtual uint32_t        idleSleepTimeUs() const = 0;    // mixer state MIXER_IDLE | 
 | 1043 |         virtual uint32_t        suspendSleepTimeUs() const = 0; // audio policy manager suspended us | 
 | 1044 |         // No sleep when mixer state == MIXER_TRACKS_READY; relies on audio HAL stream->write() | 
 | 1045 |         // No sleep in standby mode; waits on a condition | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1046 |  | 
| Glenn Kasten | 37d825e | 2012-02-24 07:21:48 -0800 | [diff] [blame] | 1047 |         // Code snippets that are temporarily lifted up out of threadLoop() until the merge | 
 | 1048 |                     void        checkSilentMode_l(); | 
 | 1049 |  | 
| Glenn Kasten | fa26a85 | 2012-03-06 11:28:04 -0800 | [diff] [blame] | 1050 |         // Non-trivial for DUPLICATING only | 
 | 1051 |         virtual     void        saveOutputTracks() { } | 
 | 1052 |         virtual     void        clearOutputTracks() { } | 
 | 1053 |  | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1054 |         // Cache various calculated values, at threadLoop() entry and after a parameter change | 
 | 1055 |         virtual     void        cacheParameters_l(); | 
 | 1056 |  | 
| Eric Laurent | e737cda | 2012-05-22 18:55:44 -0700 | [diff] [blame] | 1057 |         virtual     uint32_t    correctLatency(uint32_t latency) const; | 
 | 1058 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1059 |     private: | 
 | 1060 |  | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 1061 |         friend class AudioFlinger;      // for numerous | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1062 |  | 
 | 1063 |         PlaybackThread(const Client&); | 
 | 1064 |         PlaybackThread& operator = (const PlaybackThread&); | 
 | 1065 |  | 
 | 1066 |         status_t    addTrack_l(const sp<Track>& track); | 
 | 1067 |         void        destroyTrack_l(const sp<Track>& track); | 
| Eric Laurent | b469b94 | 2011-05-09 12:09:06 -0700 | [diff] [blame] | 1068 |         void        removeTrack_l(const sp<Track>& track); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1069 |  | 
 | 1070 |         void        readOutputParameters(); | 
 | 1071 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1072 |         virtual status_t    dumpInternals(int fd, const Vector<String16>& args); | 
 | 1073 |         status_t    dumpTracks(int fd, const Vector<String16>& args); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1074 |  | 
 | 1075 |         SortedVector< sp<Track> >       mTracks; | 
| Glenn Kasten | 263709e | 2012-01-06 08:40:01 -0800 | [diff] [blame] | 1076 |         // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by DuplicatingThread | 
| Dima Zavin | fce7a47 | 2011-04-19 22:30:36 -0700 | [diff] [blame] | 1077 |         stream_type_t                   mStreamTypes[AUDIO_STREAM_CNT + 1]; | 
| Glenn Kasten | aed850d | 2012-01-26 09:46:34 -0800 | [diff] [blame] | 1078 |         AudioStreamOut                  *mOutput; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1079 |         float                           mMasterVolume; | 
 | 1080 |         nsecs_t                         mLastWriteTime; | 
 | 1081 |         int                             mNumWrites; | 
 | 1082 |         int                             mNumDelayedWrites; | 
 | 1083 |         bool                            mInWrite; | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1084 |  | 
 | 1085 |         // FIXME rename these former local variables of threadLoop to standard "m" names | 
 | 1086 |         nsecs_t                         standbyTime; | 
 | 1087 |         size_t                          mixBufferSize; | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1088 |  | 
 | 1089 |         // cached copies of activeSleepTimeUs() and idleSleepTimeUs() made by cacheParameters_l() | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1090 |         uint32_t                        activeSleepTime; | 
 | 1091 |         uint32_t                        idleSleepTime; | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1092 |  | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1093 |         uint32_t                        sleepTime; | 
| Glenn Kasten | fec279f | 2012-03-08 07:47:15 -0800 | [diff] [blame] | 1094 |  | 
 | 1095 |         // mixer status returned by prepareTracks_l() | 
| Eric Laurent | da74744 | 2012-04-25 18:53:13 -0700 | [diff] [blame] | 1096 |         mixer_state                     mMixerStatus; // current cycle | 
 | 1097 |                                                       // previous cycle when in prepareTracks_l() | 
| Glenn Kasten | 8102804 | 2012-04-30 18:15:12 -0700 | [diff] [blame] | 1098 |         mixer_state                     mMixerStatusIgnoringFastTracks; | 
 | 1099 |                                                       // FIXME or a separate ready state per track | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1100 |  | 
 | 1101 |         // FIXME move these declarations into the specific sub-class that needs them | 
 | 1102 |         // MIXER only | 
 | 1103 |         bool                            longStandbyExit; | 
 | 1104 |         uint32_t                        sleepTimeShift; | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1105 |  | 
 | 1106 |         // same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1107 |         nsecs_t                         standbyDelay; | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1108 |  | 
 | 1109 |         // MIXER only | 
 | 1110 |         nsecs_t                         maxPeriod; | 
 | 1111 |  | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1112 |         // DUPLICATING only | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1113 |         uint32_t                        writeFrames; | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1114 |  | 
 | 1115 |     private: | 
 | 1116 |         // The HAL output sink is treated as non-blocking, but current implementation is blocking | 
 | 1117 |         sp<NBAIO_Sink>          mOutputSink; | 
 | 1118 |         // If a fast mixer is present, the blocking pipe sink, otherwise clear | 
 | 1119 |         sp<NBAIO_Sink>          mPipeSink; | 
 | 1120 |         // The current sink for the normal mixer to write it's (sub)mix, mOutputSink or mPipeSink | 
 | 1121 |         sp<NBAIO_Sink>          mNormalSink; | 
| Glenn Kasten | fbae5da | 2012-05-21 09:17:20 -0700 | [diff] [blame] | 1122 |         // For dumpsys | 
 | 1123 |         sp<NBAIO_Sink>          mTeeSink; | 
 | 1124 |         sp<NBAIO_Source>        mTeeSource; | 
| Glenn Kasten | 28ed2f9 | 2012-06-07 10:17:54 -0700 | [diff] [blame] | 1125 |         uint32_t                mScreenState;   // cached copy of gScreenState | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1126 |     public: | 
 | 1127 |         virtual     bool        hasFastMixer() const = 0; | 
| Glenn Kasten | 09474df | 2012-05-10 14:48:07 -0700 | [diff] [blame] | 1128 |         virtual     FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const | 
 | 1129 |                                     { FastTrackUnderruns dummy; return dummy; } | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1130 |  | 
 | 1131 |     protected: | 
 | 1132 |                     // accessed by both binder threads and within threadLoop(), lock on mutex needed | 
 | 1133 |                     unsigned    mFastTrackAvailMask;    // bit i set if fast track [i] is available | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1134 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1135 |     }; | 
 | 1136 |  | 
 | 1137 |     class MixerThread : public PlaybackThread { | 
 | 1138 |     public: | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1139 |         MixerThread (const sp<AudioFlinger>& audioFlinger, | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 1140 |                      AudioStreamOut* output, | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1141 |                      audio_io_handle_t id, | 
| Glenn Kasten | 23bb8be | 2012-01-26 10:38:26 -0800 | [diff] [blame] | 1142 |                      uint32_t device, | 
 | 1143 |                      type_t type = MIXER); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1144 |         virtual             ~MixerThread(); | 
 | 1145 |  | 
 | 1146 |         // Thread virtuals | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1147 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1148 |         virtual     bool        checkForNewParameters_l(); | 
 | 1149 |         virtual     status_t    dumpInternals(int fd, const Vector<String16>& args); | 
 | 1150 |  | 
 | 1151 |     protected: | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1152 |         virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove); | 
| Jean-Michel Trivi | 7d5b262 | 2012-04-04 18:54:36 -0700 | [diff] [blame] | 1153 |         virtual     int         getTrackName_l(audio_channel_mask_t channelMask); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1154 |         virtual     void        deleteTrackName_l(int name); | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 1155 |         virtual     uint32_t    idleSleepTimeUs() const; | 
 | 1156 |         virtual     uint32_t    suspendSleepTimeUs() const; | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1157 |         virtual     void        cacheParameters_l(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1158 |  | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1159 |         // threadLoop snippets | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1160 |         virtual     void        threadLoop_write(); | 
 | 1161 |         virtual     void        threadLoop_standby(); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1162 |         virtual     void        threadLoop_mix(); | 
 | 1163 |         virtual     void        threadLoop_sleepTime(); | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1164 |         virtual     void        threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove); | 
| Eric Laurent | e737cda | 2012-05-22 18:55:44 -0700 | [diff] [blame] | 1165 |         virtual     uint32_t    correctLatency(uint32_t latency) const; | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1166 |  | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1167 |                     AudioMixer* mAudioMixer;    // normal mixer | 
 | 1168 |     private: | 
 | 1169 | #ifdef SOAKER | 
 | 1170 |                     Thread*     mSoaker; | 
 | 1171 | #endif | 
 | 1172 |                     // one-time initialization, no locks required | 
 | 1173 |                     FastMixer*  mFastMixer;         // non-NULL if there is also a fast mixer | 
| Glenn Kasten | c15d665 | 2012-05-30 14:52:57 -0700 | [diff] [blame] | 1174 |                     sp<AudioWatchdog> mAudioWatchdog; // non-0 if there is an audio watchdog thread | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1175 |  | 
 | 1176 |                     // contents are not guaranteed to be consistent, no locks required | 
 | 1177 |                     FastMixerDumpState mFastMixerDumpState; | 
| Glenn Kasten | 3999308 | 2012-05-31 13:40:27 -0700 | [diff] [blame] | 1178 | #ifdef STATE_QUEUE_DUMP | 
 | 1179 |                     StateQueueObserverDump mStateQueueObserverDump; | 
 | 1180 |                     StateQueueMutatorDump  mStateQueueMutatorDump; | 
 | 1181 | #endif | 
| Glenn Kasten | c15d665 | 2012-05-30 14:52:57 -0700 | [diff] [blame] | 1182 |                     AudioWatchdogDump mAudioWatchdogDump; | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1183 |  | 
 | 1184 |                     // accessible only within the threadLoop(), no locks required | 
 | 1185 |                     //          mFastMixer->sq()    // for mutating and pushing state | 
 | 1186 |                     int32_t     mFastMixerFutex;    // for cold idle | 
 | 1187 |  | 
 | 1188 |     public: | 
 | 1189 |         virtual     bool        hasFastMixer() const { return mFastMixer != NULL; } | 
| Glenn Kasten | 09474df | 2012-05-10 14:48:07 -0700 | [diff] [blame] | 1190 |         virtual     FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const { | 
| Glenn Kasten | 88cbea8 | 2012-05-15 07:39:27 -0700 | [diff] [blame] | 1191 |                                   ALOG_ASSERT(fastIndex < FastMixerState::kMaxFastTracks); | 
| Glenn Kasten | 09474df | 2012-05-10 14:48:07 -0700 | [diff] [blame] | 1192 |                                   return mFastMixerDumpState.mTracks[fastIndex].mUnderruns; | 
| Glenn Kasten | 288ed21 | 2012-04-25 17:52:27 -0700 | [diff] [blame] | 1193 |                                 } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1194 |     }; | 
 | 1195 |  | 
 | 1196 |     class DirectOutputThread : public PlaybackThread { | 
 | 1197 |     public: | 
 | 1198 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1199 |         DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, | 
 | 1200 |                             audio_io_handle_t id, uint32_t device); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 1201 |         virtual                 ~DirectOutputThread(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1202 |  | 
 | 1203 |         // Thread virtuals | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1204 |  | 
 | 1205 |         virtual     bool        checkForNewParameters_l(); | 
 | 1206 |  | 
 | 1207 |     protected: | 
| Jean-Michel Trivi | 7d5b262 | 2012-04-04 18:54:36 -0700 | [diff] [blame] | 1208 |         virtual     int         getTrackName_l(audio_channel_mask_t channelMask); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1209 |         virtual     void        deleteTrackName_l(int name); | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 1210 |         virtual     uint32_t    activeSleepTimeUs() const; | 
 | 1211 |         virtual     uint32_t    idleSleepTimeUs() const; | 
 | 1212 |         virtual     uint32_t    suspendSleepTimeUs() const; | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1213 |         virtual     void        cacheParameters_l(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1214 |  | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1215 |         // threadLoop snippets | 
| Glenn Kasten | 1465f0c | 2012-03-06 11:23:32 -0800 | [diff] [blame] | 1216 |         virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1217 |         virtual     void        threadLoop_mix(); | 
 | 1218 |         virtual     void        threadLoop_sleepTime(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1219 |  | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1220 |         // volumes last sent to audio HAL with stream->set_volume() | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1221 |         float mLeftVolFloat; | 
 | 1222 |         float mRightVolFloat; | 
| Glenn Kasten | d4513b0 | 2012-03-06 15:52:35 -0800 | [diff] [blame] | 1223 |  | 
 | 1224 | private: | 
| Glenn Kasten | b071e9b | 2012-03-07 17:05:59 -0800 | [diff] [blame] | 1225 |         // prepareTracks_l() tells threadLoop_mix() the name of the single active track | 
 | 1226 |         sp<Track>               mActiveTrack; | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1227 |     public: | 
 | 1228 |         virtual     bool        hasFastMixer() const { return false; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1229 |     }; | 
 | 1230 |  | 
 | 1231 |     class DuplicatingThread : public MixerThread { | 
 | 1232 |     public: | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1233 |         DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, | 
 | 1234 |                            audio_io_handle_t id); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 1235 |         virtual                 ~DuplicatingThread(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1236 |  | 
 | 1237 |         // Thread virtuals | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1238 |                     void        addOutputTrack(MixerThread* thread); | 
 | 1239 |                     void        removeOutputTrack(MixerThread* thread); | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 1240 |                     uint32_t    waitTimeMs() const { return mWaitTimeMs; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1241 |     protected: | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 1242 |         virtual     uint32_t    activeSleepTimeUs() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1243 |  | 
 | 1244 |     private: | 
| Glenn Kasten | e53b9ea | 2012-03-12 16:29:55 -0700 | [diff] [blame] | 1245 |                     bool        outputsReady(const SortedVector< sp<OutputTrack> > &outputTracks); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1246 |     protected: | 
 | 1247 |         // threadLoop snippets | 
 | 1248 |         virtual     void        threadLoop_mix(); | 
 | 1249 |         virtual     void        threadLoop_sleepTime(); | 
 | 1250 |         virtual     void        threadLoop_write(); | 
 | 1251 |         virtual     void        threadLoop_standby(); | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1252 |         virtual     void        cacheParameters_l(); | 
| Glenn Kasten | 438b036 | 2012-03-06 11:24:48 -0800 | [diff] [blame] | 1253 |  | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1254 |     private: | 
| Glenn Kasten | 438b036 | 2012-03-06 11:24:48 -0800 | [diff] [blame] | 1255 |         // called from threadLoop, addOutputTrack, removeOutputTrack | 
 | 1256 |         virtual     void        updateWaitTime_l(); | 
| Glenn Kasten | 66fcab9 | 2012-02-24 14:59:21 -0800 | [diff] [blame] | 1257 |     protected: | 
| Glenn Kasten | fa26a85 | 2012-03-06 11:28:04 -0800 | [diff] [blame] | 1258 |         virtual     void        saveOutputTracks(); | 
 | 1259 |         virtual     void        clearOutputTracks(); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1260 |     private: | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1261 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1262 |                     uint32_t    mWaitTimeMs; | 
| Glenn Kasten | fa26a85 | 2012-03-06 11:28:04 -0800 | [diff] [blame] | 1263 |         SortedVector < sp<OutputTrack> >  outputTracks; | 
 | 1264 |         SortedVector < sp<OutputTrack> >  mOutputTracks; | 
| Glenn Kasten | 5891256 | 2012-04-03 10:45:00 -0700 | [diff] [blame] | 1265 |     public: | 
 | 1266 |         virtual     bool        hasFastMixer() const { return false; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1267 |     }; | 
 | 1268 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1269 |               PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const; | 
 | 1270 |               MixerThread *checkMixerThread_l(audio_io_handle_t output) const; | 
 | 1271 |               RecordThread *checkRecordThread_l(audio_io_handle_t input) const; | 
| Glenn Kasten | 6637baa | 2012-01-09 09:40:36 -0800 | [diff] [blame] | 1272 |               // no range check, AudioFlinger::mLock held | 
 | 1273 |               bool streamMute_l(audio_stream_type_t stream) const | 
 | 1274 |                                 { return mStreamTypes[stream].mute; } | 
 | 1275 |               // no range check, doesn't check per-thread stream volume, AudioFlinger::mLock held | 
 | 1276 |               float streamVolume_l(audio_stream_type_t stream) const | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1277 |                                 { return mStreamTypes[stream].volume; } | 
| Glenn Kasten | b81cc8c | 2012-03-01 09:14:51 -0800 | [diff] [blame] | 1278 |               void audioConfigChanged_l(int event, audio_io_handle_t ioHandle, const void *param2); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1279 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1280 |               // allocate an audio_io_handle_t, session ID, or effect ID | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1281 |               uint32_t nextUniqueId(); | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1282 |  | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1283 |               status_t moveEffectChain_l(int sessionId, | 
| Glenn Kasten | a111792 | 2012-01-26 10:53:32 -0800 | [diff] [blame] | 1284 |                                      PlaybackThread *srcThread, | 
 | 1285 |                                      PlaybackThread *dstThread, | 
| Eric Laurent | 39e94f8 | 2010-07-28 01:32:47 -0700 | [diff] [blame] | 1286 |                                      bool reRegister); | 
| Glenn Kasten | 02fe1bf | 2012-02-24 15:42:17 -0800 | [diff] [blame] | 1287 |               // return thread associated with primary hardware device, or NULL | 
 | 1288 |               PlaybackThread *primaryPlaybackThread_l() const; | 
 | 1289 |               uint32_t primaryOutputDevice_l() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1290 |  | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1291 |     // server side of the client's IAudioTrack | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1292 |     class TrackHandle : public android::BnAudioTrack { | 
 | 1293 |     public: | 
 | 1294 |                             TrackHandle(const sp<PlaybackThread::Track>& track); | 
 | 1295 |         virtual             ~TrackHandle(); | 
| Glenn Kasten | 90716c5 | 2012-01-26 13:40:12 -0800 | [diff] [blame] | 1296 |         virtual sp<IMemory> getCblk() const; | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 1297 |         virtual status_t    start(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1298 |         virtual void        stop(); | 
 | 1299 |         virtual void        flush(); | 
 | 1300 |         virtual void        mute(bool); | 
 | 1301 |         virtual void        pause(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1302 |         virtual status_t    attachAuxEffect(int effectId); | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 1303 |         virtual status_t    allocateTimedBuffer(size_t size, | 
 | 1304 |                                                 sp<IMemory>* buffer); | 
 | 1305 |         virtual status_t    queueTimedBuffer(const sp<IMemory>& buffer, | 
 | 1306 |                                              int64_t pts); | 
 | 1307 |         virtual status_t    setMediaTimeTransform(const LinearTransform& xform, | 
 | 1308 |                                                   int target); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1309 |         virtual status_t onTransact( | 
 | 1310 |             uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); | 
 | 1311 |     private: | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 1312 |         const sp<PlaybackThread::Track> mTrack; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1313 |     }; | 
 | 1314 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1315 |                 void        removeClient_l(pid_t pid); | 
 | 1316 |                 void        removeNotificationClient(pid_t pid); | 
 | 1317 |  | 
 | 1318 |  | 
 | 1319 |     // record thread | 
 | 1320 |     class RecordThread : public ThreadBase, public AudioBufferProvider | 
 | 1321 |     { | 
 | 1322 |     public: | 
 | 1323 |  | 
 | 1324 |         // record track | 
 | 1325 |         class RecordTrack : public TrackBase { | 
 | 1326 |         public: | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 1327 |                                 RecordTrack(RecordThread *thread, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1328 |                                         const sp<Client>& client, | 
 | 1329 |                                         uint32_t sampleRate, | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 1330 |                                         audio_format_t format, | 
| Jean-Michel Trivi | 0d255b2 | 2011-05-24 15:53:33 -0700 | [diff] [blame] | 1331 |                                         uint32_t channelMask, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1332 |                                         int frameCount, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1333 |                                         int sessionId); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 1334 |             virtual             ~RecordTrack(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1335 |  | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 1336 |             virtual status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE, | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1337 |                                      int triggerSession = 0); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1338 |             virtual void        stop(); | 
 | 1339 |  | 
 | 1340 |                     bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; } | 
 | 1341 |                     bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; } | 
 | 1342 |  | 
 | 1343 |                     void        dump(char* buffer, size_t size); | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1344 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1345 |         private: | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 1346 |             friend class AudioFlinger;  // for mState | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1347 |  | 
 | 1348 |                                 RecordTrack(const RecordTrack&); | 
 | 1349 |                                 RecordTrack& operator = (const RecordTrack&); | 
 | 1350 |  | 
| Glenn Kasten | 01c4ebf | 2012-02-22 10:47:35 -0800 | [diff] [blame] | 1351 |             // AudioBufferProvider interface | 
 | 1352 |             virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS); | 
 | 1353 |             // releaseBuffer() not overridden | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1354 |  | 
 | 1355 |             bool                mOverflow; | 
 | 1356 |         }; | 
 | 1357 |  | 
 | 1358 |  | 
 | 1359 |                 RecordThread(const sp<AudioFlinger>& audioFlinger, | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 1360 |                         AudioStreamIn *input, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1361 |                         uint32_t sampleRate, | 
 | 1362 |                         uint32_t channels, | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1363 |                         audio_io_handle_t id, | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1364 |                         uint32_t device); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 1365 |                 virtual     ~RecordThread(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1366 |  | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1367 |         // Thread | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1368 |         virtual bool        threadLoop(); | 
| Eric Laurent | b8ba0a9 | 2011-08-07 16:32:26 -0700 | [diff] [blame] | 1369 |         virtual status_t    readyToRun(); | 
| Glenn Kasten | 000f0e3 | 2012-03-01 17:10:56 -0800 | [diff] [blame] | 1370 |  | 
 | 1371 |         // RefBase | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1372 |         virtual void        onFirstRef(); | 
 | 1373 |  | 
| Glenn Kasten | e0feee3 | 2011-12-13 11:53:26 -0800 | [diff] [blame] | 1374 |         virtual status_t    initCheck() const { return (mInput == NULL) ? NO_INIT : NO_ERROR; } | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1375 |                 sp<AudioFlinger::RecordThread::RecordTrack>  createRecordTrack_l( | 
 | 1376 |                         const sp<AudioFlinger::Client>& client, | 
 | 1377 |                         uint32_t sampleRate, | 
| Glenn Kasten | 58f3021 | 2012-01-12 12:27:51 -0800 | [diff] [blame] | 1378 |                         audio_format_t format, | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1379 |                         int channelMask, | 
 | 1380 |                         int frameCount, | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1381 |                         int sessionId, | 
 | 1382 |                         status_t *status); | 
 | 1383 |  | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 1384 |                 status_t    start(RecordTrack* recordTrack, | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1385 |                                   AudioSystem::sync_event_t event, | 
 | 1386 |                                   int triggerSession); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1387 |                 void        stop(RecordTrack* recordTrack); | 
 | 1388 |                 status_t    dump(int fd, const Vector<String16>& args); | 
| Glenn Kasten | aed850d | 2012-01-26 09:46:34 -0800 | [diff] [blame] | 1389 |                 AudioStreamIn* getInput() const; | 
| Eric Laurent | b8ba0a9 | 2011-08-07 16:32:26 -0700 | [diff] [blame] | 1390 |                 AudioStreamIn* clearInput(); | 
| Glenn Kasten | 0bf65bd | 2012-02-28 18:32:53 -0800 | [diff] [blame] | 1391 |                 virtual audio_stream_t* stream() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1392 |  | 
| Glenn Kasten | 01c4ebf | 2012-02-22 10:47:35 -0800 | [diff] [blame] | 1393 |         // AudioBufferProvider interface | 
 | 1394 |         virtual status_t    getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1395 |         virtual void        releaseBuffer(AudioBufferProvider::Buffer* buffer); | 
| Glenn Kasten | 01c4ebf | 2012-02-22 10:47:35 -0800 | [diff] [blame] | 1396 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1397 |         virtual bool        checkForNewParameters_l(); | 
 | 1398 |         virtual String8     getParameters(const String8& keys); | 
 | 1399 |         virtual void        audioConfigChanged_l(int event, int param = 0); | 
 | 1400 |                 void        readInputParameters(); | 
 | 1401 |         virtual unsigned int  getInputFramesLost(); | 
 | 1402 |  | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1403 |         virtual status_t addEffectChain_l(const sp<EffectChain>& chain); | 
 | 1404 |         virtual size_t removeEffectChain_l(const sp<EffectChain>& chain); | 
 | 1405 |         virtual uint32_t hasAudioSession(int sessionId); | 
| Eric Laurent | 59bd0da | 2011-08-01 09:52:20 -0700 | [diff] [blame] | 1406 |                 RecordTrack* track(); | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1407 |  | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1408 |         virtual status_t setSyncEvent(const sp<SyncEvent>& event); | 
 | 1409 |         virtual bool     isValidSyncEvent(const sp<SyncEvent>& event); | 
 | 1410 |  | 
 | 1411 |         static void syncStartEventCallback(const wp<SyncEvent>& event); | 
 | 1412 |                void handleSyncStartEvent(const sp<SyncEvent>& event); | 
 | 1413 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1414 |     private: | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1415 |                 void clearSyncStartEvent(); | 
 | 1416 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1417 |                 RecordThread(); | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 1418 |                 AudioStreamIn                       *mInput; | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1419 |                 RecordTrack*                        mTrack; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1420 |                 sp<RecordTrack>                     mActiveTrack; | 
 | 1421 |                 Condition                           mStartStopCond; | 
 | 1422 |                 AudioResampler                      *mResampler; | 
 | 1423 |                 int32_t                             *mRsmpOutBuffer; | 
 | 1424 |                 int16_t                             *mRsmpInBuffer; | 
 | 1425 |                 size_t                              mRsmpInIndex; | 
 | 1426 |                 size_t                              mInputBytes; | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 1427 |                 const int                           mReqChannelCount; | 
 | 1428 |                 const uint32_t                      mReqSampleRate; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1429 |                 ssize_t                             mBytesRead; | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1430 |                 // sync event triggering actual audio capture. Frames read before this event will | 
 | 1431 |                 // be dropped and therefore not read by the application. | 
 | 1432 |                 sp<SyncEvent>                       mSyncStartEvent; | 
 | 1433 |                 // number of captured frames to drop after the start sync event has been received. | 
| Eric Laurent | 2986460 | 2012-05-08 18:57:51 -0700 | [diff] [blame] | 1434 |                 // when < 0, maximum frames to drop before starting capture even if sync event is | 
 | 1435 |                 // not received | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1436 |                 ssize_t                             mFramestoDrop; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1437 |     }; | 
 | 1438 |  | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1439 |     // server side of the client's IAudioRecord | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1440 |     class RecordHandle : public android::BnAudioRecord { | 
 | 1441 |     public: | 
 | 1442 |         RecordHandle(const sp<RecordThread::RecordTrack>& recordTrack); | 
 | 1443 |         virtual             ~RecordHandle(); | 
| Glenn Kasten | 90716c5 | 2012-01-26 13:40:12 -0800 | [diff] [blame] | 1444 |         virtual sp<IMemory> getCblk() const; | 
| Glenn Kasten | 3acbd05 | 2012-02-28 10:39:56 -0800 | [diff] [blame] | 1445 |         virtual status_t    start(int event, int triggerSession); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1446 |         virtual void        stop(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1447 |         virtual status_t onTransact( | 
 | 1448 |             uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); | 
 | 1449 |     private: | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 1450 |         const sp<RecordThread::RecordTrack> mRecordTrack; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1451 |     }; | 
 | 1452 |  | 
 | 1453 |     //--- Audio Effect Management | 
 | 1454 |  | 
 | 1455 |     // EffectModule and EffectChain classes both have their own mutex to protect | 
 | 1456 |     // state changes or resource modifications. Always respect the following order | 
 | 1457 |     // if multiple mutexes must be acquired to avoid cross deadlock: | 
 | 1458 |     // AudioFlinger -> ThreadBase -> EffectChain -> EffectModule | 
 | 1459 |  | 
 | 1460 |     // The EffectModule class is a wrapper object controlling the effect engine implementation | 
 | 1461 |     // in the effect library. It prevents concurrent calls to process() and command() functions | 
 | 1462 |     // from different client threads. It keeps a list of EffectHandle objects corresponding | 
 | 1463 |     // to all client applications using this effect and notifies applications of effect state, | 
 | 1464 |     // control or parameter changes. It manages the activation state machine to send appropriate | 
 | 1465 |     // reset, enable, disable commands to effect engine and provide volume | 
 | 1466 |     // ramping when effects are activated/deactivated. | 
 | 1467 |     // When controlling an auxiliary effect, the EffectModule also provides an input buffer used by | 
 | 1468 |     // the attached track(s) to accumulate their auxiliary channel. | 
 | 1469 |     class EffectModule: public RefBase { | 
 | 1470 |     public: | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 1471 |         EffectModule(ThreadBase *thread, | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1472 |                         const wp<AudioFlinger::EffectChain>& chain, | 
 | 1473 |                         effect_descriptor_t *desc, | 
 | 1474 |                         int id, | 
 | 1475 |                         int sessionId); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 1476 |         virtual ~EffectModule(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1477 |  | 
 | 1478 |         enum effect_state { | 
 | 1479 |             IDLE, | 
 | 1480 |             RESTART, | 
 | 1481 |             STARTING, | 
 | 1482 |             ACTIVE, | 
 | 1483 |             STOPPING, | 
| Eric Laurent | ec437d8 | 2011-07-26 20:54:46 -0700 | [diff] [blame] | 1484 |             STOPPED, | 
 | 1485 |             DESTROYED | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1486 |         }; | 
 | 1487 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1488 |         int         id() const { return mId; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1489 |         void process(); | 
 | 1490 |         void updateState(); | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 1491 |         status_t command(uint32_t cmdCode, | 
 | 1492 |                          uint32_t cmdSize, | 
 | 1493 |                          void *pCmdData, | 
 | 1494 |                          uint32_t *replySize, | 
 | 1495 |                          void *pReplyData); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1496 |  | 
 | 1497 |         void reset_l(); | 
 | 1498 |         status_t configure(); | 
 | 1499 |         status_t init(); | 
| Glenn Kasten | 28243dd | 2012-01-26 13:43:46 -0800 | [diff] [blame] | 1500 |         effect_state state() const { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1501 |             return mState; | 
 | 1502 |         } | 
 | 1503 |         uint32_t status() { | 
 | 1504 |             return mStatus; | 
 | 1505 |         } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1506 |         int sessionId() const { | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1507 |             return mSessionId; | 
 | 1508 |         } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1509 |         status_t    setEnabled(bool enabled); | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1510 |         bool isEnabled() const; | 
 | 1511 |         bool isProcessEnabled() const; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1512 |  | 
 | 1513 |         void        setInBuffer(int16_t *buffer) { mConfig.inputCfg.buffer.s16 = buffer; } | 
 | 1514 |         int16_t     *inBuffer() { return mConfig.inputCfg.buffer.s16; } | 
 | 1515 |         void        setOutBuffer(int16_t *buffer) { mConfig.outputCfg.buffer.s16 = buffer; } | 
 | 1516 |         int16_t     *outBuffer() { return mConfig.outputCfg.buffer.s16; } | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1517 |         void        setChain(const wp<EffectChain>& chain) { mChain = chain; } | 
 | 1518 |         void        setThread(const wp<ThreadBase>& thread) { mThread = thread; } | 
| Glenn Kasten | 84afa3b | 2012-01-25 15:28:08 -0800 | [diff] [blame] | 1519 |         const wp<ThreadBase>& thread() { return mThread; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1520 |  | 
| Glenn Kasten | 435dbe6 | 2012-01-30 10:15:48 -0800 | [diff] [blame] | 1521 |         status_t addHandle(const sp<EffectHandle>& handle); | 
| Glenn Kasten | 58123c3 | 2012-02-03 10:32:24 -0800 | [diff] [blame] | 1522 |         void disconnect(const wp<EffectHandle>& handle, bool unpinIfLast); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1523 |         size_t removeHandle (const wp<EffectHandle>& handle); | 
 | 1524 |  | 
 | 1525 |         effect_descriptor_t& desc() { return mDescriptor; } | 
 | 1526 |         wp<EffectChain>&     chain() { return mChain; } | 
 | 1527 |  | 
 | 1528 |         status_t         setDevice(uint32_t device); | 
 | 1529 |         status_t         setVolume(uint32_t *left, uint32_t *right, bool controller); | 
| Glenn Kasten | f78aee7 | 2012-01-04 11:00:47 -0800 | [diff] [blame] | 1530 |         status_t         setMode(audio_mode_t mode); | 
| Eric Laurent | ec35a14 | 2011-10-05 17:42:25 -0700 | [diff] [blame] | 1531 |         status_t         start(); | 
| Eric Laurent | ec437d8 | 2011-07-26 20:54:46 -0700 | [diff] [blame] | 1532 |         status_t         stop(); | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1533 |         void             setSuspended(bool suspended); | 
| Glenn Kasten | a3a8548 | 2012-01-04 11:01:11 -0800 | [diff] [blame] | 1534 |         bool             suspended() const; | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1535 |  | 
 | 1536 |         sp<EffectHandle> controlHandle(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1537 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1538 |         bool             isPinned() const { return mPinned; } | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 1539 |         void             unPin() { mPinned = false; } | 
 | 1540 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1541 |         status_t         dump(int fd, const Vector<String16>& args); | 
 | 1542 |  | 
 | 1543 |     protected: | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 1544 |         friend class AudioFlinger;      // for mHandles | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 1545 |         bool                mPinned; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1546 |  | 
 | 1547 |         // Maximum time allocated to effect engines to complete the turn off sequence | 
 | 1548 |         static const uint32_t MAX_DISABLE_TIME_MS = 10000; | 
 | 1549 |  | 
 | 1550 |         EffectModule(const EffectModule&); | 
 | 1551 |         EffectModule& operator = (const EffectModule&); | 
 | 1552 |  | 
 | 1553 |         status_t start_l(); | 
 | 1554 |         status_t stop_l(); | 
 | 1555 |  | 
| Glenn Kasten | a3a8548 | 2012-01-04 11:01:11 -0800 | [diff] [blame] | 1556 | mutable Mutex               mLock;      // mutex for process, commands and handles list protection | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1557 |         wp<ThreadBase>      mThread;    // parent thread | 
 | 1558 |         wp<EffectChain>     mChain;     // parent effect chain | 
 | 1559 |         int                 mId;        // this instance unique ID | 
 | 1560 |         int                 mSessionId; // audio session ID | 
 | 1561 |         effect_descriptor_t mDescriptor;// effect descriptor received from effect engine | 
 | 1562 |         effect_config_t     mConfig;    // input and output audio configuration | 
| Eric Laurent | e1315cf | 2011-05-17 19:16:02 -0700 | [diff] [blame] | 1563 |         effect_handle_t  mEffectInterface; // Effect module C API | 
| Glenn Kasten | 28243dd | 2012-01-26 13:43:46 -0800 | [diff] [blame] | 1564 |         status_t            mStatus;    // initialization status | 
 | 1565 |         effect_state        mState;     // current activation state | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1566 |         Vector< wp<EffectHandle> > mHandles;    // list of client handles | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1567 |                     // First handle in mHandles has highest priority and controls the effect module | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1568 |         uint32_t mMaxDisableWaitCnt;    // maximum grace period before forcing an effect off after | 
 | 1569 |                                         // sending disable command. | 
 | 1570 |         uint32_t mDisableWaitCnt;       // current process() calls count during disable period. | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1571 |         bool     mSuspended;            // effect is suspended: temporarily disabled by framework | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1572 |     }; | 
 | 1573 |  | 
 | 1574 |     // The EffectHandle class implements the IEffect interface. It provides resources | 
 | 1575 |     // to receive parameter updates, keeps track of effect control | 
 | 1576 |     // ownership and state and has a pointer to the EffectModule object it is controlling. | 
 | 1577 |     // There is one EffectHandle object for each application controlling (or using) | 
 | 1578 |     // an effect module. | 
 | 1579 |     // The EffectHandle is obtained by calling AudioFlinger::createEffect(). | 
 | 1580 |     class EffectHandle: public android::BnEffect { | 
 | 1581 |     public: | 
 | 1582 |  | 
 | 1583 |         EffectHandle(const sp<EffectModule>& effect, | 
 | 1584 |                 const sp<AudioFlinger::Client>& client, | 
 | 1585 |                 const sp<IEffectClient>& effectClient, | 
 | 1586 |                 int32_t priority); | 
 | 1587 |         virtual ~EffectHandle(); | 
 | 1588 |  | 
 | 1589 |         // IEffect | 
 | 1590 |         virtual status_t enable(); | 
 | 1591 |         virtual status_t disable(); | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 1592 |         virtual status_t command(uint32_t cmdCode, | 
 | 1593 |                                  uint32_t cmdSize, | 
 | 1594 |                                  void *pCmdData, | 
 | 1595 |                                  uint32_t *replySize, | 
 | 1596 |                                  void *pReplyData); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1597 |         virtual void disconnect(); | 
| Glenn Kasten | 58123c3 | 2012-02-03 10:32:24 -0800 | [diff] [blame] | 1598 |     private: | 
 | 1599 |                 void disconnect(bool unpinIfLast); | 
 | 1600 |     public: | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1601 |         virtual sp<IMemory> getCblk() const { return mCblkMemory; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1602 |         virtual status_t onTransact(uint32_t code, const Parcel& data, | 
 | 1603 |                 Parcel* reply, uint32_t flags); | 
 | 1604 |  | 
 | 1605 |  | 
 | 1606 |         // Give or take control of effect module | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1607 |         // - hasControl: true if control is given, false if removed | 
 | 1608 |         // - signal: true client app should be signaled of change, false otherwise | 
 | 1609 |         // - enabled: state of the effect when control is passed | 
 | 1610 |         void setControl(bool hasControl, bool signal, bool enabled); | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 1611 |         void commandExecuted(uint32_t cmdCode, | 
 | 1612 |                              uint32_t cmdSize, | 
 | 1613 |                              void *pCmdData, | 
 | 1614 |                              uint32_t replySize, | 
 | 1615 |                              void *pReplyData); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1616 |         void setEnabled(bool enabled); | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1617 |         bool enabled() const { return mEnabled; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1618 |  | 
 | 1619 |         // Getters | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1620 |         int id() const { return mEffect->id(); } | 
 | 1621 |         int priority() const { return mPriority; } | 
 | 1622 |         bool hasControl() const { return mHasControl; } | 
 | 1623 |         sp<EffectModule> effect() const { return mEffect; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1624 |  | 
 | 1625 |         void dump(char* buffer, size_t size); | 
 | 1626 |  | 
 | 1627 |     protected: | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 1628 |         friend class AudioFlinger;          // for mEffect, mHasControl, mEnabled | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1629 |         EffectHandle(const EffectHandle&); | 
 | 1630 |         EffectHandle& operator =(const EffectHandle&); | 
 | 1631 |  | 
 | 1632 |         sp<EffectModule> mEffect;           // pointer to controlled EffectModule | 
 | 1633 |         sp<IEffectClient> mEffectClient;    // callback interface for client notifications | 
| Glenn Kasten | 98ec94c | 2012-01-25 14:28:29 -0800 | [diff] [blame] | 1634 |         /*const*/ sp<Client> mClient;       // client for shared memory allocation, see disconnect() | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1635 |         sp<IMemory>         mCblkMemory;    // shared memory for control block | 
 | 1636 |         effect_param_cblk_t* mCblk;         // control block for deferred parameter setting via shared memory | 
 | 1637 |         uint8_t*            mBuffer;        // pointer to parameter area in shared memory | 
 | 1638 |         int mPriority;                      // client application priority to control the effect | 
 | 1639 |         bool mHasControl;                   // true if this handle is controlling the effect | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1640 |         bool mEnabled;                      // cached enable state: needed when the effect is | 
 | 1641 |                                             // restored after being suspended | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1642 |     }; | 
 | 1643 |  | 
 | 1644 |     // the EffectChain class represents a group of effects associated to one audio session. | 
 | 1645 |     // There can be any number of EffectChain objects per output mixer thread (PlaybackThread). | 
 | 1646 |     // The EffecChain with session ID 0 contains global effects applied to the output mix. | 
 | 1647 |     // Effects in this chain can be insert or auxiliary. Effects in other chains (attached to tracks) | 
 | 1648 |     // are insert only. The EffectChain maintains an ordered list of effect module, the order corresponding | 
 | 1649 |     // in the effect process order. When attached to a track (session ID != 0), it also provide it's own | 
 | 1650 |     // input buffer used by the track as accumulation buffer. | 
 | 1651 |     class EffectChain: public RefBase { | 
 | 1652 |     public: | 
 | 1653 |         EffectChain(const wp<ThreadBase>& wThread, int sessionId); | 
| Glenn Kasten | 9eaa557 | 2012-01-20 13:32:16 -0800 | [diff] [blame] | 1654 |         EffectChain(ThreadBase *thread, int sessionId); | 
| Glenn Kasten | c19e224 | 2012-01-30 14:54:39 -0800 | [diff] [blame] | 1655 |         virtual ~EffectChain(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1656 |  | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1657 |         // special key used for an entry in mSuspendedEffects keyed vector | 
 | 1658 |         // corresponding to a suspend all request. | 
 | 1659 |         static const int        kKeyForSuspendAll = 0; | 
 | 1660 |  | 
| Eric Laurent | 544fe9b | 2011-11-11 15:42:52 -0800 | [diff] [blame] | 1661 |         // minimum duration during which we force calling effect process when last track on | 
 | 1662 |         // a session is stopped or removed to allow effect tail to be rendered | 
 | 1663 |         static const int        kProcessTailDurationMs = 1000; | 
 | 1664 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1665 |         void process_l(); | 
 | 1666 |  | 
 | 1667 |         void lock() { | 
 | 1668 |             mLock.lock(); | 
 | 1669 |         } | 
 | 1670 |         void unlock() { | 
 | 1671 |             mLock.unlock(); | 
 | 1672 |         } | 
 | 1673 |  | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1674 |         status_t addEffect_l(const sp<EffectModule>& handle); | 
| Eric Laurent | cab1124 | 2010-07-15 12:50:15 -0700 | [diff] [blame] | 1675 |         size_t removeEffect_l(const sp<EffectModule>& handle); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1676 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1677 |         int sessionId() const { return mSessionId; } | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 1678 |         void setSessionId(int sessionId) { mSessionId = sessionId; } | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1679 |  | 
| Eric Laurent | cab1124 | 2010-07-15 12:50:15 -0700 | [diff] [blame] | 1680 |         sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor); | 
 | 1681 |         sp<EffectModule> getEffectFromId_l(int id); | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1682 |         sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type); | 
| Eric Laurent | cab1124 | 2010-07-15 12:50:15 -0700 | [diff] [blame] | 1683 |         bool setVolume_l(uint32_t *left, uint32_t *right); | 
 | 1684 |         void setDevice_l(uint32_t device); | 
| Glenn Kasten | f78aee7 | 2012-01-04 11:00:47 -0800 | [diff] [blame] | 1685 |         void setMode_l(audio_mode_t mode); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1686 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1687 |         void setInBuffer(int16_t *buffer, bool ownsBuffer = false) { | 
 | 1688 |             mInBuffer = buffer; | 
 | 1689 |             mOwnInBuffer = ownsBuffer; | 
 | 1690 |         } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1691 |         int16_t *inBuffer() const { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1692 |             return mInBuffer; | 
 | 1693 |         } | 
 | 1694 |         void setOutBuffer(int16_t *buffer) { | 
 | 1695 |             mOutBuffer = buffer; | 
 | 1696 |         } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1697 |         int16_t *outBuffer() const { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1698 |             return mOutBuffer; | 
 | 1699 |         } | 
 | 1700 |  | 
| Eric Laurent | b469b94 | 2011-05-09 12:09:06 -0700 | [diff] [blame] | 1701 |         void incTrackCnt() { android_atomic_inc(&mTrackCnt); } | 
 | 1702 |         void decTrackCnt() { android_atomic_dec(&mTrackCnt); } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1703 |         int32_t trackCnt() const { return mTrackCnt;} | 
| Eric Laurent | b469b94 | 2011-05-09 12:09:06 -0700 | [diff] [blame] | 1704 |  | 
| Eric Laurent | 544fe9b | 2011-11-11 15:42:52 -0800 | [diff] [blame] | 1705 |         void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); | 
 | 1706 |                                    mTailBufferCount = mMaxTailBuffers; } | 
| Eric Laurent | b469b94 | 2011-05-09 12:09:06 -0700 | [diff] [blame] | 1707 |         void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); } | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1708 |         int32_t activeTrackCnt() const { return mActiveTrackCnt;} | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1709 |  | 
| Glenn Kasten | c59c004 | 2012-02-02 14:06:11 -0800 | [diff] [blame] | 1710 |         uint32_t strategy() const { return mStrategy; } | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1711 |         void setStrategy(uint32_t strategy) | 
| Glenn Kasten | e53b9ea | 2012-03-12 16:29:55 -0700 | [diff] [blame] | 1712 |                 { mStrategy = strategy; } | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1713 |  | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1714 |         // suspend effect of the given type | 
 | 1715 |         void setEffectSuspended_l(const effect_uuid_t *type, | 
 | 1716 |                                   bool suspend); | 
 | 1717 |         // suspend all eligible effects | 
 | 1718 |         void setEffectSuspendedAll_l(bool suspend); | 
 | 1719 |         // check if effects should be suspend or restored when a given effect is enable or disabled | 
| Eric Laurent | a85a74a | 2011-10-19 11:44:54 -0700 | [diff] [blame] | 1720 |         void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1721 |                                               bool enabled); | 
 | 1722 |  | 
| Eric Laurent | 91b14c4 | 2012-05-30 12:30:29 -0700 | [diff] [blame] | 1723 |         void clearInputBuffer(); | 
 | 1724 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1725 |         status_t dump(int fd, const Vector<String16>& args); | 
 | 1726 |  | 
 | 1727 |     protected: | 
| Glenn Kasten | 1998661 | 2012-03-09 12:07:30 -0800 | [diff] [blame] | 1728 |         friend class AudioFlinger;  // for mThread, mEffects | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1729 |         EffectChain(const EffectChain&); | 
 | 1730 |         EffectChain& operator =(const EffectChain&); | 
 | 1731 |  | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1732 |         class SuspendedEffectDesc : public RefBase { | 
 | 1733 |         public: | 
 | 1734 |             SuspendedEffectDesc() : mRefCount(0) {} | 
 | 1735 |  | 
 | 1736 |             int mRefCount; | 
 | 1737 |             effect_uuid_t mType; | 
 | 1738 |             wp<EffectModule> mEffect; | 
 | 1739 |         }; | 
 | 1740 |  | 
 | 1741 |         // get a list of effect modules to suspend when an effect of the type | 
 | 1742 |         // passed is enabled. | 
| Glenn Kasten | d053971 | 2012-01-30 12:56:03 -0800 | [diff] [blame] | 1743 |         void                       getSuspendEligibleEffects(Vector< sp<EffectModule> > &effects); | 
 | 1744 |  | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1745 |         // get an effect module if it is currently enable | 
 | 1746 |         sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type); | 
| Eric Laurent | db7c079 | 2011-08-10 10:37:50 -0700 | [diff] [blame] | 1747 |         // true if the effect whose descriptor is passed can be suspended | 
 | 1748 |         // OEMs can modify the rules implemented in this method to exclude specific effect | 
 | 1749 |         // types or implementations from the suspend/restore mechanism. | 
 | 1750 |         bool isEffectEligibleForSuspend(const effect_descriptor_t& desc); | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1751 |  | 
| Eric Laurent | 91b14c4 | 2012-05-30 12:30:29 -0700 | [diff] [blame] | 1752 |         void clearInputBuffer_l(sp<ThreadBase> thread); | 
 | 1753 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1754 |         wp<ThreadBase> mThread;     // parent mixer thread | 
 | 1755 |         Mutex mLock;                // mutex protecting effect list | 
| Glenn Kasten | e53b9ea | 2012-03-12 16:29:55 -0700 | [diff] [blame] | 1756 |         Vector< sp<EffectModule> > mEffects; // list of effect modules | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1757 |         int mSessionId;             // audio session ID | 
 | 1758 |         int16_t *mInBuffer;         // chain input buffer | 
 | 1759 |         int16_t *mOutBuffer;        // chain output buffer | 
| Eric Laurent | b469b94 | 2011-05-09 12:09:06 -0700 | [diff] [blame] | 1760 |         volatile int32_t mActiveTrackCnt;  // number of active tracks connected | 
 | 1761 |         volatile int32_t mTrackCnt;        // number of tracks connected | 
| Eric Laurent | 544fe9b | 2011-11-11 15:42:52 -0800 | [diff] [blame] | 1762 |         int32_t mTailBufferCount;   // current effect tail buffer count | 
 | 1763 |         int32_t mMaxTailBuffers;    // maximum effect tail buffers | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1764 |         bool mOwnInBuffer;          // true if the chain owns its input buffer | 
| Eric Laurent | cab1124 | 2010-07-15 12:50:15 -0700 | [diff] [blame] | 1765 |         int mVolumeCtrlIdx;         // index of insert effect having control over volume | 
 | 1766 |         uint32_t mLeftVolume;       // previous volume on left channel | 
 | 1767 |         uint32_t mRightVolume;      // previous volume on right channel | 
| Eric Laurent | f997cab | 2010-07-19 06:24:46 -0700 | [diff] [blame] | 1768 |         uint32_t mNewLeftVolume;       // new volume on left channel | 
 | 1769 |         uint32_t mNewRightVolume;      // new volume on right channel | 
| Eric Laurent | de07013 | 2010-07-13 04:45:46 -0700 | [diff] [blame] | 1770 |         uint32_t mStrategy; // strategy for this effect chain | 
| Glenn Kasten | 17a736c | 2012-02-14 08:52:15 -0800 | [diff] [blame] | 1771 |         // mSuspendedEffects lists all effects currently suspended in the chain. | 
 | 1772 |         // Use effect type UUID timelow field as key. There is no real risk of identical | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1773 |         // timeLow fields among effect type UUIDs. | 
| Glenn Kasten | 17a736c | 2012-02-14 08:52:15 -0800 | [diff] [blame] | 1774 |         // Updated by updateSuspendedSessions_l() only. | 
| Eric Laurent | 59255e4 | 2011-07-27 19:49:51 -0700 | [diff] [blame] | 1775 |         KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1776 |     }; | 
 | 1777 |  | 
| Glenn Kasten | aed850d | 2012-01-26 09:46:34 -0800 | [diff] [blame] | 1778 |     // AudioStreamOut and AudioStreamIn are immutable, so their fields are const. | 
 | 1779 |     // For emphasis, we could also make all pointers to them be "const *", | 
 | 1780 |     // but that would clutter the code unnecessarily. | 
 | 1781 |  | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 1782 |     struct AudioStreamOut { | 
| Glenn Kasten | aed850d | 2012-01-26 09:46:34 -0800 | [diff] [blame] | 1783 |         audio_hw_device_t*  const hwDev; | 
 | 1784 |         audio_stream_out_t* const stream; | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 1785 |  | 
 | 1786 |         AudioStreamOut(audio_hw_device_t *dev, audio_stream_out_t *out) : | 
 | 1787 |             hwDev(dev), stream(out) {} | 
 | 1788 |     }; | 
 | 1789 |  | 
 | 1790 |     struct AudioStreamIn { | 
| Glenn Kasten | aed850d | 2012-01-26 09:46:34 -0800 | [diff] [blame] | 1791 |         audio_hw_device_t* const hwDev; | 
 | 1792 |         audio_stream_in_t* const stream; | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 1793 |  | 
 | 1794 |         AudioStreamIn(audio_hw_device_t *dev, audio_stream_in_t *in) : | 
 | 1795 |             hwDev(dev), stream(in) {} | 
 | 1796 |     }; | 
 | 1797 |  | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1798 |     // for mAudioSessionRefs only | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 1799 |     struct AudioSessionRef { | 
| Glenn Kasten | 012ca6b | 2012-03-06 11:22:01 -0800 | [diff] [blame] | 1800 |         AudioSessionRef(int sessionid, pid_t pid) : | 
 | 1801 |             mSessionid(sessionid), mPid(pid), mCnt(1) {} | 
 | 1802 |         const int   mSessionid; | 
 | 1803 |         const pid_t mPid; | 
 | 1804 |         int         mCnt; | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 1805 |     }; | 
 | 1806 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 1807 |     enum master_volume_support { | 
 | 1808 |         // MVS_NONE: | 
 | 1809 |         // Audio HAL has no support for master volume, either setting or | 
 | 1810 |         // getting.  All master volume control must be implemented in SW by the | 
 | 1811 |         // AudioFlinger mixing core. | 
 | 1812 |         MVS_NONE, | 
 | 1813 |  | 
 | 1814 |         // MVS_SETONLY: | 
 | 1815 |         // Audio HAL has support for setting master volume, but not for getting | 
 | 1816 |         // master volume (original HAL design did not include a getter). | 
 | 1817 |         // AudioFlinger needs to keep track of the last set master volume in | 
 | 1818 |         // addition to needing to set an initial, default, master volume at HAL | 
 | 1819 |         // load time. | 
 | 1820 |         MVS_SETONLY, | 
 | 1821 |  | 
 | 1822 |         // MVS_FULL: | 
 | 1823 |         // Audio HAL has support both for setting and getting master volume. | 
 | 1824 |         // AudioFlinger should send all set and get master volume requests | 
 | 1825 |         // directly to the HAL. | 
 | 1826 |         MVS_FULL, | 
 | 1827 |     }; | 
 | 1828 |  | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 1829 |     class AudioHwDevice { | 
 | 1830 |     public: | 
 | 1831 |         AudioHwDevice(const char *moduleName, audio_hw_device_t *hwDevice) : | 
 | 1832 |             mModuleName(strdup(moduleName)), mHwDevice(hwDevice){} | 
 | 1833 |         ~AudioHwDevice() { free((void *)mModuleName); } | 
 | 1834 |  | 
 | 1835 |         const char *moduleName() const { return mModuleName; } | 
 | 1836 |         audio_hw_device_t *hwDevice() const { return mHwDevice; } | 
 | 1837 |     private: | 
 | 1838 |         const char * const mModuleName; | 
 | 1839 |         audio_hw_device_t * const mHwDevice; | 
 | 1840 |     }; | 
 | 1841 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1842 |     mutable     Mutex                               mLock; | 
 | 1843 |  | 
| Glenn Kasten | 98ec94c | 2012-01-25 14:28:29 -0800 | [diff] [blame] | 1844 |                 DefaultKeyedVector< pid_t, wp<Client> >     mClients;   // see ~Client() | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1845 |  | 
 | 1846 |                 mutable     Mutex                   mHardwareLock; | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 1847 |                 // NOTE: If both mLock and mHardwareLock mutexes must be held, | 
 | 1848 |                 // always take mLock before mHardwareLock | 
| Glenn Kasten | 2b213bc | 2012-02-02 14:05:20 -0800 | [diff] [blame] | 1849 |  | 
 | 1850 |                 // These two fields are immutable after onFirstRef(), so no lock needed to access | 
 | 1851 |                 audio_hw_device_t*                  mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 1852 |                 DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>  mAudioHwDevs; | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 1853 |  | 
| Glenn Kasten | 8abf44d | 2012-02-02 14:16:03 -0800 | [diff] [blame] | 1854 |     // for dump, indicates which hardware operation is currently in progress (but not stream ops) | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 1855 |     enum hardware_call_state { | 
| Glenn Kasten | 8abf44d | 2012-02-02 14:16:03 -0800 | [diff] [blame] | 1856 |         AUDIO_HW_IDLE = 0,              // no operation in progress | 
 | 1857 |         AUDIO_HW_INIT,                  // init_check | 
 | 1858 |         AUDIO_HW_OUTPUT_OPEN,           // open_output_stream | 
 | 1859 |         AUDIO_HW_OUTPUT_CLOSE,          // unused | 
 | 1860 |         AUDIO_HW_INPUT_OPEN,            // unused | 
 | 1861 |         AUDIO_HW_INPUT_CLOSE,           // unused | 
 | 1862 |         AUDIO_HW_STANDBY,               // unused | 
 | 1863 |         AUDIO_HW_SET_MASTER_VOLUME,     // set_master_volume | 
 | 1864 |         AUDIO_HW_GET_ROUTING,           // unused | 
 | 1865 |         AUDIO_HW_SET_ROUTING,           // unused | 
 | 1866 |         AUDIO_HW_GET_MODE,              // unused | 
 | 1867 |         AUDIO_HW_SET_MODE,              // set_mode | 
 | 1868 |         AUDIO_HW_GET_MIC_MUTE,          // get_mic_mute | 
 | 1869 |         AUDIO_HW_SET_MIC_MUTE,          // set_mic_mute | 
 | 1870 |         AUDIO_HW_SET_VOICE_VOLUME,      // set_voice_volume | 
 | 1871 |         AUDIO_HW_SET_PARAMETER,         // set_parameters | 
 | 1872 |         AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size | 
 | 1873 |         AUDIO_HW_GET_MASTER_VOLUME,     // get_master_volume | 
 | 1874 |         AUDIO_HW_GET_PARAMETER,         // get_parameters | 
| Glenn Kasten | 2f732eb | 2012-01-26 09:48:03 -0800 | [diff] [blame] | 1875 |     }; | 
 | 1876 |  | 
| Glenn Kasten | a4454b4 | 2012-01-04 11:02:33 -0800 | [diff] [blame] | 1877 |     mutable     hardware_call_state                 mHardwareStatus;    // for dump only | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1878 |  | 
 | 1879 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1880 |                 DefaultKeyedVector< audio_io_handle_t, sp<PlaybackThread> >  mPlaybackThreads; | 
| Glenn Kasten | b7bf796 | 2012-02-08 12:36:25 -0800 | [diff] [blame] | 1881 |                 stream_type_t                       mStreamTypes[AUDIO_STREAM_CNT]; | 
| Glenn Kasten | 9806710 | 2011-12-13 11:47:54 -0800 | [diff] [blame] | 1882 |  | 
 | 1883 |                 // both are protected by mLock | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1884 |                 float                               mMasterVolume; | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 1885 |                 float                               mMasterVolumeSW; | 
 | 1886 |                 master_volume_support               mMasterVolumeSupportLvl; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1887 |                 bool                                mMasterMute; | 
 | 1888 |  | 
| Glenn Kasten | 72ef00d | 2012-01-17 11:09:42 -0800 | [diff] [blame] | 1889 |                 DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> >    mRecordThreads; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1890 |  | 
 | 1891 |                 DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients; | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1892 |                 volatile int32_t                    mNextUniqueId;  // updated by android_atomic_inc | 
| Glenn Kasten | f78aee7 | 2012-01-04 11:00:47 -0800 | [diff] [blame] | 1893 |                 audio_mode_t                        mMode; | 
| Eric Laurent | bee5337 | 2011-08-29 12:42:48 -0700 | [diff] [blame] | 1894 |                 bool                                mBtNrecIsOff; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1895 |  | 
| Glenn Kasten | 99e53b8 | 2012-01-19 08:59:58 -0800 | [diff] [blame] | 1896 |                 // protected by mLock | 
| Marco Nelissen | 3a34bef | 2011-08-02 13:33:41 -0700 | [diff] [blame] | 1897 |                 Vector<AudioSessionRef*> mAudioSessionRefs; | 
| Glenn Kasten | 9806710 | 2011-12-13 11:47:54 -0800 | [diff] [blame] | 1898 |  | 
| John Grossman | 4ff14ba | 2012-02-08 16:37:41 -0800 | [diff] [blame] | 1899 |                 float       masterVolume_l() const; | 
 | 1900 |                 float       masterVolumeSW_l() const  { return mMasterVolumeSW; } | 
| Glenn Kasten | 9806710 | 2011-12-13 11:47:54 -0800 | [diff] [blame] | 1901 |                 bool        masterMute_l() const    { return mMasterMute; } | 
| Eric Laurent | a4c5a55 | 2012-03-29 10:12:40 -0700 | [diff] [blame] | 1902 |                 audio_module_handle_t loadHwModule_l(const char *name); | 
| Glenn Kasten | 98ec94c | 2012-01-25 14:28:29 -0800 | [diff] [blame] | 1903 |  | 
| Eric Laurent | a011e35 | 2012-03-29 15:51:43 -0700 | [diff] [blame] | 1904 |                 Vector < sp<SyncEvent> > mPendingSyncEvents; // sync events awaiting for a session | 
 | 1905 |                                                              // to be created | 
 | 1906 |  | 
| Glenn Kasten | 98ec94c | 2012-01-25 14:28:29 -0800 | [diff] [blame] | 1907 | private: | 
 | 1908 |     sp<Client>  registerPid_l(pid_t pid);    // always returns non-0 | 
 | 1909 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1910 | }; | 
 | 1911 |  | 
| Dima Zavin | 799a70e | 2011-04-18 16:57:27 -0700 | [diff] [blame] | 1912 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1913 | // ---------------------------------------------------------------------------- | 
 | 1914 |  | 
 | 1915 | }; // namespace android | 
 | 1916 |  | 
 | 1917 | #endif // ANDROID_AUDIO_FLINGER_H |