Exemplo n.º 1
0
def dum_v():
	from Vowel import Vowel
	e1 = uniform(min_e1, max_e1)
	e2 = uniform(min_e2, max_e2)
	length = randint(100, 300)
	v = Vowel(e1, e2, length, "")
	name = []
	if is_high(v):
		name.append("high")
	elif is_low(v):
		name.append("low")
	else:
		name.append("mid")
	if is_back(v):
		name.append("back")
	elif is_front(v):
		name.append("front")
	else:
		name.append("central")
	if length > 200:
		name.append("long")
	else:
		name.append("short")

	v.name = "-".join(name)
	
	return v
 def __init__(self, verses):
     self.tohoku_tokenizer = BertJapaneseTokenizer.from_pretrained(
         'cl-tohoku/bert-base-japanese-whole-word-masking')
     self.tohoku_bert_model = AutoModelForMaskedLM.from_pretrained(
         'cl-tohoku/bert-base-japanese-whole-word-masking')
     self.lyrics = self.load_lyrics(verses)
     self.replaced_verses = []
     self.vowel = Vowel.Vowel()
Exemplo n.º 3
0
    def get_vowel_random(self):
        '''
		The vowel is the agent's phonetic representation of a vowel
		i.e. their pronunciation of their vowel percept.

		generative -> vowel is identical to percept
		mod generative -> vowel is noisy production of percept
		exemplar -> vowel is average of history (percept is a memory bank)
		'''
        from random import uniform, randint

        p = self.percept
        radius = self.noise

        if ((not radius) or (not p)):
            return p

        circle_range = self.circle_range

        #radius = perception margin in ERB units
        #imitation will be a randomly selected point inside this circle

        e1 = p.e1
        e2 = p.e2
        l = int(p.length)

        #find the domain of circle fn to get x-coord (f2 value)
        left = e2 + radius
        right = e2 - radius
        rand_x = uniform(right, left)  #generate x

        #find the range for y-coord (f1 value at x = rand_x)
        floor, c = circle_range(rand_x, e2, e1, radius)
        ceiling = min(rand_x, c)  #constraint: f1 <= f2
        rand_y = uniform(floor, ceiling)  #generate y

        #constraint: length of imitation needs to be in range [100..300]
        #random number in that range and within original length+-50
        length_min = max([100, (l - 25)])
        length_max = length_min + 50

        new_e1, new_e2 = rand_y, rand_x
        new_length = randint(length_min, length_max)
        name = p.name  #match the name for the incoming signal

        #keep the imitations in a range
        if new_e1 > max_e1:
            new_e1 = max_e1
        if new_e2 > max_e2:
            new_e2 = max_e2
        if new_e1 < min_e1:
            new_e1 = min_e1
        if new_e2 < min_e2:
            new_e2 = min_e2

        new_v = Vowel.Vowel(new_e1, new_e2, new_length, name)
        self.set_vowel(new_v)
        return new_v
Exemplo n.º 4
0
def dum_vowel(self):
    pos_lower = 700
    pos_upper = 2400
    pos = random.randint(pos_lower, pos_upper)
    closeLower = 275
    closeUpper = 800
    closed = random.randint(close_lower, close_upper)

    return Vowel.Vowel(pos, closed, random.randint(1, 250))
Exemplo n.º 5
0
 def loadDefaultVowel(self):
     f1 = self.defaultSetup.defFormants[0][0]
     f2 = self.defaultSetup.defFormants[0][1]
     f3 = self.defaultSetup.defFormants[0][2]
     self.exampleVowel = Vowel(f1, f2, f3, '')
     self.exampleVowel.setAnnotation(self.defaultSetup.defVowel)
     if (len(self.defaultSetup.soundFile)>0) :
         self.matchVowel.config(text=self.defaultSetup.soundFilename)
     else :
         self.matchVowel.config(text=self.defaultSetup.defVowel)
Exemplo n.º 6
0
 def loadVowel(self):
     # path = tk.filedialog.askopenfilename()
     # CJR Windows needed this form with the import at the start of the file
     filename = filedialog.askopenfilename()
     if (filename) :
         # clear the old vowel
         self.graphModule.unDrawVowels()
         # the selected file is the formant file
         self.exampleVowel = Vowel(0,0,0, filename)
         # add the vowel annotation to the Label
         self.loadAnyVowel(self.exampleVowel.getF(), self.exampleVowel.annotation)
         #self.matchVowel.config(text=self.exampleVowel.getAnnotation())
         #self.setupGraph(self.defaultSetup.viz)
     self.parent.focus_force()
