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

Commit 2a2f0ece authored by Eric Laurent's avatar Eric Laurent Committed by Android Git Automerger
Browse files

am 681be039: ToneGenerator: fix truncated tones

* commit '681be039':
  ToneGenerator: fix truncated tones
parents 7ffe7689 681be039
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ private:
    float mVolume;  // Volume applied to audio track
    audio_stream_type_t mStreamType; // Audio stream used for output
    unsigned int mProcessSize;  // Size of audio blocks generated at a time by audioCallback() (in PCM frames).
    struct timespec mStartTime; // tone start time: needed to guaranty actual tone duration

    bool initAudioTrack();
    static void audioCallback(int event, void* user, void *info);
+31 −1
Original line number Diff line number Diff line
@@ -922,6 +922,9 @@ bool ToneGenerator::startTone(tone_type toneType, int durationMs) {
            ALOGV("Immediate start, time %d", (unsigned int)(systemTime()/1000000));
            lResult = true;
            mState = TONE_STARTING;
            if (clock_gettime(CLOCK_MONOTONIC, &mStartTime) != 0) {
                mStartTime.tv_sec = 0;
            }
            mLock.unlock();
            mpAudioTrack->start();
            mLock.lock();
@@ -940,6 +943,7 @@ bool ToneGenerator::startTone(tone_type toneType, int durationMs) {
    } else {
        ALOGV("Delayed start");
        mState = TONE_RESTARTING;
        mStartTime.tv_sec = 0;
        lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
        if (lStatus == NO_ERROR) {
            if (mState != TONE_IDLE) {
@@ -978,8 +982,31 @@ void ToneGenerator::stopTone() {
    mLock.lock();
    if (mState != TONE_IDLE && mState != TONE_INIT) {
        if (mState == TONE_PLAYING || mState == TONE_STARTING || mState == TONE_RESTARTING) {
            struct timespec stopTime;
            // If the start time is valid, make sure that the number of audio samples produced
            // corresponds at least to the time between the start and stop commands.
            // This is needed in case of cold start of the output stream.
            if ((mStartTime. tv_sec != 0) && (clock_gettime(CLOCK_MONOTONIC, &stopTime) == 0)) {
                time_t sec = stopTime.tv_sec - mStartTime.tv_sec;
                long nsec = stopTime.tv_nsec - mStartTime.tv_nsec;
                long durationMs;
                if (nsec < 0) {
                    --sec;
                    nsec += 1000000000;
                }

                if ((sec + 1) > ((long)(INT_MAX / mSamplingRate))) {
                    mMaxSmp = sec * mSamplingRate;
                } else {
                    // mSamplingRate is always > 1000
                    sec = sec * 1000 + nsec / 1000000; // duration in milliseconds
                    mMaxSmp = (sec * mSamplingRate) / 1000;
                }
                ALOGV("stopTone() forcing mMaxSmp to %d, total for far %d", mMaxSmp,  mTotalSmp);
            } else {
                mState = TONE_STOPPING;
            }
        }
        ALOGV("waiting cond");
        status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
        if (lStatus == NO_ERROR) {
@@ -1263,6 +1290,9 @@ audioCallback_EndLoop:
            ALOGV("Cbk restarting track");
            if (lpToneGen->prepareWave()) {
                lpToneGen->mState = TONE_STARTING;
                if (clock_gettime(CLOCK_MONOTONIC, &lpToneGen->mStartTime) != 0) {
                    lpToneGen->mStartTime.tv_sec = 0;
                }
                // must reload lpToneDesc as prepareWave() may change mpToneDesc
                lpToneDesc = lpToneGen->mpToneDesc;
            } else {