[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