%PDF- %PDF-
Direktori : /usr/lib/python3/dist-packages/orca/ |
Current File : //usr/lib/python3/dist-packages/orca/sound_generator.py |
# Orca # # Copyright 2016 Igalia, S.L. # # Author: Joanmarie Diggs <jdiggs@igalia.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., Franklin Street, Fifth Floor, # Boston MA 02110-1301 USA. """Utilities for obtaining sounds to be presented for objects.""" __id__ = "$Id:$" __version__ = "$Revision:$" __date__ = "$Date:$" __copyright__ = "Copyright (c) 2016 Igalia, S.L." __license__ = "LGPL" import gi gi.require_version('Atspi', '2.0') from gi.repository import Atspi import os from . import generator from . import settings_manager from .ax_object import AXObject from .ax_utilities import AXUtilities from .ax_value import AXValue METHOD_PREFIX = "_generate" class Icon: """Sound file representing a particular aspect of an object.""" def __init__(self, location, filename): self.path = os.path.join(location, filename) def __str__(self): return f'Icon(path: {self.path}, isValid: {self.isValid()})' def isValid(self): return os.path.isfile(self.path) class Tone: """Tone representing a particular aspect of an object.""" SINE_WAVE = 0 SQUARE_WAVE = 1 SAW_WAVE = 2 TRIANGLE_WAVE = 3 SILENCE = 4 WHITE_UNIFORM_NOISE = 5 PINK_NOISE = 6 SINE_WAVE_USING_TABLE = 7 PERIODIC_TICKS = 8 WHITE_GAUSSIAN_NOISE = 9 RED_NOISE = 10 INVERTED_PINK_NOISE = 11 INVERTED_RED_NOISE = 12 def __init__(self, duration, frequency, volumeMultiplier=1, wave=SINE_WAVE): self.duration = duration self.frequency = min(max(0, frequency), 20000) self.volume = settings_manager.getManager().getSetting('soundVolume') * volumeMultiplier self.wave = wave def __str__(self): return ( f'Tone(duration: {self.duration}, ' f'frequency: {self.frequency}, ' f'volume: {self.volume}, ' f'wave: {self.wave})' ) class SoundGenerator(generator.Generator): """Takes accessible objects and produces the sound(s) to be played.""" def __init__(self, script): super().__init__(script, 'sound') self._sounds = os.path.join(settings_manager.getManager().getPrefsDir(), 'sounds') def _convertFilenameToIcon(self, filename): icon = Icon(self._sounds, filename) if icon.isValid(): return icon return None def generateSound(self, obj, **args): """Returns an array of sounds for the complete presentation of obj.""" return self.generate(obj, **args) ##################################################################### # # # State information # # # ##################################################################### def _generateAvailability(self, obj, **args): """Returns an array of sounds indicating obj is grayed out.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateAvailability(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateCheckedState(self, obj, **args): """Returns an array of sounds indicating the checked state of obj.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateCheckedState(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateClickable(self, obj, **args): """Returns an array of sounds indicating obj is clickable.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateClickable(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateExpandableState(self, obj, **args): """Returns an array of sounds indicating the expanded state of obj.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateExpandableState(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateHasLongDesc(self, obj, **args): """Returns an array of sounds indicating obj has a longdesc.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateHasLongDesc(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateMenuItemCheckedState(self, obj, **args): """Returns an array of sounds indicating the checked state of obj.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateMenuItemCheckedState(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateMultiselectableState(self, obj, **args): """Returns an array of sounds indicating obj is multiselectable.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateMultiselectableState(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateRadioState(self, obj, **args): """Returns an array of sounds indicating the selected state of obj.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateRadioState(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateReadOnly(self, obj, **args): """Returns an array of sounds indicating obj is read only.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateReadOnly(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateRequired(self, obj, **args): """Returns an array of sounds indicating obj is required.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateRequired(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateSwitchState(self, obj, **args): """Returns an array of sounds indicating the on/off state of obj.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateSwitchState(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateToggleState(self, obj, **args): """Returns an array of sounds indicating the toggled state of obj.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] filenames = super()._generateToggleState(obj, **args) result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] def _generateVisitedState(self, obj, **args): """Returns an array of sounds indicating the visited state of obj.""" if not settings_manager.getManager().getSetting('playSoundForState'): return [] if not args.get('mode', None): args['mode'] = self._mode args['stringType'] = 'visited' if AXUtilities.is_visited(obj): filenames = [self._script.formatting.getString(**args)] result = list(map(self._convertFilenameToIcon, filenames)) if result: return result return [] ##################################################################### # # # Value interface information # # # ##################################################################### def _generatePercentage(self, obj, **args): """Returns an array of sounds reflecting the percentage of obj.""" if not settings_manager.getManager().getSetting('playSoundForValue'): return [] percent = AXValue.get_value_as_percent(obj) if percent is None: return [] return [] def _generateProgressBarValue(self, obj, **args): """Returns an array of sounds representing the progress bar value.""" if args.get('isProgressBarUpdate'): if not self._shouldPresentProgressBarUpdate(obj, **args): return [] elif not settings_manager.getManager().getSetting('playSoundForValue'): return [] percent = AXValue.get_value_as_percent(obj) if percent is None: return [] # To better indicate the progress completion. if percent >= 99: duration = 1 else: duration = 0.075 # Reduce volume as pitch increases. volumeMultiplier = 1 - (percent / 120) # Adjusting so that the initial beeps are not too deep. if percent < 7: frequency = int(98 + percent * 5.4) else: frequency = int(percent * 22) return [Tone(duration, frequency, volumeMultiplier, Tone.SINE_WAVE)] def _getProgressBarUpdateInterval(self): interval = settings_manager.getManager().getSetting('progressBarBeepInterval') if interval is None: return super()._getProgressBarUpdateInterval() return int(interval) def _shouldPresentProgressBarUpdate(self, obj, **args): if not settings_manager.getManager().getSetting('beepProgressBarUpdates'): return False return super()._shouldPresentProgressBarUpdate(obj, **args) ##################################################################### # # # Role and hierarchical information # # # ##################################################################### def _generatePositionInSet(self, obj, **args): """Returns an array of sounds reflecting the set position of obj.""" if not settings_manager.getManager().getSetting('playSoundForPositionInSet'): return [] # TODO: Implement the result. # position, setSize = self._script.utilities.getPositionAndSetSize(obj) # percent = int((position / setSize) * 100) return [] def _generateRoleName(self, obj, **args): """Returns an array of sounds indicating the role of obj.""" if not settings_manager.getManager().getSetting('playSoundForRole'): return [] role = args.get('role', AXObject.get_role(obj)) filename = Atspi.role_get_name(role).replace(' ', '_') result = self._convertFilenameToIcon(filename) if result: return [result] return []