Loading core/jni/android_media_ToneGenerator.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,7 @@ static void android_media_ToneGenerator_release(JNIEnv *env, jobject thiz) { static void android_media_ToneGenerator_native_setup(JNIEnv *env, jobject thiz, jint streamType, jint volume) { ToneGenerator *lpToneGen = new ToneGenerator(streamType, AudioSystem::linearToLog(volume)); ToneGenerator *lpToneGen = new ToneGenerator(streamType, AudioSystem::linearToLog(volume), true); env->SetIntField(thiz, fields.context, 0); Loading include/media/AudioRecord.h +6 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,11 @@ private: }; bool processAudioBuffer(const sp<ClientRecordThread>& thread); status_t openRecord(uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags); sp<IAudioRecord> mAudioRecord; sp<IMemory> mCblkMemory; Loading Loading @@ -341,6 +346,7 @@ private: uint32_t mNewPosition; uint32_t mUpdatePeriod; audio_io_handle_t mInput; uint32_t mFlags; }; }; // namespace android Loading include/media/AudioTrack.h +8 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,14 @@ private: }; bool processAudioBuffer(const sp<AudioTrackThread>& thread); status_t createTrack(int streamType, uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, audio_io_handle_t output); sp<IAudioTrack> mAudioTrack; sp<IMemory> mCblkMemory; Loading include/media/ToneGenerator.h +2 −1 Original line number Diff line number Diff line Loading @@ -151,7 +151,7 @@ public: NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1 }; ToneGenerator(int streamType, float volume); ToneGenerator(int streamType, float volume, bool threadCanCallJava = false); ~ToneGenerator(); bool startTone(int toneType, int durationMs = -1); Loading Loading @@ -242,6 +242,7 @@ private: static const ToneDescriptor sToneDescriptors[]; bool mThreadCanCallJava; unsigned int mTotalSmp; // Total number of audio samples played (gives current time) unsigned int mNextSegSmp; // Position of next segment transition expressed in samples // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly Loading media/libmedia/AudioRecord.cpp +85 −42 Original line number Diff line number Diff line Loading @@ -101,11 +101,6 @@ status_t AudioRecord::set( return INVALID_OPERATION; } const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); if (audioFlinger == 0) { return NO_INIT; } if (inputSource == AUDIO_SOURCE_DEFAULT) { inputSource = AUDIO_SOURCE_MIC; } Loading Loading @@ -171,22 +166,14 @@ status_t AudioRecord::set( notificationFrames = frameCount/2; } // open record channel status_t status; sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput, sampleRate, format, channelCount, frameCount, ((uint16_t)flags) << 16, &status); if (record == 0) { LOGE("AudioFlinger could not create record track, status: %d", status); // create the IAudioRecord status_t status = openRecord(sampleRate, format, channelCount, frameCount, flags); if (status != NO_ERROR) { return status; } sp<IMemory> cblk = record->getCblk(); if (cblk == 0) { return NO_INIT; } if (cbf != 0) { mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); if (mClientRecordThread == 0) { Loading @@ -196,11 +183,6 @@ status_t AudioRecord::set( mStatus = NO_ERROR; mAudioRecord = record; mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); mCblk->out = 0; mFormat = format; // Update buffer size in case it has been limited by AudioFlinger during track creation mFrameCount = mCblk->frameCount; Loading @@ -217,6 +199,7 @@ status_t AudioRecord::set( mNewPosition = 0; mUpdatePeriod = 0; mInputSource = (uint8_t)inputSource; mFlags = flags; return NO_ERROR; } Loading Loading @@ -283,6 +266,13 @@ status_t AudioRecord::start() if (android_atomic_or(1, &mActive) == 0) { ret = AudioSystem::startInput(mInput); if (ret == NO_ERROR) { ret = mAudioRecord->start(); if (ret == DEAD_OBJECT) { LOGV("start() dead IAudioRecord: creating a new one"); ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount, mFrameCount, mFlags); } if (ret == NO_ERROR) { mNewPosition = mCblk->user + mUpdatePeriod; mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; Loading @@ -292,7 +282,11 @@ status_t AudioRecord::start() } else { setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); } ret = mAudioRecord->start(); } else { LOGV("start() failed"); AudioSystem::stopInput(mInput); android_atomic_and(~1, &mActive); } } } Loading Loading @@ -396,10 +390,48 @@ status_t AudioRecord::getPosition(uint32_t *position) // ------------------------------------------------------------------------- status_t AudioRecord::openRecord( uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags) { status_t status; const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); if (audioFlinger == 0) { return NO_INIT; } sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput, sampleRate, format, channelCount, frameCount, ((uint16_t)flags) << 16, &status); if (record == 0) { LOGE("AudioFlinger could not create record track, status: %d", status); return status; } sp<IMemory> cblk = record->getCblk(); if (cblk == 0) { LOGE("Could not get control block"); return NO_INIT; } mAudioRecord.clear(); mAudioRecord = record; mCblkMemory.clear(); mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); mCblk->out = 0; return NO_ERROR; } status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) { int active; int timeout = 0; status_t result; audio_track_cblk_t* cblk = mCblk; uint32_t framesReq = audioBuffer->frameCount; Loading @@ -411,25 +443,40 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) uint32_t framesReady = cblk->framesReady(); if (framesReady == 0) { Mutex::Autolock _l(cblk->lock); cblk->lock.lock(); goto start_loop_here; while (framesReady == 0) { active = mActive; if (UNLIKELY(!active)) if (UNLIKELY(!active)) { cblk->lock.unlock(); return NO_MORE_BUFFERS; if (UNLIKELY(!waitCount)) } if (UNLIKELY(!waitCount)) { cblk->lock.unlock(); return WOULD_BLOCK; timeout = 0; } result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); if (__builtin_expect(result!=NO_ERROR, false)) { cblk->waitTimeMs += waitTimeMs; if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { LOGW( "obtainBuffer timed out (is the CPU pegged?) " "user=%08x, server=%08x", cblk->user, cblk->server); timeout = 1; cblk->lock.unlock(); result = mAudioRecord->start(); if (result == DEAD_OBJECT) { LOGW("obtainBuffer() dead IAudioRecord: creating a new one"); result = openRecord(cblk->sampleRate, mFormat, mChannelCount, mFrameCount, mFlags); if (result == NO_ERROR) { cblk = mCblk; cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; } } cblk->lock.lock(); cblk->waitTimeMs = 0; } if (--waitCount == 0) { cblk->lock.unlock(); return TIMED_OUT; } } Loading @@ -437,13 +484,9 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) start_loop_here: framesReady = cblk->framesReady(); } cblk->lock.unlock(); } LOGW_IF(timeout, "*** SERIOUS WARNING *** obtainBuffer() timed out " "but didn't need to be locked. We recovered, but " "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server); cblk->waitTimeMs = 0; if (framesReq > framesReady) { Loading Loading
core/jni/android_media_ToneGenerator.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,7 @@ static void android_media_ToneGenerator_release(JNIEnv *env, jobject thiz) { static void android_media_ToneGenerator_native_setup(JNIEnv *env, jobject thiz, jint streamType, jint volume) { ToneGenerator *lpToneGen = new ToneGenerator(streamType, AudioSystem::linearToLog(volume)); ToneGenerator *lpToneGen = new ToneGenerator(streamType, AudioSystem::linearToLog(volume), true); env->SetIntField(thiz, fields.context, 0); Loading
include/media/AudioRecord.h +6 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,11 @@ private: }; bool processAudioBuffer(const sp<ClientRecordThread>& thread); status_t openRecord(uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags); sp<IAudioRecord> mAudioRecord; sp<IMemory> mCblkMemory; Loading Loading @@ -341,6 +346,7 @@ private: uint32_t mNewPosition; uint32_t mUpdatePeriod; audio_io_handle_t mInput; uint32_t mFlags; }; }; // namespace android Loading
include/media/AudioTrack.h +8 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,14 @@ private: }; bool processAudioBuffer(const sp<AudioTrackThread>& thread); status_t createTrack(int streamType, uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, audio_io_handle_t output); sp<IAudioTrack> mAudioTrack; sp<IMemory> mCblkMemory; Loading
include/media/ToneGenerator.h +2 −1 Original line number Diff line number Diff line Loading @@ -151,7 +151,7 @@ public: NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1 }; ToneGenerator(int streamType, float volume); ToneGenerator(int streamType, float volume, bool threadCanCallJava = false); ~ToneGenerator(); bool startTone(int toneType, int durationMs = -1); Loading Loading @@ -242,6 +242,7 @@ private: static const ToneDescriptor sToneDescriptors[]; bool mThreadCanCallJava; unsigned int mTotalSmp; // Total number of audio samples played (gives current time) unsigned int mNextSegSmp; // Position of next segment transition expressed in samples // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly Loading
media/libmedia/AudioRecord.cpp +85 −42 Original line number Diff line number Diff line Loading @@ -101,11 +101,6 @@ status_t AudioRecord::set( return INVALID_OPERATION; } const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); if (audioFlinger == 0) { return NO_INIT; } if (inputSource == AUDIO_SOURCE_DEFAULT) { inputSource = AUDIO_SOURCE_MIC; } Loading Loading @@ -171,22 +166,14 @@ status_t AudioRecord::set( notificationFrames = frameCount/2; } // open record channel status_t status; sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput, sampleRate, format, channelCount, frameCount, ((uint16_t)flags) << 16, &status); if (record == 0) { LOGE("AudioFlinger could not create record track, status: %d", status); // create the IAudioRecord status_t status = openRecord(sampleRate, format, channelCount, frameCount, flags); if (status != NO_ERROR) { return status; } sp<IMemory> cblk = record->getCblk(); if (cblk == 0) { return NO_INIT; } if (cbf != 0) { mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); if (mClientRecordThread == 0) { Loading @@ -196,11 +183,6 @@ status_t AudioRecord::set( mStatus = NO_ERROR; mAudioRecord = record; mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); mCblk->out = 0; mFormat = format; // Update buffer size in case it has been limited by AudioFlinger during track creation mFrameCount = mCblk->frameCount; Loading @@ -217,6 +199,7 @@ status_t AudioRecord::set( mNewPosition = 0; mUpdatePeriod = 0; mInputSource = (uint8_t)inputSource; mFlags = flags; return NO_ERROR; } Loading Loading @@ -283,6 +266,13 @@ status_t AudioRecord::start() if (android_atomic_or(1, &mActive) == 0) { ret = AudioSystem::startInput(mInput); if (ret == NO_ERROR) { ret = mAudioRecord->start(); if (ret == DEAD_OBJECT) { LOGV("start() dead IAudioRecord: creating a new one"); ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount, mFrameCount, mFlags); } if (ret == NO_ERROR) { mNewPosition = mCblk->user + mUpdatePeriod; mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; Loading @@ -292,7 +282,11 @@ status_t AudioRecord::start() } else { setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); } ret = mAudioRecord->start(); } else { LOGV("start() failed"); AudioSystem::stopInput(mInput); android_atomic_and(~1, &mActive); } } } Loading Loading @@ -396,10 +390,48 @@ status_t AudioRecord::getPosition(uint32_t *position) // ------------------------------------------------------------------------- status_t AudioRecord::openRecord( uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags) { status_t status; const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); if (audioFlinger == 0) { return NO_INIT; } sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput, sampleRate, format, channelCount, frameCount, ((uint16_t)flags) << 16, &status); if (record == 0) { LOGE("AudioFlinger could not create record track, status: %d", status); return status; } sp<IMemory> cblk = record->getCblk(); if (cblk == 0) { LOGE("Could not get control block"); return NO_INIT; } mAudioRecord.clear(); mAudioRecord = record; mCblkMemory.clear(); mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); mCblk->out = 0; return NO_ERROR; } status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) { int active; int timeout = 0; status_t result; audio_track_cblk_t* cblk = mCblk; uint32_t framesReq = audioBuffer->frameCount; Loading @@ -411,25 +443,40 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) uint32_t framesReady = cblk->framesReady(); if (framesReady == 0) { Mutex::Autolock _l(cblk->lock); cblk->lock.lock(); goto start_loop_here; while (framesReady == 0) { active = mActive; if (UNLIKELY(!active)) if (UNLIKELY(!active)) { cblk->lock.unlock(); return NO_MORE_BUFFERS; if (UNLIKELY(!waitCount)) } if (UNLIKELY(!waitCount)) { cblk->lock.unlock(); return WOULD_BLOCK; timeout = 0; } result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); if (__builtin_expect(result!=NO_ERROR, false)) { cblk->waitTimeMs += waitTimeMs; if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { LOGW( "obtainBuffer timed out (is the CPU pegged?) " "user=%08x, server=%08x", cblk->user, cblk->server); timeout = 1; cblk->lock.unlock(); result = mAudioRecord->start(); if (result == DEAD_OBJECT) { LOGW("obtainBuffer() dead IAudioRecord: creating a new one"); result = openRecord(cblk->sampleRate, mFormat, mChannelCount, mFrameCount, mFlags); if (result == NO_ERROR) { cblk = mCblk; cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; } } cblk->lock.lock(); cblk->waitTimeMs = 0; } if (--waitCount == 0) { cblk->lock.unlock(); return TIMED_OUT; } } Loading @@ -437,13 +484,9 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) start_loop_here: framesReady = cblk->framesReady(); } cblk->lock.unlock(); } LOGW_IF(timeout, "*** SERIOUS WARNING *** obtainBuffer() timed out " "but didn't need to be locked. We recovered, but " "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server); cblk->waitTimeMs = 0; if (framesReq > framesReady) { Loading