Page 1 of 2

Speech recognition

Posted: Sat Sep 20, 2025 7:03 pm
by jak64
Hello everyone,
I tested the Infratec program "WebViewGadget PermissionRequested callback"

viewtopic.php?p=628744&hilit=voice+recognition#p628744

I started my camera on the PC, launched the program, and spoke: What I said was displayed in the small window on the screen, but in English.

How can I get it to recognize French?

I would like to use it to write a quiz creation program so that I can directly record the questions while speaking, and have my program create the corresponding text.

Thank you for your help.

Re: Speech recognition

Posted: Sat Sep 20, 2025 7:41 pm
by infratec
Read the code and then change the line:

Code: Select all

 recognition.lang = 'en-US';\n" +
Maybe fr-FR is the correct selector.

Re: Speech recognition

Posted: Sat Sep 20, 2025 9:45 pm
by jak64
Of course !
Thank you infratec...

I would like to add a button so that the program only does speech recognition when I press this button and stops when I press it a second time. Where should I put this button in the code?

Re: Speech recognition

Posted: Sat Sep 20, 2025 10:35 pm
by infratec
It depends what you want.

Only stop the text output:
Use a global variable and use an if inside OutputJS()
Or use UnbindWebViewCallback() and BindWebViewCallback()

Stop it completely:
Use SetGadgetItemText() to set an empty wep page and use SetGadgetText() again to load the page again.

Re: Speech recognition

Posted: Sun Sep 21, 2025 8:56 am
by jak64
Hello Infratec,
Thank you for your answers. I'll try to modify the code accordingly.
I don't have your incredible knowledge of what can be done with PureBasic (which I love), and it's very kind of you to take the time to help me.

I'm going to add seven buttons: one to ask the question, four for the four suggestions, one for the answer, and a seventh to possibly provide an explanation of the answer.

If I don't succeed, I'll get back to you.

Re: Speech recognition

Posted: Sun Sep 21, 2025 9:56 am
by jak64
Hello Infratec,
I've noticed that if I don't speak for a while, the voice recognition stops. How can I prevent this from happening (or, alternatively, how can I restart it?)

Thank you.

Re: Speech recognition

Posted: Sun Sep 21, 2025 3:40 pm
by infratec
I don't use this stuff personally. I helped only dige to solve a problem.

But ...

Here is the description of the API
https://developer.mozilla.org/en-US/doc ... ecognition

And maybe this solves the problem:

Code: Select all

Html$ = ~"<!DOCTYPE html>\n" +
          ~"<html lang=en>\n" +
          ~" <head>\n" +
          ~"  <title>Voice To Text</title>\n" +
          ~" </head>\n" +
          ~" <body>\n" +
          ~"  <div id=\"output\"></div>\n" +
          ~"  \n" +
          ~"  <script>\n" +
          ~"   const outputDiv = document.getElementById('output');\n" +
          ~"   \n" +
          ~"   const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition)();\n" +
          ~"   recognition.lang = 'en-US';\n" +
          ~"   recognition.continuous = true;\n" +
          ~"   recognition.interimResults = false;\n" +
          ~"   recognition.maxAlternatives = 1;\n" +
          ~"   recognition.start();\n" +
          ~"   \n" +
          ~"   recognition.onresult = (event) => {\n" +
          ~"    const transcript = event.results[event.resultIndex][0].transcript;\n" +
          ~"    outputDiv.textContent = transcript;\n" +
          ~"    window.output(transcript);\n" +
          ~"   };\n" +
          ~"   recognition.onend = (event) => {\n" +
          ~"    outputDiv.textContent = 'END';\n" +
          ~"    recognition.start()\n" +
          ~"   };\n" +
          ~"   \n" +
          ~"  </script>\n" +
          ~" </body>\n" +
          ~"</html>\n"
It should restart the recognition if an END event is reached.

Re: Speech recognition

Posted: Sun Sep 21, 2025 4:13 pm
by jak64
Great Infratec, it's OK, voice recognition works even if you don't speak for a long time! Well done!

