Speech

Using Javascript from SpiderBasic
IdeasVacuum
Posts: 143
Joined: Tue Feb 25, 2014 1:27 pm

Speech

Post by IdeasVacuum »

Looking for a text-to-speech library that will work with SB on Andriod. Presumably Google text-to-speech is going to be the answer, anyone dabbled?
jamirokwai
Posts: 40
Joined: Fri Sep 25, 2015 12:00 pm

Re: Speech

Post by jamirokwai »

Have a look at this: https://developer.mozilla.org/en-US/doc ... _synthesis

It says, support in Android is available. I tried on an iPhone - MobileSafari doesn't work for now.

Cheers
J.
IdeasVacuum
Posts: 143
Joined: Tue Feb 25, 2014 1:27 pm

Re: Speech

Post by IdeasVacuum »

That's interesting jamirokwai, though the tutorial is aimed at browsers.
Searching for 'speech synthesis' delivers the other end of the scale - tutorials aimed at Android devices:
https://android-developers.googleblog.c ... ch-in.html

So, not sure - for the app I have in mind, which is SmartPhone only, I think it might be better to use a language designed for developing Android Apps.
jamirokwai
Posts: 40
Joined: Fri Sep 25, 2015 12:00 pm

Re: Speech

Post by jamirokwai »

IdeasVacuum wrote:That's interesting jamirokwai, though the tutorial is aimed at browsers.
Searching for 'speech synthesis' delivers the other end of the scale - tutorials aimed at Android devices:
https://android-developers.googleblog.c ... ch-in.html

So, not sure - for the app I have in mind, which is SmartPhone only, I think it might be better to use a language designed for developing Android Apps.
The page says - although I am not sure, what browser Android phones have -
Chrome for Desktop and Android have supported it since around version 33, without prefixes.
^^
User avatar
Peter
Posts: 1093
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Speech

Post by Peter »

Quick 'n Dirty implementation of speechSynthesis:

SpeechSynthesis-Module:

Code: Select all

EnableExplicit

DeclareModule SpeechSynthesis
  
  EnableExplicit
  
  Global IsInitialized
  
  Declare Init(Callback)
  
  Declare Speak(Text.s, Voice = 0, Rate = 1, Pitch = 1)
  
  Structure sVoices
    Name.s
    Language.s
  EndStructure
  
  Global NewList Voices.sVoices()
  
EndDeclareModule

Module SpeechSynthesis
  
  ! var voices = [];
  
  EnableExplicit
  
  Procedure Init(Callback)
    
    ! function populateVoiceList() {
    
    !   if (typeof speechSynthesis === "undefined") return;
    
    !   voices = speechSynthesis.getVoices();
    
    Protected Name.s
    Protected Language.s
    
    ClearList(Voices())
    
    !   $.each(voices,function(a,b) {
    !     v_name     = b.name;
    !     v_language = b.language;
    
    AddElement(Voices())
    Voices()\Name = Name
    Voices()\Language = Language
    
    !   });
    
    !    v_callback();
    
    ! }
    
    ! populateVoiceList();
    
    ! if ( typeof speechSynthesis !== "undefined" && speechSynthesis.onvoiceschanged !== undefined ) speechSynthesis.onvoiceschanged = populateVoiceList;
    
  EndProcedure  
  
  Procedure Speak(Text.s, Voice = 0, Rate = 1, Pitch = 1)
    
    !  var utterThis = new SpeechSynthesisUtterance(v_text);
    
    !  utterThis.voice = voices[v_voice];
    !  utterThis.pitch = v_pitch;
    !  utterThis.rate  = v_rate;
    
    !  window.speechSynthesis.speak(utterThis);
    
  EndProcedure
  
EndModule
Demo:

Code: Select all

XIncludeFile "SpeechSynthesis.sbi"

#Dialog = 0
#Xml = 0

Runtime Enumeration
  #txtToSpeak
  #cboVoices
  #cmdSpeak
  #trkRate
  #trkPitch
EndEnumeration

