Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove winmm support from NVDA #17496

Merged
merged 28 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e14bd71
Make espeak tests when using WASAPI
SaschaCowley Nov 7, 2024
f49373c
Make WavePlayer point to WasapiWavePlayer, and remove logic for handl…
SaschaCowley Nov 7, 2024
7263f5b
Removed nvwave.WinmmWavePlayer
SaschaCowley Nov 7, 2024
213986b
Merge branch 'master' into i16080
SaschaCowley Dec 9, 2024
c456ca7
Rewrote device enumeration to use mmdevice
SaschaCowley Dec 9, 2024
f60405f
Removed un used methods classes and attributes
SaschaCowley Dec 9, 2024
83869d3
Removed old commented winmm code
SaschaCowley Dec 10, 2024
6f1ac30
Added a default value to the GUI
SaschaCowley Dec 10, 2024
facde51
Removed 'Use WASAPI' setting from settings and UG
SaschaCowley Dec 10, 2024
d63bc78
Added change log entries
SaschaCowley Dec 10, 2024
e3cc972
Removed WASAPI check from settings
SaschaCowley Dec 11, 2024
9c23de9
Removed WASAPI check from soundsplit
SaschaCowley Dec 11, 2024
953e96b
Removed WASAPI check from apps volume
SaschaCowley Dec 11, 2024
75ef9fa
Removed WASAPI check from audio utilities initialisation and termination
SaschaCowley Dec 11, 2024
fe04d48
Removed usingWasapiWavePlayer from nvwave
SaschaCowley Dec 11, 2024
1b394a7
Made changes for developers more complete
SaschaCowley Dec 11, 2024
7a9f8c6
Removed the WASAPI option from config
SaschaCowley Dec 11, 2024
107c907
Removed references to disabling WASAPI from the user guide
SaschaCowley Dec 11, 2024
9f59c03
Merge branch 'master' into i16080
SaschaCowley Dec 11, 2024
3764928
Fixed location of changes entry and removed extranious space
SaschaCowley Dec 11, 2024
57cfeaf
Removed WASAPI disabled message
SaschaCowley Dec 11, 2024
5caee71
Type hints for _getOutputDevices
SaschaCowley Dec 11, 2024
c16618f
Added type hint for getOutputDeviceNames
SaschaCowley Dec 11, 2024
c27839c
Added type hint to deviceIDToName
SaschaCowley Dec 11, 2024
3d5ccfb
Added type hints for outputDeviceNameToID
SaschaCowley Dec 11, 2024
53b8e89
Added type hint for fileWavePlayerThread
SaschaCowley Dec 11, 2024
5afe251
Fixed type hint for _getOutputDevices
SaschaCowley Dec 11, 2024
8f9aa5e
Added note about IDs changing
SaschaCowley Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 13 additions & 19 deletions source/audio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
)
from . import appsVolume, soundSplit, utils
import atexit
import nvwave
from pycaw.utils import AudioUtilities
from comtypes import COMError
from logHandler import log
Expand All @@ -25,30 +24,25 @@


def initialize() -> None:
if nvwave.usingWasapiWavePlayer():
try:
AudioUtilities.GetAudioSessionManager()
except COMError:
log.exception("Could not initialize audio session manager")
return
log.debug("Initializing utils")
utils.initialize()
log.debug("Initializing appsVolume")
appsVolume.initialize()
log.debug("Initializing soundSplit")
soundSplit.initialize()
global audioUtilitiesInitialized
audioUtilitiesInitialized = True
else:
log.debug("Cannot initialize audio utilities as WASAPI is disabled")
try:
AudioUtilities.GetAudioSessionManager()
except COMError:
log.exception("Could not initialize audio session manager")
return
log.debug("Initializing utils")
utils.initialize()
log.debug("Initializing appsVolume")
appsVolume.initialize()
log.debug("Initializing soundSplit")
soundSplit.initialize()
global audioUtilitiesInitialized
audioUtilitiesInitialized = True


