Using a speech engine to highlight words: Difference between revisions
Content added Content deleted
(Using a speech engine to highlight words en FreeBASIC) |
(→{{header|Phix}}: syntax coloured, made p2js compatible, added online link) |
||
Line 203: | Line 203: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{libheader|Phix/pGUI}} |
|||
<lang Phix>-- demo/rosetta/Speech.exw |
|||
{{libheader|Phix/online}} |
|||
requires(WINDOWS) |
|||
You can run this online [http://phix.x10.mx/p2js/Speech.htm here]. |
|||
requires(32) -- Windows 32 bit only, for now... (runs fine on a 64-bit OS, but needs a 32-bit pw.exe) |
|||
<!--<lang Phix>(phixonline)--> |
|||
include pGUI.e |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
Ihandle t3, left, red, right, btn, bc, dlg |
|||
-- demo\rosetta\Speech.exw |
|||
-- ======================= |
|||
include pComN.ew |
|||
--</span> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
procedure speak(atom pVoice, string text, integer flags=NULL) |
|||
<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> |
|||
{} = cominvk(pVoice,ISpVoice_Speak,{unicode_string(text),flags,0}) |
|||
<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... |
|||
end procedure |
|||
-- (^ runs fine on a 64-bit OS, but needs a 32-bit p.exe)</span> |
|||
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.2"</span><span style="color: #0000FF;">)</span> |
|||
procedure set_interest(atom pVoice, sequence flags) |
|||
<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> |
|||
atom lo = #40000000, |
|||
hi = #00000002 |
|||
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
|||
for i=1 to length(flags) do |
|||
<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> |
|||
lo += power(2,flags[i]) |
|||
end for |
|||
<span style="color: #000080;font-style:italic;">-- not sure why, but a leading space really helps...</span> |
|||
-- NB 2*64-bit as 4*32-bit: |
|||
<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> |
|||
atom res = cominvk(pVoice,ISpVoice_SetInterest,{lo,hi,lo,hi}) |
|||
if res!=S_OK then crash("invalid") end if |
|||
<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> |
|||
end procedure |
|||
<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> |
|||
constant text = `<rate speed="-5">Highlight words as they are spoken.` |
|||
<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> |
|||
atom pVoice = NULL |
|||
<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> |
|||
include cffi.e |
|||
<span style="color: #7060A8;">IupRefresh</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">)</span> |
|||
constant tSPEVENT = """ |
|||
<span style="color: #7060A8;">IupRedraw</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">)</span> |
|||
typedef struct SPEVENT |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
{ |
|||
WORD eEventId; |
|||
<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> |
|||
WORD elParamType; |
|||
<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> |
|||
ULONG ulStreamNum; |
|||
<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> |
|||
ULONGLONG ullAudioStreamOffset; |
|||
<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> |
|||
WPARAM wParam; |
|||
<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> |
|||
LPARAM lParam; |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span> |
|||
} SPEVENT;""", |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
idSPEVENT = define_struct(tSPEVENT), |
|||
pSPEVENT = allocate_struct(idSPEVENT) |
|||
<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> |
|||
function eventHandler(atom wParam, lParam) |
|||
<span style="color: #000000;">left</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">()</span> |
|||
while cominvk(pVoice,ISpVoice_GetEvents,{1,pSPEVENT,NULL})=S_OK do |
|||
<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> |
|||
integer eEventId = get_struct_field(idSPEVENT,pSPEVENT,"eEventId") |
|||
<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> |
|||
if eEventId=SPEI_WORD_BOUNDARY then |
|||
<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> |
|||
integer len = get_struct_field(idSPEVENT,pSPEVENT,"wParam"), |
|||
<span style="color: #008000;">`FONT="Verdana, 18", MARGIN=0x20`</span><span style="color: #0000FF;">)</span> |
|||
pos = get_struct_field(idSPEVENT,pSPEVENT,"lParam") |
|||
<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> |
|||
IupSetStrAttribute(left,"TITLE",text[1..pos]) |
|||
<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> |
|||
IupSetStrAttribute(red,"TITLE",text[pos+1..pos+len]) |
|||
<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> |
|||
IupSetStrAttribute(right,"TITLE",text[pos+len+1..$]) |
|||
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span> |
|||
elsif eEventId=SPEI_END_INPUT_STREAM then |
|||
<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> |
|||
IupSetStrAttribute(left,"TITLE",text) |
|||
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span> |
|||
IupSetStrAttribute(red,"TITLE","") |
|||
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span> |
|||
IupSetStrAttribute(right,"TITLE","") |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
IupSetAttribute(left, "RASTERSIZE", "x0") |
|||
IupSetAttribute(red, "RASTERSIZE", "x0") |
|||
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span> |
|||
IupSetAttribute(right, "RASTERSIZE", "x0") |
|||
<!--</lang>--> |
|||
IupRefresh(t3) |
|||
IupRedraw(t3) |
|||
end while |
|||
return 0 |
|||
end function |
|||
constant cb_eventHandler = call_back(eventHandler) |
|||
function button_cb(Ihandle /*ih*/) |
|||
object res |
|||
if platform()=WINDOWS then |
|||
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 |
|||
procedure main() |
|||
IupOpen() |
|||
left = IupLabel("",`FONT="Verdana, 18"`) |
|||
red = IupLabel("",`FONT="Verdana, 18", FGCOLOR="255 0 0"`) |
|||
right = IupLabel(text,`FONT="Verdana, 18"`) |
|||
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") |
|||
IupShow(dlg) |
|||
IupMainLoop() |
|||
IupClose() |
|||
end procedure |
|||
main()</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |