22
$\begingroup$

I want to use an event handler to stop speaking:

Speak[ExampleData[{"Text", "DonQuixoteISpanish"}]]

The only way I can stop this is by restarting mathematica!

$\endgroup$
6
  • $\begingroup$ Quit[] has no effect $\endgroup$
    – M.R.
    Commented Aug 22, 2012 at 20:04
  • 1
    $\begingroup$ Fascinating - and if you execute something like Speak["test test test"]; Print["hi"], it executes the Print command before the first word is even spoken. $\endgroup$ Commented Aug 22, 2012 at 20:21
  • $\begingroup$ Yeah, it looks like everything is pushed to a queue that is then inaccessible. Quit[] won't have any effect because all of this is done by the FE (which is why you have to quit Mathematica to make it stop). I wonder if there is some hidden/undocumented token that can be used with FrontEndExecute... $\endgroup$
    – rm -rf
    Commented Aug 22, 2012 at 21:02
  • 11
    $\begingroup$ Have you tried ShutUp[]? $\endgroup$
    – acl
    Commented Aug 23, 2012 at 17:44
  • $\begingroup$ Reminds me of the render queue, it too is uninterruptable. $\endgroup$
    – rcollyer
    Commented Aug 23, 2012 at 20:36

2 Answers 2

19
$\begingroup$

Running Trace[Speak["Hello"]] and Names["*Speak*"] revealed the following possibility:

MathLink`CallFrontEnd[CurrentlySpeakingPacket]

Using this with a text that is split into a list of shorter strings allows you to interrupt the audio at well-defined points, phrase breaks, say. Here is one way to do it:

Clear[interruptibleSpeak]; 
interruptibleSpeak[text_String] := Module[{phrases}, 
   phrases = StringSplit[
      StringReplace[text, (# -> # <> "\n") & /@ {".", ";", "!", "?"}], "\n"];
   Do[While[MathLink`CallFrontEnd[CurrentlySpeakingPacket], Pause[0.1]];
     Speak[phrases[[i]]], {i, Length@phrases}]
]

You can now interrupt the computer in the usual way (Command. on Mac, Alt. on PC):

interruptibleSpeak[ExampleData[{"Text", "DonQuixoteISpanish"}]]

Now, of course, you do not get asynchronous speaking, so subsequent evaluations have to wait for the last phrase to be queued to execute.

Note This solution was tested on version 8.04, and is reported not to work on version 7.

$\endgroup$
7
  • 6
    $\begingroup$ Oy, first class spelunking! $\endgroup$
    – Yves Klett
    Commented Aug 23, 2012 at 19:54
  • $\begingroup$ Nuts! This doesn't work on version 7 and I have a session open I don't want to close out at the moment. Mute for however long DonQuixoteISpanish is. :-p $\endgroup$
    – Mr.Wizard
    Commented Aug 24, 2012 at 8:02
  • $\begingroup$ @Mr.Wizard Is it a V7 issue or a Windows/Mac issue? (I'm running Mac OS X) $\endgroup$
    – JxB
    Commented Aug 24, 2012 at 14:58
  • $\begingroup$ I don't know, I haven't fiddled with it again. I don't think I've ever had a practical application for Speak so this is not a high priority, but I'll try to return to this later to see if it can be mended for v7. $\endgroup$
    – Mr.Wizard
    Commented Aug 24, 2012 at 15:07
  • 3
    $\begingroup$ @Mr.Wizard However, it is very useful. Try Speak[Array["I should migrate to v8"&, 10]] $\endgroup$ Commented Aug 28, 2012 at 3:12
-1
$\begingroup$

To stop the Speak function in Mathematica, you can use SpeakStop. Here is how you can use an event handler to stop the Speak function:

First, start speaking the text. Use an event handler, such as a button, to stop the speaking. Here's how you can do it:

DynamicModule[{},
 Column[{
   Button["Start Speaking", Speak[ExampleData[{"Text", "DonQuixoteISpanish"}]]],
   Button["Stop Speaking", SpeakStop[]]
 }]

In this example, there are two buttons. Clicking the "Start Speaking" button will start the Speak function, and clicking the "Stop Speaking" button will stop it.

Alternatively, if you want to use an event handler programmatically without using a button, you could define a function to stop speaking:

startSpeaking := Speak[ExampleData[{"Text", "DonQuixoteISpanish"}]]
stopSpeaking := SpeakStop[]

(* Start speaking *)
startSpeaking

(* Stop speaking after 5 seconds *)
Pause[5]
stopSpeaking

    ]

This script will start speaking and then stop after 5 seconds.

$\endgroup$
1
  • $\begingroup$ Please stop posting wrong AI-generated answers. $\endgroup$
    – Domen
    Commented Jun 22 at 0:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.