Exemplo n.º 7
0
    def guess_by_margin(self, unknown_v):

        #radius = perception margin in ERB units
        #imitation will be a randomly selected point inside this circle
        radius = self.phone_radius
        if not radius:
            return self.copy_vowel(unknown_v)

        e1 = unknown_v.e1
        e2 = unknown_v.e2
        l = int(unknown_v.length)

        #find the domain of circle fn to get x-coord (f2 value)
        left = e2 + radius
        right = e2 - radius
        rand_x = uniform(right, left)  #generate x

        #find the range for y-coord (f1 value at x = rand_x)
        floor, c = circle_range(rand_x, e2, e1, radius)
        ceiling = min(rand_x, c)  #constraint: f1 <= f2
        rand_y = uniform(floor, ceiling)  #generate y

        #constraint: length of imitation needs to be in range [100..300]
        #random number in that range and within original length+-50
        length_min = max([100, (l - 25)])
        length_max = min([length_min + 50, 300])

        new_e1, new_e2 = rand_y, rand_x
        new_length = randint(length_min, length_max)
        w = unknown_v.name  #match the name for the incoming signal

        if new_e1 > max_e1:
            new_e1 = max_e1
        if new_e2 > max_e2:
            new_e2 = max_e2
        if new_e1 < min_e1:
            new_e1 = min_e1
        if new_e2 < min_e2:
            new_e2 = min_e2

        new_v = Vowel.Vowel(new_e1, new_e2, new_length, w)
        new_v.set_features(max_e1, max_e2, min_e1, min_e2)
        return new_v
Exemplo n.º 8
0
 def __init__(self, file):
     self.fileName = file
     configFile = open(self.fileName)
     # configuration file structure
     # 1) default visualzation type
     line = configFile.readline()
     self.viz = line.rstrip()
     # 2) default application mode
     line = configFile.readline()
     self.mode = line.rstrip()
     # 3) default baseline formant - vowel and formant definition
     #   plus wav file name if avalable
     line = configFile.readline()
     parts = line.split("$")
     vowelName = eval(parts[0])
     vowelName = vowelName[0]
     vowelFormants = eval(parts[1])
     # if there is a third part it is the filename for a recording of the vowel
     soundFile = ""
     soundFilename = ""
     if len(parts) > 2:
         soundFile = eval(parts[2])
         soundFile = soundFile[0]
         path, filename = os.path.split(soundFile)
         soundFilename = filename
     # if there is a 4th line then it is the length of the moving average queue
     line = configFile.readline()
     self.defQueueLength = float(line.rstrip())
     # and the final line is the tolerance for matching a vowel
     line = configFile.readline()
     self.defTolerance = float(line.rstrip())
     # create a vowel object from the vowel defaults
     self.loadedVowel = Vowel(0, 0, 0, "Female", "")
     self.loadedVowel.setF(vowelFormants[0])
     self.loadedVowel.setAnnotation(vowelName)
     if len(soundFile) > 0:
         self.loadedVowel.setSoundFile(file, soundFile, soundFilename)
     # set the current active vowel to none
     # the active vowel is the vowel that the user is singing
     self.activeVowel = None
     # set the gender to Female as the default
     self.singerGender = "Female"
Exemplo n.º 9
0
    def get_midpt(self, v1, v2):
        nv_e1 = int((v1.e1 + v2.e1) / 2)
        nv_e2 = int((v1.e2 + v2.e2) / 2)
        if nv_e1 > nv_e2:
            nv_e1 = nv_e2
        nv_l = int((v1.length + v2.length) / 2)

        ###########################################################
        #Not sure what to do here...
        #If the names don't match then new vowel should be compared
        #to the convention prototypes, except we can't access those
        #Maybe if the names match they should merge to one vowel
        #but if the names differ they should join to form a diphthong?
        ##############################################################
        name = v1.name

        nv = Vowel.Vowel(nv_e1, nv_e2, nv_l, name)
        for w in self.idio.values():
            w.merge_midpoint(v1, v2, nv)

        return nv
Exemplo n.º 10
0
def margin_tester(margin=1):
    import Convention

    v = Vowel.Vowel(10.5, 18.5, 250, 0)

    a = Agent(1, 1, margin, 1)
    v_str = str(v)
    m_str = str(margin)
    pts = [v]
    print("original:", v)
    c = Convention.Convention()
    for i in range(1000):
        im = a.guess_by_margin(v)
        dist = v.euc(im)
        #print("im: ", im, " dist: ", dist)
        pts.append(im)
        #v = im

    c.win = c.formant_space()

    c.plot_sets([pts], 0, v_str + " | " + m_str)
