Loading core/jni/android_media_AudioRecord.cpp +4 −4 Original line number Original line Diff line number Diff line Loading @@ -224,17 +224,17 @@ native_track_failure: // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static void static int android_media_AudioRecord_start(JNIEnv *env, jobject thiz) android_media_AudioRecord_start(JNIEnv *env, jobject thiz) { { AudioRecord *lpRecorder = AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj); (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj); if (lpRecorder == NULL ) { if (lpRecorder == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); jniThrowException(env, "java/lang/IllegalStateException", NULL); return; return AUDIORECORD_ERROR; } } lpRecorder->start(); return android_media_translateRecorderErrorCode(lpRecorder->start()); } } Loading Loading @@ -482,7 +482,7 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { static JNINativeMethod gMethods[] = { // name, signature, funcPtr // name, signature, funcPtr {"native_start", "()V", (void *)android_media_AudioRecord_start}, {"native_start", "()I", (void *)android_media_AudioRecord_start}, {"native_stop", "()V", (void *)android_media_AudioRecord_stop}, {"native_stop", "()V", (void *)android_media_AudioRecord_stop}, {"native_setup", "(Ljava/lang/Object;IIIII)I", {"native_setup", "(Ljava/lang/Object;IIIII)I", (void *)android_media_AudioRecord_setup}, (void *)android_media_AudioRecord_setup}, Loading libs/audioflinger/AudioFlinger.cpp +38 −17 Original line number Original line Diff line number Diff line Loading @@ -3086,23 +3086,34 @@ bool AudioFlinger::RecordThread::threadLoop() } } if (mActiveTrack != 0) { if (mActiveTrack != 0) { if (mActiveTrack->mState == TrackBase::PAUSING) { if (mActiveTrack->mState == TrackBase::PAUSING) { if (!mStandby) { mInput->standby(); mStandby = true; } mActiveTrack.clear(); mActiveTrack.clear(); mStartStopCond.broadcast(); mStartStopCond.broadcast(); } else if (mActiveTrack->mState == TrackBase::RESUMING) { } else if (mActiveTrack->mState == TrackBase::RESUMING) { mRsmpInIndex = mFrameCount; if (mReqChannelCount != mActiveTrack->channelCount()) { if (mReqChannelCount != mActiveTrack->channelCount()) { mActiveTrack.clear(); mActiveTrack.clear(); } else { mStartStopCond.broadcast(); } else if (mBytesRead != 0) { // record start succeeds only if first read from audio input // succeeds if (mBytesRead > 0) { mActiveTrack->mState = TrackBase::ACTIVE; mActiveTrack->mState = TrackBase::ACTIVE; } else { mActiveTrack.clear(); } } mStartStopCond.broadcast(); mStartStopCond.broadcast(); } } mStandby = false; mStandby = false; } } } } } if (mActiveTrack != 0) { if (mActiveTrack != 0) { if (mActiveTrack->mState != TrackBase::ACTIVE) { if (mActiveTrack->mState != TrackBase::ACTIVE && mActiveTrack->mState != TrackBase::RESUMING) { usleep(5000); usleep(5000); continue; continue; } } Loading Loading @@ -3140,18 +3151,19 @@ bool AudioFlinger::RecordThread::threadLoop() } } } } if (framesOut && mFrameCount == mRsmpInIndex) { if (framesOut && mFrameCount == mRsmpInIndex) { ssize_t bytesRead; if (framesOut == mFrameCount && if (framesOut == mFrameCount && (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) { (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) { bytesRead = mInput->read(buffer.raw, mInputBytes); mBytesRead = mInput->read(buffer.raw, mInputBytes); framesOut = 0; framesOut = 0; } else { } else { bytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mRsmpInIndex = 0; mRsmpInIndex = 0; } } if (bytesRead < 0) { if (mBytesRead < 0) { LOGE("Error reading audio input"); LOGE("Error reading audio input"); if (mActiveTrack->mState == TrackBase::ACTIVE) { sleep(1); sleep(1); } mRsmpInIndex = mFrameCount; mRsmpInIndex = mFrameCount; framesOut = 0; framesOut = 0; buffer.frameCount = 0; buffer.frameCount = 0; Loading Loading @@ -3220,7 +3232,7 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac if (recordTrack != mActiveTrack.get()) { if (recordTrack != mActiveTrack.get()) { status = -EBUSY; status = -EBUSY; } else if (mActiveTrack->mState == TrackBase::PAUSING) { } else if (mActiveTrack->mState == TrackBase::PAUSING) { mActiveTrack->mState = TrackBase::RESUMING; mActiveTrack->mState = TrackBase::ACTIVE; } } return status; return status; } } Loading @@ -3235,6 +3247,8 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac return status; return status; } } mActiveTrack->mState = TrackBase::RESUMING; mActiveTrack->mState = TrackBase::RESUMING; mRsmpInIndex = mFrameCount; mBytesRead = 0; // signal thread to start // signal thread to start LOGV("Signal record thread"); LOGV("Signal record thread"); mWaitWorkCV.signal(); mWaitWorkCV.signal(); Loading Loading @@ -3275,6 +3289,7 @@ void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) { mLock.unlock(); mLock.unlock(); AudioSystem::stopInput(mId); AudioSystem::stopInput(mId); mLock.lock(); mLock.lock(); LOGV("Record stopped OK"); } } } } } } Loading Loading @@ -3325,10 +3340,12 @@ status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* int channelCount; int channelCount; if (framesReady == 0) { if (framesReady == 0) { ssize_t bytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes); if (bytesRead < 0) { if (mBytesRead < 0) { LOGE("RecordThread::getNextBuffer() Error reading audio input"); LOGE("RecordThread::getNextBuffer() Error reading audio input"); if (mActiveTrack->mState == TrackBase::ACTIVE) { sleep(1); sleep(1); } buffer->raw = 0; buffer->raw = 0; buffer->frameCount = 0; buffer->frameCount = 0; return NOT_ENOUGH_DATA; return NOT_ENOUGH_DATA; Loading Loading @@ -3546,11 +3563,13 @@ int AudioFlinger::openOutput(uint32_t *pDevices, if (pFormat) *pFormat = format; if (pFormat) *pFormat = format; if (pChannels) *pChannels = channels; if (pChannels) *pChannels = channels; if (pLatencyMs) *pLatencyMs = thread->latency(); if (pLatencyMs) *pLatencyMs = thread->latency(); } return mNextThreadId; return mNextThreadId; } } return 0; } int AudioFlinger::openDuplicateOutput(int output1, int output2) int AudioFlinger::openDuplicateOutput(int output1, int output2) { { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); Loading Loading @@ -3694,11 +3713,13 @@ int AudioFlinger::openInput(uint32_t *pDevices, if (pChannels) *pChannels = reqChannels; if (pChannels) *pChannels = reqChannels; input->standby(); input->standby(); } return mNextThreadId; return mNextThreadId; } } return 0; } status_t AudioFlinger::closeInput(int input) status_t AudioFlinger::closeInput(int input) { { // keep strong reference on the record thread so that // keep strong reference on the record thread so that Loading libs/audioflinger/AudioFlinger.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -744,6 +744,7 @@ private: size_t mInputBytes; size_t mInputBytes; int mReqChannelCount; int mReqChannelCount; uint32_t mReqSampleRate; uint32_t mReqSampleRate; ssize_t mBytesRead; }; }; class RecordHandle : public android::BnAudioRecord { class RecordHandle : public android::BnAudioRecord { Loading media/java/android/media/AudioRecord.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -498,10 +498,11 @@ public class AudioRecord // start recording // start recording synchronized(mRecordingStateLock) { synchronized(mRecordingStateLock) { native_start(); if (native_start() == SUCCESS) { mRecordingState = RECORDSTATE_RECORDING; mRecordingState = RECORDSTATE_RECORDING; } } } } } Loading Loading @@ -764,7 +765,7 @@ public class AudioRecord private native final void native_release(); private native final void native_release(); private native final void native_start(); private native final int native_start(); private native final void native_stop(); private native final void native_stop(); Loading media/libmedia/AudioRecord.cpp +1 −2 Original line number Original line Diff line number Diff line Loading @@ -125,7 +125,7 @@ status_t AudioRecord::set( audio_io_handle_t input = AudioSystem::getInput(inputSource, audio_io_handle_t input = AudioSystem::getInput(inputSource, sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); if (input == 0) { if (input == 0) { LOGE("Could not get audio output for stream type %d", inputSource); LOGE("Could not get audio input for record source %d", inputSource); return BAD_VALUE; return BAD_VALUE; } } Loading Loading @@ -539,7 +539,6 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize) return BAD_VALUE; return BAD_VALUE; } } LOGV("read size: %d", userSize); do { do { Loading Loading
core/jni/android_media_AudioRecord.cpp +4 −4 Original line number Original line Diff line number Diff line Loading @@ -224,17 +224,17 @@ native_track_failure: // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static void static int android_media_AudioRecord_start(JNIEnv *env, jobject thiz) android_media_AudioRecord_start(JNIEnv *env, jobject thiz) { { AudioRecord *lpRecorder = AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj); (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj); if (lpRecorder == NULL ) { if (lpRecorder == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); jniThrowException(env, "java/lang/IllegalStateException", NULL); return; return AUDIORECORD_ERROR; } } lpRecorder->start(); return android_media_translateRecorderErrorCode(lpRecorder->start()); } } Loading Loading @@ -482,7 +482,7 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { static JNINativeMethod gMethods[] = { // name, signature, funcPtr // name, signature, funcPtr {"native_start", "()V", (void *)android_media_AudioRecord_start}, {"native_start", "()I", (void *)android_media_AudioRecord_start}, {"native_stop", "()V", (void *)android_media_AudioRecord_stop}, {"native_stop", "()V", (void *)android_media_AudioRecord_stop}, {"native_setup", "(Ljava/lang/Object;IIIII)I", {"native_setup", "(Ljava/lang/Object;IIIII)I", (void *)android_media_AudioRecord_setup}, (void *)android_media_AudioRecord_setup}, Loading
libs/audioflinger/AudioFlinger.cpp +38 −17 Original line number Original line Diff line number Diff line Loading @@ -3086,23 +3086,34 @@ bool AudioFlinger::RecordThread::threadLoop() } } if (mActiveTrack != 0) { if (mActiveTrack != 0) { if (mActiveTrack->mState == TrackBase::PAUSING) { if (mActiveTrack->mState == TrackBase::PAUSING) { if (!mStandby) { mInput->standby(); mStandby = true; } mActiveTrack.clear(); mActiveTrack.clear(); mStartStopCond.broadcast(); mStartStopCond.broadcast(); } else if (mActiveTrack->mState == TrackBase::RESUMING) { } else if (mActiveTrack->mState == TrackBase::RESUMING) { mRsmpInIndex = mFrameCount; if (mReqChannelCount != mActiveTrack->channelCount()) { if (mReqChannelCount != mActiveTrack->channelCount()) { mActiveTrack.clear(); mActiveTrack.clear(); } else { mStartStopCond.broadcast(); } else if (mBytesRead != 0) { // record start succeeds only if first read from audio input // succeeds if (mBytesRead > 0) { mActiveTrack->mState = TrackBase::ACTIVE; mActiveTrack->mState = TrackBase::ACTIVE; } else { mActiveTrack.clear(); } } mStartStopCond.broadcast(); mStartStopCond.broadcast(); } } mStandby = false; mStandby = false; } } } } } if (mActiveTrack != 0) { if (mActiveTrack != 0) { if (mActiveTrack->mState != TrackBase::ACTIVE) { if (mActiveTrack->mState != TrackBase::ACTIVE && mActiveTrack->mState != TrackBase::RESUMING) { usleep(5000); usleep(5000); continue; continue; } } Loading Loading @@ -3140,18 +3151,19 @@ bool AudioFlinger::RecordThread::threadLoop() } } } } if (framesOut && mFrameCount == mRsmpInIndex) { if (framesOut && mFrameCount == mRsmpInIndex) { ssize_t bytesRead; if (framesOut == mFrameCount && if (framesOut == mFrameCount && (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) { (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) { bytesRead = mInput->read(buffer.raw, mInputBytes); mBytesRead = mInput->read(buffer.raw, mInputBytes); framesOut = 0; framesOut = 0; } else { } else { bytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mRsmpInIndex = 0; mRsmpInIndex = 0; } } if (bytesRead < 0) { if (mBytesRead < 0) { LOGE("Error reading audio input"); LOGE("Error reading audio input"); if (mActiveTrack->mState == TrackBase::ACTIVE) { sleep(1); sleep(1); } mRsmpInIndex = mFrameCount; mRsmpInIndex = mFrameCount; framesOut = 0; framesOut = 0; buffer.frameCount = 0; buffer.frameCount = 0; Loading Loading @@ -3220,7 +3232,7 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac if (recordTrack != mActiveTrack.get()) { if (recordTrack != mActiveTrack.get()) { status = -EBUSY; status = -EBUSY; } else if (mActiveTrack->mState == TrackBase::PAUSING) { } else if (mActiveTrack->mState == TrackBase::PAUSING) { mActiveTrack->mState = TrackBase::RESUMING; mActiveTrack->mState = TrackBase::ACTIVE; } } return status; return status; } } Loading @@ -3235,6 +3247,8 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac return status; return status; } } mActiveTrack->mState = TrackBase::RESUMING; mActiveTrack->mState = TrackBase::RESUMING; mRsmpInIndex = mFrameCount; mBytesRead = 0; // signal thread to start // signal thread to start LOGV("Signal record thread"); LOGV("Signal record thread"); mWaitWorkCV.signal(); mWaitWorkCV.signal(); Loading Loading @@ -3275,6 +3289,7 @@ void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) { mLock.unlock(); mLock.unlock(); AudioSystem::stopInput(mId); AudioSystem::stopInput(mId); mLock.lock(); mLock.lock(); LOGV("Record stopped OK"); } } } } } } Loading Loading @@ -3325,10 +3340,12 @@ status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* int channelCount; int channelCount; if (framesReady == 0) { if (framesReady == 0) { ssize_t bytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes); if (bytesRead < 0) { if (mBytesRead < 0) { LOGE("RecordThread::getNextBuffer() Error reading audio input"); LOGE("RecordThread::getNextBuffer() Error reading audio input"); if (mActiveTrack->mState == TrackBase::ACTIVE) { sleep(1); sleep(1); } buffer->raw = 0; buffer->raw = 0; buffer->frameCount = 0; buffer->frameCount = 0; return NOT_ENOUGH_DATA; return NOT_ENOUGH_DATA; Loading Loading @@ -3546,11 +3563,13 @@ int AudioFlinger::openOutput(uint32_t *pDevices, if (pFormat) *pFormat = format; if (pFormat) *pFormat = format; if (pChannels) *pChannels = channels; if (pChannels) *pChannels = channels; if (pLatencyMs) *pLatencyMs = thread->latency(); if (pLatencyMs) *pLatencyMs = thread->latency(); } return mNextThreadId; return mNextThreadId; } } return 0; } int AudioFlinger::openDuplicateOutput(int output1, int output2) int AudioFlinger::openDuplicateOutput(int output1, int output2) { { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); Loading Loading @@ -3694,11 +3713,13 @@ int AudioFlinger::openInput(uint32_t *pDevices, if (pChannels) *pChannels = reqChannels; if (pChannels) *pChannels = reqChannels; input->standby(); input->standby(); } return mNextThreadId; return mNextThreadId; } } return 0; } status_t AudioFlinger::closeInput(int input) status_t AudioFlinger::closeInput(int input) { { // keep strong reference on the record thread so that // keep strong reference on the record thread so that Loading
libs/audioflinger/AudioFlinger.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -744,6 +744,7 @@ private: size_t mInputBytes; size_t mInputBytes; int mReqChannelCount; int mReqChannelCount; uint32_t mReqSampleRate; uint32_t mReqSampleRate; ssize_t mBytesRead; }; }; class RecordHandle : public android::BnAudioRecord { class RecordHandle : public android::BnAudioRecord { Loading
media/java/android/media/AudioRecord.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -498,10 +498,11 @@ public class AudioRecord // start recording // start recording synchronized(mRecordingStateLock) { synchronized(mRecordingStateLock) { native_start(); if (native_start() == SUCCESS) { mRecordingState = RECORDSTATE_RECORDING; mRecordingState = RECORDSTATE_RECORDING; } } } } } Loading Loading @@ -764,7 +765,7 @@ public class AudioRecord private native final void native_release(); private native final void native_release(); private native final void native_start(); private native final int native_start(); private native final void native_stop(); private native final void native_stop(); Loading
media/libmedia/AudioRecord.cpp +1 −2 Original line number Original line Diff line number Diff line Loading @@ -125,7 +125,7 @@ status_t AudioRecord::set( audio_io_handle_t input = AudioSystem::getInput(inputSource, audio_io_handle_t input = AudioSystem::getInput(inputSource, sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); if (input == 0) { if (input == 0) { LOGE("Could not get audio output for stream type %d", inputSource); LOGE("Could not get audio input for record source %d", inputSource); return BAD_VALUE; return BAD_VALUE; } } Loading Loading @@ -539,7 +539,6 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize) return BAD_VALUE; return BAD_VALUE; } } LOGV("read size: %d", userSize); do { do { Loading