Procedure Speak()
  
  Protected TextToSpeak.s = GetGadgetText (#txtToSpeak)
  Protected Voice         = GetGadgetState(#cboVoices)
  Protected Pitch         = GetGadgetState(#trkPitch)
  Protected Rate          = GetGadgetState(#trkRate)
  
  SpeechSynthesis::Speak(TextToSpeak, Voice, Rate, Pitch)
  
EndProcedure


Procedure Main()
  
  Protected XML.s
  
  XML = "<window id='#PB_Any' name='test' text='SpeechSynthesis' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu'>" +
        "  <vbox>" +
        "    <text text='Enter some text in the input below and press the speak-button to hear it. change voices using the dropdown menu.' />" +
        "    <empty />" +
        "    <editor id='#txtToSpeak' text='SpiderBasic is new web client-side programming language based on established BASIC rules.' height='60' flags='#PB_Editor_WordWrap' />" +
        "    <empty />" +
        "    <hbox expand='item:2'>" + 
        "      <text text='Rate:' flags='#PB_Text_VerticalCenter' />" + 
        "      <trackbar id='#trkRate' min='0' max='2' value='1' />" +
        "    </hbox>" + 
        "    <hbox expand='item:2'>" + 
        "      <text text='Pitch:' flags='#PB_Text_VerticalCenter' />" + 
        "      <trackbar id='#trkPitch' min='0' max='2' value='1' />" +
        "    </hbox>" + 
        "    <empty />" +
        "    <hbox expand='item:2'>" + 
        "      <text text='Voice:' flags='#PB_Text_VerticalCenter' />" + 
        "      <combobox id='#cboVoices' height='25' />" +
        "    </hbox>" + 
        "    <empty />" +
        "    <button id='#cmdSpeak' text='Speak!' height='60' />" +
        "  </vbox>" +
        "</window>"
  
  If ParseXML(#Xml, XML) And XMLStatus(#Xml) = #PB_XML_Success
    
    If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
      
      SetWindowTitle(DialogWindow(#Dialog), "SpeechSynthesis: " + Str(ListSize(SpeechSynthesis::Voices())) + " Voices loaded")
      
      ForEach SpeechSynthesis::Voices()
        AddGadgetItem(#cboVoices, -1, SpeechSynthesis::Voices()\Name)
      Next
      
      SetGadgetState(#cboVoices, 0)
      
      BindGadgetEvent(#cmdSpeak, @Speak())
      
      DisableGadget(#trkPitch, #True)
      DisableGadget(#trkRate, #True)
      
    Else  
      Debug "Dialog error: " + DialogError(#Dialog)
    EndIf
  Else
    Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
  EndIf
  
EndProcedure

SpeechSynthesis::Init(@Main())
Greetings ... Peter

// Edit 11.04.2024: The code has been changed so that it now also works with Firefox. However, considerably more voices are loaded in the Chrome browser (321 voices) than in Firefox (5 voices).
IdeasVacuum
Posts: 143
Joined: Tue Feb 25, 2014 1:27 pm

Re: Speech

Post by IdeasVacuum »

Interesting code Peter but I can't get it to work :cry:

The Demo Window is not displayed? Tried it on Win7 x86 + FireFox and also as an APK. The Debug Window is displayed but it is empty.
User avatar
Peter
Posts: 1093
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Speech

Post by Peter »

@IdeasVacuum: can you take a look into the Browser-Console (<F12>)? Perhaps there is an Error-Message?

Greetings ... Peter
IdeasVacuum
Posts: 143
Joined: Tue Feb 25, 2014 1:27 pm

Re: Speech

Post by IdeasVacuum »

Hi Peter

Nothing at all in the Console - no errors, warnings, info or debug info. Win7x86 + FireFox 54.0
Quin
Posts: 24
Joined: Wed Nov 08, 2023 4:38 pm

Re: Speech

Post by Quin »

Peter wrote: Mon Jun 19, 2017 3:48 pm Quick 'n Dirty implementation of speechSynthesis:

SpeechSynthesis-Module:

Code: Select all

EnableExplicit

DeclareModule SpeechSynthesis
  
  EnableExplicit
  
  Global IsInitialized
  
  Declare Init(Callback)
  
  Declare Speak(Text.s, Voice = 0, Rate = 1, Pitch = 1)
  
  Structure sVoices
    Name.s
    Language.s
  EndStructure
  
  Global NewList Voices.sVoices()
  
EndDeclareModule

Module SpeechSynthesis
  
  ! var voices = [];
  
  EnableExplicit
  
  Procedure Init(Callback)
    
    ! window.speechSynthesis.onvoiceschanged = function() {
    
    If IsInitialized 
      ProcedureReturn
    EndIf
    
    !    voices = window.speechSynthesis.getVoices();
    
    Protected Name.s
    Protected Language.s
    
    ClearList(Voices())
    
    ! $.each(voices,function(a,b) {
    
    !    v_name     = b.name;
    !    v_language = b.language;
    
    AddElement(Voices())
    Voices()\Name = Name
    Voices()\Language = Language
    
    !  });
    
    IsInitialized = #True
    
    !    v_callback();
    ! };
    
  EndProcedure  
  
  Procedure Speak(Text.s, Voice = 0, Rate = 1, Pitch = 1)
    
    !  var utterThis = new SpeechSynthesisUtterance(v_text);
    
    !  utterThis.voice = voices[v_voice];
    !  utterThis.pitch = v_pitch;
    !  utterThis.rate  = v_rate;
    
    !  window.speechSynthesis.speak(utterThis);
    
  EndProcedure
  
EndModule
Demo:

Code: Select all

XIncludeFile "SpeechSynthesis.sbi"

#Dialog = 0
#Xml = 0

Runtime Enumeration
  #txtToSpeak
  #cboVoices
  #cmdSpeak
  #trkRate
  #trkPitch
EndEnumeration

Procedure Speak()
  
  Protected TextToSpeak.s = GetGadgetText (#txtToSpeak)
  Protected Voice         = GetGadgetState(#cboVoices)
  Protected Pitch         = GetGadgetState(#trkPitch)
  Protected Rate          = GetGadgetState(#trkRate)
  
  SpeechSynthesis::Speak(TextToSpeak, Voice, Rate, Pitch)
  
EndProcedure


Procedure Main()
  
  Protected XML.s
  
  XML = "<window id='#PB_Any' name='test' text='Dialog example' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu'>" +
        "  <vbox>" +
        "    <text text='Enter some text in the input below and press the speak-button to hear it. change voices using the dropdown menu.' />" +
        "    <empty />" +
        "    <editor id='#txtToSpeak' text='SpiderBasic is new web client-side programming language based on established BASIC rules.' height='60' flags='#PB_Editor_WordWrap' />" +
        "    <empty />" +
        "    <hbox expand='item:2'>" + 
        "      <text text='Rate:' flags='#PB_Text_VerticalCenter' />" + 
        "      <trackbar id='#trkRate' min='0' max='2' value='1' />" +
        "    </hbox>" + 
        "    <hbox expand='item:2'>" + 
        "      <text text='Pitch:' flags='#PB_Text_VerticalCenter' />" + 
        "      <trackbar id='#trkPitch' min='0' max='2' value='1' />" +
        "    </hbox>" + 
        "    <empty />" +
        "    <hbox expand='item:2'>" + 
        "      <text text='Voice:' flags='#PB_Text_VerticalCenter' />" + 
        "      <combobox id='#cboVoices' height='25' />" +
        "    </hbox>" + 
        "    <empty />" +
        "    <button id='#cmdSpeak' text='Speak!' height='60' />" +
        "  </vbox>" +
        "</window>"
  
  If ParseXML(#Xml, XML) And XMLStatus(#Xml) = #PB_XML_Success
    
    If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
      
      ForEach SpeechSynthesis::Voices()
        AddGadgetItem(#cboVoices, -1, SpeechSynthesis::Voices()\Name)
      Next
      
      SetGadgetState(#cboVoices, 0)
      
      BindGadgetEvent(#cmdSpeak, @Speak())
      
      DisableGadget(#trkPitch, #True)
      DisableGadget(#trkRate, #True)
      
    Else  
      Debug "Dialog error: " + DialogError(#Dialog)
    EndIf
  Else
    Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
  EndIf
  
EndProcedure

SpeechSynthesis::Init(@Main())
Greetings ... Peter
Just tested, and this still appears to work for me! Excellent work!
Post Reply