Using a speech engine to highlight words: Difference between revisions

m
m (→‎{{header|Phix}}: clarification)
m (→‎{{header|Wren}}: Minor tidy)
 
(18 intermediate revisions by 11 users not shown)
Line 14:
We use the simple SAPI.SPVoice COM Object and a parsing loop.
The highlighting is done with [http://msdn.microsoft.com/en-us/library/bb761661 EM_SETSEL] and Notepad. Rather crude, but it works. Due to the simplistic nature of the parsing loop, the text ends with a space.
<langsyntaxhighlight AutoHotkeylang="autohotkey">SetTitleMatchMode 2
EM_SETSEL := 0x00B1
 
Line 32:
}
Else word .= lf, i++
}</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
FreeBASIC does not have a native command for them.
 
We are going to invoke vbscript directly
<syntaxhighlight lang="freebasic">''This works on Windows. Does anyone know how it would be done in Linux?
 
Sub Speak(Texto As String)
Shell "mshta vbscript:Execute(""CreateObject(""""SAPI.SpVoice"""").Speak("""""+Texto+""""")(window.close)"")"
End Sub
 
Function Split(Texto As String, SplitL As String, Direcc As Byte = 0) As String
Dim As Integer LocA = Instr(Texto, SplitL)
Return Iif(Direcc <= 0, Left(Texto, LocA), Right(Texto, Len(Texto) - LocA))
End Function
 
Dim As String texto = "Actions speak louder than words"
Dim As String palabra()
Dim As Integer cont = -1
Do
cont += 1
Redim Preserve palabra(cont)
palabra(cont) = Split(texto," ")
texto = Right(texto, Len(texto)-Len(palabra(cont)))
If Len(palabra(cont)) = 0 Then palabra(cont) = texto : Exit Do
Loop
 
For n As Integer = 0 To Ubound(palabra)
Print palabra(n)
Speak palabra(n)
Next n</syntaxhighlight>
 
 
=={{header|Go}}==
Line 40 ⟶ 73:
 
Very robotic but it works.
<langsyntaxhighlight lang="go">package main
 
import (
Line 70 ⟶ 103:
time.Sleep(time.Second)
fmt.Printf("%s%s\n", bs, prev)
}</langsyntaxhighlight>
 
 
=={{header|Julia}}==
{{trans|Go}}
<syntaxhighlight lang="julia">function speak(sentence, cmd = "/utl/espeak.bat")
for word in split(sentence)
s = replace(lowercase(word), r"[^a-z]" => "")
if length(s) > 0
print(uppercase(s))
run(`$cmd $s`)
sleep(1)
print("\b"^length(s))
end
print(word, " ")
end
end
 