@atexit.register
def terminate():
if not audioUtilitiesInitialized:
log.debug("Skipping terminating audio utilities as initialization was skipped.")
elif not nvwave.usingWasapiWavePlayer():
log.debug("Skipping terminating audio utilites as WASAPI is disabled.")
else:
soundSplit.terminate()
appsVolume.terminate()
Expand Down
17 changes: 0 additions & 17 deletions source/audio/appsVolume.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import config
import globalVars
from logHandler import log
import nvwave
from pycaw.utils import AudioSession
import ui
from dataclasses import dataclass
Expand Down Expand Up @@ -105,13 +104,6 @@ def _updateAppsVolumeImpl(
_activeCallback.register()


_WASAPI_DISABLED_MESSAGE: str = _(
# Translators: error message when wasapi is turned off.
"Application volume cannot be controlled by NVDA when WASAPI is disabled. "
"Please enable it in the advanced settings panel.",
)


_VOLUME_ADJUSTMENT_DISABLED_MESSAGE: str = _(
# Translators: error message when applications' volume is disabled
"Application volume control disabled",
Expand All @@ -121,9 +113,6 @@ def _updateAppsVolumeImpl(
def _adjustAppsVolume(
volumeAdjustment: int | None = None,
):
if not nvwave.usingWasapiWavePlayer():
ui.message(_WASAPI_DISABLED_MESSAGE)
SaschaCowley marked this conversation as resolved.
Show resolved Hide resolved
return
volume: int = config.conf["audio"]["applicationsSoundVolume"]
muted: bool = config.conf["audio"]["applicationsSoundMuted"]
state = config.conf["audio"]["applicationsVolumeMode"]
Expand All @@ -149,9 +138,6 @@ def _adjustAppsVolume(


def _toggleAppsVolumeState():
if not nvwave.usingWasapiWavePlayer():
ui.message(_WASAPI_DISABLED_MESSAGE)
return
state = config.conf["audio"]["applicationsVolumeMode"]
volume: int = config.conf["audio"]["applicationsSoundVolume"]
muted: bool = config.conf["audio"]["applicationsSoundMuted"]
Expand All @@ -175,9 +161,6 @@ def _toggleAppsVolumeState():


def _toggleAppsVolumeMute():
if not nvwave.usingWasapiWavePlayer():
ui.message(_WASAPI_DISABLED_MESSAGE)
return
state = config.conf["audio"]["applicationsVolumeMode"]
volume: int = config.conf["audio"]["applicationsSoundVolume"]
muted: bool = config.conf["audio"]["applicationsSoundMuted"]
Expand Down
9 changes: 0 additions & 9 deletions source/audio/soundSplit.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from enum import IntEnum, unique
import globalVars
from logHandler import log
import nvwave
from pycaw.utils import AudioSession
import ui
from utils.displayString import DisplayStringIntEnum
Expand Down Expand Up @@ -163,14 +162,6 @@ def _setSoundSplitState(state: SoundSplitState) -> dict:


def _toggleSoundSplitState() -> None:
if not nvwave.usingWasapiWavePlayer():
message = _(
# Translators: error message when wasapi is turned off.
"Sound split cannot be used. "
"Please enable WASAPI in the Advanced category in NVDA Settings to use it.",
)
ui.message(message)
return
state = SoundSplitState(config.conf["audio"]["soundSplitState"])
allowedStates: list[int] = config.conf["audio"]["includedSoundSplitModes"]
try:
Expand Down
1 change: 0 additions & 1 deletion source/config/configSpec.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
# Audio settings
[audio]
audioDuckingMode = integer(default=0)
WASAPI = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="enabled")
soundVolumeFollowsVoice = boolean(default=false)
soundVolume = integer(default=100, min=0, max=100)
audioAwakeTime = integer(default=30, min=0, max=3600)
Expand Down
68 changes: 20 additions & 48 deletions source/gui/settingsDialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3048,17 +3048,19 @@ def makeSettings(self, settingsSizer: wx.BoxSizer) -> None:
# Translators: This is the label for the select output device combo in NVDA audio settings.
# Examples of an output device are default soundcard, usb headphones, etc.
deviceListLabelText = _("Audio output &device:")
deviceNames = nvwave.getOutputDeviceNames()
# #11349: On Windows 10 20H1 and 20H2, Microsoft Sound Mapper returns an empty string.
if deviceNames[0] in ("", "Microsoft Sound Mapper"):
# Translators: name for default (Microsoft Sound Mapper) audio output device.
deviceNames[0] = _("Microsoft Sound Mapper")
# The Windows Core Audio device enumeration does not have the concept of an ID for the default output device, so we have to insert something ourselves instead.
# Translators: Value to show when choosing to use the default audio output device.
deviceNames = (_("Default output device"), *nvwave.getOutputDeviceNames())
self.deviceList = sHelper.addLabeledControl(deviceListLabelText, wx.Choice, choices=deviceNames)
self.bindHelpEvent("SelectSynthesizerOutputDevice", self.deviceList)
try:
selection = deviceNames.index(config.conf["speech"]["outputDevice"])
except ValueError:
selectedOutputDevice = config.conf["speech"]["outputDevice"]
if selectedOutputDevice == "default":
selection = 0
else:
try:
selection = deviceNames.index(selectedOutputDevice)
except ValueError:
selection = 0
self.deviceList.SetSelection(selection)

# Translators: This is a label for the audio ducking combo box in the Audio Settings dialog.
Expand Down Expand Up @@ -3164,7 +3166,6 @@ def makeSettings(self, settingsSizer: wx.BoxSizer) -> None:
initial=config.conf["audio"]["audioAwakeTime"],
)
self.bindHelpEvent("AudioAwakeTime", self.audioAwakeTimeEdit)
self.audioAwakeTimeEdit.Enable(nvwave.usingWasapiWavePlayer())

def _appendSoundSplitModesList(self, settingsSizerHelper: guiHelper.BoxSizerHelper) -> None:
self._allSoundSplitModes = list(audio.SoundSplitState)
Expand All @@ -3182,9 +3183,13 @@ def _appendSoundSplitModesList(self, settingsSizerHelper: guiHelper.BoxSizerHelp
self.soundSplitModesList.Select(0)

def onSave(self):
if config.conf["speech"]["outputDevice"] != self.deviceList.GetStringSelection():
# We already use "default" as the key in the config spec, so use it here as an alternative to Microsoft Sound Mapper.
selectedOutputDevice = (
"default" if self.deviceList.GetSelection() == 0 else self.deviceList.GetStringSelection()
)
if config.conf["speech"]["outputDevice"] != selectedOutputDevice:
# Synthesizer must be reload if output device changes
config.conf["speech"]["outputDevice"] = self.deviceList.GetStringSelection()
config.conf["speech"]["outputDevice"] = selectedOutputDevice
currentSynth = getSynth()
if not setSynth(currentSynth.name):
_synthWarningDialog(currentSynth.name)
Expand All @@ -3200,8 +3205,7 @@ def onSave(self):

index = self.soundSplitComboBox.GetSelection()
config.conf["audio"]["soundSplitState"] = index
if nvwave.usingWasapiWavePlayer():
audio._setSoundSplitState(audio.SoundSplitState(index))
audio._setSoundSplitState(audio.SoundSplitState(index))
config.conf["audio"]["includedSoundSplitModes"] = [
mIndex
for mIndex in range(len(self._allSoundSplitModes))
Expand Down Expand Up @@ -3229,22 +3233,11 @@ def onPanelActivated(self):

def _onSoundVolChange(self, event: wx.Event) -> None:
"""Called when the sound volume follow checkbox is checked or unchecked."""
wasapi = nvwave.usingWasapiWavePlayer()
self.soundVolFollowCheckBox.Enable(wasapi)
self.soundVolSlider.Enable(
wasapi and not self.soundVolFollowCheckBox.IsChecked(),
)
self.soundSplitComboBox.Enable(wasapi)
self.soundSplitModesList.Enable(wasapi)
self.soundVolSlider.Enable(not self.soundVolFollowCheckBox.IsChecked())

avEnabled = config.featureFlagEnums.AppsVolumeAdjusterFlag.ENABLED
self.appSoundVolSlider.Enable(
wasapi and self.appVolAdjusterCombo._getControlCurrentValue() == avEnabled,
)
self.muteOtherAppsCheckBox.Enable(
wasapi and self.appVolAdjusterCombo._getControlCurrentValue() == avEnabled,
)
self.appVolAdjusterCombo.Enable(wasapi)
self.appSoundVolSlider.Enable(self.appVolAdjusterCombo._getControlCurrentValue() == avEnabled)
self.muteOtherAppsCheckBox.Enable(self.appVolAdjusterCombo._getControlCurrentValue() == avEnabled)

def isValid(self) -> bool:
enabledSoundSplitModes = self.soundSplitModesList.CheckedItems
Expand Down Expand Up @@ -3838,26 +3831,6 @@ def __init__(self, parent):
["documentFormatting", "reportTransparentColor"],
)

# Translators: This is the label for a group of advanced options in the
# Advanced settings panel
label = _("Audio")
audio = wx.StaticBoxSizer(wx.VERTICAL, self, label=label)
audioGroup = guiHelper.BoxSizerHelper(self, sizer=audio)
sHelper.addItem(audioGroup)

# Translators: This is the label for a checkbox control in the Advanced settings panel.
label = _("Use WASAPI for audio output (requires restart)")
self.wasapiComboBox = cast(
nvdaControls.FeatureFlagCombo,
audioGroup.addLabeledControl(
labelText=label,
wxCtrlClass=nvdaControls.FeatureFlagCombo,
keyPath=["audio", "WASAPI"],
conf=config.conf,
),
)
self.bindHelpEvent("WASAPI", self.wasapiComboBox)

# Translators: This is the label for a group of advanced options in the
# Advanced settings panel
label = _("Debug logging")
Expand Down Expand Up @@ -4044,7 +4017,6 @@ def onSave(self):
config.conf["documentFormatting"]["reportTransparentColor"] = (
self.reportTransparentColorCheckBox.IsChecked()
)
self.wasapiComboBox.saveCurrentValueToConf()
config.conf["annotations"]["reportDetails"] = self.annotationsDetailsCheckBox.IsChecked()
config.conf["annotations"]["reportAriaDescription"] = self.ariaDescCheckBox.IsChecked()
self.brailleLiveRegionsCombo.saveCurrentValueToConf()
Expand Down
Loading
Loading