Loading include/media/ToneGenerator.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading media/libmedia/ToneGenerator.cpp +31 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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 { Loading Loading
include/media/ToneGenerator.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
media/libmedia/ToneGenerator.cpp +31 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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 { Loading