speak("Are those 144 shy Eurasian footwear, cowboy chaps, or jolly earthmoving headgear?")
</syntaxhighlight>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module UsingEvents {
Form 60, 32
Line 94 ⟶ 146:
Call Local LocalTxt()
Function sp_Word {
Read New &StreamNumber, &StreamPosition, &CharacterPosition, &Length
Call Local LocalTxt()
Cursor 0, height/2
Line 115 ⟶ 167:
UsingEvents
 
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="text">DynamicModule[{text = "This is some text.", words, i = 0},
Panel@Column@{Dynamic[
Row[Riffle[
Line 125 ⟶ 177:
Button["Speak",
While[i < Length@words, i++; FinishDynamic[]; Speak[words[[i]]];
Pause[Max[0.7, 0.12 StringLength[words[[i]]]]]]; i = 0]}]</langsyntaxhighlight>
 
=={{header|PhixNim}}==
{{trans|Go}}
Requires 0.8.2+, and as-is, this will only work on Windows 32 bit (sorry)<br>
Works on Linux but may also work on other platforms provided "espeak" is installed.
(You can of course run it on a 64-bit OS using a 32-bit version of the compiler/interpreter.)
<syntaxhighlight lang="nim">import os, osproc, strutils
<lang Phix>-- demo/rosetta/Speech.exw
include pGUI.e
Ihandle t3, left, red, right, btn, bc, dlg
 
const S = "Actions speak louder than words."
include pComN.ew
 
var prev, bs = ""
procedure speak(atom pVoice, string text, integer flags=NULL)
var prevlen = 0
{} = cominvk(pVoice,ISpVoice_Speak,{unicode_string(text),flags,0})
end procedure
 
for word in S.splitWhitespace():
procedure set_interest(atom pVoice, sequence flags)
discard execProcess("espeak " & word)
atom lo = #40000000,
if prevlen > 0:
hi = #00000002
forbs i=1 torepeat('\b', length(flagsprevlen) do
stdout.write bs, prev, word.toUpper, ' '
lo += power(2,flags[i])
stdout.flushFile()
end for
prev = word & ' '
-- NB 2*64-bit as 4*32-bit:
prevlen = word.len + 1
atom res = cominvk(pVoice,ISpVoice_SetInterest,{lo,hi,lo,hi})
if res!=S_OK then crash("invalid") end if
end procedure
 
bs = repeat('\b', prevlen)
constant text = `<rate speed="-5">Highlight words as they are spoken.`
sleep(1000)
atom pVoice = NULL
echo bs, prev</syntaxhighlight>
 
=={{header|Phix}}==
include cffi.e
{{libheader|Phix/pGUI}}
constant tSPEVENT = """
{{libheader|Phix/online}}
typedef struct SPEVENT
You can run this online [http://phix.x10.mx/p2js/Speech.htm here].
{
<!--<syntaxhighlight lang="phix">(phixonline)-->
WORD eEventId;
<span style="color: #000080;font-style:italic;">--
WORD elParamType;
-- demo\rosetta\Speech.exw
ULONG ulStreamNum;
-- =======================
ULONGLONG ullAudioStreamOffset;
--</span>
WPARAM wParam;
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
LPARAM lParam;
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #000000;">6</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- WINDOWS or JS, not LINUX</span>
} SPEVENT;""",
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #000000;">32</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- Windows 32 bit only, for now...
idSPEVENT = define_struct(tSPEVENT),
-- (^ runs fine on a 64-bit OS, but needs a 32-bit p.exe)</span>
pSPEVENT = allocate_struct(idSPEVENT)
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.2"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #7060A8;">speak</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #000080;font-style:italic;">-- (new in 1.0.2)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">left</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">red</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">right</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">btn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hbc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dlg</span>
<span style="color: #000080;font-style:italic;">-- not sure why, but a leading space really helps...</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">text</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">` Highlight words as they are spoken.`</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">speech_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">left</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">red</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">+</span><span style="color: #000000;">len</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">right</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">+</span><span style="color: #000000;">len</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$])</span>
<span style="color: #7060A8;">IupSetAttributes</span><span style="color: #0000FF;">({</span><span style="color: #000000;">left</span><span style="color: #0000FF;">,</span><span style="color: #000000;">red</span><span style="color: #0000FF;">,</span><span style="color: #000000;">right</span><span style="color: #0000FF;">},</span> <span style="color: #008000;">"RASTERSIZE=x0"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupRefresh</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupRedraw</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">button_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">rate</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">WINDOWS</span><span style="color: #0000FF;">?-</span><span style="color: #000000;">5</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">-- -10..+10, voice dependent</span>
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">0.3</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">-- 0.1..10, 0.5 = half speed</span>
<span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- linux, anyone?...</span>
<span style="color: #7060A8;">speak</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rate</span><span style="color: #0000FF;">,</span><span style="color: #000000;">speech_cb</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">left</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">red</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`FGCOLOR="255 0 0"`</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">right</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">t3</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupHbox</span><span style="color: #0000FF;">({</span><span style="color: #7060A8;">IupFill</span><span style="color: #0000FF;">(),</span><span style="color: #000000;">left</span><span style="color: #0000FF;">,</span><span style="color: #000000;">red</span><span style="color: #0000FF;">,</span><span style="color: #000000;">right</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupFill</span><span style="color: #0000FF;">()},</span>
<span style="color: #008000;">`FONT="Verdana, 18", MARGIN=0x20`</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">btn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupButton</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Speak"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"button_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">hbc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupHbox</span><span style="color: #0000FF;">({</span><span style="color: #7060A8;">IupFill</span><span style="color: #0000FF;">(),</span><span style="color: #000000;">btn</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupFill</span><span style="color: #0000FF;">()},</span><span style="color: #008000;">"MARGIN=0x10"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">IupVbox</span><span style="color: #0000FF;">({</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">hbc</span><span style="color: #0000FF;">}),</span><span style="color: #008000;">"TITLE=Speak"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
 
=={{header|Raku}}==
function eventHandler(atom wParam, lParam)
{{trans|Go}}
while cominvk(pVoice,ISpVoice_GetEvents,{1,pSPEVENT,NULL})=S_OK do
<syntaxhighlight lang="raku" line># 20200826 Raku programming solution
integer eEventId = get_struct_field(idSPEVENT,pSPEVENT,"eEventId")
if eEventId=SPEI_WORD_BOUNDARY then
integer len = get_struct_field(idSPEVENT,pSPEVENT,"wParam"),
pos = get_struct_field(idSPEVENT,pSPEVENT,"lParam")
IupSetStrAttribute(left,"TITLE",text[1..pos])
IupSetStrAttribute(red,"TITLE",text[pos+1..pos+len])
IupSetStrAttribute(right,"TITLE",text[pos+len+1..$])
elsif eEventId=SPEI_END_INPUT_STREAM then
IupSetStrAttribute(left,"TITLE",text)
IupSetStrAttribute(red,"TITLE","")
IupSetStrAttribute(right,"TITLE","")
end if
IupSetAttribute(left, "RASTERSIZE", "x0")
IupSetAttribute(red, "RASTERSIZE", "x0")
IupSetAttribute(right, "RASTERSIZE", "x0")
IupRefresh(t3)
IupRedraw(t3)
end while
return 0
end function
constant cb_eventHandler = call_back(eventHandler)
 
my \s = "Actions speak louder than words.";
function button_cb(Ihandle /*ih*/)
my \prev = $ object= res"";
my \prevLen = $ = 0;
if platform()=WINDOWS then
my \bs = $ = "";
if pVoice=NULL then
pVoice = allocate(machine_word())
res = CoCreateInstance(CLSID_SpVoice,IID_ISpVoice,pVoice)
if res!=S_OK then
crash("Failed to initialize SpeechAPI. (%08x)\n",res)
end if
end if
if cominvk(pVoice,ISpVoice_SetNotifyCallbackFunction,{cb_eventHandler,0,0})!=S_OK then ?9/0 end if
set_interest(pVoice, {SPEI_WORD_BOUNDARY,SPEI_END_INPUT_STREAM})
speak(pVoice,text,SPF_IS_XML+SPF_ASYNC)
else
-- DEV no highlighting here...
{} = system_exec(sprintf(`espeak "%s"`,{text}))
end if
return IUP_CONTINUE
end function
 
for s.split(' ', :skip-empty) {
procedure main()
run "/usr/bin/espeak", $_ or die;
IupOpen()
bs = "\b" x prevLen if prevLen > 0;
left = IupLabel("",`FONT="Verdana, 18"`)
printf "%s%s%s ", bs, prev, $_.uc;
red = IupLabel("",`FONT="Verdana, 18", FGCOLOR="255 0 0"`)
prev = "$_ ";
right = IupLabel(text,`FONT="Verdana, 18"`)
prevLen = $_.chars + 1
t3 = IupHbox({IupFill(),left,red,right,IupFill()},"MARGIN=20x20")
}
btn = IupButton("Speak",Icallback("button_cb"))
bc = IupHbox({IupFill(),btn,IupFill()},"MARGIN=10x10")
dlg = IupDialog(IupVbox({t3,bc}),"TITLE=Speak")
IupCloseOnEscape(dlg)
IupShow(dlg)
IupMainLoop()
IupClose()
end procedure
 
printf "%s%s\n", "\b" x prevLen, prev;</syntaxhighlight>
main()</lang>
 
=={{header|REXX}}==
Line 234 ⟶ 286:
 
Each word of the text is highlighted (by showing the word in uppercase). &nbsp; the terminal screen is cleared before showing the text that is being spoken; &nbsp; the repeated calls to the (Windows) speech engine makes for a slower speech rate.
<langsyntaxhighlight lang="rexx">/*REXX program uses a command line interface to invoke Windows SAM for speech synthesis.*/
parse arg t /*get the (optional) text from the C.L.*/
#= words(t)
Line 251 ⟶ 303:
oneWord= dq x dq /*surround a word in double quotes (").*/
'NIRCMD' "speak text" oneWord rate /*NIRCMD invokes Microsoft's Sam voice*/
end /*j*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
Note: &nbsp; The name of the above REXX program is &nbsp; '''SPEAKHI.REX'''<br>
 
Line 257 ⟶ 309:
<pre>
speakhi This is an example of speech synthesis.
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
load "guilib.ring"
 
MyApp = New qApp {
 
win1 = new qWidget() {
 
setwindowtitle("Hello World")
setGeometry(100,100,370,250)
 
Text = "Welcome to the Ring Programming Language"
Text = split(Text," ")
 
label1 = new qLabel(win1) {
settext("What is your name ?")
setGeometry(10,20,350,30)
setalignment(Qt_AlignHCenter)
}
 
btn1 = new qpushbutton(win1) {
setGeometry(10,200,100,30)
settext("Say Hello")
setclickevent("pHello()")
}
 
btn2 = new qpushbutton(win1) {
setGeometry(150,200,100,30)
settext("Close")
setclickevent("pClose()")
}
 
lineedit1 = new qlineedit(win1) {
setGeometry(10,100,350,30)
}
 
voice = new QTextToSpeech(win1) {
}
show()
}
exec()}
 
Func pHello
lineedit1.settext( "Hello " + lineedit1.text())
for n = 1 to len(Text)
voice.Say(Text[n])
see Text[n] + nl
next
 
Func pClose
MyApp.quit()
</syntaxhighlight>
{{out}}
<pre>
Welcome
to
the
Ring
Programming
Language
</pre>
 
Line 264 ⟶ 378:
 
Uses the Ruby code from [[Speech synthesis]]
<langsyntaxhighlight lang="ruby">load 'speechsynthesis.rb'
 
if ARGV.length == 1
Line 294 ⟶ 408:
@sentence.replace($words.each_with_index.map {|word, idx| idx == @idx ? strong(word + " ") : span(word + " ")})
end
end</langsyntaxhighlight>
 
=={{header|Tcl}}==
This code uses the external <code>/usr/bin/say</code> program (known available on Mac OS X) as its interface to the speech engine; this produces rather stilted speech because it forces the text to be spoken one word at a time instead of as a whole sentence (in order to keep the highlighting synchronized).
{{libheader|Tk}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
package require Tk 8.5
proc say {text button} {
Line 323 ⟶ 437:
pack [text .t]
pack [button .b -text "Speak, computer!" -command {say .t .b}] -fill x
.t insert 1.0 "This is an example of speech synthesis with Tcl/Tk."</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-str}}
The ability to call external processes such as ''espeak'' is expected to be added to Wren-cli in the next release. In the meantime, we embed the following Wren script in a minimal C host (no error checking) to complete this task.
<syntaxhighlight lang="wren">/* Using_a_speech_engine_to_highlight_words.wren */
 
import "./str" for Str
 
class C {
foreign static usleep(usec)
 
foreign static espeak(s)
 
foreign static flushStdout()
}
 
var s = "Actions speak louder than words."
var prev = ""
var prevLen = 0
var bs = ""
for (word in s.split(" ")) {
if (prevLen > 0) bs = "\b" * prevLen
System.write("%(bs)%(prev)%(Str.upper(word)) ")
C.flushStdout()
C.espeak(word)
prev= word + " "
prevLen = word.count + 1
}
bs = "\b" * prevLen
C.usleep(1000)
System.print("%(bs)%(prev)")</syntaxhighlight>
<br>
We now embed this in the following C program, compile and run it.
<syntaxhighlight lang="c">/* gcc Using_a_speech_engine_to_highlight_words.c -o Using_a_speech_engine_to_highlight_words -lwren -lm */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "wren.h"
 
void C_usleep(WrenVM* vm) {
useconds_t usec = (useconds_t)wrenGetSlotDouble(vm, 1);
usleep(usec);
}
 
void C_espeak(WrenVM* vm) {
const char *arg = wrenGetSlotString(vm, 1);
char command[strlen(arg) + 10];
strcpy(command, "espeak \"");
strcat(command, arg);
strcat(command, "\"");
system(command);
}
 
void C_flushStdout(WrenVM* vm) {
fflush(stdout);
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "usleep(_)") == 0) return C_usleep;
if (isStatic && strcmp(signature, "espeak(_)") == 0) return C_espeak;
if (isStatic && strcmp(signature, "flushStdout()") == 0) return C_flushStdout;
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
if( result.source) free((void*)result.source);
}
 
WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0};
if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) {
result.onComplete = loadModuleComplete;
char fullName[strlen(name) + 6];
strcpy(fullName, name);
strcat(fullName, ".wren");
result.source = readFile(fullName);
}
return result;
}
 
int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.bindForeignMethodFn = &bindForeignMethod;
config.loadModuleFn = &loadModule;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "Using_a_speech_engine_to_highlight_words.wren";
char *script = readFile(fileName);
wrenInterpret(vm, module, script);
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
 
{{omit from|EasyLang}}
9,476

edits