Re: Speech recognition

Posted: Sun Sep 21, 2025 4:17 pm
by jak64
Here's the program I adapted. Since I don't understand the speech recognition code, I haven't modified it; perhaps this program can be simplified.

This program allows you to record multiple-choice questions by speaking.

Of course, I'll then put all this into a database.

Code: Select all

;
; https://www.purebasic.fr/english/viewtopic.php?p=628744
;

;----- Options
EnableExplicit

;----- Déclaration des procédures
Declare afficher_gadgets()
Declare afficher_tous_les_boutons()
Declare cacher_tous_les_boutons()
Declare creer_gadgets()

;----- Constantes
#couleur_fond_fenetre = $85E6EE
#couleur_fond_texte = $5F3A1E
#couleur_texte = $F0F0F0
#largeur_jeu = 1366
#hauteur_jeu = 768


;----- Variables
Global bt_proposition_1.i
Global bt_proposition_2.i
Global bt_proposition_3.i
Global bt_proposition_4.i
Global bt_question.i          ; Bouton à appuyer pour enregistrer la question
Global bt_quitter.i
Global bt_reponse.i
Global bt_theme.i
Global fenetre_windows.i
Global gadget_id.i
Global police_14.i
Global police_18.i
Global quitter.b
Global txt_proposition_1.i
Global txt_proposition_2.i
Global txt_proposition_3.i
Global txt_proposition_4.i
Global txt_question.i         ; Zone de texte où s'affichera la question
Global txt_reponse.i
Global txt_theme.i            ; Zone de texte où s'affichera le thème       
Global web_gadget.i

