1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "SoundPool"
19
20#include <inttypes.h>
21
22#include <utils/Log.h>
23
24#define USE_SHARED_MEM_BUFFER
25
26#include <media/AudioTrack.h>
27#include <media/IMediaHTTPService.h>
28#include <media/mediaplayer.h>
29#include <media/stagefright/MediaExtractor.h>
30#include "SoundPool.h"
31#include "SoundPoolThread.h"
32#include <media/AudioPolicyHelper.h>
33#include <ndk/NdkMediaCodec.h>
34#include <ndk/NdkMediaExtractor.h>
35#include <ndk/NdkMediaFormat.h>
36
37namespace android
38{
39
40int kDefaultBufferCount = 4;
41uint32_t kMaxSampleRate = 48000;
42uint32_t kDefaultSampleRate = 44100;
43uint32_t kDefaultFrameCount = 1200;
44size_t kDefaultHeapSize = 1024 * 1024; // 1MB
45
46
47SoundPool::SoundPool(int maxChannels, const audio_attributes_t* pAttributes)
48{
49    ALOGV("SoundPool constructor: maxChannels=%d, attr.usage=%d, attr.flags=0x%x, attr.tags=%s",
50            maxChannels, pAttributes->usage, pAttributes->flags, pAttributes->tags);
51
52    // check limits
53    mMaxChannels = maxChannels;
54    if (mMaxChannels < 1) {
55        mMaxChannels = 1;
56    }
57    else if (mMaxChannels > 32) {
58        mMaxChannels = 32;
59    }
60    ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels);
61
62    mQuit = false;
63    mDecodeThread = 0;
64    memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
65    mAllocated = 0;
66    mNextSampleID = 0;
67    mNextChannelID = 0;
68
69    mCallback = 0;
70    mUserData = 0;
71
72    mChannelPool = new SoundChannel[mMaxChannels];
73    for (int i = 0; i < mMaxChannels; ++i) {
74        mChannelPool[i].init(this);
75        mChannels.push_back(&mChannelPool[i]);
76    }
77
78    // start decode thread
79    startThreads();
80}
81
82SoundPool::~SoundPool()
83{
84    ALOGV("SoundPool destructor");
85    mDecodeThread->quit();
86    quit();
87
88    Mutex::Autolock lock(&mLock);
89
90    mChannels.clear();
91    if (mChannelPool)
92        delete [] mChannelPool;
93    // clean up samples
94    ALOGV("clear samples");
95    mSamples.clear();
96
97    if (mDecodeThread)
98        delete mDecodeThread;
99}
100
101void SoundPool::addToRestartList(SoundChannel* channel)
102{
103    Mutex::Autolock lock(&mRestartLock);
104    if (!mQuit) {
105        mRestart.push_back(channel);
106        mCondition.signal();
107    }
108}
109
110void SoundPool::addToStopList(SoundChannel* channel)
111{
112    Mutex::Autolock lock(&mRestartLock);
113    if (!mQuit) {
114        mStop.push_back(channel);
115        mCondition.signal();
116    }
117}
118
119int SoundPool::beginThread(void* arg)
120{
121    SoundPool* p = (SoundPool*)arg;
122    return p->run();
123}
124
125int SoundPool::run()
126{
127    mRestartLock.lock();
128    while (!mQuit) {
129        mCondition.wait(mRestartLock);
130        ALOGV("awake");
131        if (mQuit) break;
132
133        while (!mStop.empty()) {
134            SoundChannel* channel;
135            ALOGV("Getting channel from stop list");
136            List<SoundChannel* >::iterator iter = mStop.begin();
137            channel = *iter;
138            mStop.erase(iter);
139            mRestartLock.unlock();
140            if (channel != 0) {
141                Mutex::Autolock lock(&mLock);
142                channel->stop();
143            }
144            mRestartLock.lock();
145            if (mQuit) break;
146        }
147
148        while (!mRestart.empty()) {
149            SoundChannel* channel;
150            ALOGV("Getting channel from list");
151            List<SoundChannel*>::iterator iter = mRestart.begin();
152            channel = *iter;
153            mRestart.erase(iter);
154            mRestartLock.unlock();
155            if (channel != 0) {
156                Mutex::Autolock lock(&mLock);
157                channel->nextEvent();
158            }
159            mRestartLock.lock();
160            if (mQuit) break;
161        }
162    }
163
164    mStop.clear();
165    mRestart.clear();
166    mCondition.signal();
167    mRestartLock.unlock();
168    ALOGV("goodbye");
169    return 0;
170}
171
172void SoundPool::quit()
173{
174    mRestartLock.lock();
175    mQuit = true;
176    mCondition.signal();
177    mCondition.wait(mRestartLock);
178    ALOGV("return from quit");
179    mRestartLock.unlock();
180}
181
182bool SoundPool::startThreads()
183{
184    createThreadEtc(beginThread, this, "SoundPool");
185    if (mDecodeThread == NULL)
186        mDecodeThread = new SoundPoolThread(this);
187    return mDecodeThread != NULL;
188}
189
190sp<Sample> SoundPool::findSample(int sampleID)
191{
192    Mutex::Autolock lock(&mLock);
193    return findSample_l(sampleID);
194}
195
196sp<Sample> SoundPool::findSample_l(int sampleID)
197{
198    return mSamples.valueFor(sampleID);
199}
200
201SoundChannel* SoundPool::findChannel(int channelID)
202{
203    for (int i = 0; i < mMaxChannels; ++i) {
204        if (mChannelPool[i].channelID() == channelID) {
205            return &mChannelPool[i];
206        }
207    }
208    return NULL;
209}
210
211SoundChannel* SoundPool::findNextChannel(int channelID)
212{
213    for (int i = 0; i < mMaxChannels; ++i) {
214        if (mChannelPool[i].nextChannelID() == channelID) {
215            return &mChannelPool[i];
216        }
217    }
218    return NULL;
219}
220
221int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused)
222{
223    ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d",
224            fd, offset, length, priority);
225    int sampleID;
226    {
227        Mutex::Autolock lock(&mLock);
228        sampleID = ++mNextSampleID;
229        sp<Sample> sample = new Sample(sampleID, fd, offset, length);
230        mSamples.add(sampleID, sample);
231        sample->startLoad();
232    }
233    // mDecodeThread->loadSample() must be called outside of mLock.
234    // mDecodeThread->loadSample() may block on mDecodeThread message queue space;
235    // the message queue emptying may block on SoundPool::findSample().
236    //
237    // It theoretically possible that sample loads might decode out-of-order.
238    mDecodeThread->loadSample(sampleID);
239    return sampleID;
240}
241
242bool SoundPool::unload(int sampleID)
243{
244    ALOGV("unload: sampleID=%d", sampleID);
245    Mutex::Autolock lock(&mLock);
246    return mSamples.removeItem(sampleID) >= 0; // removeItem() returns index or BAD_VALUE
247}
248
249int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
250        int priority, int loop, float rate)
251{
252    ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
253            sampleID, leftVolume, rightVolume, priority, loop, rate);
254    SoundChannel* channel;
255    int channelID;
256
257    Mutex::Autolock lock(&mLock);
258
259    if (mQuit) {
260        return 0;
261    }
262    // is sample ready?
263    sp<Sample> sample(findSample_l(sampleID));
264    if ((sample == 0) || (sample->state() != Sample::READY)) {
265        ALOGW("  sample %d not READY", sampleID);
266        return 0;
267    }
268
269    dump();
270
271    // allocate a channel
272    channel = allocateChannel_l(priority, sampleID);
273
274    // no channel allocated - return 0
275    if (!channel) {
276        ALOGV("No channel allocated");
277        return 0;
278    }
279
280    channelID = ++mNextChannelID;
281
282    ALOGV("play channel %p state = %d", channel, channel->state());
283    channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate);
284    return channelID;
285}
286
287SoundChannel* SoundPool::allocateChannel_l(int priority, int sampleID)
288{
289    List<SoundChannel*>::iterator iter;
290    SoundChannel* channel = NULL;
291
292    // check if channel for given sampleID still available
293    if (!mChannels.empty()) {
294        for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) {
295            if (sampleID == (*iter)->getPrevSampleID() && (*iter)->state() == SoundChannel::IDLE) {
296                channel = *iter;
297                mChannels.erase(iter);
298                ALOGV("Allocated recycled channel for same sampleID");
299                break;
300            }
301        }
302    }
303
304    // allocate any channel
305    if (!channel && !mChannels.empty()) {
306        iter = mChannels.begin();
307        if (priority >= (*iter)->priority()) {
308            channel = *iter;
309            mChannels.erase(iter);
310            ALOGV("Allocated active channel");
311        }
312    }
313
314    // update priority and put it back in the list
315    if (channel) {
316        channel->setPriority(priority);
317        for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) {
318            if (priority < (*iter)->priority()) {
319                break;
320            }
321        }
322        mChannels.insert(iter, channel);
323    }
324    return channel;
325}
326
327// move a channel from its current position to the front of the list
328void SoundPool::moveToFront_l(SoundChannel* channel)
329{
330    for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) {
331        if (*iter == channel) {
332            mChannels.erase(iter);
333            mChannels.push_front(channel);
334            break;
335        }
336    }
337}
338
339void SoundPool::pause(int channelID)
340{
341    ALOGV("pause(%d)", channelID);
342    Mutex::Autolock lock(&mLock);
343    SoundChannel* channel = findChannel(channelID);
344    if (channel) {
345        channel->pause();
346    }
347}
348
349void SoundPool::autoPause()
350{
351    ALOGV("autoPause()");
352    Mutex::Autolock lock(&mLock);
353    for (int i = 0; i < mMaxChannels; ++i) {
354        SoundChannel* channel = &mChannelPool[i];
355        channel->autoPause();
356    }
357}
358
359void SoundPool::resume(int channelID)
360{
361    ALOGV("resume(%d)", channelID);
362    Mutex::Autolock lock(&mLock);
363    SoundChannel* channel = findChannel(channelID);
364    if (channel) {
365        channel->resume();
366    }
367}
368
369void SoundPool::autoResume()
370{
371    ALOGV("autoResume()");
372    Mutex::Autolock lock(&mLock);
373    for (int i = 0; i < mMaxChannels; ++i) {
374        SoundChannel* channel = &mChannelPool[i];
375        channel->autoResume();
376    }
377}
378
379void SoundPool::stop(int channelID)
380{
381    ALOGV("stop(%d)", channelID);
382    Mutex::Autolock lock(&mLock);
383    SoundChannel* channel = findChannel(channelID);
384    if (channel) {
385        channel->stop();
386    } else {
387        channel = findNextChannel(channelID);
388        if (channel)
389            channel->clearNextEvent();
390    }
391}
392
393void SoundPool::setVolume(int channelID, float leftVolume, float rightVolume)
394{
395    Mutex::Autolock lock(&mLock);
396    SoundChannel* channel = findChannel(channelID);
397    if (channel) {
398        channel->setVolume(leftVolume, rightVolume);
399    }
400}
401
402void SoundPool::setPriority(int channelID, int priority)
403{
404    ALOGV("setPriority(%d, %d)", channelID, priority);
405    Mutex::Autolock lock(&mLock);
406    SoundChannel* channel = findChannel(channelID);
407    if (channel) {
408        channel->setPriority(priority);
409    }
410}
411
412void SoundPool::setLoop(int channelID, int loop)
413{
414    ALOGV("setLoop(%d, %d)", channelID, loop);
415    Mutex::Autolock lock(&mLock);
416    SoundChannel* channel = findChannel(channelID);
417    if (channel) {
418        channel->setLoop(loop);
419    }
420}
421
422void SoundPool::setRate(int channelID, float rate)
423{
424    ALOGV("setRate(%d, %f)", channelID, rate);
425    Mutex::Autolock lock(&mLock);
426    SoundChannel* channel = findChannel(channelID);
427    if (channel) {
428        channel->setRate(rate);
429    }
430}
431
432// call with lock held
433void SoundPool::done_l(SoundChannel* channel)
434{
435    ALOGV("done_l(%d)", channel->channelID());
436    // if "stolen", play next event
437    if (channel->nextChannelID() != 0) {
438        ALOGV("add to restart list");
439        addToRestartList(channel);
440    }
441
442    // return to idle state
443    else {
444        ALOGV("move to front");
445        moveToFront_l(channel);
446    }
447}
448
449void SoundPool::setCallback(SoundPoolCallback* callback, void* user)
450{
451    Mutex::Autolock lock(&mCallbackLock);
452    mCallback = callback;
453    mUserData = user;
454}
455
456void SoundPool::notify(SoundPoolEvent event)
457{
458    Mutex::Autolock lock(&mCallbackLock);
459    if (mCallback != NULL) {
460        mCallback(event, this, mUserData);
461    }
462}
463
464void SoundPool::dump()
465{
466    for (int i = 0; i < mMaxChannels; ++i) {
467        mChannelPool[i].dump();
468    }
469}
470
471
472Sample::Sample(int sampleID, int fd, int64_t offset, int64_t length)
473{
474    init();
475    mSampleID = sampleID;
476    mFd = dup(fd);
477    mOffset = offset;
478    mLength = length;
479    ALOGV("create sampleID=%d, fd=%d, offset=%" PRId64 " length=%" PRId64,
480        mSampleID, mFd, mLength, mOffset);
481}
482
483void Sample::init()
484{
485    mSize = 0;
486    mRefCount = 0;
487    mSampleID = 0;
488    mState = UNLOADED;
489    mFd = -1;
490    mOffset = 0;
491    mLength = 0;
492}
493
494Sample::~Sample()
495{
496    ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd);
497    if (mFd > 0) {
498        ALOGV("close(%d)", mFd);
499        ::close(mFd);
500    }
501}
502
503static status_t decode(int fd, int64_t offset, int64_t length,
504        uint32_t *rate, int *numChannels, audio_format_t *audioFormat,
505        sp<MemoryHeapBase> heap, size_t *memsize) {
506
507    ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length);
508    AMediaExtractor *ex = AMediaExtractor_new();
509    status_t err = AMediaExtractor_setDataSourceFd(ex, fd, offset, length);
510
511    if (err != AMEDIA_OK) {
512        AMediaExtractor_delete(ex);
513        return err;
514    }
515
516    *audioFormat = AUDIO_FORMAT_PCM_16_BIT;
517
518    size_t numTracks = AMediaExtractor_getTrackCount(ex);
519    for (size_t i = 0; i < numTracks; i++) {
520        AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
521        const char *mime;
522        if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
523            AMediaExtractor_delete(ex);
524            AMediaFormat_delete(format);
525            return UNKNOWN_ERROR;
526        }
527        if (strncmp(mime, "audio/", 6) == 0) {
528
529            AMediaCodec *codec = AMediaCodec_createDecoderByType(mime);
530            if (codec == NULL
531                    || AMediaCodec_configure(codec, format,
532                            NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK
533                    || AMediaCodec_start(codec) != AMEDIA_OK
534                    || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) {
535                AMediaExtractor_delete(ex);
536                AMediaCodec_delete(codec);
537                AMediaFormat_delete(format);
538                return UNKNOWN_ERROR;
539            }
540
541            bool sawInputEOS = false;
542            bool sawOutputEOS = false;
543            uint8_t* writePos = static_cast<uint8_t*>(heap->getBase());
544            size_t available = heap->getSize();
545            size_t written = 0;
546
547            AMediaFormat_delete(format);
548            format = AMediaCodec_getOutputFormat(codec);
549
550            while (!sawOutputEOS) {
551                if (!sawInputEOS) {
552                    ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000);
553                    ALOGV("input buffer %zd", bufidx);
554                    if (bufidx >= 0) {
555                        size_t bufsize;
556                        uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize);
557                        if (buf == nullptr) {
558                            ALOGE("AMediaCodec_getInputBuffer returned nullptr, short decode");
559                            break;
560                        }
561                        int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize);
562                        ALOGV("read %d", sampleSize);
563                        if (sampleSize < 0) {
564                            sampleSize = 0;
565                            sawInputEOS = true;
566                            ALOGV("EOS");
567                        }
568                        int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex);
569
570                        media_status_t mstatus = AMediaCodec_queueInputBuffer(codec, bufidx,
571                                0 /* offset */, sampleSize, presentationTimeUs,
572                                sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);
573                        if (mstatus != AMEDIA_OK) {
574                            // AMEDIA_ERROR_UNKNOWN == { -ERANGE -EINVAL -EACCES }
575                            ALOGE("AMediaCodec_queueInputBuffer returned status %d, short decode",
576                                    (int)mstatus);
577                            break;
578                        }
579                        (void)AMediaExtractor_advance(ex);
580                    }
581                }
582
583                AMediaCodecBufferInfo info;
584                int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1);
585                ALOGV("dequeueoutput returned: %d", status);
586                if (status >= 0) {
587                    if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
588                        ALOGV("output EOS");
589                        sawOutputEOS = true;
590                    }
591                    ALOGV("got decoded buffer size %d", info.size);
592
593                    uint8_t *buf = AMediaCodec_getOutputBuffer(codec, status, NULL /* out_size */);
594                    if (buf == nullptr) {
595                        ALOGE("AMediaCodec_getOutputBuffer returned nullptr, short decode");
596                        break;
597                    }
598                    size_t dataSize = info.size;
599                    if (dataSize > available) {
600                        dataSize = available;
601                    }
602                    memcpy(writePos, buf + info.offset, dataSize);
603                    writePos += dataSize;
604                    written += dataSize;
605                    available -= dataSize;
606                    media_status_t mstatus = AMediaCodec_releaseOutputBuffer(
607                            codec, status, false /* render */);
608                    if (mstatus != AMEDIA_OK) {
609                        // AMEDIA_ERROR_UNKNOWN == { -ERANGE -EINVAL -EACCES }
610                        ALOGE("AMediaCodec_releaseOutputBuffer returned status %d, short decode",
611                                (int)mstatus);
612                        break;
613                    }
614                    if (available == 0) {
615                        // there might be more data, but there's no space for it
616                        sawOutputEOS = true;
617                    }
618                } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
619                    ALOGV("output buffers changed");
620                } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
621                    AMediaFormat_delete(format);
622                    format = AMediaCodec_getOutputFormat(codec);
623                    ALOGV("format changed to: %s", AMediaFormat_toString(format));
624                } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
625                    ALOGV("no output buffer right now");
626                } else if (status <= AMEDIA_ERROR_BASE) {
627                    ALOGE("decode error: %d", status);
628                    break;
629                } else {
630                    ALOGV("unexpected info code: %d", status);
631                }
632            }
633
634            (void)AMediaCodec_stop(codec);
635            (void)AMediaCodec_delete(codec);
636            (void)AMediaExtractor_delete(ex);
637            if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) ||
638                    !AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels)) {
639                (void)AMediaFormat_delete(format);
640                return UNKNOWN_ERROR;
641            }
642            (void)AMediaFormat_delete(format);
643            *memsize = written;
644            return OK;
645        }
646        (void)AMediaFormat_delete(format);
647    }
648    (void)AMediaExtractor_delete(ex);
649    return UNKNOWN_ERROR;
650}
651
652status_t Sample::doLoad()
653{
654    uint32_t sampleRate;
655    int numChannels;
656    audio_format_t format;
657    status_t status;
658    mHeap = new MemoryHeapBase(kDefaultHeapSize);
659
660    ALOGV("Start decode");
661    status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format,
662                                 mHeap, &mSize);
663    ALOGV("close(%d)", mFd);
664    ::close(mFd);
665    mFd = -1;
666    if (status != NO_ERROR) {
667        ALOGE("Unable to load sample");
668        goto error;
669    }
670    ALOGV("pointer = %p, size = %zu, sampleRate = %u, numChannels = %d",
671          mHeap->getBase(), mSize, sampleRate, numChannels);
672
673    if (sampleRate > kMaxSampleRate) {
674       ALOGE("Sample rate (%u) out of range", sampleRate);
675       status = BAD_VALUE;
676       goto error;
677    }
678
679    if ((numChannels < 1) || (numChannels > FCC_8)) {
680        ALOGE("Sample channel count (%d) out of range", numChannels);
681        status = BAD_VALUE;
682        goto error;
683    }
684
685    mData = new MemoryBase(mHeap, 0, mSize);
686    mSampleRate = sampleRate;
687    mNumChannels = numChannels;
688    mFormat = format;
689    mState = READY;
690    return NO_ERROR;
691
692error:
693    mHeap.clear();
694    return status;
695}
696
697
698void SoundChannel::init(SoundPool* soundPool)
699{
700    mSoundPool = soundPool;
701    mPrevSampleID = -1;
702}
703
704// call with sound pool lock held
705void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume,
706        float rightVolume, int priority, int loop, float rate)
707{
708    sp<AudioTrack> oldTrack;
709    sp<AudioTrack> newTrack;
710    status_t status = NO_ERROR;
711
712    { // scope for the lock
713        Mutex::Autolock lock(&mLock);
714
715        ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f,"
716                " priority=%d, loop=%d, rate=%f",
717                this, sample->sampleID(), nextChannelID, leftVolume, rightVolume,
718                priority, loop, rate);
719
720        // if not idle, this voice is being stolen
721        if (mState != IDLE) {
722            ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID);
723            mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate);
724            stop_l();
725            return;
726        }
727
728        // initialize track
729        size_t afFrameCount;
730        uint32_t afSampleRate;
731        audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes());
732        if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
733            afFrameCount = kDefaultFrameCount;
734        }
735        if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
736            afSampleRate = kDefaultSampleRate;
737        }
738        int numChannels = sample->numChannels();
739        uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5);
740        size_t frameCount = 0;
741
742        if (loop) {
743            const audio_format_t format = sample->format();
744            const size_t frameSize = audio_is_linear_pcm(format)
745                    ? numChannels * audio_bytes_per_sample(format) : 1;
746            frameCount = sample->size() / frameSize;
747        }
748
749#ifndef USE_SHARED_MEM_BUFFER
750        uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate;
751        // Ensure minimum audio buffer size in case of short looped sample
752        if(frameCount < totalFrames) {
753            frameCount = totalFrames;
754        }
755#endif
756
757        // check if the existing track has the same sample id.
758        if (mAudioTrack != 0 && mPrevSampleID == sample->sampleID()) {
759            // the sample rate may fail to change if the audio track is a fast track.
760            if (mAudioTrack->setSampleRate(sampleRate) == NO_ERROR) {
761                newTrack = mAudioTrack;
762                ALOGV("reusing track %p for sample %d", mAudioTrack.get(), sample->sampleID());
763            }
764        }
765        if (newTrack == 0) {
766            // mToggle toggles each time a track is started on a given channel.
767            // The toggle is concatenated with the SoundChannel address and passed to AudioTrack
768            // as callback user data. This enables the detection of callbacks received from the old
769            // audio track while the new one is being started and avoids processing them with
770            // wrong audio audio buffer size  (mAudioBufferSize)
771            unsigned long toggle = mToggle ^ 1;
772            void *userData = (void *)((unsigned long)this | toggle);
773            audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels);
774
775            // do not create a new audio track if current track is compatible with sample parameters
776    #ifdef USE_SHARED_MEM_BUFFER
777            newTrack = new AudioTrack(streamType, sampleRate, sample->format(),
778                    channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData,
779                    0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
780                    AudioTrack::TRANSFER_DEFAULT,
781                    NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes());
782    #else
783            uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount;
784            newTrack = new AudioTrack(streamType, sampleRate, sample->format(),
785                    channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData,
786                    bufferFrames, AUDIO_SESSION_ALLOCATE, AudioTrack::TRANSFER_DEFAULT,
787                    NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes());
788    #endif
789            oldTrack = mAudioTrack;
790            status = newTrack->initCheck();
791            if (status != NO_ERROR) {
792                ALOGE("Error creating AudioTrack");
793                // newTrack goes out of scope, so reference count drops to zero
794                goto exit;
795            }
796            // From now on, AudioTrack callbacks received with previous toggle value will be ignored.
797            mToggle = toggle;
798            mAudioTrack = newTrack;
799            ALOGV("using new track %p for sample %d", newTrack.get(), sample->sampleID());
800        }
801        newTrack->setVolume(leftVolume, rightVolume);
802        newTrack->setLoop(0, frameCount, loop);
803        mPos = 0;
804        mSample = sample;
805        mChannelID = nextChannelID;
806        mPriority = priority;
807        mLoop = loop;
808        mLeftVolume = leftVolume;
809        mRightVolume = rightVolume;
810        mNumChannels = numChannels;
811        mRate = rate;
812        clearNextEvent();
813        mState = PLAYING;
814        mAudioTrack->start();
815        mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize();
816    }
817
818exit:
819    ALOGV("delete oldTrack %p", oldTrack.get());
820    if (status != NO_ERROR) {
821        mAudioTrack.clear();
822    }
823}
824
825void SoundChannel::nextEvent()
826{
827    sp<Sample> sample;
828    int nextChannelID;
829    float leftVolume;
830    float rightVolume;
831    int priority;
832    int loop;
833    float rate;
834
835    // check for valid event
836    {
837        Mutex::Autolock lock(&mLock);
838        nextChannelID = mNextEvent.channelID();
839        if (nextChannelID  == 0) {
840            ALOGV("stolen channel has no event");
841            return;
842        }
843
844        sample = mNextEvent.sample();
845        leftVolume = mNextEvent.leftVolume();
846        rightVolume = mNextEvent.rightVolume();
847        priority = mNextEvent.priority();
848        loop = mNextEvent.loop();
849        rate = mNextEvent.rate();
850    }
851
852    ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID);
853    play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate);
854}
855
856void SoundChannel::callback(int event, void* user, void *info)
857{
858    SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1));
859
860    channel->process(event, info, (unsigned long)user & 1);
861}
862
863void SoundChannel::process(int event, void *info, unsigned long toggle)
864{
865    //ALOGV("process(%d)", mChannelID);
866
867    Mutex::Autolock lock(&mLock);
868
869    AudioTrack::Buffer* b = NULL;
870    if (event == AudioTrack::EVENT_MORE_DATA) {
871       b = static_cast<AudioTrack::Buffer *>(info);
872    }
873
874    if (mToggle != toggle) {
875        ALOGV("process wrong toggle %p channel %d", this, mChannelID);
876        if (b != NULL) {
877            b->size = 0;
878        }
879        return;
880    }
881
882    sp<Sample> sample = mSample;
883
884//    ALOGV("SoundChannel::process event %d", event);
885
886    if (event == AudioTrack::EVENT_MORE_DATA) {
887
888        // check for stop state
889        if (b->size == 0) return;
890
891        if (mState == IDLE) {
892            b->size = 0;
893            return;
894        }
895
896        if (sample != 0) {
897            // fill buffer
898            uint8_t* q = (uint8_t*) b->i8;
899            size_t count = 0;
900
901            if (mPos < (int)sample->size()) {
902                uint8_t* p = sample->data() + mPos;
903                count = sample->size() - mPos;
904                if (count > b->size) {
905                    count = b->size;
906                }
907                memcpy(q, p, count);
908//              ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size,
909//                      count);
910            } else if (mPos < mAudioBufferSize) {
911                count = mAudioBufferSize - mPos;
912                if (count > b->size) {
913                    count = b->size;
914                }
915                memset(q, 0, count);
916//              ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count);
917            }
918
919            mPos += count;
920            b->size = count;
921            //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]);
922        }
923    } else if (event == AudioTrack::EVENT_UNDERRUN || event == AudioTrack::EVENT_BUFFER_END) {
924        ALOGV("process %p channel %d event %s",
925              this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" :
926                      "BUFFER_END");
927        mSoundPool->addToStopList(this);
928    } else if (event == AudioTrack::EVENT_LOOP_END) {
929        ALOGV("End loop %p channel %d", this, mChannelID);
930    } else if (event == AudioTrack::EVENT_NEW_IAUDIOTRACK) {
931        ALOGV("process %p channel %d NEW_IAUDIOTRACK", this, mChannelID);
932    } else {
933        ALOGW("SoundChannel::process unexpected event %d", event);
934    }
935}
936
937
938// call with lock held
939bool SoundChannel::doStop_l()
940{
941    if (mState != IDLE) {
942        setVolume_l(0, 0);
943        ALOGV("stop");
944        mAudioTrack->stop();
945        mPrevSampleID = mSample->sampleID();
946        mSample.clear();
947        mState = IDLE;
948        mPriority = IDLE_PRIORITY;
949        return true;
950    }
951    return false;
952}
953
954// call with lock held and sound pool lock held
955void SoundChannel::stop_l()
956{
957    if (doStop_l()) {
958        mSoundPool->done_l(this);
959    }
960}
961
962// call with sound pool lock held
963void SoundChannel::stop()
964{
965    bool stopped;
966    {
967        Mutex::Autolock lock(&mLock);
968        stopped = doStop_l();
969    }
970
971    if (stopped) {
972        mSoundPool->done_l(this);
973    }
974}
975
976//FIXME: Pause is a little broken right now
977void SoundChannel::pause()
978{
979    Mutex::Autolock lock(&mLock);
980    if (mState == PLAYING) {
981        ALOGV("pause track");
982        mState = PAUSED;
983        mAudioTrack->pause();
984    }
985}
986
987void SoundChannel::autoPause()
988{
989    Mutex::Autolock lock(&mLock);
990    if (mState == PLAYING) {
991        ALOGV("pause track");
992        mState = PAUSED;
993        mAutoPaused = true;
994        mAudioTrack->pause();
995    }
996}
997
998void SoundChannel::resume()
999{
1000    Mutex::Autolock lock(&mLock);
1001    if (mState == PAUSED) {
1002        ALOGV("resume track");
1003        mState = PLAYING;
1004        mAutoPaused = false;
1005        mAudioTrack->start();
1006    }
1007}
1008
1009void SoundChannel::autoResume()
1010{
1011    Mutex::Autolock lock(&mLock);
1012    if (mAutoPaused && (mState == PAUSED)) {
1013        ALOGV("resume track");
1014        mState = PLAYING;
1015        mAutoPaused = false;
1016        mAudioTrack->start();
1017    }
1018}
1019
1020void SoundChannel::setRate(float rate)
1021{
1022    Mutex::Autolock lock(&mLock);
1023    if (mAudioTrack != NULL && mSample != 0) {
1024        uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5);
1025        mAudioTrack->setSampleRate(sampleRate);
1026        mRate = rate;
1027    }
1028}
1029
1030// call with lock held
1031void SoundChannel::setVolume_l(float leftVolume, float rightVolume)
1032{
1033    mLeftVolume = leftVolume;
1034    mRightVolume = rightVolume;
1035    if (mAudioTrack != NULL)
1036        mAudioTrack->setVolume(leftVolume, rightVolume);
1037}
1038
1039void SoundChannel::setVolume(float leftVolume, float rightVolume)
1040{
1041    Mutex::Autolock lock(&mLock);
1042    setVolume_l(leftVolume, rightVolume);
1043}
1044
1045void SoundChannel::setLoop(int loop)
1046{
1047    Mutex::Autolock lock(&mLock);
1048    if (mAudioTrack != NULL && mSample != 0) {
1049        uint32_t loopEnd = mSample->size()/mNumChannels/
1050            ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t));
1051        mAudioTrack->setLoop(0, loopEnd, loop);
1052        mLoop = loop;
1053    }
1054}
1055
1056SoundChannel::~SoundChannel()
1057{
1058    ALOGV("SoundChannel destructor %p", this);
1059    {
1060        Mutex::Autolock lock(&mLock);
1061        clearNextEvent();
1062        doStop_l();
1063    }
1064    // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack
1065    // callback thread to exit which may need to execute process() and acquire the mLock.
1066    mAudioTrack.clear();
1067}
1068
1069void SoundChannel::dump()
1070{
1071    ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d",
1072            mState, mChannelID, mNumChannels, mPos, mPriority, mLoop);
1073}
1074
1075void SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume,
1076            float rightVolume, int priority, int loop, float rate)
1077{
1078    mSample = sample;
1079    mChannelID = channelID;
1080    mLeftVolume = leftVolume;
1081    mRightVolume = rightVolume;
1082    mPriority = priority;
1083    mLoop = loop;
1084    mRate =rate;
1085}
1086
1087} // end namespace android
1088