[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] TTS and Pitch Parameter
"Gary BIshop" <gb@xxxxxxxxxx> Wrote:
I repeat, pyTTS, at least the version 3.0 that I have, does not have a
method or property named Pitch. You are, I think simply assigned those
values to an instance variable that you are adding to the tts object.
Do you hear the pitch change when you assign to the pitch variable?
Gary,
I do not know why I thought there was a pitch command. I did a test just
in python and could not get it to work. Do not know what or where I was when
I thought there was a pitch command.
so, could not duplicate it.
Below is the modifications to the maze game you could test and run. I left
the pitch in there but it is just an instance, and does not affect anything.
I changed, modified the game for volume and rate. I also give it voices
to change and also a good bye message.
Bruce
# Pyramid Puzzles
# A Maze Exploration Game
# By Shane Dittmar And Gary Bishop
# Version 1.0
# use the arrow keys to play. Up arrow moves you forward. Left arrow turns
90 degrees left.
# Right arrow turns 90 degrees right. Down arrow turns around 180 degrees.
Escape quits.
#
# Listen for the hint in the sound of the wind.
# Load Modules
import pygame
from pygame.locals import *
import random, sys
import time
import math
import pyTTS
tts = pyTTS.Create()
tts.Volume = 70
tts.Pitch = 1
# go to the program directory
import os
mydir = os.path.dirname(sys.argv[0])
if mydir:
os.chdir(mydir)
# Constants -- cell marks
BOTTOMWALL = 0
RIGHTWALL = 1
VISITED = 2
PATH = 3
# Directions. I have numbered them so adding 1 rotates right and subtracting
one rotates
left
NORTH = 0
SOUTH = 2
WEST = 3
EAST = 1
class Maze:
def __init__( self, n_rows, n_cols ):
"""Create a maze with given number of rows and cols.
member variable longest_path is the sequence of cells you pass
through to get to the
end.
"""
self.n_rows = n_rows
self.n_cols = n_cols
self.maze = [ [ [True,True,False,tuple()] for c in range(n_cols) ]
for r in
range(n_rows) ]
self.longest_path = tuple() # will be the longest path through the
maze
def randomize( self ):
# Choose a random end point
currCol = random.randrange(self.n_cols)
currRow = random.randrange(self.n_rows)
# The search can be quite deep
if self.n_rows*self.n_cols > sys.getrecursionlimit():
sys.setrecursionlimit( self.n_rows*self.n_cols+5 )
# Recursively Remove Walls - Depth First Algorithm
self._make_path( currRow, currCol, tuple() )
#*****************************************
def _make_path( self, R, C, path, D=None ):
'''Used internally to generate the maze.'''
maze = self.maze # speed up a bit
maze[R][C][PATH] = path
# track the longest path
path = ((R,C),) + path
if len(path) > len(self.longest_path):
self.longest_path = path
# Knock out wall between this and previous cell
maze[R][C][VISITED] = True;
if D==NORTH: maze[R] [C] [BOTTOMWALL] = False
elif D==SOUTH: maze[R-1][C] [BOTTOMWALL] = False
elif D==WEST: maze[R] [C] [RIGHTWALL] = False
elif D==EAST: maze[R] [C-1][RIGHTWALL] = False
# Build legal directions array
directions = []
if R>0 : directions.append(NORTH)
if R<self.n_rows-1: directions.append(SOUTH)
if C>0 : directions.append(WEST)
if C<self.n_cols-1: directions.append(EAST)
# Shuffle the directions array randomly
random.shuffle(directions)
# Call the function recursively
for dir in directions:
if dir==NORTH:
if not maze[R-1][C][VISITED]:
self._make_path( R-1,C,path,NORTH )
elif dir==SOUTH:
if not maze[R+1][C][VISITED]:
self._make_path( R+1,C,path,SOUTH )
elif dir==EAST:
if not maze[R][C+1][VISITED]:
self._make_path( R,C+1,path,EAST )
elif dir==WEST:
if not maze[R][C-1][VISITED]:
self._make_path( R,C-1,path,WEST )
def _find_path( self, R, C, path, goal=None):
'''Used internally to fill-in the maze.'''
maze = self.maze # speed up a bit
maze[R][C][PATH] = path
# track the longest path
path = ((R,C),) + path
if goal and goal == (R,C):
self.longest_path = path
elif not goal and len(path) > len(self.longest_path):
self.longest_path = path
# note that we've been here
maze[R][C][VISITED] = True;
# Build directions array
directions = []
if R>0 and not maze[R-1][C][BOTTOMWALL]: directions.append(NORTH)
if R<self.n_rows-1 and not maze[R][C][BOTTOMWALL]:
directions.append(SOUTH)
if C>0 and not maze[R][C-1][RIGHTWALL]: directions.append(WEST)
if C<self.n_cols-1 and not maze[R][C][RIGHTWALL]:
directions.append(EAST)
# Call the function recursively
for dir in directions:
if dir==NORTH:
if not maze[R-1][C][VISITED]:
self._find_path( R-1,C,path,goal )
elif dir==SOUTH:
if not maze[R+1][C][VISITED]:
self._find_path( R+1,C,path,goal )
elif dir==EAST:
if not maze[R][C+1][VISITED]:
self._find_path( R,C+1,path,goal )
elif dir==WEST:
if not maze[R][C-1][VISITED]:
self._find_path( R,C-1,path,goal )
def wayout(self, row, col):
'''The direction from this cell to the exit.'''
path = self.maze[row][col][PATH]
next = path[0]
dr = next[0] - row
dc = next[1] - col
distance = len(path)
if dr < 0: return NORTH, distance
if dr > 0: return SOUTH, distance
if dc > 0: return EAST, distance
if dc < 0: return WEST, distance
def openings(self, row, col):
'''For each direction indicate if there is an opening'''
result = [False]*4
result[NORTH] = row>0 and not self.maze[row-1][col][BOTTOMWALL]
result[SOUTH] = not self.maze[row][col][BOTTOMWALL]
result[EAST] = not self.maze[row][col][RIGHTWALL]
result[WEST] = col>0 and not self.maze[row][col-1][RIGHTWALL]
return result
def __str__(self):
"""Return a simple visual representation of the maze in ASCII"""
if self.longest_path:
result = str((self.longest_path[0],self.longest_path[-1]))+'\n'
else:
result = '((-1,-1),(-1,-1))\n'
result += '.' + self.n_cols*'_.'
result += '\n'
for i in range(self.n_rows):
result += '|'
for j in range(self.n_cols):
if i==self.n_rows-1 or self.maze[i][j][BOTTOMWALL]:
result += '_'
else:
result += ' '
if j==self.n_cols-1 or self.maze[i][j][RIGHTWALL]:
result += '|'
else:
result += '.'
result += '\n'
return result
def fromstring(self, init):
'''Parse the string we built in __str__ to initialize the maze.
No error checking. Assumes the maze is exactly in printed format.
Really needs lots of work.
'''
lines = init.split('\n')
start, goal = eval(lines[0])
lines = lines[2:] # toss the first row
for i in range(self.n_rows):
line = lines[i][1:] # toss the first col
for j in range(self.n_cols):
if i < self.n_rows-1 and line[2*j] == '_':
self.maze[i][j][BOTTOMWALL] = True
elif line[2*j] == ' ':
self.maze[i][j][BOTTOMWALL] = False
if j < self.n_cols-1 and line[2*j+1] == '|':
self.maze[i][j][RIGHTWALL] = True
elif line[2*j+1] == '.':
self.maze[i][j][RIGHTWALL] = False
self._find_path( goal[0], goal[1], tuple(), start )
directions = ['North', 'East', 'South', 'West'] # names for the directions
steps = [ (-1,0), (0,1), (1,0), (0,-1) ] # increments to step in each
direction
pygame.init()
screen = pygame.display.set_mode((320,240))
purge = pyTTS.tts_purge_before_speak
async = pyTTS.tts_async
def Game(maze):
facing = NORTH # direction you are facing currently
position = maze.longest_path[0]
goal = maze.longest_path[-1]
RATE = tts.Rate
VOL_LEVEL = tts.Volume
PITCH = tts.Pitch
windsnd = pygame.mixer.Sound('wind.wav')
success = pygame.mixer.Sound('success.wav')
wind = windsnd.play(-1)
moves = 0
print maze
moved = True
while True:
# make the sound come from the right direction
if moved:
direction, distance = maze.wayout(position[0], position[1])
rotation = (facing - direction) % 4
vol = 1/math.sqrt(distance)
if rotation == 0:
wind.set_volume(vol)
elif rotation == 1:
wind.set_volume(vol, 0)
elif rotation == 3:
wind.set_volume(0, vol)
elif rotation == 2:
wind.set_volume(vol/2)
openings = maze.openings(position[0], position[1])
tts.Speak('In cell %d, %d, facing %s. There is %s here.' %
(position[0], position[1], directions[facing],
('a wall', 'an opening')[openings[facing]]), async,
purge)
event = pygame.event.poll()
moved = False
if event.type == pygame.QUIT:
return 0
elif event.type == pygame.KEYDOWN:
key = event.key
if key == 27: # escape
return 0
elif key == ord('s'):
tts.Speak("Directional Sound Toggle")
if wind.get_busy():
wind.stop() #pause()
else:
wind = windsnd.play(-1) #.unpause()
moved = True #ONLY USED FOR GET_BUSY AND NOT FOR PAUSE.
elif key == K_HOME:
VOL_LEVEL += 5
if VOL_LEVEL > 100:
VOL_LEVEL = 100
tts.Volume = VOL_LEVEL
tts.Speak('Volume Maximum!', async, purge)
else:
tts.Volume = VOL_LEVEL
tts.Speak('Volume Up!', async, purge)
elif key == K_END:
VOL_LEVEL -= 5
if VOL_LEVEL < 0:
VOL_LEVEL = 0
tts.Volume = 70
tts.Speak('Volume Minimum!', async, purge)
tts.Volume = VOL_LEVEL
else:
tts.Volume = VOL_LEVEL
tts.Speak('Volume Down!', async, purge)
elif key == K_PAGEUP:
RATE += .5; tts.Rate = RATE
tts.Speak('Rate Up!', async, purge)
elif key == K_PAGEDOWN:
RATE -= .5; tts.Rate = RATE
tts.Speak('Rate down!', async, purge)
elif key == K_INSERT:
PITCH += .5; tts.Pitch = PITCH
tts.Speak('Pitch Up!', async, purge)
elif key == K_DELETE:
PITCH -= .5; tts.Pitch = PITCH
tts.Speak('Pitch down!', async, purge)
elif key == ord('f'):
tts.SetVoiceByName('MSSam')
tts.Speak('Sam!', async, purge)
elif key == ord('w'):
tts.SetVoiceByName('MSMary')
tts.Speak('Mary!', async, purge)
elif key == ord('m'):
tts.SetVoiceByName('MSMike')
tts.Speak('Mike!', async, purge)
elif key == ord('d'):
tts.Speak("Destination: %s" % str(goal))
elif key == pygame.K_UP:
if openings[facing]:
step = steps[facing]
moves += 1
position = (position[0]+step[0], position[1]+step[1])
moved = True
if position == goal:
wind.stop()
chan = success.play()
tts.Speak("You found the end in %d moves!" % moves,
purge)
tts.Speak("Congratulations. You finished the
level!")
return 1
else:
tts.Speak("You bump into the wall!")
elif key == pygame.K_RIGHT: # right arrow
facing = (facing + 1) % 4
moved = True
elif key == pygame.K_DOWN: # down arrow
facing = (facing + 2) % 4
moved = True
elif key == pygame.K_LEFT: # left arrow
facing = (facing - 1) % 4
moved = True
pygame.display.flip()
if __name__ == '__main__':
n = 3
while True:
tts.Speak('This level is %d cells on a side.' % n)
m = Maze(n,n)
m.randomize()
if not Game(m):
tts.Speak("Good! Bye!")
pygame.quit()
sys.exit()
break
n += 1