Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b94613a8 authored by Dhananjay Kumar's avatar Dhananjay Kumar Committed by Steve Kondik
Browse files

soundpool: reuse channel for same sample if available

Reuse channel for same sample if the channel completed
current playback and is not reallocated to another sample,
i.e. not stolen by other sample.

CRs-Fixed: 769440
Change-Id: Ibe7ee318c7dc11f3c4fd3a2f57d861318b10973b
parent d47ea7ca
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ public:
    void nextEvent();
    int nextChannelID() { return mNextEvent.channelID(); }
    void dump();
    int getPrevSampleID(void) { return mPrevSampleID; }

private:
    static void callback(int event, void* user, void *info);
@@ -160,6 +161,7 @@ private:
    int                 mAudioBufferSize;
    unsigned long       mToggle;
    bool                mAutoPaused;
    int                 mPrevSampleID;
};

// application object for managing a pool of sounds
@@ -202,7 +204,7 @@ private:
    sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); }
    SoundChannel* findChannel (int channelID);
    SoundChannel* findNextChannel (int channelID);
    SoundChannel* allocateChannel_l(int priority);
    SoundChannel* allocateChannel_l(int priority, int sampleID);
    void moveToFront_l(SoundChannel* channel);
    void notify(SoundPoolEvent event);
    void dump();
+44 −25
Original line number Diff line number Diff line
@@ -262,7 +262,7 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
    dump();

    // allocate a channel
    channel = allocateChannel_l(priority);
    channel = allocateChannel_l(priority, sampleID);

    // no channel allocated - return 0
    if (!channel) {
@@ -277,13 +277,25 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
    return channelID;
}

SoundChannel* SoundPool::allocateChannel_l(int priority)
SoundChannel* SoundPool::allocateChannel_l(int priority, int sampleID)
{
    List<SoundChannel*>::iterator iter;
    SoundChannel* channel = NULL;

    // allocate a channel
    // check if channel for given sampleID still available
    if (!mChannels.empty()) {
        for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) {
            if (sampleID == (*iter)->getPrevSampleID() && (*iter)->state() == SoundChannel::IDLE) {
                channel = *iter;
                mChannels.erase(iter);
                ALOGV("Allocated recycled channel for same sampleID");
                break;
            }
        }
    }

    // allocate any channel
    if (!channel && !mChannels.empty()) {
        iter = mChannels.begin();
        if (priority >= (*iter)->priority()) {
            channel = *iter;
@@ -551,6 +563,7 @@ error:
void SoundChannel::init(SoundPool* soundPool)
{
    mSoundPool = soundPool;
    mPrevSampleID = -1;
}

// call with sound pool lock held
@@ -559,7 +572,7 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
{
    sp<AudioTrack> oldTrack;
    sp<AudioTrack> newTrack;
    status_t status;
    status_t status = NO_ERROR;

    { // scope for the lock
        Mutex::Autolock lock(&mLock);
@@ -605,6 +618,7 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
        }
#endif

        if (!mAudioTrack.get() || mPrevSampleID != sample->sampleID()) {
            // mToggle toggles each time a track is started on a given channel.
            // The toggle is concatenated with the SoundChannel address and passed to AudioTrack
            // as callback user data. This enables the detection of callbacks received from the old
@@ -629,13 +643,17 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
                ALOGE("Error creating AudioTrack");
                goto exit;
            }
        ALOGV("setVolume %p", newTrack.get());
        newTrack->setVolume(leftVolume, rightVolume);
        newTrack->setLoop(0, frameCount, loop);

            // From now on, AudioTrack callbacks received with previous toggle value will be ignored.
            mToggle = toggle;
            mAudioTrack = newTrack;
            ALOGV("using new track %p for sample %d", newTrack.get(), sample->sampleID());
        } else {
            newTrack = mAudioTrack;
            ALOGV("reusing track %p for sample %d", mAudioTrack.get(), sample->sampleID());
        }
        newTrack->setVolume(leftVolume, rightVolume);
        newTrack->setLoop(0, frameCount, loop);

        mPos = 0;
        mSample = sample;
        mChannelID = nextChannelID;
@@ -777,6 +795,7 @@ bool SoundChannel::doStop_l()
        setVolume_l(0, 0);
        ALOGV("stop");
        mAudioTrack->stop();
        mPrevSampleID = mSample->sampleID();
        mSample.clear();
        mState = IDLE;
        mPriority = IDLE_PRIORITY;