Exemplo n.º 11
0
    def merge_mid(self, v1, v2):
        '''two vowels of equal fnl load merge to their midpoint'''

        nv_e1 = ((v1.e1 + v2.e1) / 2)
        nv_e2 = ((v1.e2 + v2.e2) / 2)
        if nv_e1 > nv_e2:
            nv_e1 = nv_e2
        nv_l = int((v1.length + v2.length) / 2)

        ###########################################################
        #Not sure what to do here...
        #If the names don't match then new vowel should be compared
        #to the convention prototypes, except we can't access those
        #UPDATE: Convention fixes this in get_rep_set method
        # ^Not a great fix
        #Maybe if the names match they should merge to one vowel
        #but if the names differ they should join to form a diphthong?
        ##############################################################
        #name = ""
        name = v1.name
        nv = Vowel.Vowel(nv_e1, nv_e2, nv_l, name)
        nv.weight = v1.weight + v2.weight
        #
        if self.chosen:
            print("\nCONFLICT:", v1, "and", v2, "merging to midpoint at", nv)
            v1n = v1.name
            v2n = v2.name
            nvn = nv.name
            if v1n != nvn:
                print(v1n, ">", nvn)
            if v2n != nvn:
                print(v2n, ">", nvn)

        for w in self.idio.values():
            w.merge_midpoint(v1, v2, nv)
        rep = self.repertoire
        rep.remove(v1)
        rep.remove(v2)
        rep.append(nv)
Exemplo n.º 12
0
 def record(self):
     print("in the record method ", self.id)
     if (self.recordButton["text"] == "Record") :
         self.recordButton.config(text="Stop")
         self.playButton.config(state=tk.DISABLED)
         # initialize the activeVowel
         self.activeVowel = Vowel(10,10,10,"")
         # CJR add in the tkSnack commands to start the recording
         if (useTkSnack) :
             self.snd.flush()
             self.snd.record()
         self.start()
     else:
         print("Stop")
         self.recordButton.config(text="Record")
         # check the state - do not make the Record button normal
         # when in Study/Review mode
         if (self.defaultSetup.mode == "Practice" or self.defaultSetup.mode == "Mentor") :
             self.playButton.config(state=tk.NORMAL)
         # CJR add in the tkSnack commands to stop the recording
         if (useTkSnack) :
             self.snd.stop()
         self.stop()
     print("exiting the record method ", self.id)
Exemplo n.º 13
0
    def get_vowel(self):
        '''
		applies random noise
		then assimilation
		
		'''
        from random import uniform, randint
        fm = phon_fd
        P = Phonology.Phonology
        onset = self.onset.name
        nuc = self.percept
        coda = self.coda.name

        #apply random noise first
        radius = self.noise
        if radius > 0:
            circle_range = self.circle_range

            #radius = perception margin in ERB units
            #imitation will be a randomly selected point inside this circle

            e1 = nuc.e1
            e2 = nuc.e2
            l = int(nuc.length)

            #find the domain of circle fn to get x-coord (f2 value)
            left = e2 + radius
            right = e2 - radius
            rand_x = uniform(right, left)  #generate x

            #find the range for y-coord (f1 value at x = rand_x)
            floor, c = circle_range(rand_x, e2, e1, radius)
            ceiling = min(rand_x, c)  #constraint: f1 <= f2
            rand_y = uniform(floor, ceiling)  #generate y

            #constraint: length of imitation needs to be in range [100..300]
            #random number in that range and within original length+-50
            length_min = max([100, (l - 50)])
            length_max = min([length_min + 50, 300])

            new_e1, new_e2 = rand_y, rand_x
            new_length = randint(length_min, length_max)
            name = nuc.name  #match the name for the incoming signal

            #keep the imitations in a range
            if new_e1 > max_e1:
                new_e1 = max_e1
            if new_e2 > max_e2:
                new_e2 = max_e2
            if new_e1 < min_e1:
                new_e1 = min_e1
            if new_e2 < min_e2:
                new_e2 = min_e2

            n_nuc = Vowel.Vowel(new_e1, new_e2, new_length, name)

        else:
            n_nuc = nuc.cc()

        #APPLY COARTICULATION TRANSFORMS

        c1 = P(fm[onset])
        c2 = P(fm[coda])
        nfl = n_nuc.features
        ofl = c1.features
        cfl = c2.features

        #simulated morphological alternations
        #chance of a feature being "left off" due to context/use (inflectional/derivational)
        #morphable_features = ["stop", "voiced", "fricative", "spread"]
        morph_chance = 50

        #onset transformations (coart)
        for of in ofl:
            ofns = c1.articulations
            of_nuc = ofns[of]((onset, n_nuc, coda), 0, True)
            n_nuc = of_nuc

        #nucleus production noise (art)
        for nf in nfl:
            nf_nuc = ofns[nf]((onset, n_nuc, coda), 1, True)
            n_nuc = nf_nuc

        #coda transformations (coart)
        for cf in cfl:
            cfns = c2.articulations
            cf_nuc = cfns[cf]((onset, n_nuc, coda), 2, True)
            n_nuc = cf_nuc

        return n_nuc
