Loading media/libaaudio/src/legacy/AudioStreamLegacy.cpp +57 −28 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ using namespace android; using namespace aaudio; AudioStreamLegacy::AudioStreamLegacy() : AudioStream() { : AudioStream(), mDeviceCallback(new StreamDeviceCallback(this)) { } AudioStreamLegacy::~AudioStreamLegacy() { Loading Loading @@ -60,9 +60,16 @@ int32_t AudioStreamLegacy::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) { aaudio_data_callback_result_t callbackResult; if (!mCallbackEnabled.load()) { return; } switch (opcode) { case AAUDIO_CALLBACK_OPERATION_PROCESS_DATA: { // Note that this code assumes an AudioTrack::Buffer is the same as AudioRecord::Buffer if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { // Note that this code assumes an AudioTrack::Buffer is the same as // AudioRecord::Buffer // TODO define our own AudioBuffer and pass it from the subclasses. AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info); if (audioBuffer->frameCount == 0) return; Loading @@ -70,8 +77,8 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode // If the caller specified an exact size then use a block size adapter. if (mBlockAdapter != nullptr) { int32_t byteCount = audioBuffer->frameCount * getBytesPerFrame(); callbackResult = mBlockAdapter->processVariableBlock((uint8_t *) audioBuffer->raw, byteCount); callbackResult = mBlockAdapter->processVariableBlock( (uint8_t *) audioBuffer->raw, byteCount); } else { // Call using the AAudio callback interface. callbackResult = (*getDataCallbackProc())( Loading @@ -87,17 +94,20 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode } else { audioBuffer->size = 0; } } break; } } /// FALL THROUGH // Stream got rerouted so we disconnect. case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: { ALOGD("AudioStreamAAudio(): callbackLoop() stream disconnected"); setState(AAUDIO_STREAM_STATE_DISCONNECTED); ALOGD("processCallbackCommon() stream disconnected"); if (getErrorCallbackProc() != nullptr) { (*getErrorCallbackProc())( (AAudioStream *) this, getErrorCallbackUserData(), AAUDIO_OK AAUDIO_ERROR_DISCONNECTED ); } mCallbackEnabled.store(false); Loading Loading @@ -129,3 +139,22 @@ aaudio_result_t AudioStreamLegacy::getBestTimestamp(clockid_t clockId, status_t status = extendedTimestamp->getBestTimestamp(framePosition, timeNanoseconds, timebase); return AAudioConvert_androidToAAudioResult(status); } void AudioStreamLegacy::onAudioDeviceUpdate(audio_port_handle_t deviceId) { ALOGD("onAudioDeviceUpdate() deviceId %d", (int)deviceId); if (getDeviceId() != AAUDIO_UNSPECIFIED && getDeviceId() != deviceId && getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); // if we have a data callback and the stream is active, send the error callback from // data callback thread when it sees the DISCONNECTED state if (!isDataCallbackActive() && getErrorCallbackProc() != nullptr) { (*getErrorCallbackProc())( (AAudioStream *) this, getErrorCallbackUserData(), AAUDIO_ERROR_DISCONNECTED ); } } setDeviceId(deviceId); } media/libaaudio/src/legacy/AudioStreamLegacy.h +24 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define LEGACY_AUDIO_STREAM_LEGACY_H #include <media/AudioTimestamp.h> #include <media/AudioSystem.h> #include <aaudio/AAudio.h> Loading Loading @@ -75,14 +76,37 @@ public: protected: class StreamDeviceCallback : public android::AudioSystem::AudioDeviceCallback { public: StreamDeviceCallback(AudioStreamLegacy *parent) : mParent(parent) {} virtual ~StreamDeviceCallback() {} virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo __unused, audio_port_handle_t deviceId) { if (mParent != nullptr) { mParent->onAudioDeviceUpdate(deviceId); } } AudioStreamLegacy *mParent; }; aaudio_result_t getBestTimestamp(clockid_t clockId, int64_t *framePosition, int64_t *timeNanoseconds, android::ExtendedTimestamp *extendedTimestamp); void onAudioDeviceUpdate(audio_port_handle_t deviceId); void onStart() { mCallbackEnabled.store(true); } void onStop() { mCallbackEnabled.store(false); } FixedBlockAdapter *mBlockAdapter = nullptr; aaudio_wrapping_frames_t mPositionWhenStarting = 0; int32_t mCallbackBufferSize = 0; const android::sp<StreamDeviceCallback> mDeviceCallback; }; } /* namespace aaudio */ Loading media/libaaudio/src/legacy/AudioStreamRecord.cpp +21 −1 Original line number Diff line number Diff line Loading @@ -99,15 +99,21 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) ALOGD("AudioStreamRecord::open(), request notificationFrames = %u, frameCount = %u", notificationFrames, (uint)frameCount); mAudioRecord = new AudioRecord( mOpPackageName // const String16& opPackageName TODO does not compile ); if (getDeviceId() != AAUDIO_UNSPECIFIED) { mAudioRecord->setInputDevice(getDeviceId()); } mAudioRecord->set( AUDIO_SOURCE_VOICE_RECOGNITION, getSampleRate(), format, channelMask, mOpPackageName, // const String16& opPackageName TODO does not compile frameCount, callback, callbackData, notificationFrames, false /*threadCanCallJava*/, AUDIO_SESSION_ALLOCATE, streamTransferType, flags Loading Loading @@ -162,6 +168,8 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) perfMode, actualPerformanceMode); setState(AAUDIO_STREAM_STATE_OPEN); setDeviceId(mAudioRecord->getRoutedDeviceId()); mAudioRecord->addAudioDeviceCallback(mDeviceCallback); return AAUDIO_OK; } Loading Loading @@ -209,6 +217,7 @@ aaudio_result_t AudioStreamRecord::requestStart() if (err != OK) { return AAudioConvert_androidToAAudioResult(err); } else { onStart(); setState(AAUDIO_STREAM_STATE_STARTING); } return AAUDIO_OK; Loading @@ -230,6 +239,7 @@ aaudio_result_t AudioStreamRecord::requestStop() { if (mAudioRecord.get() == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } onStop(); setState(AAUDIO_STREAM_STATE_STOPPING); incrementFramesWritten(getFramesRead() - getFramesWritten()); // TODO review mAudioRecord->stop(); Loading Loading @@ -274,12 +284,22 @@ aaudio_result_t AudioStreamRecord::read(void *buffer, return result; } if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) { return AAUDIO_ERROR_DISCONNECTED; } // TODO add timeout to AudioRecord bool blocking = (timeoutNanoseconds > 0); ssize_t bytesRead = mAudioRecord->read(buffer, numBytes, blocking); if (bytesRead == WOULD_BLOCK) { return 0; } else if (bytesRead < 0) { // in this context, a DEAD_OBJECT is more likely to be a disconnect notification due to // AudioRecord invalidation if (bytesRead == DEAD_OBJECT) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); return AAUDIO_ERROR_DISCONNECTED; } return AAudioConvert_androidToAAudioResult(bytesRead); } int32_t framesRead = (int32_t)(bytesRead / bytesPerFrame); Loading media/libaaudio/src/legacy/AudioStreamTrack.cpp +21 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,11 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) ALOGD("AudioStreamTrack::open(), request notificationFrames = %d, frameCount = %u", notificationFrames, (uint)frameCount); mAudioTrack = new AudioTrack( mAudioTrack = new AudioTrack(); if (getDeviceId() != AAUDIO_UNSPECIFIED) { mAudioTrack->setOutputDevice(getDeviceId()); } mAudioTrack->set( (audio_stream_type_t) AUDIO_STREAM_MUSIC, getSampleRate(), format, Loading @@ -125,6 +129,8 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) callback, callbackData, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, AUDIO_SESSION_ALLOCATE, streamTransferType ); Loading Loading @@ -160,6 +166,7 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) setState(AAUDIO_STREAM_STATE_OPEN); setDeviceId(mAudioTrack->getRoutedDeviceId()); mAudioTrack->addAudioDeviceCallback(mDeviceCallback); // Update performance mode based on the actual stream. // For example, if the sample rate is not allowed then you won't get a FAST track. Loading Loading @@ -229,6 +236,7 @@ aaudio_result_t AudioStreamTrack::requestStart() if (err != OK) { return AAudioConvert_androidToAAudioResult(err); } else { onStart(); setState(AAUDIO_STREAM_STATE_STARTING); } return AAUDIO_OK; Loading @@ -246,6 +254,7 @@ aaudio_result_t AudioStreamTrack::requestPause() AAudio_convertStreamStateToText(getState())); return AAUDIO_ERROR_INVALID_STATE; } onStop(); setState(AAUDIO_STREAM_STATE_PAUSING); mAudioTrack->pause(); status_t err = mAudioTrack->getPosition(&mPositionWhenPausing); Loading Loading @@ -276,6 +285,7 @@ aaudio_result_t AudioStreamTrack::requestStop() { if (mAudioTrack.get() == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } onStop(); setState(AAUDIO_STREAM_STATE_STOPPING); incrementFramesRead(getFramesWritten() - getFramesRead()); // TODO review mAudioTrack->stop(); Loading Loading @@ -339,6 +349,10 @@ aaudio_result_t AudioStreamTrack::write(const void *buffer, return result; } if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) { return AAUDIO_ERROR_DISCONNECTED; } // TODO add timeout to AudioTrack bool blocking = timeoutNanoseconds > 0; ssize_t bytesWritten = mAudioTrack->write(buffer, numBytes, blocking); Loading @@ -346,6 +360,12 @@ aaudio_result_t AudioStreamTrack::write(const void *buffer, return 0; } else if (bytesWritten < 0) { ALOGE("invalid write, returned %d", (int)bytesWritten); // in this context, a DEAD_OBJECT is more likely to be a disconnect notification due to // AudioTrack invalidation if (bytesWritten == DEAD_OBJECT) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); return AAUDIO_ERROR_DISCONNECTED; } return AAudioConvert_androidToAAudioResult(bytesWritten); } int32_t framesWritten = (int32_t)(bytesWritten / bytesPerFrame); Loading media/libaudioclient/AudioRecord.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -481,6 +481,7 @@ status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) { AutoMutex lock(mLock); if (mSelectedDeviceId != deviceId) { mSelectedDeviceId = deviceId; if (mStatus == NO_ERROR) { // stop capture so that audio policy manager does not reject the new instance start request // as only one capture can be active at a time. if (mAudioRecord != 0 && mActive) { Loading @@ -488,6 +489,7 @@ status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) { } android_atomic_or(CBLK_INVALID, &mCblk->mFlags); } } return NO_ERROR; } Loading Loading
media/libaaudio/src/legacy/AudioStreamLegacy.cpp +57 −28 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ using namespace android; using namespace aaudio; AudioStreamLegacy::AudioStreamLegacy() : AudioStream() { : AudioStream(), mDeviceCallback(new StreamDeviceCallback(this)) { } AudioStreamLegacy::~AudioStreamLegacy() { Loading Loading @@ -60,9 +60,16 @@ int32_t AudioStreamLegacy::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) { aaudio_data_callback_result_t callbackResult; if (!mCallbackEnabled.load()) { return; } switch (opcode) { case AAUDIO_CALLBACK_OPERATION_PROCESS_DATA: { // Note that this code assumes an AudioTrack::Buffer is the same as AudioRecord::Buffer if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { // Note that this code assumes an AudioTrack::Buffer is the same as // AudioRecord::Buffer // TODO define our own AudioBuffer and pass it from the subclasses. AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info); if (audioBuffer->frameCount == 0) return; Loading @@ -70,8 +77,8 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode // If the caller specified an exact size then use a block size adapter. if (mBlockAdapter != nullptr) { int32_t byteCount = audioBuffer->frameCount * getBytesPerFrame(); callbackResult = mBlockAdapter->processVariableBlock((uint8_t *) audioBuffer->raw, byteCount); callbackResult = mBlockAdapter->processVariableBlock( (uint8_t *) audioBuffer->raw, byteCount); } else { // Call using the AAudio callback interface. callbackResult = (*getDataCallbackProc())( Loading @@ -87,17 +94,20 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode } else { audioBuffer->size = 0; } } break; } } /// FALL THROUGH // Stream got rerouted so we disconnect. case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: { ALOGD("AudioStreamAAudio(): callbackLoop() stream disconnected"); setState(AAUDIO_STREAM_STATE_DISCONNECTED); ALOGD("processCallbackCommon() stream disconnected"); if (getErrorCallbackProc() != nullptr) { (*getErrorCallbackProc())( (AAudioStream *) this, getErrorCallbackUserData(), AAUDIO_OK AAUDIO_ERROR_DISCONNECTED ); } mCallbackEnabled.store(false); Loading Loading @@ -129,3 +139,22 @@ aaudio_result_t AudioStreamLegacy::getBestTimestamp(clockid_t clockId, status_t status = extendedTimestamp->getBestTimestamp(framePosition, timeNanoseconds, timebase); return AAudioConvert_androidToAAudioResult(status); } void AudioStreamLegacy::onAudioDeviceUpdate(audio_port_handle_t deviceId) { ALOGD("onAudioDeviceUpdate() deviceId %d", (int)deviceId); if (getDeviceId() != AAUDIO_UNSPECIFIED && getDeviceId() != deviceId && getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); // if we have a data callback and the stream is active, send the error callback from // data callback thread when it sees the DISCONNECTED state if (!isDataCallbackActive() && getErrorCallbackProc() != nullptr) { (*getErrorCallbackProc())( (AAudioStream *) this, getErrorCallbackUserData(), AAUDIO_ERROR_DISCONNECTED ); } } setDeviceId(deviceId); }
media/libaaudio/src/legacy/AudioStreamLegacy.h +24 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define LEGACY_AUDIO_STREAM_LEGACY_H #include <media/AudioTimestamp.h> #include <media/AudioSystem.h> #include <aaudio/AAudio.h> Loading Loading @@ -75,14 +76,37 @@ public: protected: class StreamDeviceCallback : public android::AudioSystem::AudioDeviceCallback { public: StreamDeviceCallback(AudioStreamLegacy *parent) : mParent(parent) {} virtual ~StreamDeviceCallback() {} virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo __unused, audio_port_handle_t deviceId) { if (mParent != nullptr) { mParent->onAudioDeviceUpdate(deviceId); } } AudioStreamLegacy *mParent; }; aaudio_result_t getBestTimestamp(clockid_t clockId, int64_t *framePosition, int64_t *timeNanoseconds, android::ExtendedTimestamp *extendedTimestamp); void onAudioDeviceUpdate(audio_port_handle_t deviceId); void onStart() { mCallbackEnabled.store(true); } void onStop() { mCallbackEnabled.store(false); } FixedBlockAdapter *mBlockAdapter = nullptr; aaudio_wrapping_frames_t mPositionWhenStarting = 0; int32_t mCallbackBufferSize = 0; const android::sp<StreamDeviceCallback> mDeviceCallback; }; } /* namespace aaudio */ Loading
media/libaaudio/src/legacy/AudioStreamRecord.cpp +21 −1 Original line number Diff line number Diff line Loading @@ -99,15 +99,21 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) ALOGD("AudioStreamRecord::open(), request notificationFrames = %u, frameCount = %u", notificationFrames, (uint)frameCount); mAudioRecord = new AudioRecord( mOpPackageName // const String16& opPackageName TODO does not compile ); if (getDeviceId() != AAUDIO_UNSPECIFIED) { mAudioRecord->setInputDevice(getDeviceId()); } mAudioRecord->set( AUDIO_SOURCE_VOICE_RECOGNITION, getSampleRate(), format, channelMask, mOpPackageName, // const String16& opPackageName TODO does not compile frameCount, callback, callbackData, notificationFrames, false /*threadCanCallJava*/, AUDIO_SESSION_ALLOCATE, streamTransferType, flags Loading Loading @@ -162,6 +168,8 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) perfMode, actualPerformanceMode); setState(AAUDIO_STREAM_STATE_OPEN); setDeviceId(mAudioRecord->getRoutedDeviceId()); mAudioRecord->addAudioDeviceCallback(mDeviceCallback); return AAUDIO_OK; } Loading Loading @@ -209,6 +217,7 @@ aaudio_result_t AudioStreamRecord::requestStart() if (err != OK) { return AAudioConvert_androidToAAudioResult(err); } else { onStart(); setState(AAUDIO_STREAM_STATE_STARTING); } return AAUDIO_OK; Loading @@ -230,6 +239,7 @@ aaudio_result_t AudioStreamRecord::requestStop() { if (mAudioRecord.get() == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } onStop(); setState(AAUDIO_STREAM_STATE_STOPPING); incrementFramesWritten(getFramesRead() - getFramesWritten()); // TODO review mAudioRecord->stop(); Loading Loading @@ -274,12 +284,22 @@ aaudio_result_t AudioStreamRecord::read(void *buffer, return result; } if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) { return AAUDIO_ERROR_DISCONNECTED; } // TODO add timeout to AudioRecord bool blocking = (timeoutNanoseconds > 0); ssize_t bytesRead = mAudioRecord->read(buffer, numBytes, blocking); if (bytesRead == WOULD_BLOCK) { return 0; } else if (bytesRead < 0) { // in this context, a DEAD_OBJECT is more likely to be a disconnect notification due to // AudioRecord invalidation if (bytesRead == DEAD_OBJECT) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); return AAUDIO_ERROR_DISCONNECTED; } return AAudioConvert_androidToAAudioResult(bytesRead); } int32_t framesRead = (int32_t)(bytesRead / bytesPerFrame); Loading
media/libaaudio/src/legacy/AudioStreamTrack.cpp +21 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,11 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) ALOGD("AudioStreamTrack::open(), request notificationFrames = %d, frameCount = %u", notificationFrames, (uint)frameCount); mAudioTrack = new AudioTrack( mAudioTrack = new AudioTrack(); if (getDeviceId() != AAUDIO_UNSPECIFIED) { mAudioTrack->setOutputDevice(getDeviceId()); } mAudioTrack->set( (audio_stream_type_t) AUDIO_STREAM_MUSIC, getSampleRate(), format, Loading @@ -125,6 +129,8 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) callback, callbackData, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, AUDIO_SESSION_ALLOCATE, streamTransferType ); Loading Loading @@ -160,6 +166,7 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) setState(AAUDIO_STREAM_STATE_OPEN); setDeviceId(mAudioTrack->getRoutedDeviceId()); mAudioTrack->addAudioDeviceCallback(mDeviceCallback); // Update performance mode based on the actual stream. // For example, if the sample rate is not allowed then you won't get a FAST track. Loading Loading @@ -229,6 +236,7 @@ aaudio_result_t AudioStreamTrack::requestStart() if (err != OK) { return AAudioConvert_androidToAAudioResult(err); } else { onStart(); setState(AAUDIO_STREAM_STATE_STARTING); } return AAUDIO_OK; Loading @@ -246,6 +254,7 @@ aaudio_result_t AudioStreamTrack::requestPause() AAudio_convertStreamStateToText(getState())); return AAUDIO_ERROR_INVALID_STATE; } onStop(); setState(AAUDIO_STREAM_STATE_PAUSING); mAudioTrack->pause(); status_t err = mAudioTrack->getPosition(&mPositionWhenPausing); Loading Loading @@ -276,6 +285,7 @@ aaudio_result_t AudioStreamTrack::requestStop() { if (mAudioTrack.get() == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } onStop(); setState(AAUDIO_STREAM_STATE_STOPPING); incrementFramesRead(getFramesWritten() - getFramesRead()); // TODO review mAudioTrack->stop(); Loading Loading @@ -339,6 +349,10 @@ aaudio_result_t AudioStreamTrack::write(const void *buffer, return result; } if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) { return AAUDIO_ERROR_DISCONNECTED; } // TODO add timeout to AudioTrack bool blocking = timeoutNanoseconds > 0; ssize_t bytesWritten = mAudioTrack->write(buffer, numBytes, blocking); Loading @@ -346,6 +360,12 @@ aaudio_result_t AudioStreamTrack::write(const void *buffer, return 0; } else if (bytesWritten < 0) { ALOGE("invalid write, returned %d", (int)bytesWritten); // in this context, a DEAD_OBJECT is more likely to be a disconnect notification due to // AudioTrack invalidation if (bytesWritten == DEAD_OBJECT) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); return AAUDIO_ERROR_DISCONNECTED; } return AAudioConvert_androidToAAudioResult(bytesWritten); } int32_t framesWritten = (int32_t)(bytesWritten / bytesPerFrame); Loading
media/libaudioclient/AudioRecord.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -481,6 +481,7 @@ status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) { AutoMutex lock(mLock); if (mSelectedDeviceId != deviceId) { mSelectedDeviceId = deviceId; if (mStatus == NO_ERROR) { // stop capture so that audio policy manager does not reject the new instance start request // as only one capture can be active at a time. if (mAudioRecord != 0 && mActive) { Loading @@ -488,6 +489,7 @@ status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) { } android_atomic_or(CBLK_INVALID, &mCblk->mFlags); } } return NO_ERROR; } Loading