diff --git a/src/fenrir-package/inputDriver/evdev.py b/src/fenrir-package/inputDriver/evdev.py new file mode 100644 index 00000000..17523e90 --- /dev/null +++ b/src/fenrir-package/inputDriver/evdev.py @@ -0,0 +1,73 @@ +#!/bin/python + +import evdev +from evdev import InputDevice, UInput +from select import select +import time +from utils import debug + +class driver(): + def __init__(self): + self.iDevices = {} + self.uDevices = {} + self.getInputDevices() + def initialize(self, environment): + return environment + def shutdown(self, environment): + return environment + def getInput(self, environment): + event = None + r, w, x = select(self.iDevices, [], [], environment['runtime']['settingsManager'].getSettingAsFloat(environment, 'screen', 'screenUpdateDelay')) + print(len(list(r))) + if r != []: + for fd in r: + event = self.iDevices[fd].read_one() + return event + return None + + def writeUInput(self, uDevice, event,environment): + uDevice.write_event(event) + uDevice.syn() + + def getInputDevices(self): + self.iDevices = map(evdev.InputDevice, (evdev.list_devices())) + self.iDevices = {dev.fd: dev for dev in self.iDevices if 1 in dev.capabilities()} + + def grabDevices(self): + for fd in self.iDevices: + dev = self.iDevices[fd] + cap = dev.capabilities() + del cap[0] + self.uDevices[fd] = UInput( + cap, + dev.name, + #dev.info.vendor, + #dev.info.product, + #dev.version, + #dev.info.bustype, + #'/dev/uinput' + ) + dev.grab() + + def releaseDevices(self): + for fd in self.iDevices: + try: + self.iDevices[fd].ungrab() + except: + pass + try: + self.iDevices[fd].close() + except: + pass + try: + self.uDevices[fd].close() + except: + pass + + self.iDevices.clear() + self.uDevices.clear() + + def __del__(self): + self.releaseDevices() + + diff --git a/src/fenrir-package/screenDriver/__init__.py b/src/fenrir-package/screenDriver/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/src/fenrir-package/screenDriver/linux.py b/src/fenrir-package/screenDriver/linux.py new file mode 100644 index 00000000..d14ec701 --- /dev/null +++ b/src/fenrir-package/screenDriver/linux.py @@ -0,0 +1,116 @@ +#!/bin/python +# -*- coding: utf-8 -*- + +import difflib +from utils import debug + +class driver(): + def __init__(self): + self.vcsaDevicePath = '/dev/vcsa' + + def initialize(self, environment): + return environment + + def shutdown(self, environment): + return environment + + def insert_newlines(self, string, every=64): + return '\n'.join(string[i:i+every] for i in range(0, len(string), every)) + + def getCurrScreen(self): + currScreen = -1 + try: + currScreenFile = open('/sys/devices/virtual/tty/tty0/active','r') + currScreen = currScreenFile.read()[3:-1] + currScreenFile.close() + except Exception as e: + environment['runtime']['debug'].writeDebugOut(environment,str(e),debug.debugLevel.ERROR) + + return currScreen + + def getIgnoreScreens(self): + xlist = [] + try: + x = subprocess.Popen('ps a -o tty,comm | grep -e irssi | grep -v "grep -e irssi"', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n') + except: + return xlist + for i in x: + if x[:3].upper() == 'TTY': + xlist.append(i[4]) + return xlist + + def update(self, environment, trigger='updateScreen'): + newTTY = '' + newContentBytes = b'' + try: + # read screen + newTTY = self.getCurrScreen() + vcsa = open(self.vcsaDevicePath + newTTY,'rb',0) + newContentBytes = vcsa.read() + vcsa.close() + if len(newContentBytes) < 5: + return environment + except Exception as e: + environment['runtime']['debug'].writeDebugOut(environment,str(e),debug.debugLevel.ERROR) + return environment + screenEncoding = environment['runtime']['settingsManager'].getSetting(environment,'screen', 'encoding') + # set new "old" values + environment['screenData']['oldContentBytes'] = environment['screenData']['newContentBytes'] + environment['screenData']['oldContentText'] = environment['screenData']['newContentText'] + environment['screenData']['oldContentTextAttrib'] = environment['screenData']['newContentAttrib'] + environment['screenData']['oldCursor']['x'] = environment['screenData']['newCursor']['x'] + environment['screenData']['oldCursor']['y'] = environment['screenData']['newCursor']['y'] + if environment['screenData']['oldTTY'] == '-1': + environment['screenData']['oldTTY'] = newTTY # dont recognice starting fenrir as change + else: + environment['screenData']['oldTTY'] = environment['screenData']['newTTY'] + environment['screenData']['oldDelta'] = environment['screenData']['newDelta'] + environment['screenData']['oldNegativeDelta'] = environment['screenData']['newNegativeDelta'] + environment['screenData']['newTTY'] = newTTY + environment['screenData']['newContentBytes'] = newContentBytes + # get metadata like cursor or screensize + environment['screenData']['lines'] = int( environment['screenData']['newContentBytes'][0]) + environment['screenData']['columns'] = int( environment['screenData']['newContentBytes'][1]) + environment['screenData']['newCursor']['x'] = int( environment['screenData']['newContentBytes'][2]) + environment['screenData']['newCursor']['y'] = int( environment['screenData']['newContentBytes'][3]) + # analyze content + environment['screenData']['newContentText'] = environment['screenData']['newContentBytes'][4:][::2].decode(screenEncoding, "replace").encode('utf-8').decode('utf-8') + environment['screenData']['newContentAttrib'] = environment['screenData']['newContentBytes'][5:][::2] + environment['screenData']['newContentText'] = self.insert_newlines(environment['screenData']['newContentText'], environment['screenData']['columns']) + + if environment['screenData']['newTTY'] != environment['screenData']['oldTTY']: + environment['screenData']['oldContentBytes'] = b'' + environment['screenData']['oldContentAttrib'] = b'' + environment['screenData']['oldContentText'] = '' + environment['screenData']['oldCursor']['x'] = 0 + environment['screenData']['oldCursor']['y'] = 0 + environment['screenData']['oldDelta'] = '' + environment['screenData']['oldNegativeDelta'] = '' + # always clear current deltas + environment['screenData']['newNegativeDelta'] = '' + environment['screenData']['newDelta'] = '' + # changes on the screen + if (environment['screenData']['oldContentText'] != environment['screenData']['newContentText']) and \ + (environment['screenData']['newContentText'] != '' ): + if environment['screenData']['oldContentText'] == '' and\ + environment['screenData']['newContentText'] != '': + environment['screenData']['newDelta'] = environment['screenData']['newContentText'] + else: + diffStart = 0 + if environment['screenData']['oldCursor']['x'] != environment['screenData']['newCursor']['x'] and \ + environment['screenData']['oldCursor']['y'] == environment['screenData']['newCursor']['y'] and \ + environment['screenData']['newContentText'][:environment['screenData']['newCursor']['y']] == environment['screenData']['oldContentText'][:environment['screenData']['newCursor']['y']]: + diffStart = environment['screenData']['newCursor']['y'] * environment['screenData']['columns'] + environment['screenData']['newCursor']['y'] + diff = difflib.ndiff(environment['screenData']['oldContentText'][diffStart:diffStart + environment['screenData']['columns']],\ + environment['screenData']['newContentText'][diffStart:diffStart + environment['screenData']['columns']]) + else: + diff = difflib.ndiff( environment['screenData']['oldContentText'][diffStart:].split('\n'),\ + environment['screenData']['newContentText'][diffStart:].split('\n')) + + diffList = list(diff) + + environment['screenData']['newDelta'] = ''.join(x[2:] for x in diffList if x.startswith('+ ')) + environment['screenData']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x.startswith('- ')) + + return environment + diff --git a/src/fenrir-package/soundDriver/__init__.py b/src/fenrir-package/soundDriver/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/src/fenrir-package/soundDriver/gstreamer.py b/src/fenrir-package/soundDriver/gstreamer.py new file mode 100644 index 00000000..09e41867 --- /dev/null +++ b/src/fenrir-package/soundDriver/gstreamer.py @@ -0,0 +1,103 @@ +import gi +import time +from gi.repository import GLib + +try: + gi.require_version('Gst', '1.0') + from gi.repository import Gst +except: + _gstreamerAvailable = False +else: + _gstreamerAvailable, args = Gst.init_check(None) + +class driver: + def __init__(self): + self._initialized = False + self._source = None + self._sink = None + self.volume = 1 + if not _gstreamerAvailable: + return + def initialize(self, environment): + if self._initialized: + return environment + if not _gstreamerAvailable: + return environment + + self._player = Gst.ElementFactory.make('playbin', 'player') + bus = self._player.get_bus() + bus.add_signal_watch() + bus.connect("message", self._onPlayerMessage) + + self._pipeline = Gst.Pipeline(name='fenrir-pipeline') + bus = self._pipeline.get_bus() + bus.add_signal_watch() + bus.connect("message", self._onPipelineMessage) + + self._source = Gst.ElementFactory.make('audiotestsrc', 'src') + self._sink = Gst.ElementFactory.make('autoaudiosink', 'output') + self._pipeline.add(self._source) + self._pipeline.add(self._sink) + self._source.link(self._sink) + + self._initialized = True + return environment + def shutdown(self, environment): + return environment + + def _onPlayerMessage(self, bus, message): + if message.type == Gst.MessageType.EOS: + self._player.set_state(Gst.State.NULL) + elif message.type == Gst.MessageType.ERROR: + self._player.set_state(Gst.State.NULL) + error, info = message.parse_error() + print(error, info) + print('_onPlayerMessage') + def _onPipelineMessage(self, bus, message): + if message.type == Gst.MessageType.EOS: + self._pipeline.set_state(Gst.State.NULL) + elif message.type == Gst.MessageType.ERROR: + self._pipeline.set_state(Gst.State.NULL) + error, info = message.parse_error() + print(error, info) + print('_onPipelineMessage') + + def _onTimeout(self, element): + element.set_state(Gst.State.NULL) + return False + + def playSoundFile(self, fileName, interrupt=True): + if interrupt: + self.cancel() + self._player.set_property('uri', 'file://%s' % fileName) + self._player.set_state(Gst.State.PLAYING) + print('playSoundFile') + def playFrequence(self, frequence, duration, adjustVolume, interrupt=True): + if interrupt: + self.cancel() + self._source.set_property('volume', tone.volume) + self._source.set_property('freq', tone.frequency) + self._source.set_property('wave', tone.wave) + self._pipeline.set_state(Gst.State.PLAYING) + duration = int(1000 * tone.duration) + GLib.timeout_add(duration, self._onTimeout, self._pipeline) + + def cancel(self, element=None): + if not _gstreamerAvailable: + return + if element: + element.set_state(Gst.State.NULL) + return + self._player.set_state(Gst.State.NULL) + self._pipeline.set_state(Gst.State.NULL) + def setVolume(self, volume): + self.volume = volume + def shutdown(self): + global _gstreamerAvailable + if not _gstreamerAvailable: + return + self.cancel() + self._initialized = False + _gstreamerAvailable = False + + diff --git a/src/fenrir-package/soundDriver/sox.py b/src/fenrir-package/soundDriver/sox.py new file mode 100644 index 00000000..3ca55810 --- /dev/null +++ b/src/fenrir-package/soundDriver/sox.py @@ -0,0 +1,20 @@ +#!/bin/python +import subprocess + +class driver(): + def __init__(self): + self.volume = 1.0; + def initialize(self, environment): + return environment + def shutdown(self, environment): + return environment + def playFrequence(self, frequence, duration, adjustVolume): + pass + def playSoundFile(self, filePath, interrupt = True): + self.proc = subprocess.Popen("play -q -v " + str(self.volume ) + ' ' + filePath, shell=True) + def cancel(self): + pass + def setCallback(self, callback): + pass + def setVolume(self, volume): + self.volume = volume diff --git a/src/fenrir-package/speechDriver/Readme.md b/src/fenrir-package/speechDriver/Readme.md new file mode 100644 index 00000000..de077fd4 --- /dev/null +++ b/src/fenrir-package/speechDriver/Readme.md @@ -0,0 +1,3 @@ +espeak = espeak driver +speechd = speech-dispatcher driver +generic = generic driver via /bin/say diff --git a/src/fenrir-package/speechDriver/__init__.py b/src/fenrir-package/speechDriver/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/src/fenrir-package/speechDriver/espeak.py b/src/fenrir-package/speechDriver/espeak.py new file mode 100644 index 00000000..70064a61 --- /dev/null +++ b/src/fenrir-package/speechDriver/espeak.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +# Espeak driver + +class driver(): + def __init__(self ): + self._es = None + self._isInitialized = False + try: + from espeak import espeak + self._es = espeak + self._isInitialized = True + except: + self._initialized = False + def initialize(self, environment): + return environment + def shutdown(self, environment): + return environment + + def speak(self,text, queueable=True): + if not self._isInitialized: + return False + if not queueable: + self.cancel() + self._es.synth(text) + return True + + def cancel(self): + if not self._isInitialized: + return False + self._es.cancel() + return True + + def setCallback(self, callback): + pass + + def clear_buffer(self): + if not self._isInitialized: + return False + return True + + def setVoice(self, voice): + if not self._isInitialized: + return False + return self._es.set_voice(voice) + + def setPitch(self, pitch): + if not self._isInitialized: + return False + + def setRate(self, rate): + if not self._isInitialized: + return False + return self._es.set_parameter(self._es.Parameter().Rate, int(rate*450 + 80)) + + return self._es.set_parameter(self._es.Parameter().Pitch, int(pitch * 99)) + def setModule(self, module): + if not self._isInitialized: + return False + + def setLanguage(self, language): + if not self._isInitialized: + return False + return self._es.set_voice(language) + + def setVolume(self, volume): + if not self._isInitialized: + return False + return self._es.set_parameter(self._es.Parameter().Volume, int(volume * 200)) diff --git a/src/fenrir-package/speechDriver/generic.py b/src/fenrir-package/speechDriver/generic.py new file mode 100644 index 00000000..b67a3264 --- /dev/null +++ b/src/fenrir-package/speechDriver/generic.py @@ -0,0 +1,61 @@ +#!/usr/bin/python + +# generic driver + +class driver(): + def __init__(self ): + pass + def initialize(self, environment): + self._isInitialized = False + return environment + def shutdown(self, environment): + return environment + + def speak(self,text, queueable=True): + if not self._isInitialized: + return False + if not queueable: + self.cancel() + return True + + def cancel(self): + if not self._isInitialized: + return False + return True + + def setCallback(self, callback): + pass + + def clear_buffer(self): + if not self._isInitialized: + return False + return True + + def setVoice(self, voice): + if not self._isInitialized: + return False + return True + + def setPitch(self, pitch): + if not self._isInitialized: + return False + return True + + def setRate(self, rate): + if not self._isInitialized: + return False + return True + + def setModule(self, module): + if not self._isInitialized: + return False + + def setLanguage(self, language): + if not self._isInitialized: + return False + return True + + def setVolume(self, volume): + if not self._isInitialized: + return False + return True diff --git a/src/fenrir-package/speechDriver/speechd.py b/src/fenrir-package/speechDriver/speechd.py new file mode 100644 index 00000000..a8bf526a --- /dev/null +++ b/src/fenrir-package/speechDriver/speechd.py @@ -0,0 +1,97 @@ +#!/usr/bin/python + +# speech-dispatcher driver + +class driver(): + def __init__(self ): + self._sd = None + self._isInitialized = False + self._language = '' + try: + import speechd + self._sd = speechd.SSIPClient('fenrir') + self._isInitialized = True + except: + self._initialized = False + def initialize(self, environment): + return environment + def shutdown(self, environment): + if not self._isInitialized: + return environment + self._isInitialized = False + self.cancel() + self._sd.close() + return environment + + def speak(self,text, queueable=True): + if not self._isInitialized: + return False + if queueable == False: self.cancel() + try: + self._sd.set_synthesis_voice(self._language) + except: + pass + self._sd.speak(text) + return True + + def cancel(self): + if not self._isInitialized: + return False + self._sd.cancel() + return True + + def setCallback(self, callback): + pass + + def clear_buffer(self): + if not self._isInitialized: + return False + return True + + def setVoice(self, voice): + if not self._isInitialized: + return False + try: + if voice != '': + self._sd.set_voice(voice) + return True + except: + return False + + def setPitch(self, pitch): + if not self._isInitialized: + return False + try: + self._sd.set_pitch(int(-100 + pitch * 200)) + return True + except: + return False + + def setRate(self, rate): + if not self._isInitialized: + return False + try: + self._sd.set_rate(int(-100 + rate * 200)) + return True + except: + return False + + def setModule(self, module): + if not self._isInitialized: + return False + try: + self._sd.set_output_module(module) + return True + except: + return False + + def setLanguage(self, language): + if not self._isInitialized: + return False + self._language = language + + def setVolume(self, volume): + if not self._isInitialized: + return False + self._sd.set_volume(int(-100 + volume * 200)) +