Voice control

Official forum for open source FreePIE discussion and development.
Post Reply
Maers
One Eyed Hopeful
Posts: 3
Joined: Sun Sep 25, 2016 3:41 pm

Voice control

Post by Maers »

Code: Select all

import time;

# ***********************************
# Key Actions Classes
# ***********************************

class KeyAction:
	def __init__(self, key):
		self.keys = []
		# append or extend (both are valid)
		if isinstance(key, list):
			self.keys.extend(key)
		else:
			self.keys.append(key)
	
	def setKeyDown(self):
		for key in self.keys:
			keyboard.setKeyDown(key)	
		
	def setKeyUp(self):
		for key in self.keys:
			keyboard.setKeyUp(key)	
	
	def setKey(self, down):
		for key in self.keys:
			keyboard.setKey(key, down)
			
	def setKeyPressed(self):
		for key in self.keys:
			#keyboard.setPressed(key)
			keyboard.setKeyDown(key)
			keyboard.setKeyUp(key)
						
	def execute(self):
		raise NotImplementedError("Subclass must implement execute method")

	def update(self, curentTime):
		pass


class KeyPress(KeyAction):
	def __init__(self, key, duration = 0.07):
		KeyAction.__init__(self, key)
		self.duration = duration
		self.time = time.time()
		self.needUpdate = False
		
	def execute(self):
		# set the keys down
		self.setKeyDown()
		# start the update timer
		self.time = time.time()
		self.needUpdate = True
			
	def update(self, currentTime):
		if self.needUpdate:
			# determine if we should stop pressing the keys
			if (currentTime - self.time) >= self.duration:
				self.setKeyUp()
				self.needUpdate = False


class KeyRepeat(KeyAction):
	def __init__(self, key, times, timeInterval = 0.14, duration = 0.07):
		KeyAction.__init__(self, key)
		self.times = times-1 
		self.timeInterval = timeInterval
		# Duration cannot be larger than time interval
		if (duration > timeInterval):
			self.duration = timeInterval
		else:
			self.duration = duration
		#internal use variables
		self.time = time.time()
		self.timesLeft = 0
		self.needUpdate = False
		
	def execute(self):
		# set the keys down
		self.setKeyDown()
		# start the update timer
		self.time = time.time()
		self.timesLeft = self.times
		self.needUpdate = True
			
	def update(self, currentTime):
		if self.needUpdate:
			elapsedTime = currentTime - self.time
			# Release Current Key
			if (elapsedTime >= self.duration):
				self.setKeyUp()
				# End the update if the last key has been released
				if (self.timesLeft == 0):
					self.needUpdate = False
			# Press Next KeyDown
			if (elapsedTime >= self.timeInterval):
				self.setKeyDown()
				self.time = time.time()
				self.timesLeft = self.timesLeft - 1
			

# ***********************************
# VoiceCommand Class
# ***********************************

class VoiceCommand:
	def __init__(self, cmd, response, action = None):
		self.cmd = cmd
		self.response = response
		self.action = action
		
	def said(self, confidence, response=False):
		return ((self.cmd != "") and speech.said(self.cmd, confidence))

	def playResponse(self):
		if self.response:
			speech.say(self.response)
		
	def execute(self):
		if self.action:
			self.action.execute()
			
	def update(self, currentTime):
		if self.action:
			self.action.update(currentTime)
			
			
# ***********************************
# VoiceToKeyboard
# ***********************************

class VoiceToKeyboard:
	def __init__(self, confidenceLevel, commands = None):
		self.confidenceLevel = confidenceLevel
		self.commands = []
		self.setCommands(commands)
	
	def setCommands(self, commands):
		if isinstance(commands, list):
			self.commands = commands
	
	def addCommand(self, cmd, response, action = None):
		self.commands.append( VoiceCommand(cmd, response, action) )

	def executeLoop(self):
		currentTime = time.time()
		for command in self.commands:
			# if said execute action
			if command.said(self.confidenceLevel):
				command.playResponse()
				command.execute()
			command.update(currentTime)
			
			
# ***********************************
# Config and commands
# ***********************************

if starting:
	confidenceLevel = 0.7
	v2k = VoiceToKeyboard( confidenceLevel )
	
	# Voice response only
	v2k.addCommand("Hello", "!Welcome! Initialising system.")
	
	# Key Press 
	v2k.addCommand("Test single press", "Single key press", KeyPress( Key.A ))
	v2k.addCommand("Test multiple press", "Multiple keys press", KeyPress( [ Key.LeftShift, Key.A ] ))
	
	# Key Hold
	v2k.addCommand("Test single hold", "Single key hold. 2 seconds", KeyPress( Key.B, 2 ))
	v2k.addCommand("Test multiple hold", "Multiple keys hold. 2 seconds", KeyPress( [ Key.LeftShift, Key.B ], 2 ))
	
	# Key Repeat
	v2k.addCommand("Test single repeat", "Pressing C key 5 times", KeyRepeat( Key.C, 5 ))
	v2k.addCommand("Test multiple repeat", "Pressing Shift and C keys 5 times", KeyRepeat( [ Key.LeftShift, Key.C ], 5 , 0.1, 0.07 ))
	

v2k.executeLoop() 

I found this sample script but it throws an error when I try to run. Any help would be appreciated.
rscott6666
One Eyed Hopeful
Posts: 8
Joined: Sun Aug 21, 2016 6:06 pm

Re: Voice control

Post by rscott6666 »

I'm no expert, but if the error is about time not being defined, then you probably need to add the command

import time

if it complains about speech or something, make sure you have a working microphone or something.
Maers
One Eyed Hopeful
Posts: 3
Joined: Sun Sep 25, 2016 3:41 pm

Re: Voice control

Post by Maers »

Reinstalling mic driver fixed it

While I'm here, how would one make a key toggle?
rscott6666
One Eyed Hopeful
Posts: 8
Joined: Sun Aug 21, 2016 6:06 pm

Re: Voice control

Post by rscott6666 »

You'll have to be more specific.

Is it where one phrase holds the button in and another releases it?
Maers
One Eyed Hopeful
Posts: 3
Joined: Sun Sep 25, 2016 3:41 pm

Re: Voice control

Post by Maers »

I'm hoping to use the same phrase. Say it once to hold and say it again to release it
rscott6666
One Eyed Hopeful
Posts: 8
Joined: Sun Aug 21, 2016 6:06 pm

Re: Voice control

Post by rscott6666 »

I'm a little busy to write the script but it would involve checking the current state of the button, and then calliing the up or the down method as is appropriate.
User avatar
LordAshes
One Eyed Hopeful
Posts: 24
Joined: Sat Jan 27, 2018 10:27 pm

Re: Voice control

Post by LordAshes »

Maers wrote:I'm hoping to use the same phrase. Say it once to hold and say it again to release it
The keyboard portion of the code should be something like this:

Code: Select all

#This function toggles the key state 
def toggle(key):
    if lastState == 0:
        lastState = 1
        keyboard.setKeyDown(key)
    else:
        lastState = 1
        keyboard.setKeyUp(key)

if starting:
    #Assume button is not pressed on startup
    lastState = 0;
Now when the desired command is recognized just call the toggle() function defined above passing the desired key to be toggled as the parameter.
Post Reply

Return to “FreePIE”