Skip to content

Commit 8a335bf

Browse files
authored
Merge 87dba21 into 7736fdd
2 parents 7736fdd + 87dba21 commit 8a335bf

2 files changed

Lines changed: 18 additions & 9 deletions

File tree

nvdaHelper/local/wasapi.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ class WasapiPlayer {
202202

203203
// Reset our state due to being stopped. This runs on the feeder thread
204204
// rather than on the thread which called stop() because writing to a vector
205-
// isn't thread safe.
205+
// isn't thread safe. We also reset the stream here because this can't be done
206+
// in stop() if the feeder thread is currently writing to the buffer.
206207
void completeStop();
207208

208209
// Convert frames into ms.
@@ -586,22 +587,21 @@ bool WasapiPlayer::didPreferredDeviceBecomeAvailable() {
586587
}
587588

588589
HRESULT WasapiPlayer::stop() {
589-
playState = PlayState::stopping;
590590
HRESULT hr = client->Stop();
591+
// It's important that we set playState *after*
592+
// calling client->Stop() because otherwise, the feeder thread might see the
593+
// playState change and call client->Reset() before client->Stop() runs,
594+
// causing AUDCLNT_E_NOT_STOPPED.
595+
playState = PlayState::stopping;
591596
// If the device has been invalidated, it has already stopped. Just ignore
592597
// this and behave as if we were successful to avoid a cascade of breakage.
593598
// feed() will attempt to reopen the device next time it is called.
594599
if (
595600
hr != AUDCLNT_E_DEVICE_INVALIDATED
596601
&& hr != AUDCLNT_E_NOT_INITIALIZED
602+
&& FAILED(hr)
597603
) {
598-
if (FAILED(hr)) {
599-
return hr;
600-
}
601-
hr = client->Reset();
602-
if (FAILED(hr)) {
603-
return hr;
604-
}
604+
return hr;
605605
}
606606
// If there is a feed/sync call waiting, wake it up so it can immediately
607607
// return to the caller.
@@ -610,6 +610,14 @@ HRESULT WasapiPlayer::stop() {
610610
}
611611

612612
void WasapiPlayer::completeStop() {
613+
HRESULT hr = client->Reset();
614+
if (FAILED(hr)) {
615+
// We must not use LOG_ERROR here because that plays a sound and we might be
616+
// in the middle of stopping our sound player.
617+
LOG_DEBUGWARNING(L"Couldn't reset stream: " << hr);
618+
// We deliberately continue here. If Reset failed, the stream is probably
619+
// already cleared or unusable anyway. We should always reset our state.
620+
}
613621
nextFeedId = 0;
614622
sentFrames = 0;
615623
feedEnds.clear();

user_docs/en/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ There have also been a number of other fixes and improvements, including to mous
7171
* It is now possible to review and spell the labels of controls in Google Chrome menus and dialogs. (#11285, @jcsteh)
7272
* When typing into a cell in Microsoft Excel, the braille display is now correctly updated to show the new content. (#18391)
7373
* Fixed bug where NLS eReader Zoomax driver did not work with all devices. (#18406, @florin-trutiu)
74+
* When using NVDA Remote Access, speech from User Account Control screens on the remote computer now works reliably. (#18101, @jcsteh)
7475

7576
### Changes for Developers
7677

0 commit comments

Comments
 (0)