Exemplo n.º 14
0
class Application(tk.Frame):
    def __init__(self, parent, sound, width, height):
        tk.Frame.__init__(self, parent, background="white") # Call the superclass' constructor method
        self.parent = parent
        self.parent.title("Vowel Shapes")
        #self.pack(fill=tk.BOTH, expand=1) # set expand=0 if you don't want the window to be resizable
        # CJR make the sound object of tkSnack part of the Application class
        self.snd = sound
        #initialize the defaults for the sound
        self.sound_length = 1024
        self.sound_pos = 0
        self.id = None
        # Dimensions
        self.width = width
        self.height = height
        
        # The graphWin canvas
        self.graphWin = None
        self.setupCanvas()
        
        # The menubar
        self.menubar = tk.Menu(self.parent)
        self.parent.config(menu=self.menubar)
        
        # The menus
        self.setupFileMenu()
        self.setupActionMenu()
        self.setupDemoVowelMenu()
        self.setupDemoVizMenu()
        self.setupMicMenu()
        self.setupHelpMenu()

        # from the tkSnack demo files
        #Button(f, bitmap='snackRecord', fg='red', command=start).pack(side='left')
        #Button(f, bitmap='snackStop', command=stop).pack(side='left')
        #Button(f, text='Exit', command=root.quit).pack(side='left')

        # The buttons
        self.recordButton = tk.Button(self.parent, text="Record", command=self.record)
        self.recordButton.grid(column=0, row=1)

        self.saveVowelAnnotation = None
        self.annotationButton = tk.Button(self.parent, text="Set Save Name", command=self.vowelAnnotationBox)
        self.annotationButton.grid(column=0, row=2)

        self.playButton = tk.Button(self.parent, text="Play", command=self.play)
        self.playButton.grid(column=1, row=1)

        # Demo matching vowel
        self.matchVowel = tk.Label(self.parent, text="")
        self.matchVowel.grid(column=1, row=2)

        # CJR
        # options for the file dialogs
        self.save_file_opt = options = {}
        options['filetypes'] = [('all files', '.*'), ('audio files', '.mp3')]
        options['initialfile'] = 'myfile_i.mp3'
        options['parent'] = self.parent

        # read the application configuration file
        self.defaultSetup = self.readConfiguration("./vowelShapeConfig.txt")
        # Vowel objects
        self.loadDefaultVowel() # loads the example vowel and corrects the display
        self.activeVowel = None

        #initialize the graphics module
        self.graphModule = GraphicsModule(self.graphWin, self.defaultSetup.viz,
                                        self.exampleVowel.getAnnotation(), self.exampleVowel.getF())
        self.setupGraph(self.defaultSetup.viz)
        self.graphModule.drawMatchingViz(self.defaultSetup.defFormants)



    def setupCanvas(self):
        self.graphWin = g.GraphWin(self)
        #self.graphWin.setCoords(0,0,100,75)
        self.graphWin.setCoords(0,0,100,75)
        self.graphWin.grid(column=0,row=0,columnspan=2)
        

    # Menus
    
    def setupFileMenu(self):
        fileMenu = tk.Menu(self.menubar)
        
        fileMenu.add_command(label="About", command=self.showAbout)
        fileMenu.add_command(label="Save Vowel", command=self.saveVowel)
        fileMenu.add_command(label="Load Vowel", command=self.loadVowel)
        fileMenu.add_command(label="Load Vowel Sound", command=self.loadVowelSound)
        fileMenu.add_command(label="Clear Vowel", command=self.clearVowel)
        fileMenu.add_command(label="Exit", command=self.exitApp)  # CJR added an exit function

        self.menubar.add_cascade(label="File", menu=fileMenu)
    
    def setupActionMenu(self):
        actionMenu = tk.Menu(self.menubar)
    
        #actionMenu.add_command(label="Test Canvas", command = self.testCanvas)
        actionMenu.add_radiobutton(label="Mentor", command = self.mentorMode)
        actionMenu.add_radiobutton(label="Study", command = self.studyMode)
        actionMenu.add_radiobutton(label="Practice", command = self.practiceMode)
        actionMenu.add_radiobutton(label="Review", command = self.reviewMode)
    
        self.menubar.add_cascade(label="Mode", menu = actionMenu)
    
    def setupHelpMenu(self):
        helpMenu = tk.Menu(self.menubar)
    
        helpMenu.add_command(label="The Different Modes", command=self.modesHelp)
    
        self.menubar.add_cascade(label="Help", menu=helpMenu)

    # only for the Demo - Vowels and Viza
    def setupDemoVowelMenu(self):
        demoMenu = tk.Menu(self.menubar)

        demoMenu.add_command(label="i", command=self.loadi)
        demoMenu.add_command(label="I", command=self.loadI)
        demoMenu.add_command(label="E", command=self.loadE)
        demoMenu.add_command(label="ae", command=self.loadae)
        demoMenu.add_command(label="as", command=self.loadas)
        demoMenu.add_command(label="o", command=self.loado)
        demoMenu.add_command(label="u", command=self.loadu)

        self.menubar.add_cascade(label="Vowel", menu=demoMenu)

    def setupDemoVizMenu(self):
        demovizMenu = tk.Menu(self.menubar)

        demovizMenu.add_command(label="Graph", command=self.doGraph)
        demovizMenu.add_command(label="Triangle", command=self.doTriangle)
        demovizMenu.add_command(label="Oval", command=self.doOval)

        self.menubar.add_cascade(label="Viz", menu=demovizMenu)

    def setupMicMenu(self):
        micMenu = tk.Menu(self.menubar)
        if (useTkSnack) :
            # build the menu using the microphones listed
            self.inputDevices = tkSnack.audio.inputDevices()
            self.inputSelected = []
            count = 0
            for mic in self.inputDevices :
                print("mic ", mic, " count ", count)
                micMenu.add_radiobutton(label=mic, command=lambda index=count : self.setInputDevice(index))
                count = count + 1
        self.menubar.add_cascade(label="Input Devices", menu=micMenu)

    def setInputDevice(self, item):
        print("select ", item)
        tkSnack.audio.selectInput(self.inputDevices[item])

    # menu commands
    def saveVowel(self):
        # make sure there is something to save
        if (self.snd.length() > 0) :
            # should also check the the formants exist ???
            # need a name to save with the vowel - is this the annotation also?
            if (self.saveVowelAnnotation) :
                self.activeVowel.setAnnotation(self.saveVowelAnnotation)
                #path = tk.filedialog.asksaveasfilename()
                # CJR Windows needed this form with the import at the start of the file
                fileSave = filedialog.asksaveasfilename()
                if (fileSave) :
                    # the user did not cancel the operation
                    if (self.snd.length() > 0) :
                        # this save the formant values of the last note
                        # we could resample the snd object and get the formants from
                        # the whole clip ???
                        self.activeVowel.saveToFile(fileSave)
                        # this saves the audio as a wav file
                        # it is saved in the save directory with the annotation name
                        path, filename = os.path.split(fileSave)
                        # WARNING - this is platform dependent ???
                        sndFileName = self.activeVowel.getAnnotation() + ".wav"
                        sndPath = path + "/" + sndFileName
                        os.path.join(path, sndFileName)
                        self.snd.write(sndPath)
                        self.snd.flush()
                self.saveVowelAnnotation = None
                # CJR is this the correct action? reload the default vowel as
                # the example vowel
                self.clearVowel()
                self.loadDefaultVowel()
                self.graphModule.drawMatchingViz(self.defaultSetup.defFormants)
            else :
                #request that the user supply an annotation
                messagebox.showinfo("Need an annotation", "Please click on the Set Save Name button and enter an annotation for this vowel")
        else :
            #request that the user record a vowel first
            messagebox.showinfo("Record a Vowel", "Please record a vowel and use the Set Save Name button to associate an annotation")
        self.parent.focus_force()

    def loadVowel(self):
        # path = tk.filedialog.askopenfilename()
        # CJR Windows needed this form with the import at the start of the file
        filename = filedialog.askopenfilename()
        if (filename) :
            # clear the old vowel
            self.graphModule.unDrawVowels()
            # the selected file is the formant file
            self.exampleVowel = Vowel(0,0,0, filename)
            # add the vowel annotation to the Label
            self.loadAnyVowel(self.exampleVowel.getF(), self.exampleVowel.annotation)
            #self.matchVowel.config(text=self.exampleVowel.getAnnotation())
            #self.setupGraph(self.defaultSetup.viz)
        self.parent.focus_force()

    # load a previously saved sound file
    def loadVowelSound(self):
        fileName = filedialog.askopenfilename()
        if (fileName) :
            # load the file into the sound object
            # disable record and enable play
            if (useTkSnack) :
                self.snd.flush()
                self.snd.read(fileName)
            self.recordButton.config(state=tk.NORMAL)
            self.playButton.config(state=tk.NORMAL)
            # load the filename into the annotation
            path, filename = os.path.split(fileName)
            self.matchVowel.config(text=filename)
            self.defaultSetup.soundFile = fileName
            self.defaultSetup.soundFilename = filename
        self.parent.focus_force()
    
    def clearVowel(self):
        self.exampleVowel = None
        self.defaultSetup.soundFile = ""
        self.defaultSetup.soundFilename = ""
        self.recordButton.config(state=tk.NORMAL)
        self.playButton.config(state=tk.NORMAL)
        # remove the vowel text from the Label
        self.matchVowel.config(text="")
        # undraw all the vowels - active and example
        self.graphModule.unDrawVowels()

    # CJR added an exit function
    def exitApp(self):
        # CJR how do we exit a Tcl application cleanly?
        self.parent.destroy()
        self.parent.quit()

    def modesHelp(self):
        f = open("modesHelp.txt", "r")
        msg = f.read()
        self.vowelAnnotationBox(msg, False)
    
    def showAbout(self):
        f = open("about.txt", "r")
        msg = f.read()
        # Use Cyndi's vowelAnnotationBox to display the about information
        self.vowelAnnotationBox(msg, False)

    # demo only - viz and vowel
    # demo changing of the matching vowel
    def loadi(self):
        formants = [ [274.2, 2022.0, 3012.4] ]
        self.loadAnyVowel(formants, "i")

    def loadI(self):
        formants = [ [268.8, 2353.4, 3420.8] ]
        self.loadAnyVowel(formants, "I")

    def loadE(self):
        formants = [ [492.7, 2088.3, 2656.1] ]
        self.loadAnyVowel(formants, "E")

    def loadae(self):
        formants = [ [753.9, 1619.9, 2494.4] ]
        self.loadAnyVowel(formants, "ae")

    def loadas(self):
        formants = [ [707.6, 1027.2, 2695.7] ]
        self.loadAnyVowel(formants, "as")

    def loado(self):
        formants = [ [405.6, 696.7, 2779.6] ]
        self.loadAnyVowel(formants, "o")

    def loadu(self):
        formants = [ [360.2, 858.6,  2654.7] ]
        self.loadAnyVowel(formants, "u")

    # load any vowel with formant and annotation
    def loadAnyVowel(self, formantList, annotation):
        self.defaultSetup.defFormants = formantList
        self.defaultSetup.defVowel = annotation
        self.loadDefaultVowel()
        # undraw all the old vowels - active and example
        self.graphModule.unDrawVowels()
        self.graphModule.drawMatchingViz(self.defaultSetup.defFormants)

    # load the vowel that is the application default vowel
    def loadDefaultVowel(self):
        f1 = self.defaultSetup.defFormants[0][0]
        f2 = self.defaultSetup.defFormants[0][1]
        f3 = self.defaultSetup.defFormants[0][2]
        self.exampleVowel = Vowel(f1, f2, f3, '')
        self.exampleVowel.setAnnotation(self.defaultSetup.defVowel)
        if (len(self.defaultSetup.soundFile)>0) :
            self.matchVowel.config(text=self.defaultSetup.soundFilename)
        else :
            self.matchVowel.config(text=self.defaultSetup.defVowel)

    # for demo vizs menu items
    def doGraph(self):
        self.setupGraph("Graph")

    def doTriangle(self):
        self.setupGraph("Triangle")

    def doOval(self):
        self.setupGraph("Oval")

    # Action menu items - the modes of the application
    # Practice mode - How should this work?
    def practiceMode(self):
        # if coming from the mentor mode reload the default vowel
        if (self.defaultSetup.mode == "Mentor") :
            self.loadDefaultVowel()
            self.graphModule.drawMatchingViz(self.defaultSetup.defFormants)
        # Practice mode should enable and disable the correct buttons
        # and should make sure that there is a vowel loaded
        if (self.exampleVowel) :
            # there is a sample vowel loaded - diable the Play button
            self.playButton.config(state=tk.DISABLED)
            self.recordButton.config(state=tk.NORMAL)
            # set the state in the defaault configuration
            self.defaultSetup.mode = "Practice"
        else :
            # no sample vowel let the user know to do this first
            messagebox.showinfo("Need to Load Vowel", "Practice Mode requires a vowel to be loaded. Please load a vowel with File->Load Vowel")
        self.parent.focus_force()

    # Mentor mode - How should this work?
    def mentorMode(self):
        # it should also clear all previous vowel drawings - clearVowels resets
        # the buttons - do it first
        self.clearVowel()
        # Then Mentor mode should enable and disable the correct buttons
        self.playButton.config(state=tk.DISABLED)
        self.recordButton.config(state=tk.NORMAL)
        # set the state in the defaault configuration
        self.defaultSetup.mode = "Mentor"

    # Study mode - How should this work
    def studyMode(self):
        # if coming from the mentor mode reload the default vowel
        if (self.defaultSetup.mode == "Mentor") :
            self.loadDefaultVowel()
            self.graphModule.drawMatchingViz(self.defaultSetup.defFormants)
        # Study mode should enable and disable the correct buttons
        # and should make sure that there is a vowel sound loaded
        if ( self.exampleVowel and len(self.defaultSetup.soundFile) > 0) :
            # there is a sample vowel sound selected - diable the record button
            self.recordButton.config(state=tk.DISABLED)
            self.playButton.config(state=tk.NORMAL)
            # load the sound file
            self.snd.read(self.defaultSetup.soundFile)
            # CJR also need to associate an annotation with the sound file somehow - name of file?
            # set the state in the defaault configuration
            self.defaultSetup.mode = "Study"
        else :
            # no sample vowel let the user know to do this first
            messagebox.showinfo("Need to Load Vowel Sound", "Study Mode requires a vowel to be loaded. Please load a vowel sound with File->Load Vowel Sound")
        self.parent.focus_force()

    # Review mode - How should this work
    def reviewMode(self):
        # if coming from the mentor mode reload the default vowel
        if (self.defaultSetup.mode == "Mentor") :
            self.loadDefaultVowel()
            self.graphModule.drawMatchingViz(self.defaultSetup.defFormants)
        # Review mode should enable and disable the correct buttons
        # and should make sure that there is a vowel loaded
        if (self.exampleVowel) :
            # there is a sample vowel loaded - diable the Play button
            self.recordButton.config(state=tk.DISABLED)
            self.playButton.config(state=tk.NORMAL)
            # set the state in the defaault configuration
            self.defaultSetup.mode = "Review"
        else :
            # no sample vowel let the user know to do this first
            messagebox.showinfo("Need to Load Vowel", "Review Mode requires a vowel to be loaded. Please load a vowel with File->Load Vowel")
        self.parent.focus_force()

    def testCanvas(self):
        box = g.Rectangle( Point(1,1), Point(99,74))
        box.draw(self.graphWin)

    # Button commands
    def record(self):
        print("in the record method ", self.id)
        if (self.recordButton["text"] == "Record") :
            self.recordButton.config(text="Stop")
            self.playButton.config(state=tk.DISABLED)
            # initialize the activeVowel
            self.activeVowel = Vowel(10,10,10,"")
            # CJR add in the tkSnack commands to start the recording
            if (useTkSnack) :
                self.snd.flush()
                self.snd.record()
            self.start()
        else:
            print("Stop")
            self.recordButton.config(text="Record")
            # check the state - do not make the Record button normal
            # when in Study/Review mode
            if (self.defaultSetup.mode == "Practice" or self.defaultSetup.mode == "Mentor") :
                self.playButton.config(state=tk.NORMAL)
            # CJR add in the tkSnack commands to stop the recording
            if (useTkSnack) :
                self.snd.stop()
            self.stop()
        print("exiting the record method ", self.id)

    def start(self):
        self.id = self.parent.after(100,self.draw)

    def stop(self):
        self.parent.after_cancel(self.id)

    def play(self):
        if self.playButton["text"] == "Play":
            self.playButton.config(text="Stop")
            self.recordButton.config(state=tk.DISABLED)
            if (useTkSnack) :
                self.snd.play()
        else:
            self.playButton.config(text="Play")
            self.recordButton.config(state=tk.NORMAL)
            if (useTkSnack) :
                self.snd.stop()

    # CJR window methods
    def draw(self):
        #print("draw ", self.id)
        if (useTkSnack) :
            if (self.snd.length() > self.sound_length) :
                self.sound_pos = self.snd.length() - self.sound_length
                formants = self.snd.formant(start=self.sound_pos,numformants=4, framelength=0.005, windowtype='Hanning', windowlength=0.024, lpctype=1)
                #print(formants[0][0], formants[0][1], formants[0][2], formants[0][3] )
                fSum = [ sum(x) for x in zip(*formants) ]
                fLength = len(formants)
                fAvg = [x/fLength for x in fSum]
                audioData = [ [ fAvg[0], fAvg[1], fAvg[2] ] ]
                formantList = [ fAvg[0], fAvg[1], fAvg[2] ]
                self.activeVowel.setF(formantList)
                #print(fLength, formantList)
            else :
            # CJR [f1, f2, f3] duplicate for now - change later when Mac works
                audioData = [
                         [274.2, 2022.0, 3012.4], #i
                         [268.8, 2353.4, 3420.8], #I
                         [492.7, 2088.3, 2656.1], #E
                         [753.9, 1619.9, 2494.4], #ae
                         [707.6, 1027.2, 2695.7], #\as
                         [405.6, 696.7, 2779.6], #o
                         [360.2, 858.6,  2654.7] #u
                         ]
        else:
        # [f1, f2, f3]
            audioData = [
                         [274.2, 2022.0, 3012.4], #i
                         [268.8, 2353.4, 3420.8], #I
                         [492.7, 2088.3, 2656.1], #E
                         [753.9, 1619.9, 2494.4], #ae
                         [707.6, 1027.2, 2695.7], #\as
                         [405.6, 696.7, 2779.6], #o
                         [360.2, 858.6,  2654.7] #u
                         ]

        if self.graphModule.useViz == "Graph" :
            self.graphModule.drawWithGraph(audioData)
        elif self.graphModule.useViz == "Oval" :
            self.graphModule.drawWithOval(audioData)
        elif self.graphModule.useViz == "Triangle" :
            self.graphModule.drawWithTriangle(audioData)

#        if (useTkSnack) :
#            if (self.snd.length(unit='sec') > 20) :
#                print("calling stop")
#                # CJR calling record as if it was clicked will stop the recording
#                # as the predetermined time.
#                self.record()
#                 # CJR let's see if pausing for a second helps the jitter display
#        time.sleep(0.25)
#        else :
#            time.sleep(1)

        self.id = self.parent.after(100,self.draw)

    # CJR how to stop the process when the window is closed with the X
    def close(self):
        self.parent.quit()

    # CJR undraw and draw the new configuration
    def setupGraph(self, viz):
        self.graphModule.unDrawVowels()
        self.graphModule.reDraw(viz)
        if self.graphModule.originViz :
            self.graphModule.axesDraw()
        if (self.defaultSetup.mode == "Practice") :
            self.graphModule.drawMatchingViz(self.exampleVowel.getF())

    # CJR application setup and configuration methods.
    def readConfiguration(self, filename):
        configVars = VowelShapeConfig(filename)
        #print(configVars.viz, configVars.mode)
        #print(configVars.defFormants, configVars.defVowel)
        return configVars

    # CJR pop up window to collect the name to save a vowel under
    # complements of
    # http://stackoverflow.com/questions/10057672/correct-way-to-implement-a-custom-popup-tkinter-dialog-box
    #
    def vowelAnnotationBox(self, msg='Enter an annotation for the Vowel', extra=True):
        top = self.top = tk.Toplevel(self)
        label0 = tk.Label(top, text=msg)
        label0.pack()

        if extra:
            self.entry0 = tk.Entry(top)
            self.entry0.pack()
            self.entry0.focus_set()

            button2 = tk.Button(top, text='Submit', command=self.submitVowelName)
            button2.pack()

        button3 = tk.Button(top, text='Cancel',
                                command=lambda: self.top.destroy())
        button3.pack()
        top.focus_force()

    def submitVowelName(self):
        data = self.entry0.get()
        if data:
            self.saveVowelAnnotation = data
            self.top.destroy()