def test3(self): """Change pitch, text, end utterance, text. wx.CallLater(500, speech.speak, [ speech.PitchCommand(offset=50), u"This is the first utterance in a higher pitch", speech.EndUtteranceCommand(), u"And this is the second" ]) Expected: All should be higher pitch. """ smi = SpeechManagerInteractions(self) sequence = [ speech.PitchCommand(offset=50), u"This is the first utterance in a higher pitch", # EndUtterance effectively splits the sequence, two sequence numbers are returned # from smi.speak for ease of adding expectations. smi.create_EndUtteranceCommand(expectedToBecomeIndex=1), smi.create_ExpectedProsodyCommand(speech.PitchCommand(offset=50)), u"And this is the second", smi.create_ExpectedIndex(expectedToBecomeIndex=2), ] with smi.expectation(): smi.speak(sequence) smi.expect_synthSpeak(0) with smi.expectation(): smi.indexReached(1) smi.pumpAll() smi.expect_synthSpeak(1)
def test_convertComplex(self): """Test converting a complex speech sequence to SSML. XML generation is already tested by TestXmlBalancer. However, SSML is what callers expect at the end of the day, so test converting a complex speech sequence to SSML. Depends on behavior tested by TestXmlBalancer. """ converter = speechXml.SsmlConverter("en_US") xml = converter.convertToXml([ "t1", speech.PitchCommand(multiplier=2), speech.VolumeCommand(multiplier=2), "t2", speech.PitchCommand(), speech.LangChangeCommand("de_DE"), speech.CharacterModeCommand(True), speech.IndexCommand(1), "c", speech.CharacterModeCommand(False), speech.PhonemeCommand("phIpa", text="phText") ]) self.assertEqual( xml, '<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">' 't1' '<prosody pitch="200%" volume="200%">t2</prosody>' '<prosody volume="200%"><voice xml:lang="de-DE">' '<mark name="1"/><say-as interpret-as="characters">c</say-as>' '<phoneme alphabet="ipa" ph="phIpa">phText</phoneme>' '</voice></prosody></speak>')
def generateBalancerCommands(self, speechSequence): commands = super(_OcPreAPI5SsmlConverter, self).generateBalancerCommands(speechSequence) # The EncloseAllCommand from SSML must be first. yield next(commands) # OneCore didn't provide a way to set base prosody values before API version 5. # Therefore, the base values need to be set using SSML. yield self.convertRateCommand(speech.RateCommand(multiplier=1)) yield self.convertVolumeCommand(speech.VolumeCommand(multiplier=1)) yield self.convertPitchCommand(speech.PitchCommand(multiplier=1)) for command in commands: yield command
def speakMathLine(self, spokenLine): spokenLine = EditableLatex.speech.translate (spokenLine) out = [] sups = 0 #How many superscripts we are in. subs = 0 #How many subscripts we are in. for expr in MATH_MATCHER.finditer(spokenLine): if expr.group(1) == "sup": sups+=1 #If there are any subscripts, do not pitch it, as we pitched the subscript. #If there are any superscripts nessted, don't pitch it, because voice control isn't good enough for this in NVDA. if sups == 1 and not subs: out.append(speech.PitchCommand(1.25)) out.append("soop") out.append(speech.BreakCommand(200)) elif expr.group(1) == "/sup": sups -= 1 out.append("End soop") if not sups and not subs: #we know we are in nothing. turn the pitch change off. out.append(speech.PitchCommand(1)) out.append(speech.BreakCommand(200)) elif expr.group(1) == "sub": subs += 1 if subs == 1 and sups == 0: out.append(speech.PitchCommand(.25)) out.append("sub") out.append(speech.BreakCommand(200)) elif expr.group(1) == "/sub": subs -= 1 out.append("End sub") if not subs and not sups: out.append(speech.PitchCommand(1)) out.append(speech.BreakCommand(200)) else: #all other math. Send er. out.append(expr.group(0)) speech.speak(out)
def test_1(self, mock_BeepCommand_run, mock_WaveFileCommand_run): r"""Text, beep, beep, sound, text. Manual Test (in NVDA python console): wx.CallLater(500, speech.speak, [ u"This is some speech and then comes a", speech.BeepCommand(440, 10), u"beep. If you liked that, let's ", speech.BeepCommand(880, 10), u"beep again. I'll speak the rest of this in a ", speech.PitchCommand(offset=50), u"higher pitch. And for the finale, let's ", speech.WaveFileCommand(r"waves\browseMode.wav"), u"play a sound." ]) """ smi = SpeechManagerInteractions(self) smi.addMockCallMonitoring( [mock_BeepCommand_run, mock_WaveFileCommand_run]) _beepCommand = smi.create_BeepCommand _waveFileCommand = smi.create_WaveFileCommand sequence = [ "This is some speech and then comes a", _beepCommand(440, 10, expectedToBecomeIndex=1), "beep. If you liked that, let's ", _beepCommand(880, 10, expectedToBecomeIndex=2), "beep again. I'll speak the rest of this in a ", speech.PitchCommand(offset=50), "higher pitch. And for the finale, let's ", _waveFileCommand(r"waves\browseMode.wav", expectedToBecomeIndex=3), "play a sound.", smi.create_ExpectedIndex(expectedToBecomeIndex=4) ] with smi.expectation(): smi.speak(sequence) smi.expect_synthSpeak(0) for i in range(1, 5): with smi.expectation(): smi.indexReached(i) smi.pumpAll() if i in [ 1, 2, ]: smi.expect_mockCall(mock_BeepCommand_run) if i in [ 3, ]: smi.expect_mockCall(mock_WaveFileCommand_run)
def test_4_profiles(self): """Text, pitch, text, enter profile1, enter profile2, text, exit profile1, text. Manual Test (in NVDA python console): import sayAllHandler, appModuleHandler t1 = sayAllHandler.SayAllProfileTrigger() t2 = appModuleHandler.AppProfileTrigger("notepad") wx.CallLater(500, speech.speak, [ u"Testing testing ", speech.PitchCommand(offset=100), "1 2 3 4", speech.ConfigProfileTriggerCommand(t1, True), speech.ConfigProfileTriggerCommand(t2, True), u"5 6 7 8", speech.ConfigProfileTriggerCommand(t1, False), u"9 10 11 12" ]) Expected: All text after 1 2 3 4 should be higher pitch. 5 6 7 8 should have profile 1 and 2. 9 10 11 12 should be just profile 2. """ t1 = InitialDevelopmentTests.FakeProfileTrigger("t1") t2 = InitialDevelopmentTests.FakeProfileTrigger("t2") smi = SpeechManagerInteractions(self) smi.addMockCallMonitoring([t1.enter, t1.exit, t2.enter, t2.exit]) seq = [ "Testing testing ", speech.PitchCommand(offset=100), "1 2 3 4", smi.create_ExpectedIndex(1), # The preceeding index is expected, # as the following profile trigger commands will cause the utterance to be split here. ConfigProfileTriggerCommand(t1, True), ConfigProfileTriggerCommand(t2, True), "5 6 7 8", smi.create_ExpectedIndex(2), # The preceeding index is expected, # as the following profile trigger commands will cause the utterance to be split here. ConfigProfileTriggerCommand(t1, False), "9 10 11 12" ] with smi.expectation(): smi.speak(seq) smi.expect_synthSpeak(sequence=seq[:4]) with smi.expectation(): smi.indexReached(1) smi.pumpAll() with smi.expectation(): smi.doneSpeaking() smi.pumpAll() smi.expect_synthCancel() smi.expect_mockCall(t1.enter) smi.expect_synthCancel() smi.expect_mockCall(t2.enter) smi.expect_synthSpeak(sequence=[ seq[1], # PitchCommand '5 6 7 8', seq[7], # IndexCommand index=2 (due to a ConfigProfileTriggerCommand following it) ]) with smi.expectation(): smi.indexReached(2) smi.pumpAll() with smi.expectation(): smi.doneSpeaking() smi.pumpAll() smi.expect_synthCancel() smi.expect_synthSpeak(sequence=[ seq[1], # PitchCommand '9 10 11 12', smi.create_ExpectedIndex(expectedToBecomeIndex=3) ]) smi.expect_mockCall(t1.exit) with smi.expectation(): smi.indexReached(3) smi.pumpAll() with smi.expectation(): smi.doneSpeaking() smi.pumpAll() smi.expect_synthCancel() smi.expect_mockCall(t2.exit)
def test_expectedProsodyNotMatching(self): p = speech.PitchCommand(offset=2) e = ExpectedProsody(speech.PitchCommand(offset=5)) self.assertNotEqual(p, e)