Loading media/libaaudio/src/legacy/AudioStreamLegacy.cpp +56 −33 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ using namespace android; using namespace aaudio; AudioStreamLegacy::AudioStreamLegacy() : AudioStream(), mDeviceCallback(new StreamDeviceCallback(this)) { : AudioStream() , mDeviceCallback(new StreamDeviceCallback(this)) { } AudioStreamLegacy::~AudioStreamLegacy() { Loading Loading @@ -78,18 +79,20 @@ 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: { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { checkForDisconnectRequest(); // 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; if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED || !mCallbackEnabled.load()) { audioBuffer->size = 0; // silence the buffer } else { if (audioBuffer->frameCount == 0) { return; } // If the caller specified an exact size then use a block size adapter. if (mBlockAdapter != nullptr) { Loading @@ -107,17 +110,40 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode audioBuffer->size = 0; } if (updateStateMachine() == AAUDIO_OK) { break; // don't fall through if (updateStateMachine() != AAUDIO_OK) { forceDisconnect(); mCallbackEnabled.store(false); } } } /// FALL THROUGH break; // Stream got rerouted so we disconnect. case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: { setState(AAUDIO_STREAM_STATE_DISCONNECTED); case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: ALOGD("processCallbackCommon() stream disconnected"); forceDisconnect(); mCallbackEnabled.store(false); break; default: break; } } void AudioStreamLegacy::checkForDisconnectRequest() { if (mRequestDisconnect.isRequested()) { ALOGD("checkForDisconnectRequest() mRequestDisconnect acknowledged"); forceDisconnect(); mRequestDisconnect.acknowledge(); mCallbackEnabled.store(false); } } void AudioStreamLegacy::forceDisconnect() { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); if (getErrorCallbackProc() != nullptr) { (*getErrorCallbackProc())( (AAudioStream *) this, Loading @@ -125,12 +151,6 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode AAUDIO_ERROR_DISCONNECTED ); } mCallbackEnabled.store(false); } break; default: break; } } Loading Loading @@ -175,15 +195,18 @@ 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 ); // Note that isDataCallbackActive() is affected by state so call it before DISCONNECTING. // If we have a data callback and the stream is active, then ask the data callback // to DISCONNECT and call the error callback. if (isDataCallbackActive()) { ALOGD("onAudioDeviceUpdate() request DISCONNECT in data callback due to device change"); // If the stream is stopped before the data callback has a chance to handle the // request then the requestStop() and requestPause() methods will handle it after // the callback has stopped. mRequestDisconnect.request(); } else { ALOGD("onAudioDeviceUpdate() DISCONNECT the stream now"); forceDisconnect(); } } setDeviceId(deviceId); Loading media/libaaudio/src/legacy/AudioStreamLegacy.h +7 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "AudioStream.h" #include "AAudioLegacy.h" #include "utility/AAudioUtilities.h" #include "utility/FixedBlockAdapter.h" namespace aaudio { Loading Loading @@ -111,6 +112,10 @@ protected: void onAudioDeviceUpdate(audio_port_handle_t deviceId); void checkForDisconnectRequest(); void forceDisconnect(); void onStart() { mCallbackEnabled.store(true); } void onStop() { mCallbackEnabled.store(false); } Loading @@ -130,6 +135,8 @@ protected: aaudio_wrapping_frames_t mPositionWhenStarting = 0; int32_t mCallbackBufferSize = 0; const android::sp<StreamDeviceCallback> mDeviceCallback; AtomicRequestor mRequestDisconnect; }; } /* namespace aaudio */ Loading media/libaaudio/src/legacy/AudioStreamRecord.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ aaudio_result_t AudioStreamRecord::requestStop() { mAudioRecord->stop(); mFramesRead.reset32(); mTimestampPosition.reset32(); checkForDisconnectRequest(); return AAUDIO_OK; } Loading media/libaaudio/src/legacy/AudioStreamTrack.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ aaudio_result_t AudioStreamTrack::requestPause() { onStop(); setState(AAUDIO_STREAM_STATE_PAUSING); mAudioTrack->pause(); checkForDisconnectRequest(); status_t err = mAudioTrack->getPosition(&mPositionWhenPausing); if (err != OK) { return AAudioConvert_androidToAAudioResult(err); Loading Loading @@ -300,6 +301,7 @@ aaudio_result_t AudioStreamTrack::requestStop() { mFramesWritten.reset32(); mTimestampPosition.reset32(); mAudioTrack->stop(); checkForDisconnectRequest(); return AAUDIO_OK; } Loading media/libaaudio/src/utility/AAudioUtilities.h +5 −2 Original line number Diff line number Diff line Loading @@ -346,15 +346,18 @@ private: */ class AtomicRequestor { public: __attribute__((no_sanitize("integer"))) void request() { // TODO handle overflows, very unlikely mRequested++; } __attribute__((no_sanitize("integer"))) bool isRequested() { return mRequested.load() > mAcknowledged.load(); return (mRequested.load() - mAcknowledged.load()) > 0; } __attribute__((no_sanitize("integer"))) void acknowledge() { mAcknowledged++; } Loading Loading
media/libaaudio/src/legacy/AudioStreamLegacy.cpp +56 −33 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ using namespace android; using namespace aaudio; AudioStreamLegacy::AudioStreamLegacy() : AudioStream(), mDeviceCallback(new StreamDeviceCallback(this)) { : AudioStream() , mDeviceCallback(new StreamDeviceCallback(this)) { } AudioStreamLegacy::~AudioStreamLegacy() { Loading Loading @@ -78,18 +79,20 @@ 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: { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { checkForDisconnectRequest(); // 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; if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED || !mCallbackEnabled.load()) { audioBuffer->size = 0; // silence the buffer } else { if (audioBuffer->frameCount == 0) { return; } // If the caller specified an exact size then use a block size adapter. if (mBlockAdapter != nullptr) { Loading @@ -107,17 +110,40 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode audioBuffer->size = 0; } if (updateStateMachine() == AAUDIO_OK) { break; // don't fall through if (updateStateMachine() != AAUDIO_OK) { forceDisconnect(); mCallbackEnabled.store(false); } } } /// FALL THROUGH break; // Stream got rerouted so we disconnect. case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: { setState(AAUDIO_STREAM_STATE_DISCONNECTED); case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: ALOGD("processCallbackCommon() stream disconnected"); forceDisconnect(); mCallbackEnabled.store(false); break; default: break; } } void AudioStreamLegacy::checkForDisconnectRequest() { if (mRequestDisconnect.isRequested()) { ALOGD("checkForDisconnectRequest() mRequestDisconnect acknowledged"); forceDisconnect(); mRequestDisconnect.acknowledge(); mCallbackEnabled.store(false); } } void AudioStreamLegacy::forceDisconnect() { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { setState(AAUDIO_STREAM_STATE_DISCONNECTED); if (getErrorCallbackProc() != nullptr) { (*getErrorCallbackProc())( (AAudioStream *) this, Loading @@ -125,12 +151,6 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode AAUDIO_ERROR_DISCONNECTED ); } mCallbackEnabled.store(false); } break; default: break; } } Loading Loading @@ -175,15 +195,18 @@ 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 ); // Note that isDataCallbackActive() is affected by state so call it before DISCONNECTING. // If we have a data callback and the stream is active, then ask the data callback // to DISCONNECT and call the error callback. if (isDataCallbackActive()) { ALOGD("onAudioDeviceUpdate() request DISCONNECT in data callback due to device change"); // If the stream is stopped before the data callback has a chance to handle the // request then the requestStop() and requestPause() methods will handle it after // the callback has stopped. mRequestDisconnect.request(); } else { ALOGD("onAudioDeviceUpdate() DISCONNECT the stream now"); forceDisconnect(); } } setDeviceId(deviceId); Loading
media/libaaudio/src/legacy/AudioStreamLegacy.h +7 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "AudioStream.h" #include "AAudioLegacy.h" #include "utility/AAudioUtilities.h" #include "utility/FixedBlockAdapter.h" namespace aaudio { Loading Loading @@ -111,6 +112,10 @@ protected: void onAudioDeviceUpdate(audio_port_handle_t deviceId); void checkForDisconnectRequest(); void forceDisconnect(); void onStart() { mCallbackEnabled.store(true); } void onStop() { mCallbackEnabled.store(false); } Loading @@ -130,6 +135,8 @@ protected: aaudio_wrapping_frames_t mPositionWhenStarting = 0; int32_t mCallbackBufferSize = 0; const android::sp<StreamDeviceCallback> mDeviceCallback; AtomicRequestor mRequestDisconnect; }; } /* namespace aaudio */ Loading
media/libaaudio/src/legacy/AudioStreamRecord.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ aaudio_result_t AudioStreamRecord::requestStop() { mAudioRecord->stop(); mFramesRead.reset32(); mTimestampPosition.reset32(); checkForDisconnectRequest(); return AAUDIO_OK; } Loading
media/libaaudio/src/legacy/AudioStreamTrack.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ aaudio_result_t AudioStreamTrack::requestPause() { onStop(); setState(AAUDIO_STREAM_STATE_PAUSING); mAudioTrack->pause(); checkForDisconnectRequest(); status_t err = mAudioTrack->getPosition(&mPositionWhenPausing); if (err != OK) { return AAudioConvert_androidToAAudioResult(err); Loading Loading @@ -300,6 +301,7 @@ aaudio_result_t AudioStreamTrack::requestStop() { mFramesWritten.reset32(); mTimestampPosition.reset32(); mAudioTrack->stop(); checkForDisconnectRequest(); return AAUDIO_OK; } Loading
media/libaaudio/src/utility/AAudioUtilities.h +5 −2 Original line number Diff line number Diff line Loading @@ -346,15 +346,18 @@ private: */ class AtomicRequestor { public: __attribute__((no_sanitize("integer"))) void request() { // TODO handle overflows, very unlikely mRequested++; } __attribute__((no_sanitize("integer"))) bool isRequested() { return mRequested.load() > mAcknowledged.load(); return (mRequested.load() - mAcknowledged.load()) > 0; } __attribute__((no_sanitize("integer"))) void acknowledge() { mAcknowledged++; } Loading