;----- Polices
police_18 = LoadFont(#PB_Any, "verdana", 18)
police_14 = LoadFont(#PB_Any, "verdana", 14)


CompilerIf Not Defined(IID_IUnknown, #PB_Label)
  DataSection
    IID_IUnknown:
    Data.l $00000000
    Data.w $0000, $0000
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46
  EndDataSection
CompilerEndIf

CompilerIf Not Defined(IUnknownBase_Structure, #PB_Structure)
  Structure IUnknownBase_Structure
    *pVtable
    lRefCount.l
    *pQueryInterface
    *pAddRef
    *pRelease
  EndStructure
CompilerEndIf


Prototype.i WebViewPermissionCallBack_Prototype(Type.i)

Structure ICoreWebView2PermissionRequestedEventHandler_Structure Extends IUnknownBase_Structure
  *pInvoke
  Token.q
  *pCallback.WebViewPermissionCallBack_Prototype
EndStructure


Global NewMap WebViewPermissionRequestedEventHandlerMap.ICoreWebView2PermissionRequestedEventHandler_Structure()




Procedure.l ICoreWebView2PermissionRequestedEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  
  Protected Result.l
  
  
  ;Debug "WebView PermissionRequested QueryInterface"
  
  Result = #S_OK
  
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      Result = #E_NOINTERFACE
    EndIf
  Else
    Result = #E_POINTER
  EndIf
  
  ProcedureReturn Result
  
EndProcedure




Procedure.l ICoreWebView2PermissionRequestedEventHandler_AddRef(*this.IUnknownBase_Structure)
  
  ;Debug "WebView PermissionRequested AddRef"
  
  *this\lRefCount + 1
  
  ProcedureReturn *this\lRefCount
  
EndProcedure




Procedure.l ICoreWebView2PermissionRequestedEventHandler_Release(*this.IUnknownBase_Structure)
  
  ;Debug "WebView PermissionRequested Release"
  
  *this\lRefCount - 1
  
  ProcedureReturn *this\lRefCount
  
EndProcedure




Enumeration COREWEBVIEW2_PERMISSION_KIND
  #UnknownPermission = 0            ; Indicates an unknown permission.
  #Microphone = 1                   ; Indicates permission To capture audio.
  #Camera =	2                       ; Indicates permission To capture video.
  #Geolocation = 3                  ; Indicates permission To access geolocation.
  #Notifications = 4                ; Indicates permission To send web notifications. Apps that would like To show notifications should handle PermissionRequested And/Or PermissionRequested events And no browser permission prompt will be shown For notification requests. Note that push notifications are currently unavailable in WebView2.
  #OtherSensors = 5                 ; Indicates permission To access generic sensor. Generic Sensor covers ambient-light-sensor, accelerometer, gyroscope, And magnetometer.
  #ClipboardRead = 6                ; Indicates permission To Read the system clipboard without a user gesture.
  #MultipleAutomaticDownloads = 7   ; Indicates permission To automatically download multiple files. Permission is requested when multiple downloads are triggered in quick succession.
  #FileReadWrite =	8               ; Indicates permission To Read And write To files Or folders on the device. Permission is requested when developers use the File System Access API To show the file Or folder picker To the End user, And then request "readwrite" permission For the user's selection.
  #Autoplay = 9                     ; Indicates permission To play audio And video automatically on sites. This permission affects the autoplay attribute And play method of the audio And video HTML elements, And the start method of the Web Audio API. See the Autoplay guide For media And Web Audio APIs For details.
  #LocalFonts = 10                  ; Indicates permission To use fonts on the device. Permission is requested when developers use the Local Font Access API To query the system fonts available For styling web content.
  #MidiSystemExclusiveMessages = 11 ; Indicates permission To send And receive system exclusive messages To/from MIDI (Musical Instrument Digital Interface) devices. Permission is requested when developers use the Web MIDI API To request access To system exclusive MIDI messages.
  #WindowManagement = 12            ; Indicates permission to open and place windows on the screen. Permission is requested when developers use the Multi-Screen Window Placement API to get screen details.
EndEnumeration


Enumeration COREWEBVIEW2_PERMISSION_STATE
  #Default = 0  ; Specifies that the Default browser behavior is used, which normally prompts users For decision.
  #Allow = 1    ; Specifies that the permission request is granted.
  #Deny = 2     ; Specifies that the permission request is denied.
EndEnumeration


Procedure.l ICoreWebView2PermissionRequestedEventHandler_Invoke(*this.ICoreWebView2PermissionRequestedEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2PermissionRequestedEventArgs)
  
  Protected PermissionKind.i, *def.ICoreWebView2Deferral, State.i
  
  
  ;Debug "WebView PermissionRequested Invoke"
  
  *args\GetDeferral(@*def)
  If *args\get_PermissionKind(@PermissionKind) = #S_OK
    State = *this\pCallback(PermissionKind)
    *args\put_State(State)
  EndIf
  *def\Complete()
  
  ProcedureReturn #S_OK
  
EndProcedure




Procedure WebViewRemovePermissionRequestedCallback(WebView.i, Core.ICoreWebView2)
  
  If FindMapElement(WebViewPermissionRequestedEventHandlerMap(), Str(WebView))
    
    If WebViewPermissionRequestedEventHandlerMap()\Token
      If Core
        Core\remove_PermissionRequested(WebViewPermissionRequestedEventHandlerMap()\Token)
      EndIf
    EndIf
    
    DeleteMapElement(WebViewPermissionRequestedEventHandlerMap())
  EndIf
  
EndProcedure




Procedure.i WebViewAddPermissionRequestedCallback(WebView, *Callback.WebViewPermissionCallBack_Prototype)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *EventHandler.ICoreWebView2PermissionRequestedEventHandler_Structure
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *Callback <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK And Core <> #Null
        
        WebViewRemovePermissionRequestedCallback(WebView, Core)
        
        *EventHandler = AddMapElement(WebViewPermissionRequestedEventHandlerMap(), Str(WebView))
        If *EventHandler
          *EventHandler\pVtable = *EventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
          *EventHandler\pQueryInterface = @ICoreWebView2PermissionRequestedEventHandler_QueryInterface()
          *EventHandler\pAddRef = @ICoreWebView2PermissionRequestedEventHandler_AddRef()
          *EventHandler\pRelease = @ICoreWebView2PermissionRequestedEventHandler_Release()
          *EventHandler\pInvoke = @ICoreWebView2PermissionRequestedEventHandler_Invoke()
          
          *EventHandler\pCallback = *Callback
                        
          If Core\add_PermissionRequested(*EventHandler, @*EventHandler\Token) = #S_OK
            ;Debug *EventHandler\Token
            Result = #True
          Else
            WebViewRemovePermissionRequestedCallback(WebView, Core)
          EndIf
            
        EndIf
        
        Core\Release()
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure




CompilerIf #PB_Compiler_IsMainFile
  
  ;-Demo
  
  
  Procedure.i PermissionRequestedCallback(PermissionKind.i)
    
    Protected.i Permission
    
    
    ;Debug "PermissionKind: " + Str(PermissionKind)
    
    Select PermissionKind
      Case #Microphone  : Permission = #Allow
      Default           : Permission = #Default
    EndSelect
    
    ProcedureReturn Permission
    
  EndProcedure
  
;----- Choix de la zone à alimenter
  Procedure OutputJS(JsonParameters$)
    Protected texte.s
    ;Debug "From Page" + JsonParameters$
    texte = Mid(JsonParameters$, 3, Len(JsonParameters$) - 4)
    
    ; Thème
    If GetGadgetText(bt_theme) = "Clique quand l'enregistrement est OK"
      texte = Left(texte, Len(texte) - 1)
      SetGadgetText(txt_theme, texte)
    EndIf

     ; Question
    If GetGadgetText(bt_question) = "Clique quand l'enregistrement est OK"
      SetGadgetText(txt_question, texte)
    EndIf
    
    ; Proposition 1
    If GetGadgetText(bt_proposition_1) = "Clique quand l'enregistrement est OK"
      texte = Left(texte, Len(texte) - 1)
      texte = "A) " + texte
      SetGadgetText(txt_proposition_1, texte)
    EndIf
    
    ; Proposition 2
    If GetGadgetText(bt_proposition_2) = "Clique quand l'enregistrement est OK"
      texte = Left(texte, Len(texte) - 1)
      texte = "B) " + texte
      SetGadgetText(txt_proposition_2, texte)
    EndIf
    
    ; Proposition 3
    If GetGadgetText(bt_proposition_3) = "Clique quand l'enregistrement est OK"
      texte = Left(texte, Len(texte) - 1)
      texte = "C) " + texte
      SetGadgetText(txt_proposition_3, texte)
    EndIf
    
    ; Proposition 4
    If GetGadgetText(bt_proposition_4) = "Clique quand l'enregistrement est OK"
      texte = Left(texte, Len(texte) - 1)
      texte = "D) " + texte
      SetGadgetText(txt_proposition_4, texte)
    EndIf
    
    ; Réponse
    If GetGadgetText(bt_reponse) = "Clique quand l'enregistrement est OK"
      SetGadgetText(txt_reponse, texte)
    EndIf

  EndProcedure
  
  Define Html$, Filename$, Event.i
  
  Html$ = ~"<!DOCTYPE html>\n" +
          ~"<html lang=fr>\n" +
          ~" <head>\n" +
          ~"  <title>Voice To Text</title>\n" +
          ~" </head>\n" +
          ~" <body>\n" +
          ~"  <div id=\"output\"></div>\n" +
          ~"  \n" +
          ~"  <script>\n" +
          ~"   const outputDiv = document.getElementById('output');\n" +
          ~"   \n" +
          ~"   const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition)();\n" +
          ~"   recognition.lang = 'fr-FR';\n" +
          ~"   recognition.continuous = true;\n" +
          ~"   recognition.interimResults = false;\n" +
          ~"   recognition.maxAlternatives = 1;\n" +
          ~"   recognition.start();\n" +
          ~"   \n" +
          ~"   recognition.onresult = (event) => {\n" +
          ~"    const transcript = event.results[event.resultIndex][0].transcript;\n" +
          ~"    outputDiv.textContent = transcript;\n" +
          ~"    window.output(transcript);\n" +
          ~"   };\n" +
          ~"   recognition.onend = (event) => {\n" +
          ~"    outputDiv.textContent = 'END';\n" +
          ~"    recognition.start()\n" +
          ~"   };\n" +
          ~"   \n" +
          ~"  </script>\n" +
          ~" </body>\n" +
          ~"</html>\n"

  
  Filename$ = GetTemporaryDirectory() + "speech_transcription.html"
  If CreateFile(0, Filename$)
    WriteString(0, Html$)
    CloseFile(0)
  EndIf
  
  ;----- Création de la fenêtre Windows
  fenetre_windows = OpenWindow(#PB_Any, 0, 0, #largeur_jeu, #hauteur_jeu, "Reconnaissance vocale - Jacques Joly - 2025",#PB_Window_BorderLess |#PB_Window_ScreenCentered)
  SetWindowColor(fenetre_windows, #couleur_fond_fenetre)

  creer_gadgets()
  
  web_gadget = WebViewGadget(#PB_Any, 0, 0, 420, 460, #PB_WebView_Debug)
  HideGadget(web_gadget, #True)
  WebViewAddPermissionRequestedCallback(web_gadget, @PermissionRequestedCallback())
  
  SetGadgetText(web_gadget, "file://" + Filename$)
  
  BindWebViewCallback(web_gadget, "output", @OutputJS())
  
  afficher_gadgets()
  
  ;----- Boucle principale
  Repeat 
    Event = WaitWindowEvent()
    Select Event
        
      ;===== Evènements sur les gadgets
      Case #PB_Event_Gadget
        gadget_id = EventGadget()
        
        ;===== Clic sur bouton Quitter
        If gadget_id = bt_quitter
          Select EventType()
            Case #PB_EventType_LeftClick
              quitter = #True
          EndSelect 
        EndIf
        
        ;===== Clic sur bouton Enregistrer le theme
        If gadget_id = bt_theme
          Select EventType()
            Case #PB_EventType_LeftClick
              If GetGadgetText(bt_theme) = "Clique pour enregistrer le thème"
                SetGadgetText(bt_theme, "Clique quand l'enregistrement est OK")
                cacher_tous_les_boutons()
                HideGadget(bt_theme, #False)
              Else
                SetGadgetText(bt_theme, "Clique pour enregistrer le thème")
                afficher_tous_les_boutons()
              EndIf
          EndSelect 
        EndIf

        ;===== Clic sur bouton Enregistrer la question
        If gadget_id = bt_question
          Select EventType()
            Case #PB_EventType_LeftClick
              If GetGadgetText(bt_question) = "Clique pour enregistrer la question"
                SetGadgetText(bt_question, "Clique quand l'enregistrement est OK")
                cacher_tous_les_boutons()
                HideGadget(bt_question, #False)
              Else
                SetGadgetText(bt_question, "Clique pour enregistrer la question")
                afficher_tous_les_boutons()
              EndIf
          EndSelect 
        EndIf
        
        ;===== Clic sur bouton Enregistrer la proposition 1
        If gadget_id = bt_proposition_1
          Select EventType()
            Case #PB_EventType_LeftClick
              If GetGadgetText(bt_proposition_1) = "Clique pour enregistrer la proposition 1"
                SetGadgetText(bt_proposition_1, "Clique quand l'enregistrement est OK")
                cacher_tous_les_boutons()
                HideGadget(bt_proposition_1, #False)
              Else
                SetGadgetText(bt_proposition_1, "Clique pour enregistrer la proposition 1")
                afficher_tous_les_boutons()
              EndIf
          EndSelect 
        EndIf
        
        ;===== Clic sur bouton Enregistrer la proposition 2
        If gadget_id = bt_proposition_2
          Select EventType()
            Case #PB_EventType_LeftClick
              If GetGadgetText(bt_proposition_2) = "Clique pour enregistrer la proposition 2"
                SetGadgetText(bt_proposition_2, "Clique quand l'enregistrement est OK")
                cacher_tous_les_boutons()
                HideGadget(bt_proposition_2, #False)
              Else
                SetGadgetText(bt_proposition_2, "Clique pour enregistrer la proposition 2")
                afficher_tous_les_boutons()
              EndIf
          EndSelect 
        EndIf
        
        ;===== Clic sur bouton Enregistrer la proposition 3
        If gadget_id = bt_proposition_3
          Select EventType()
            Case #PB_EventType_LeftClick
              If GetGadgetText(bt_proposition_3) = "Clique pour enregistrer la proposition 3"
                SetGadgetText(bt_proposition_3, "Clique quand l'enregistrement est OK")
                cacher_tous_les_boutons()
                HideGadget(bt_proposition_3, #False)
              Else
                SetGadgetText(bt_proposition_3, "Clique pour enregistrer la proposition 3")
                afficher_tous_les_boutons()
              EndIf
          EndSelect 
        EndIf
        
        ;===== Clic sur bouton Enregistrer la proposition 4
        If gadget_id = bt_proposition_4
          Select EventType()
            Case #PB_EventType_LeftClick
              If GetGadgetText(bt_proposition_4) = "Clique pour enregistrer la proposition 4"
                SetGadgetText(bt_proposition_4, "Clique quand l'enregistrement est OK")
                cacher_tous_les_boutons()
                HideGadget(bt_proposition_4, #False)
              Else
                SetGadgetText(bt_proposition_4, "Clique pour enregistrer la proposition 4")
                afficher_tous_les_boutons()
              EndIf
          EndSelect 
        EndIf
        
        ;===== Clic sur bouton Enregistrer la réponse
        If gadget_id = bt_reponse
          Select EventType()
            Case #PB_EventType_LeftClick
              If GetGadgetText(bt_reponse) = "Clique pour enregistrer la réponse"
                SetGadgetText(bt_reponse, "Clique quand l'enregistrement est OK")
                cacher_tous_les_boutons()
                HideGadget(bt_reponse, #False)
              Else
                SetGadgetText(bt_reponse, "Clique pour enregistrer la réponse")
                afficher_tous_les_boutons()
              EndIf
          EndSelect 
        EndIf

    EndSelect
    
  Until quitter
  
  DeleteFile(Filename$)
  
CompilerEndIf

Procedure afficher_gadgets()
  HideGadget(txt_theme, #False)
  HideGadget(bt_theme, #False)
  HideGadget(txt_question, #False)
  HideGadget(bt_question, #False)
  HideGadget(txt_proposition_1, #False)
  HideGadget(bt_proposition_1, #False)
  HideGadget(txt_proposition_2, #False)
  HideGadget(bt_proposition_2, #False)
  HideGadget(txt_proposition_3, #False)
  HideGadget(bt_proposition_3, #False)
  HideGadget(txt_proposition_4, #False)
  HideGadget(bt_proposition_4, #False)
  HideGadget(txt_reponse, #False)
  HideGadget(bt_reponse, #False)
  HideGadget(bt_quitter, #False)
EndProcedure

Procedure afficher_tous_les_boutons()
  HideGadget(bt_theme, #False)
  HideGadget(bt_question, #False)
  HideGadget(bt_proposition_1, #False)
  HideGadget(bt_proposition_2, #False)
  HideGadget(bt_proposition_3, #False)
  HideGadget(bt_proposition_4, #False)
  HideGadget(bt_reponse, #False)
EndProcedure

Procedure cacher_tous_les_boutons()
  HideGadget(bt_theme, #True)
  HideGadget(bt_question, #True)
  HideGadget(bt_proposition_1, #True)
  HideGadget(bt_proposition_2, #True)
  HideGadget(bt_proposition_3, #True)
  HideGadget(bt_proposition_4, #True)
  HideGadget(bt_reponse, #True)
EndProcedure

Procedure creer_gadgets()
  Protected x.w, y.w, l.w, h.w
  
  ; Zone de texte où s'affichera le thème
  x=10 : y=10 : l=900 : h=40
  txt_theme = StringGadget(#PB_Any, x, y, l, h, "")
  SetGadgetFont(txt_theme, FontID(police_18))
  SetGadgetColor(txt_theme, #PB_Gadget_FrontColor, #couleur_texte)
  SetGadgetColor(txt_theme, #PB_Gadget_BackColor, #couleur_fond_texte)
  HideGadget(txt_theme, #True)
  
  ; Bouton à appuyer pour enregistrer le thème
  x=920 : y=10 : l=420 : h=40
  bt_theme = ButtonGadget(#PB_Any, x, y,l, h, "Clique pour enregistrer le thème", #PB_Button_MultiLine)
  SetGadgetFont(bt_theme, FontID(police_14))
  HideGadget(bt_theme, #True)

  ; Zone de texte où s'affichera la question
  x=10 : y=70 : l=1150 : h=100
  txt_question = EditorGadget(#PB_Any, x, y, l, h, #PB_Editor_WordWrap)
  SetGadgetFont(txt_question, FontID(police_18))
  SetGadgetColor(txt_question, #PB_Gadget_FrontColor, #couleur_texte)
  SetGadgetColor(txt_question, #PB_Gadget_BackColor, #couleur_fond_texte)
  HideGadget(txt_question, #True)
  
  ; Bouton à appuyer pour enregistrer la question
  x=1170 : y=70 : l=170 : h=100
  bt_question = ButtonGadget(#PB_Any, x, y,l, h, "Clique pour enregistrer la question", #PB_Button_MultiLine)
  SetGadgetFont(bt_question, FontID(police_14))
  HideGadget(bt_question, #True)
  
  ; Zone de texte où s'affichera la proposition 1
  x=10 : y=190 : l=900 : h=40
  txt_proposition_1 = StringGadget(#PB_Any, x, y, l, h, "")
  SetGadgetFont(txt_proposition_1, FontID(police_18))
  SetGadgetColor(txt_proposition_1, #PB_Gadget_FrontColor, #couleur_texte)
  SetGadgetColor(txt_proposition_1, #PB_Gadget_BackColor, #couleur_fond_texte)
  HideGadget(txt_proposition_1, #True)
  
  ; Bouton à appuyer pour enregistrer la proposition 1
  x=920 : y=190 : l=420 : h=40
  bt_proposition_1 = ButtonGadget(#PB_Any, x, y,l, h, "Clique pour enregistrer la proposition 1", #PB_Button_MultiLine)
  SetGadgetFont(bt_proposition_1, FontID(police_14))
  HideGadget(bt_proposition_1, #True)

  ; Zone de texte où s'affichera la proposition 2
  x=10 : y=240 : l=900 : h=40
  txt_proposition_2 = StringGadget(#PB_Any, x, y, l, h, "")
  SetGadgetFont(txt_proposition_2, FontID(police_18))
  SetGadgetColor(txt_proposition_2, #PB_Gadget_FrontColor, #couleur_texte)
  SetGadgetColor(txt_proposition_2, #PB_Gadget_BackColor, #couleur_fond_texte)
  HideGadget(txt_proposition_2, #True)
  
  ; Bouton à appuyer pour enregistrer la proposition 2
  x=920 : y=240 : l=420 : h=40
  bt_proposition_2 = ButtonGadget(#PB_Any, x, y,l, h, "Clique pour enregistrer la proposition 2", #PB_Button_MultiLine)
  SetGadgetFont(bt_proposition_2, FontID(police_14))
  HideGadget(bt_proposition_2, #True)
  
  ; Zone de texte où s'affichera la proposition 3
  x=10 : y=290 : l=900 : h=40
  txt_proposition_3 = StringGadget(#PB_Any, x, y, l, h, "")
  SetGadgetFont(txt_proposition_3, FontID(police_18))
  SetGadgetColor(txt_proposition_3, #PB_Gadget_FrontColor, #couleur_texte)
  SetGadgetColor(txt_proposition_3, #PB_Gadget_BackColor, #couleur_fond_texte)
  HideGadget(txt_proposition_3, #True)
  
  ; Bouton à appuyer pour enregistrer la proposition 3
  x=920 : y=290 : l=420 : h=40
  bt_proposition_3 = ButtonGadget(#PB_Any, x, y,l, h, "Clique pour enregistrer la proposition 3", #PB_Button_MultiLine)
  SetGadgetFont(bt_proposition_3, FontID(police_14))
  HideGadget(bt_proposition_3, #True)
  
  ; Zone de texte où s'affichera la proposition 4
  x=10 : y=340 : l=900 : h=40
  txt_proposition_4 = StringGadget(#PB_Any, x, y, l, h, "")
  SetGadgetFont(txt_proposition_4, FontID(police_18))
  SetGadgetColor(txt_proposition_4, #PB_Gadget_FrontColor, #couleur_texte)
  SetGadgetColor(txt_proposition_4, #PB_Gadget_BackColor, #couleur_fond_texte)
  HideGadget(txt_proposition_4, #True)
  
  ; Bouton à appuyer pour enregistrer la proposition 4
  x=920 : y=340 : l=420 : h=40
  bt_proposition_4 = ButtonGadget(#PB_Any, x, y,l, h, "Clique pour enregistrer la proposition 4", #PB_Button_MultiLine)
  SetGadgetFont(bt_proposition_4, FontID(police_14))
  HideGadget(bt_proposition_4, #True)
  
  ; Zone de texte où s'affichera la réponse
  x=10 : l=1150 : h=100 : y=#hauteur_jeu - h - 30 - 20
  txt_reponse = EditorGadget(#PB_Any, x, y, l, h, #PB_Editor_WordWrap)
  SetGadgetFont(txt_reponse, FontID(police_18))
  SetGadgetColor(txt_reponse, #PB_Gadget_FrontColor, #couleur_texte)
  SetGadgetColor(txt_reponse, #PB_Gadget_BackColor, #couleur_fond_texte)
  HideGadget(txt_reponse, #True)
  
  ; Bouton à appuyer pour enregistrer la réponse
  x=1170 : y=y : l=170 : h=100
  bt_reponse = ButtonGadget(#PB_Any, x, y,l, h, "Clique pour enregistrer la réponse", #PB_Button_MultiLine)
  SetGadgetFont(bt_reponse, FontID(police_14))
  HideGadget(bt_reponse, #True)
  
  ; Bouton Quitter
  l=110 : h=30 : x=#largeur_jeu - l - 10 : y=#hauteur_jeu - h - 10
  bt_quitter = ButtonGadget(#PB_Any, x, y,l, h, "Quitter")
  SetGadgetFont(bt_quitter, FontID(police_14))
  HideGadget(bt_quitter, #True)
  
EndProcedure


Re: Speech recognition

Posted: Sun Sep 21, 2025 5:31 pm
by infratec
Of course you can remove this disturbing line:

Code: Select all

 ~"    outputDiv.textContent = 'END';\n" +

Re: Speech recognition

Posted: Sun Sep 21, 2025 5:48 pm
by jak64
Why? With this new html code, voice recognition works very well even if I don't speak for 1 minute, when I speak again, voice recognition still works, this is what I want and this was not the case with the old html code.

Re: Speech recognition

Posted: Sun Sep 21, 2025 6:06 pm
by infratec
What do you think this line does?

Re: Speech recognition

Posted: Sun Sep 21, 2025 6:08 pm
by jak64
I don't know !!!

Re: Speech recognition

Posted: Sun Sep 21, 2025 6:16 pm
by infratec
It shows the text END.
Nothing more, nothing less.
I implemented this only for debugging, to see if the callback is reached.

You can remove it without loss of any functionality.

Re: Speech recognition

Posted: Sun Sep 21, 2025 6:32 pm
by jak64
That's what I did.
Thanks, Infratec.