sipxmedialib  Version 3.3
MpAndroidX_XAudioTrack.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2010-2013 SIPez LLC. All rights reserved.
3 //
4 // $$
6 
7 // Author: Dan Petrie <dpetrie AT SIPez DOT com>
8 
9 #ifndef _MpAndroidX_XAudioTrack_h_
10 #define _MpAndroidX_XAudioTrack_h_
11 
12 // Must be included before Android utils/log.h so we define LOG_TAG first
13 
14 #ifdef ANDROID_2_0
15 # define MP_ANDROID_AUDIO_TRACK MpAndroid2_0AudioTrack
16 # define QUOTED_MP_ANDROID_AUDIO_TRACK "MpAndroid2_0AudioTrack"
17 # ifndef LOG_TAG
18 # define LOG_TAG QUOTED_MP_ANDROID_AUDIO_TRACK
19 # endif
20 #elif ANDROID_2_3
21 # define MP_ANDROID_AUDIO_TRACK MpAndroid2_3AudioTrack
22 # define QUOTED_MP_ANDROID_AUDIO_TRACK "MpAndroid2_3AudioTrack"
23 # define CREATE_TRACK_METHOD createTrack
24 # ifndef LOG_TAG
25 # define LOG_TAG QUOTED_MP_ANDROID_AUDIO_TRACK
26 # endif
27  extern "C" int setpriority(int, int, int);
28 # define PRIO_PROCESS 0
29 #elif ANDROID_2_3_4
30 # define MP_ANDROID_AUDIO_TRACK MpAndroid2_3_4AudioTrack
31 # define QUOTED_MP_ANDROID_AUDIO_TRACK "MpAndroid2_3_4AudioTrack"
32 # ifndef LOG_TAG
33 # define LOG_TAG QUOTED_MP_ANDROID_AUDIO_TRACK
34 # endif
35 # define CREATE_TRACK_METHOD createTrack_l
36  extern "C" int setpriority(int, int, int);
37 # define PRIO_PROCESS 0
38 #elif ANDROID_4_0_1
39 # define MP_ANDROID_AUDIO_TRACK MpAndroid4_0_1AudioTrack
40 # define QUOTED_MP_ANDROID_AUDIO_TRACK "MpAndroid4_0_1AudioTrack"
41 # ifndef LOG_TAG
42 # define LOG_TAG QUOTED_MP_ANDROID_AUDIO_TRACK
43 # endif
44 # define CREATE_TRACK_METHOD createTrack_l
45  extern "C" int setpriority(int, int, int);
46 # define PRIO_PROCESS 0
47 #elif ANDROID_4_1_1
48 # define MP_ANDROID_AUDIO_TRACK MpAndroid4_1_1AudioTrack
49 # define QUOTED_MP_ANDROID_AUDIO_TRACK "MpAndroid4_1_1AudioTrack"
50 # ifndef LOG_TAG
51 # define LOG_TAG QUOTED_MP_ANDROID_AUDIO_TRACK
52 # endif
53 # define CREATE_TRACK_METHOD createTrack_l
54  extern "C" int setpriority(int, int, int);
55 # define PRIO_PROCESS 0
56 # define LOGV ALOGV
57 # define LOGD ALOGD
58 #elif ANDROID_4_2_1
59 # define MP_ANDROID_AUDIO_TRACK MpAndroid4_2_1AudioTrack
60 # define QUOTED_MP_ANDROID_AUDIO_TRACK "MpAndroid4_2_1AudioTrack"
61 # ifndef LOG_TAG
62 # define LOG_TAG QUOTED_MP_ANDROID_AUDIO_TRACK
63 # endif
64 # define CREATE_TRACK_METHOD createTrack_l
65  extern "C" int setpriority(int, int, int);
66 # define PRIO_PROCESS 0
67 # define LOGV ALOGV
68 # define LOGD ALOGD
69 #else
70 # error Unsupported version of Android AudioTrack
71 #endif
72 
73 // SIPX INCLUDES
75 #include <mp/MpAndroidAudioTrack.h>
76 
77 // SYSTEM INCLUDES
78 #include <media/AudioTrack.h>
79 #include <private/media/AudioTrackShared.h>
80 
81 // DEFINES
82 // MACROS
83 // EXTERNAL FUNCTIONS
84 extern "C" MpAndroidAudioTrack* createAndroidAudioTrack(int streamType,
85  uint32_t sampleRate,
86  int format,
87  int channels,
88  int frameCount,
89  uint32_t flags,
90  sipXcallback_t cbf,
91  void* user,
92  int notificationFrames);
93 
94 using namespace android;
95 
96 // EXTERNAL VARIABLES
97 // CONSTANTS
98 // STRUCTS
99 // TYPEDEFS
100 // FORWARD DECLARATIONS
101 
102 // This wraper class is used to create some extra memory padding
103 // at the end of the AudioTrack class. on Droid X an assert was
104 // firing because memory was getting trashed in the footer of the
105 // malloc memory chunk for the AudioTrack. It is not clear why
106 // this was happening. However when we got lucky and used a chunk
107 // with an extra 8 bytes at the end, everything was happy. Hense
108 // this wrapper class with 2 int of bufer space at the end.
109 class SipxAudioTrack : public AudioTrack
110 {
111 public:
112  SipxAudioTrack(int streamType,
113  uint32_t sampleRate,
114  int format,
115  int channels,
116  int frameCount,
117  uint32_t flags,
118  callback_t cbf,
119  void* user,
120  int notificationFrames) :
121  AudioTrack(streamType, sampleRate, format, channels, frameCount, flags, cbf, user, notificationFrames)
122  {
123  //dummy1 = 11;
124  //dummy2 = 7;
125  };
126 
127  void start()
128  {
129  LOGD("SipxAudioTrack::start() entered");
130 #if defined(ANDROID_2_3) || defined(ANDROID_2_3_4)
131  // Code from Android 2.3 AudioTrack::start() added here as it hangs on Android 3.0
132  // BEGIN ANDROID CODE
134 /* //device/extlibs/pv/android/AudioTrack.cpp
135 **
136 ** Copyright 2007, The Android Open Source Project
137 **
138 ** Licensed under the Apache License, Version 2.0 (the "License");
139 ** you may not use this file except in compliance with the License.
140 ** You may obtain a copy of the License at
141 **
142 ** http://www.apache.org/licenses/LICENSE-2.0
143 **
144 ** Unless required by applicable law or agreed to in writing, software
145 ** distributed under the License is distributed on an "AS IS" BASIS,
146 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147 ** See the License for the specific language governing permissions and
148 ** limitations under the License.
149 */
150  LOGD("%s line: %d", __FILE__, __LINE__);
151  LOGD("mAudioTrackThread: %p", &mAudioTrackThread);
152  LOGD("exit pending: %s", mAudioTrackThread->exitPending() ? "TRUE" : "FALSE");
153  LOGD("ref count: %d", mAudioTrackThread->getStrongCount());
154 
155  LOGD("%s line: %d", __FILE__, __LINE__);
156  sp<AudioTrackThread> t = mAudioTrackThread;
157  LOGD("%s line: %d", __FILE__, __LINE__);
158  status_t status;
159 
160  LOGV("start %p", this);
161  if (t != 0) {
162  if (t->exitPending()) {
163  LOGD("SipxAudioTrack::start() exitPending");
164 
165  if (t->requestExitAndWait() == WOULD_BLOCK) {
166  LOGE("AudioTrack::start called from thread");
167  return;
168  }
169  }
170  else
171  {
172  LOGD("SipxAudioTrack::start() NOT exitPending");
173  }
174  t->mLock.lock();
175  }
176  LOGD("SipxAudioTrack::start() after t->mLock.lock");
177 
178  if (android_atomic_or(1, &mActive) == 0) {
179  mNewPosition = mCblk->server + mUpdatePeriod;
180  mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
181  mCblk->waitTimeMs = 0;
182  mCblk->flags &= ~CBLK_DISABLED_ON;
183  if (t != 0) {
184  LOGD("SipxAudioTrack::start() about to t->run");
185  t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
186  } else {
187  LOGD("SipxAudioTrack::start() about to setpriority");
188  setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
189  }
190  LOGD("SipxAudioTrack::start() after set priority");
191 
192  if (mCblk->flags & CBLK_INVALID_MSK) {
193  LOGW("start() track %p invalidated, creating a new one", this);
194  // no need to clear the invalid flag as this cblk will not be used anymore
195  // force new track creation
196  status = DEAD_OBJECT;
197  } else {
198  status = mAudioTrack->start();
199  }
200  LOGD("SipxAudioTrack::start() after mAudioTrack->start()");
201  if (status == DEAD_OBJECT) {
202  LOGV("start() dead IAudioTrack: creating a new one");
203  status = CREATE_TRACK_METHOD(mStreamType, mCblk->sampleRate, mFormat, mChannelCount,
204  mFrameCount, mFlags, mSharedBuffer, getOutput(), false);
205  if (status == NO_ERROR) {
206  status = mAudioTrack->start();
207  if (status == NO_ERROR) {
208  mNewPosition = mCblk->server + mUpdatePeriod;
209  }
210  }
211  }
212  if (status != NO_ERROR) {
213  LOGV("start() failed");
214  android_atomic_and(~1, &mActive);
215  if (t != 0) {
216  t->requestExit();
217  } else {
218  setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
219  }
220  }
221  }
222 
223  LOGD("SipxAudioTrack::start() end unlock");
224  if (t != 0) {
225  t->mLock.unlock();
226  }
228  // END ANDROID CODE
229  LOGD("SipxAudioTrack::start() exit");
230 #else
231  AudioTrack::start();
232  LOGD("SipxAudioTrack::start() exited");
233 #endif
234  };
235 
236 private:
237  SipxAudioTrack(const SipxAudioTrack&); // no copy
238  SipxAudioTrack& operator=(const SipxAudioTrack&); // no copy
239 
240  int dummy1; // Padding to prevent overwrite on Droid X
241  int dummy2;
242 };
243 
244 
245 
253 {
254 /* //////////////////////////// PUBLIC //////////////////////////////////// */
255 public:
256  friend MpAndroidAudioTrack* createAndroidAudioTrack(int streamType,
257  uint32_t sampleRate,
258  int format,
259  int channels,
260  int frameCount,
261  uint32_t flags,
262  sipXcallback_t cbf,
263  void* user,
264  int notificationFrames);
265 
267 
268 /* ============================ CREATORS ================================== */
270 
271 
272 private:
274  MP_ANDROID_AUDIO_TRACK(int streamType,
275  uint32_t sampleRate0,
276  int format,
277  int channels,
278  int frameCount,
279  uint32_t flags,
280  sipXcallback_t cbf,
281  void* user,
282  int notificationFrames);
283 
284 public:
286  virtual ~MP_ANDROID_AUDIO_TRACK();
287 
289 
290 /* ============================ MANIPULATORS ============================== */
292 
293 
294  virtual void start();
295 
296  virtual void stop();
297 
299 
300 /* ============================ ACCESSORS ================================= */
302 
303 
304  virtual int /*status_t*/ initCheck() const;
305 
306  virtual uint32_t getSampleRate();
307 
308  virtual int frameSize() const;
309 
310  virtual uint32_t frameCount() const;
311 
312  virtual uint32_t latency() const;
313 
314  virtual void setVolume(float left, float right);
315 
316  virtual void dumpAudioTrack(const char* label);
317 
319 
320 /* ============================ INQUIRY =================================== */
322 
323 
325 
326 /* //////////////////////////// PROTECTED ///////////////////////////////// */
327 
328 /* //////////////////////////// PRIVATE /////////////////////////////////// */
329 private:
330 
332  MP_ANDROID_AUDIO_TRACK(const MP_ANDROID_AUDIO_TRACK& rMpAndroidAudioTrack);
333 
336 
338 };
339 
340 /* ============================ INLINE METHODS ============================ */
341 
342 #endif // _MpAndroidX_XAudioTrack_h_
Audio input driver for Android OS.
Definition: MpAndroidAudioTrack.h:37
SipxAudioTrack(int streamType, uint32_t sampleRate, int format, int channels, int frameCount, uint32_t flags, callback_t cbf, void *user, int notificationFrames)
Definition: MpAndroidX_XAudioTrack.h:112
MpAndroidAudioTrack * createAndroidAudioTrack(int streamType, uint32_t sampleRate, int format, int channels, int frameCount, uint32_t flags, sipXcallback_t cbf, void *user, int notificationFrames)
Definition: MpAndroidX_XAudioTrack.cpp:34
int dummy2
Definition: MpAndroidX_XAudioTrack.h:241
int frameCount
Definition: dmaTaskWnt.cpp:61
void start()
Definition: MpAndroidX_XAudioTrack.h:127
Definition: MpAndroidX_XAudioTrack.h:109
int dummy1
Definition: MpAndroidX_XAudioTrack.h:240
void(* sipXcallback_t)(int event, void *user, void *info)
Definition: MpAndroidAudioBindingInterface.h:32
MP_ANDROID_AUDIO_BINDING_INTERFACE & operator=(const MP_ANDROID_AUDIO_BINDING_INTERFACE &rhs)
Assignment operator (not implemented for this class)
Audio input driver for Android OS.
Definition: MpAndroidX_XAudioTrack.h:252
Audio interface for Android OS version specific differences.
Definition: MpAndroidX_XAudioBinding.h:95
SipxAudioTrack * mpAudioTrack
Definition: MpAndroidX_XAudioTrack.h:337