AudioTrack.cpp revision 25658fd43d150a45fb37734a9f9f27f48bb5c133
1/* //device/extlibs/pv/android/AudioTrack.cpp
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
19//#define LOG_NDEBUG 0
20#define LOG_TAG "AudioTrack"
21
22#include <stdint.h>
23#include <sys/types.h>
24#include <limits.h>
25
26#include <sched.h>
27#include <sys/resource.h>
28
29#include <private/media/AudioTrackShared.h>
30
31#include <media/AudioSystem.h>
32#include <media/AudioTrack.h>
33
34#include <utils/Log.h>
35#include <utils/MemoryDealer.h>
36#include <utils/Parcel.h>
37#include <utils/IPCThreadState.h>
38#include <utils/Timers.h>
39#include <cutils/atomic.h>
40
41#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
42#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
43
44namespace android {
45
46// ---------------------------------------------------------------------------
47
48AudioTrack::AudioTrack()
49    : mStatus(NO_INIT)
50{
51}
52
53AudioTrack::AudioTrack(
54        int streamType,
55        uint32_t sampleRate,
56        int format,
57        int channelCount,
58        int frameCount,
59        uint32_t flags,
60        callback_t cbf,
61        void* user,
62        int notificationFrames)
63    : mStatus(NO_INIT)
64{
65    mStatus = set(streamType, sampleRate, format, channelCount,
66            frameCount, flags, cbf, user, notificationFrames, 0);
67}
68
69AudioTrack::AudioTrack(
70        int streamType,
71        uint32_t sampleRate,
72        int format,
73        int channelCount,
74        const sp<IMemory>& sharedBuffer,
75        uint32_t flags,
76        callback_t cbf,
77        void* user,
78        int notificationFrames)
79    : mStatus(NO_INIT)
80{
81    mStatus = set(streamType, sampleRate, format, channelCount,
82            0, flags, cbf, user, notificationFrames, sharedBuffer);
83}
84
85AudioTrack::~AudioTrack()
86{
87    LOGV_IF(mSharedBuffer != 0, "Destructor sharedBuffer: %p", mSharedBuffer->pointer());
88
89    if (mStatus == NO_ERROR) {
90        // Make sure that callback function exits in the case where
91        // it is looping on buffer full condition in obtainBuffer().
92        // Otherwise the callback thread will never exit.
93        stop();
94        if (mAudioTrackThread != 0) {
95            mCblk->cv.signal();
96            mAudioTrackThread->requestExitAndWait();
97            mAudioTrackThread.clear();
98        }
99        mAudioTrack.clear();
100        IPCThreadState::self()->flushCommands();
101    }
102}
103
104status_t AudioTrack::set(
105        int streamType,
106        uint32_t sampleRate,
107        int format,
108        int channelCount,
109        int frameCount,
110        uint32_t flags,
111        callback_t cbf,
112        void* user,
113        int notificationFrames,
114        const sp<IMemory>& sharedBuffer,
115        bool threadCanCallJava)
116{
117
118    LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
119
120    if (mAudioFlinger != 0) {
121        LOGE("Track already in use");
122        return INVALID_OPERATION;
123    }
124
125    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
126    if (audioFlinger == 0) {
127       LOGE("Could not get audioflinger");
128       return NO_INIT;
129    }
130    int afSampleRate;
131    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
132        return NO_INIT;
133    }
134    int afFrameCount;
135    if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
136        return NO_INIT;
137    }
138    uint32_t afLatency;
139    if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
140        return NO_INIT;
141    }
142
143    // handle default values first.
144    if (streamType == AudioSystem::DEFAULT) {
145        streamType = AudioSystem::MUSIC;
146    }
147    if (sampleRate == 0) {
148        sampleRate = afSampleRate;
149    }
150    // these below should probably come from the audioFlinger too...
151    if (format == 0) {
152        format = AudioSystem::PCM_16_BIT;
153    }
154    if (channelCount == 0) {
155        channelCount = 2;
156    }
157
158    // validate parameters
159    if (((format != AudioSystem::PCM_8_BIT) || sharedBuffer != 0) &&
160        (format != AudioSystem::PCM_16_BIT)) {
161        LOGE("Invalid format");
162        return BAD_VALUE;
163    }
164    if (channelCount != 1 && channelCount != 2) {
165        LOGE("Invalid channel number");
166        return BAD_VALUE;
167    }
168
169    // Ensure that buffer depth covers at least audio hardware latency
170    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
171    // When playing from shared buffer, playback will start even if last audioflinger
172    // block is partly filled.
173    if (sharedBuffer != 0 && minBufCount > 1) {
174        minBufCount--;
175    }
176
177    int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
178
179    if (sharedBuffer == 0) {
180        if (frameCount == 0) {
181            frameCount = minFrameCount;
182        }
183        if (notificationFrames == 0) {
184            notificationFrames = frameCount/2;
185        }
186        // Make sure that application is notified with sufficient margin
187        // before underrun
188        if (notificationFrames > frameCount/2) {
189            notificationFrames = frameCount/2;
190        }
191    } else {
192        // Ensure that buffer alignment matches channelcount
193        if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) {
194            LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount);
195            return BAD_VALUE;
196        }
197        frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t);
198    }
199
200    if (frameCount < minFrameCount) {
201      LOGE("Invalid buffer size: minFrameCount %d, frameCount %d", minFrameCount, frameCount);
202      return BAD_VALUE;
203    }
204
205    // create the track
206    status_t status;
207    sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
208                streamType, sampleRate, format, channelCount, frameCount, flags, sharedBuffer, &status);
209
210    if (track == 0) {
211        LOGE("AudioFlinger could not create track, status: %d", status);
212        return status;
213    }
214    sp<IMemory> cblk = track->getCblk();
215    if (cblk == 0) {
216        LOGE("Could not get control block");
217        return NO_INIT;
218    }
219    if (cbf != 0) {
220        mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
221        if (mAudioTrackThread == 0) {
222          LOGE("Could not create callback thread");
223          return NO_INIT;
224        }
225    }
226
227    mStatus = NO_ERROR;
228
229    mAudioFlinger = audioFlinger;
230    mAudioTrack = track;
231    mCblkMemory = cblk;
232    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
233    mCblk->out = 1;
234    // Update buffer size in case it has been limited by AudioFlinger during track creation
235    mFrameCount = mCblk->frameCount;
236    if (sharedBuffer == 0) {
237        mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
238    } else {
239        mCblk->buffers = sharedBuffer->pointer();
240         // Force buffer full condition as data is already present in shared memory
241        mCblk->stepUser(mFrameCount);
242    }
243    mCblk->volume[0] = mCblk->volume[1] = 0x1000;
244    mVolume[LEFT] = 1.0f;
245    mVolume[RIGHT] = 1.0f;
246    mSampleRate = sampleRate;
247    mStreamType = streamType;
248    mFormat = format;
249    mChannelCount = channelCount;
250    mSharedBuffer = sharedBuffer;
251    mMuted = false;
252    mActive = 0;
253    mCbf = cbf;
254    mNotificationFrames = notificationFrames;
255    mRemainingFrames = notificationFrames;
256    mUserData = user;
257    mLatency = afLatency + (1000*mFrameCount) / mSampleRate;
258    mLoopCount = 0;
259    mMarkerPosition = 0;
260    mNewPosition = 0;
261    mUpdatePeriod = 0;
262
263    return NO_ERROR;
264}
265
266status_t AudioTrack::initCheck() const
267{
268    return mStatus;
269}
270
271// -------------------------------------------------------------------------
272
273uint32_t AudioTrack::latency() const
274{
275    return mLatency;
276}
277
278int AudioTrack::streamType() const
279{
280    return mStreamType;
281}
282
283uint32_t AudioTrack::sampleRate() const
284{
285    return mSampleRate;
286}
287
288int AudioTrack::format() const
289{
290    return mFormat;
291}
292
293int AudioTrack::channelCount() const
294{
295    return mChannelCount;
296}
297
298uint32_t AudioTrack::frameCount() const
299{
300    return mFrameCount;
301}
302
303int AudioTrack::frameSize() const
304{
305    return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
306}
307
308sp<IMemory>& AudioTrack::sharedBuffer()
309{
310    return mSharedBuffer;
311}
312
313// -------------------------------------------------------------------------
314
315void AudioTrack::start()
316{
317    sp<AudioTrackThread> t = mAudioTrackThread;
318
319    LOGV("start");
320    if (t != 0) {
321        if (t->exitPending()) {
322            if (t->requestExitAndWait() == WOULD_BLOCK) {
323                LOGE("AudioTrack::start called from thread");
324                return;
325            }
326        }
327        t->mLock.lock();
328     }
329
330    if (android_atomic_or(1, &mActive) == 0) {
331        mNewPosition = mCblk->server + mUpdatePeriod;
332        mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
333        mCblk->waitTimeMs = 0;
334        if (t != 0) {
335           t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
336        } else {
337            setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
338        }
339        mAudioTrack->start();
340    }
341
342    if (t != 0) {
343        t->mLock.unlock();
344    }
345}
346
347void AudioTrack::stop()
348{
349    sp<AudioTrackThread> t = mAudioTrackThread;
350
351    LOGV("stop");
352    if (t != 0) {
353        t->mLock.lock();
354    }
355
356    if (android_atomic_and(~1, &mActive) == 1) {
357        mAudioTrack->stop();
358        // Cancel loops (If we are in the middle of a loop, playback
359        // would not stop until loopCount reaches 0).
360        setLoop(0, 0, 0);
361        // Force flush if a shared buffer is used otherwise audioflinger
362        // will not stop before end of buffer is reached.
363        if (mSharedBuffer != 0) {
364            flush();
365        }
366        if (t != 0) {
367            t->requestExit();
368        } else {
369            setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
370        }
371    }
372
373    if (t != 0) {
374        t->mLock.unlock();
375    }
376}
377
378bool AudioTrack::stopped() const
379{
380    return !mActive;
381}
382
383void AudioTrack::flush()
384{
385    LOGV("flush");
386
387    if (!mActive) {
388        mCblk->lock.lock();
389        mAudioTrack->flush();
390        // Release AudioTrack callback thread in case it was waiting for new buffers
391        // in AudioTrack::obtainBuffer()
392        mCblk->cv.signal();
393        mCblk->lock.unlock();
394    }
395}
396
397void AudioTrack::pause()
398{
399    LOGV("pause");
400    if (android_atomic_and(~1, &mActive) == 1) {
401        mActive = 0;
402        mAudioTrack->pause();
403    }
404}
405
406void AudioTrack::mute(bool e)
407{
408    mAudioTrack->mute(e);
409    mMuted = e;
410}
411
412bool AudioTrack::muted() const
413{
414    return mMuted;
415}
416
417void AudioTrack::setVolume(float left, float right)
418{
419    mVolume[LEFT] = left;
420    mVolume[RIGHT] = right;
421
422    // write must be atomic
423    mCblk->volumeLR = (int32_t(int16_t(left * 0x1000)) << 16) | int16_t(right * 0x1000);
424}
425
426void AudioTrack::getVolume(float* left, float* right)
427{
428    *left  = mVolume[LEFT];
429    *right = mVolume[RIGHT];
430}
431
432void AudioTrack::setSampleRate(int rate)
433{
434    int afSamplingRate;
435
436    if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
437        return;
438    }
439    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
440    if (rate > afSamplingRate*2) rate = afSamplingRate*2;
441
442    if (rate > MAX_SAMPLE_RATE) rate = MAX_SAMPLE_RATE;
443
444    mCblk->sampleRate = rate;
445}
446
447uint32_t AudioTrack::getSampleRate()
448{
449    return uint32_t(mCblk->sampleRate);
450}
451
452status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount)
453{
454    audio_track_cblk_t* cblk = mCblk;
455
456
457    Mutex::Autolock _l(cblk->lock);
458
459    if (loopCount == 0) {
460        cblk->loopStart = UINT_MAX;
461        cblk->loopEnd = UINT_MAX;
462        cblk->loopCount = 0;
463        mLoopCount = 0;
464        return NO_ERROR;
465    }
466
467    if (loopStart >= loopEnd ||
468        loopEnd - loopStart > mFrameCount) {
469        LOGW("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, mFrameCount, cblk->user);
470        return BAD_VALUE;
471    }
472    // TODO handle shared buffer here: limit loop end to framecount
473
474    cblk->loopStart = loopStart;
475    cblk->loopEnd = loopEnd;
476    cblk->loopCount = loopCount;
477    mLoopCount = loopCount;
478
479    return NO_ERROR;
480}
481
482status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount)
483{
484    if (loopStart != 0) {
485        *loopStart = mCblk->loopStart;
486    }
487    if (loopEnd != 0) {
488        *loopEnd = mCblk->loopEnd;
489    }
490    if (loopCount != 0) {
491        if (mCblk->loopCount < 0) {
492            *loopCount = -1;
493        } else {
494            *loopCount = mCblk->loopCount;
495        }
496    }
497
498    return NO_ERROR;
499}
500
501status_t AudioTrack::setMarkerPosition(uint32_t marker)
502{
503    if (mCbf == 0) return INVALID_OPERATION;
504
505    mMarkerPosition = marker;
506
507    return NO_ERROR;
508}
509
510status_t AudioTrack::getMarkerPosition(uint32_t *marker)
511{
512    if (marker == 0) return BAD_VALUE;
513
514    *marker = mMarkerPosition;
515
516    return NO_ERROR;
517}
518
519status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod)
520{
521    if (mCbf == 0) return INVALID_OPERATION;
522
523    uint32_t curPosition;
524    getPosition(&curPosition);
525    mNewPosition = curPosition + updatePeriod;
526    mUpdatePeriod = updatePeriod;
527
528    return NO_ERROR;
529}
530
531status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod)
532{
533    if (updatePeriod == 0) return BAD_VALUE;
534
535    *updatePeriod = mUpdatePeriod;
536
537    return NO_ERROR;
538}
539
540status_t AudioTrack::setPosition(uint32_t position)
541{
542    Mutex::Autolock _l(mCblk->lock);
543
544    if (!stopped()) return INVALID_OPERATION;
545
546    if (position > mCblk->user) return BAD_VALUE;
547
548    mCblk->server = position;
549    mCblk->forceReady = 1;
550
551    return NO_ERROR;
552}
553
554status_t AudioTrack::getPosition(uint32_t *position)
555{
556    if (position == 0) return BAD_VALUE;
557
558    *position = mCblk->server;
559
560    return NO_ERROR;
561}
562
563status_t AudioTrack::reload()
564{
565    if (!stopped()) return INVALID_OPERATION;
566
567    flush();
568
569    mCblk->stepUser(mFrameCount);
570
571    return NO_ERROR;
572}
573
574// -------------------------------------------------------------------------
575
576status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
577{
578    int active;
579    int timeout = 0;
580    status_t result;
581    audio_track_cblk_t* cblk = mCblk;
582    uint32_t framesReq = audioBuffer->frameCount;
583
584    audioBuffer->frameCount  = 0;
585    audioBuffer->size = 0;
586
587    uint32_t framesAvail = cblk->framesAvailable();
588
589    if (framesAvail == 0) {
590        Mutex::Autolock _l(cblk->lock);
591        goto start_loop_here;
592        while (framesAvail == 0) {
593            active = mActive;
594            if (UNLIKELY(!active)) {
595                LOGV("Not active and NO_MORE_BUFFERS");
596                return NO_MORE_BUFFERS;
597            }
598            if (UNLIKELY(!waitCount))
599                return WOULD_BLOCK;
600            timeout = 0;
601            result = cblk->cv.waitRelative(cblk->lock, milliseconds(WAIT_PERIOD_MS));
602            if (__builtin_expect(result!=NO_ERROR, false)) {
603                cblk->waitTimeMs += WAIT_PERIOD_MS;
604                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
605                    // timing out when a loop has been set and we have already written upto loop end
606                    // is a normal condition: no need to wake AudioFlinger up.
607                    if (cblk->user < cblk->loopEnd) {
608                        LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
609                                "user=%08x, server=%08x", cblk->user, cblk->server);
610                        mAudioFlinger->wakeUp();
611                        timeout = 1;
612                    }
613                    cblk->waitTimeMs = 0;
614                }
615
616                if (--waitCount == 0) {
617                    return TIMED_OUT;
618                }
619            }
620            // read the server count again
621        start_loop_here:
622            framesAvail = cblk->framesAvailable_l();
623        }
624    }
625
626    cblk->waitTimeMs = 0;
627
628    if (framesReq > framesAvail) {
629        framesReq = framesAvail;
630    }
631
632    uint32_t u = cblk->user;
633    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
634
635    if (u + framesReq > bufferEnd) {
636        framesReq = bufferEnd - u;
637    }
638
639    LOGW_IF(timeout,
640        "*** SERIOUS WARNING *** obtainBuffer() timed out "
641        "but didn't need to be locked. We recovered, but "
642        "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server);
643
644    audioBuffer->flags       = mMuted ? Buffer::MUTE : 0;
645    audioBuffer->channelCount= mChannelCount;
646    audioBuffer->format      = AudioSystem::PCM_16_BIT;
647    audioBuffer->frameCount  = framesReq;
648    audioBuffer->size = framesReq*mChannelCount*sizeof(int16_t);
649    audioBuffer->raw         = (int8_t *)cblk->buffer(u);
650    active = mActive;
651    return active ? status_t(NO_ERROR) : status_t(STOPPED);
652}
653
654void AudioTrack::releaseBuffer(Buffer* audioBuffer)
655{
656    audio_track_cblk_t* cblk = mCblk;
657    cblk->stepUser(audioBuffer->frameCount);
658}
659
660// -------------------------------------------------------------------------
661
662ssize_t AudioTrack::write(const void* buffer, size_t userSize)
663{
664
665    if (mSharedBuffer != 0) return INVALID_OPERATION;
666
667    if (ssize_t(userSize) < 0) {
668        // sanity-check. user is most-likely passing an error code.
669        LOGE("AudioTrack::write(buffer=%p, size=%u (%d)",
670                buffer, userSize, userSize);
671        return BAD_VALUE;
672    }
673
674    LOGV("write %d bytes, mActive=%d", userSize, mActive);
675
676    ssize_t written = 0;
677    const int8_t *src = (const int8_t *)buffer;
678    Buffer audioBuffer;
679
680    do {
681        audioBuffer.frameCount = userSize/mChannelCount;
682        if (mFormat == AudioSystem::PCM_16_BIT) {
683            audioBuffer.frameCount >>= 1;
684        }
685        // Calling obtainBuffer() with a negative wait count causes
686        // an (almost) infinite wait time.
687        status_t err = obtainBuffer(&audioBuffer, -1);
688        if (err < 0) {
689            // out of buffers, return #bytes written
690            if (err == status_t(NO_MORE_BUFFERS))
691                break;
692            return ssize_t(err);
693        }
694
695        size_t toWrite;
696        if (mFormat == AudioSystem::PCM_8_BIT) {
697            // Divide capacity by 2 to take expansion into account
698            toWrite = audioBuffer.size>>1;
699            // 8 to 16 bit conversion
700            int count = toWrite;
701            int16_t *dst = (int16_t *)(audioBuffer.i8);
702            while(count--) {
703                *dst++ = (int16_t)(*src++^0x80) << 8;
704            }
705        }else {
706            toWrite = audioBuffer.size;
707            memcpy(audioBuffer.i8, src, toWrite);
708            src += toWrite;
709        }
710        userSize -= toWrite;
711        written += toWrite;
712
713        releaseBuffer(&audioBuffer);
714    } while (userSize);
715
716    return written;
717}
718
719// -------------------------------------------------------------------------
720
721bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
722{
723    Buffer audioBuffer;
724    uint32_t frames;
725    size_t writtenSize;
726
727    // Manage underrun callback
728    if (mActive && (mCblk->framesReady() == 0)) {
729        LOGV("Underrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag);
730        if (mCblk->flowControlFlag == 0) {
731            mCbf(EVENT_UNDERRUN, mUserData, 0);
732            if (mCblk->server == mCblk->frameCount) {
733                mCbf(EVENT_BUFFER_END, mUserData, 0);
734            }
735            mCblk->flowControlFlag = 1;
736            if (mSharedBuffer != 0) return false;
737        }
738    }
739
740    // Manage loop end callback
741    while (mLoopCount > mCblk->loopCount) {
742        int loopCount = -1;
743        mLoopCount--;
744        if (mLoopCount >= 0) loopCount = mLoopCount;
745
746        mCbf(EVENT_LOOP_END, mUserData, (void *)&loopCount);
747    }
748
749    // Manage marker callback
750    if(mMarkerPosition > 0) {
751        if (mCblk->server >= mMarkerPosition) {
752            mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
753            mMarkerPosition = 0;
754        }
755    }
756
757    // Manage new position callback
758    if(mUpdatePeriod > 0) {
759        while (mCblk->server >= mNewPosition) {
760            mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
761            mNewPosition += mUpdatePeriod;
762        }
763    }
764
765    // If Shared buffer is used, no data is requested from client.
766    if (mSharedBuffer != 0) {
767        frames = 0;
768    } else {
769        frames = mRemainingFrames;
770    }
771
772    do {
773
774        audioBuffer.frameCount = frames;
775
776        // Calling obtainBuffer() with a wait count of 1
777        // limits wait time to WAIT_PERIOD_MS. This prevents from being
778        // stuck here not being able to handle timed events (position, markers, loops).
779        status_t err = obtainBuffer(&audioBuffer, 1);
780        if (err < NO_ERROR) {
781            if (err != TIMED_OUT) {
782                LOGE("Error obtaining an audio buffer, giving up.");
783                return false;
784            }
785            break;
786        }
787        if (err == status_t(STOPPED)) return false;
788
789        // Divide buffer size by 2 to take into account the expansion
790        // due to 8 to 16 bit conversion: the callback must fill only half
791        // of the destination buffer
792        if (mFormat == AudioSystem::PCM_8_BIT) {
793            audioBuffer.size >>= 1;
794        }
795
796        size_t reqSize = audioBuffer.size;
797        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
798        writtenSize = audioBuffer.size;
799
800        // Sanity check on returned size
801        if (ssize_t(writtenSize) <= 0) break;
802        if (writtenSize > reqSize) writtenSize = reqSize;
803
804        if (mFormat == AudioSystem::PCM_8_BIT) {
805            // 8 to 16 bit conversion
806            const int8_t *src = audioBuffer.i8 + writtenSize-1;
807            int count = writtenSize;
808            int16_t *dst = audioBuffer.i16 + writtenSize-1;
809            while(count--) {
810                *dst-- = (int16_t)(*src--^0x80) << 8;
811            }
812            writtenSize <<= 1;
813        }
814
815        audioBuffer.size = writtenSize;
816        audioBuffer.frameCount = writtenSize/mChannelCount/sizeof(int16_t);
817        frames -= audioBuffer.frameCount;
818
819        releaseBuffer(&audioBuffer);
820    }
821    while (frames);
822
823    if (frames == 0) {
824        mRemainingFrames = mNotificationFrames;
825    } else {
826        mRemainingFrames = frames;
827    }
828    return true;
829}
830
831status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
832{
833
834    const size_t SIZE = 256;
835    char buffer[SIZE];
836    String8 result;
837
838    result.append(" AudioTrack::dump\n");
839    snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]);
840    result.append(buffer);
841    snprintf(buffer, 255, "  format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mFrameCount);
842    result.append(buffer);
843    snprintf(buffer, 255, "  sample rate(%d), status(%d), muted(%d)\n", mSampleRate, mStatus, mMuted);
844    result.append(buffer);
845    snprintf(buffer, 255, "  active(%d), latency (%d)\n", mActive, mLatency);
846    result.append(buffer);
847    ::write(fd, result.string(), result.size());
848    return NO_ERROR;
849}
850
851// =========================================================================
852
853AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava)
854    : Thread(bCanCallJava), mReceiver(receiver)
855{
856}
857
858bool AudioTrack::AudioTrackThread::threadLoop()
859{
860    return mReceiver.processAudioBuffer(this);
861}
862
863status_t AudioTrack::AudioTrackThread::readyToRun()
864{
865    return NO_ERROR;
866}
867
868void AudioTrack::AudioTrackThread::onFirstRef()
869{
870}
871
872// =========================================================================
873
874audio_track_cblk_t::audio_track_cblk_t()
875    : user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0),
876    loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), flowControlFlag(1), forceReady(0)
877{
878}
879
880uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)
881{
882    uint32_t u = this->user;
883
884    u += frameCount;
885    // Ensure that user is never ahead of server for AudioRecord
886    if (out) {
887        // If stepServer() has been called once, switch to normal obtainBuffer() timeout period
888        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
889            bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
890        }
891    } else if (u > this->server) {
892        LOGW("stepServer occured after track reset");
893        u = this->server;
894    }
895
896    if (u >= userBase + this->frameCount) {
897        userBase += this->frameCount;
898    }
899
900    this->user = u;
901
902    // Clear flow control error condition as new data has been written/read to/from buffer.
903    flowControlFlag = 0;
904
905    return u;
906}
907
908bool audio_track_cblk_t::stepServer(uint32_t frameCount)
909{
910    // the code below simulates lock-with-timeout
911    // we MUST do this to protect the AudioFlinger server
912    // as this lock is shared with the client.
913    status_t err;
914
915    err = lock.tryLock();
916    if (err == -EBUSY) { // just wait a bit
917        usleep(1000);
918        err = lock.tryLock();
919    }
920    if (err != NO_ERROR) {
921        // probably, the client just died.
922        return false;
923    }
924
925    uint32_t s = this->server;
926
927    s += frameCount;
928    if (out) {
929        // Mark that we have read the first buffer so that next time stepUser() is called
930        // we switch to normal obtainBuffer() timeout period
931        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
932            bufferTimeoutMs = MAX_RUN_TIMEOUT_MS - 1;
933        }
934        // It is possible that we receive a flush()
935        // while the mixer is processing a block: in this case,
936        // stepServer() is called After the flush() has reset u & s and
937        // we have s > u
938        if (s > this->user) {
939            LOGW("stepServer occured after track reset");
940            s = this->user;
941        }
942    }
943
944    if (s >= loopEnd) {
945        LOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd);
946        s = loopStart;
947        if (--loopCount == 0) {
948            loopEnd = UINT_MAX;
949            loopStart = UINT_MAX;
950        }
951    }
952    if (s >= serverBase + this->frameCount) {
953        serverBase += this->frameCount;
954    }
955
956    this->server = s;
957
958    cv.signal();
959    lock.unlock();
960    return true;
961}
962
963void* audio_track_cblk_t::buffer(uint32_t offset) const
964{
965    return (int16_t *)this->buffers + (offset-userBase)*this->channels;
966}
967
968uint32_t audio_track_cblk_t::framesAvailable()
969{
970    Mutex::Autolock _l(lock);
971    return framesAvailable_l();
972}
973
974uint32_t audio_track_cblk_t::framesAvailable_l()
975{
976    uint32_t u = this->user;
977    uint32_t s = this->server;
978
979    if (out) {
980        uint32_t limit = (s < loopStart) ? s : loopStart;
981        return limit + frameCount - u;
982    } else {
983        return frameCount + u - s;
984    }
985}
986
987uint32_t audio_track_cblk_t::framesReady()
988{
989    uint32_t u = this->user;
990    uint32_t s = this->server;
991
992    if (out) {
993        if (u < loopEnd) {
994            return u - s;
995        } else {
996            Mutex::Autolock _l(lock);
997            if (loopCount >= 0) {
998                return (loopEnd - loopStart)*loopCount + u - s;
999            } else {
1000                return UINT_MAX;
1001            }
1002        }
1003    } else {
1004        return s - u;
1005    }
1006}
1007
1008// -------------------------------------------------------------------------
1009
1010}; // namespace android
1011
1012