Speak and recording of text in 59 languages styles (win32).

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Speak and recording of text in 59 languages styles (win32).

Post by D.J.Peters »

Some of you asked for "text to wav" .
This is a stripped down win32 version of eSpeak.
(I added *.wav recording. source code are included)

Some of the supported language styles by eSpeak:
afrikaans, catalan, welsh-test, german, default
english, english_rp, english-us, esperanto, spanish-latin-american
finnish, french (Belgium), hindi, hungarian, armenian-west
icelandic-test, lojban, kannada, latin, macedonian-test
nahuatl - classical, norwegian, polish, portugal, russian_test
albanian, swedish, tamil, vietnam, cantonese

More infos about eSpeak can be found at: http://espeak.sourceforge.net

Download: eSpeakSynth.zip

speak text: (string and wstring both are supported)

Code: Select all

#include once "eSpeakSynth.bi"
eSpeak.Speak("I like free basic")
? "wait ...":sleep
speak and record text:

Code: Select all

#include once "eSpeakSynth.bi"
eSpeak.Speak("You can play the voice back from wave file later, if you like.","Test.wav")
? "wait ...":sleep
get all voice styles:

Code: Select all

#include once "eSpeakSynth.bi"
var nVoices=eSpeak.VoiceCount
? "list of all " & nVoices & " language styles."
? string(40,"=")
for i as integer = 0 to nVoices step 2
  ? eSpeak.GetVoiceName(i),eSpeak.GetVoiceName(i+1)
next
sleep
use different voices:

Code: Select all

#include once "eSpeakSynth.bi"
eSpeak.Speak("Be or not to be. This is the question.")
eSpeak.CurrentVoice = "german"
eSpeak.Speak("Sein oder nicht sein. Das ist die Frage.")
? "wait...":sleep
You can set/get WordsPerMinute,WordGap,Volume,Pitch ...
You can get back the default values WordsPerMinuteDefault,WordGapDefault,VolumeDefault,PitchDefault ...
take a look at "eSpeakSynth.bi"

Code: Select all

#include once "eSpeakSynth.bi"
for i as integer=0 to 100 step 10
  eSpeak.Pitch=i
  eSpeak.Speak("pitch ")
next
eSpeak.Pitch=50
eSpeak.Speak("default pitch")
? "wait ...":sleep
Don't speak to much :-)

Joshy

"eSpeakSnth.bi"

Code: Select all

#ifndef __EPEAK_SYNTH_BI__
#define __EPEAK_SYNTH_BI__

#include once "espeak.bi"
#include once "windows.bi"
#include once "win/mmsystem.bi"
#include once "crt/string.bi"
#include once "crt/stdlib.bi"

#ifndef WAVE_MAPPER
#define WAVE_MAPPER cuint(-1)
#endif

#define FCC(c) *(cptr(uinteger ptr,@##c))

type ESPEAKSYNTH
  declare constructor(datapath as string="",DeviceIndex as uinteger=WAVE_MAPPER)
  declare destructor
  declare function VoiceCount as integer
  declare function GetVoiceName(index as integer) as string
  declare sub      SetVoiceName(voicename as string)
    
  declare property Volume(value as integer)
  declare property Volume as integer
  declare property VolumeDefault as integer
   
  declare property Pitch(value as integer)
  declare property Pitch as integer
  declare property PitchDefault as integer
  
  declare property Range(value as integer)
  declare property Range as integer
  declare property RangeDefault as integer

  declare property WordsPerMinute(words as integer)
  declare property WordsPerMinute as integer
  declare property WordsPerMinuteDefault as integer
  
  declare property WordGap(value as integer)
  declare property WordGap as integer
  declare property WordGapDefault as integer

  declare property Synchron(onoff as integer)
  declare property Synchron as integer
        
  declare function Speak(txt as string,file as string="") as integer
  declare function Speak(txt as wstring,file as string="") as integer
  
  declare function SpeakKey(txt as string) as integer
  
  private:
  declare sub InRange(byref value as integer,min as integer,max as integer)
  declare sub BeginRecording(file as string)
  declare sub EndRecording  
  declare static sub AudioCallback( _
    hDevice as HWAVEOUT, _
    DriverMessage as uinteger, _
    pESpeakSynth  as ESPEAKSYNTH ptr, _
    pWaveHeader   as PWAVEHDR, _
    Param2        as DWORD)
  declare static function SynthCallback cdecl (_
    pSamples      as short ptr, _
    nNewSamples   as integer, _
    pEvent        as ESPEAK_EVENT ptr) as CallbackResult                                 
  as integer        nVoices,nSamplesPerBuffer,nRate,hFile,nActiveBuffers
  as integer        IsAudioOpen,IsSynchron,nByesRecorded
  as uinteger ptr   pWAVEHeader
  as VOICELIST      Voices
  as WAVEFORMATEX   wfex
  as WAVEOUTCAPS    Caps
  as HWAVEOUT       hDevice
  as MMRESULT       LastResult
end type
' one global instance
dim shared as ESPEAKSYNTH eSpeak

' init datapath, synth and voices
constructor ESPEAKSYNTH(datapath as string,DeviceIndex as uinteger)
  
  ' ####################
  ' # init speak synth #
  ' ####################
  nRate=22050:nSamplesPerBuffer=2205
  if datapath="" then datapath=ExePath()
  if (espeak_Initialize(2,nSamplesPerBuffer,datapath)<>nRate) then
    open ERR for output as #99
    print #99,"error: Initialize(" & datapath & ") !"
    close #99
    beep:sleep:end 1
  end if
  Voices = espeak_ListVoices(0)
  while Voices[nVoices]<>0
    nVoices+=1
  wend
  if (nVoices<1) then
    open ERR for output as #99
    print #99,"error: no voices !"
    close #99
    beep:sleep:end 1
  end if
  espeak_SetSynthCallback(@SynthCallback)
  
  ' ######################
  ' # setup audio device #
  ' ######################
  LastResult=waveOutGetDevCaps(DeviceIndex, _
                               @Caps, _
                               sizeof(WAVEOUTCAPS))
  if (LastResult<>MMSYSERR_NOERROR) then
    open ERR for output as #99
    print #99,"error: get audio caps !"
    close #99
    beep:sleep:end 1
  end if
  with wfex
    .wFormatTag      = WAVE_FORMAT_PCM
    .nSamplesPerSec  = nRate
    .nChannels       = 1
    .wBitsPerSample  = 16
    .nBlockAlign     = (.wBitsPerSample shr 3) * .nChannels
    .nAvgBytesPerSec = .nBlockAlign * .nSamplesPerSec
    .cbSize          = 0 ' no extra bytes
  end with
  LastResult = waveOutOpen(@hDevice, _
                           DeviceIndex, _
                           cptr(LPCWAVEFORMATEX,@wfex), _
                           cast(uinteger,@AudioCallback), _
                           cast(uinteger,@this), _
                           CALLBACK_FUNCTION) 
  if (LastResult<>MMSYSERR_NOERROR) or (IsAudioOpen<>1) then
    open ERR for output as #99
    print #99,"error: open audio device !"
    close #99
    beep:sleep:end 1
  end if
  pWAVEHeader=calloc(11,sizeof(uinteger))
end constructor

' stop audiodevice, voicesynth and  free all resources
destructor ESPEAKSYNTH
  ' ##############
  ' # stop synth #
  ' ##############
  if espeak_IsPlaying() then 
    espeak_Cancel()
    sleep 100,1
  end if  
  ' ########################
  ' # free synth resources #
  ' ########################
  espeak_Terminate()
  
  ' ##############
  ' # stop audio #
  ' ##############
  if IsAudioOpen then
    waveOutReset(hDevice)
    sleep 500,1
    dim as integer count = 100
    ' ######################## 
    ' # free audio resources #
    ' ########################
    LastResult=waveOutClose(hDevice)
    while (LastResult=WAVERR_STILLPLAYING) andalso (count>0)
      sleep 10,1:count-=1
      LastResult=waveOutClose(hDevice)
    wend  
  end if  
  if pWAVEHeader then
    free(pWAVEHeader)
  end if  
end destructor

sub ESPEAKSYNTH.AudioCallBack(hDevice   as HWAVEOUT, _
                              DriverMsg as uinteger, _
                              pSynth    as ESPEAKSYNTH ptr, _
                              pBuffer   as PWAVEHDR, _
                              Param2    as DWORD)
  select case as const DriverMsg
  case WOM_DONE 
    if (pBuffer<>NULL) then
      ' unprepare and free buffer
      waveOutUnprepareHeader(pSynth->hDevice,pBuffer,sizeof(WAVEHDR))
      free(pBuffer->lpData)
      free(pBuffer)
      pSynth->nActiveBuffers-=1
    end if  
  case WOM_OPEN
    pSynth->IsAudioOpen = 1
  case WOM_CLOSE
    pSynth->IsAudioOpen = 0
  end select
end sub

function ESPEAKSYNTH.SynthCallback cdecl (pWave       as short ptr, _
                                          nNewSamples as integer, _
                                          pEvent      as ESPEAK_EVENT ptr) as CallbackResult
                                                          

  
  if (nNewSamples>0) then
    nNewSamples shl=1 ' n samples to n bytes
    dim as ESPEAKSYNTH ptr pSynth = pEvent->User_Data                                          
    if (pSynth<>NULL) then
      if (pSynth->IsAudioOpen) then
        dim as PWAVEHDR pBuffer = calloc(1,sizeof(WAVEHDR))
        pBuffer->lpData=calloc(1,nNewSamples)
        pBuffer->dwBufferLength=nNewSamples
        memcpy(pBuffer->lpData,pWave,nNewSamples) 
        waveOutPrepareHeader(pSynth->hDevice,pBuffer,sizeof(WAVEHDR))
        waveOutWrite(pSynth->hDevice,pBuffer,sizeof(WAVEHDR))
        pSynth->nActiveBuffers+=1
      end if
      ' in recording mode ?
      if (pSynth->hFile<>0) then
        dim as ubyte ptr p=cptr(ubyte ptr,pWave)
        put #pSynth->hFile,,*p,nNewSamples 
        pSynth->nByesRecorded+=nNewSamples 
      end if
    end if    
  end if
  return OK
end function

sub ESPEAKSYNTH.InRange(byref value as integer,min as integer,max as integer)
  if value<min then
    value=min
  elseif value>max then
    value=max
  end if    
end sub

function ESPEAKSYNTH.VoiceCount as integer
  return nVoices
end function  

function ESPEAKSYNTH.GetVoiceName(index as integer) as string
  InRange(index,0,nVoices-1)
  return *Voices[index]->Name
end function

sub ESPEAKSYNTH.SetVoiceName(voicename as string)
  espeak_SetVoiceByName(voicename)
end sub

property ESPEAKSYNTH.WordsPerMinute(value as integer)
  InRange(value,80,450):espeak_SetParameter(PARAM_RATE,value)
end property
property ESPEAKSYNTH.WordsPerMinute as integer
  return espeak_GetParameter(PARAM_RATE,1)
end property
property ESPEAKSYNTH.WordsPerMinuteDefault as integer
  return espeak_GetParameter(PARAM_RATE,0)
end property

property ESPEAKSYNTH.WordGap(value as integer)
  value\=10
  InRange(value,0,100):espeak_SetParameter(PARAM_WORDGAP,value)
end property
property ESPEAKSYNTH.WordGap as integer
  return espeak_GetParameter(PARAM_WORDGAP,1)*10
end property
property ESPEAKSYNTH.WordGapDefault as integer
  return espeak_GetParameter(PARAM_WORDGAP,0)*10
end property

property ESPEAKSYNTH.Volume(value as integer)
  InRange(value,0,200):espeak_SetParameter(PARAM_VOLUME,value)
end property
property ESPEAKSYNTH.Volume as integer
  return espeak_GetParameter(PARAM_VOLUME,1)
end property
property ESPEAKSYNTH.VolumeDefault as integer
  return espeak_GetParameter(PARAM_VOLUME,0)
end property

property ESPEAKSYNTH.Pitch(value as integer)
  InRange(value,0,100):espeak_SetParameter(PARAM_PITCH,value)
end property
property ESPEAKSYNTH.Pitch as integer
  return espeak_GetParameter(PARAM_PITCH,1)
end property
property ESPEAKSYNTH.PitchDefault as integer
  return espeak_GetParameter(PARAM_PITCH,0)
end property

property ESPEAKSYNTH.Range(value as integer)
  InRange(value,0,100):espeak_SetParameter(PARAM_RANGE,value)
end property
property ESPEAKSYNTH.Range as integer
  return espeak_GetParameter(PARAM_RANGE,1)
end property
property ESPEAKSYNTH.RangeDefault as integer
  return espeak_GetParameter(PARAM_RANGE,0)
end property

property ESPEAKSYNTH.Synchron(onoff as integer)
  IsSynchron=(onoff<>0)
end property
property ESPEAKSYNTH.Synchron as integer
  return IsSynchron
end property

sub ESPEAKSYNTH.BeginRecording(file as string)
  ' reset counter
  nByesRecorded=0
  hFile=FreeFile()
  if open(file,for binary,access write,as #hFile) then
    ? "error: can't create '" & file & " !"
    beep:hFile=0
  else
    ' write placeholder RIFF WAVE header
    put #hFile,,*pWAVEHeader,11
  end if
end sub
sub ESPEAKSYNTH.EndRecording
  ' create and write the real WAVE header 
  pWAVEHeader[ 0]=FCC("RIFF")                   ' RIFF chunk
  pWAVEHeader[ 1]=36 + nByesRecorded           ' size of WAVE chunk + data size
  pWAVEHeader[ 2]=FCC("WAVE")                   ' WAVE chunk
  pWAVEHeader[ 3]=FCC("fmt ")                   ' fmt chunk
  pWAVEHeader[ 4]=16                            ' size of fmt chunk
  pWAVEHeader[ 5]=(wfex.nChannels shl 16) or 1  ' nchannels + PCM_FORMAT flag
  pWAVEHeader[ 6]=wfex.nSamplesPerSec           ' playback rate
  pWAVEHeader[ 7]=wfex.nAvgBytesPerSec          ' bytes per sec.
  pWAVEHeader[ 8]=(wfex.wBitsPerSample shl 16) or wfex.nBlockAlign    ' bits per sample + blockalign
  pWAVEHeader[ 9]=FCC("data")                   ' data chunk
  pWAVEHeader[10]=nByesRecorded
  seek #hFile,1
  put #hFile,,*pWaveHeader,11
  close #hFile
  hFile=0
  nByesRecorded=0
end sub
function ESPEAKSYNTH.Speak(txt as string,file as string) as integer
  dim as integer n=len(txt)
  if (n>0) then
    dim as uinteger unicid
    if len(file) then BeginRecording(file)
    function = espeak_Synth(strptr(txt),n,0,POS_CHARACTER,0,espeakCHARS_8bit,@unicid,@this)
    ' in sync or recording mode wait on end
    if (IsSynchron<>0) or (hFile<>0) then 
      espeak_Synchronize()
      while (nActiveBuffers>0):sleep(10):wend
    end if  
    if (hFile) then EndRecording()
  end if
end function  

function ESPEAKSYNTH.Speak(txt as wstring,file as string) as integer
  dim as integer n=len(txt)
  if (n>0) then
    dim as uinteger unicid
    if len(file) then BeginRecording(file)
    function = espeak_Synth(strptr(txt),n,0,POS_CHARACTER,0,espeakCHARS_WCHAR,@unicid,@this)
    ' in sync or recording mode wait on end
    if (IsSynchron<>0) or (hFile<>0) then 
      espeak_Synchronize()
      while (nActiveBuffers>0):sleep(10):wend
    end if  
    if (hFile) then EndRecording()
  end if
end function 


#endif  ' __ESPEAK_SYNTH_BI__
Last edited by D.J.Peters on Oct 12, 2022 18:06, edited 10 times in total.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Speak text and recording the voice in 59 languages style

Post by VANYA »

Good. Thank you Joshy!
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Speak text and recording 59 languages styles (win32).

Post by D.J.Peters »

Fixed: eSpeak.Synchron
Changed: eSpeak.Get/SetVoiceName()
Added: more examples

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Speak text and recording 59 languages styles (win32).

Post by D.J.Peters »

Hello mod you can move it to libraries.

Thank you

Joshy
pestery
Posts: 493
Joined: Jun 16, 2007 2:00
Location: Australia

Re: Speak text and recording 59 languages styles (win32).

Post by pestery »

Nice work Joshy
Coolman
Posts: 294
Joined: Nov 05, 2010 15:09

Re: Speak text and recording 59 languages styles (win32).

Post by Coolman »

Very nice work...
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

Re: Speak and recording of text in 59 languages styles (win3

Post by TESLACOIL »

.
.
.
spelling errors ? I cant compile anything, none of the above , getting heap of errors
( i have Downloaded: eSpeakSynth.zip )

EPEAK ? spelling error ? , first two lines, meant to be ESPEAK ?


spelling errors ? "eSpeakSnth.bi" correct name ? no Y in eSpeakSnth.bi

Code: Select all

    #ifndef __EPEAK_SYNTH_BI__
    #define __EPEAK_SYNTH_BI__

    #include once "espeak.bi"
    #include once "windows.bi"
    #include once "win/mmsystem.bi"
    #include once "crt/string.bi"
    #include once "crt/stdlib.bi"

    #ifndef WAVE_MAPPER
    #define WAVE_MAPPER cuint(-1)
    #endif

    #define FCC(c) *(cptr(uinteger ptr,@##c))

    type ESPEAKSYNTH
      declare constructor(datapath as string="",DeviceIndex as uinteger=WAVE_MAPPER)
      declare destructor
      declare function VoiceCount as integer
      declare function GetVoiceName(index as integer) as string
      declare sub      SetVoiceName(voicename as string)
       
      declare property Volume(value as integer)
      declare property Volume as integer
      declare property VolumeDefault as integer
       
      declare property Pitch(value as integer)
      declare property Pitch as integer
      declare property PitchDefault as integer
     
      declare property Range(value as integer)
      declare property Range as integer
      declare property RangeDefault as integer

      declare property WordsPerMinute(words as integer)
      declare property WordsPerMinute as integer
      declare property WordsPerMinuteDefault as integer
     
      declare property WordGap(value as integer)
      declare property WordGap as integer
      declare property WordGapDefault as integer

      declare property Synchron(onoff as integer)
      declare property Synchron as integer
           
      declare function Speak(txt as string,file as string="") as integer
      declare function Speak(txt as wstring,file as string="") as integer
     
      declare function SpeakKey(txt as string) as integer
     
      private:
      declare sub InRange(byref value as integer,min as integer,max as integer)
      declare sub BeginRecording(file as string)
      declare sub EndRecording 
      declare static sub AudioCallback( _
        hDevice as HWAVEOUT, _
        DriverMessage as uinteger, _
        pESpeakSynth  as ESPEAKSYNTH ptr, _
        pWaveHeader   as PWAVEHDR, _
        Param2        as DWORD)
      declare static function SynthCallback cdecl (_
        pSamples      as short ptr, _
        nNewSamples   as integer, _
        pEvent        as ESPEAK_EVENT ptr) as CallbackResult                                 
      as integer        nVoices,nSamplesPerBuffer,nRate,hFile,nActiveBuffers
      as integer        IsAudioOpen,IsSynchron,nByesRecorded
      as uinteger ptr   pWAVEHeader
      as VOICELIST      Voices
      as WAVEFORMATEX   wfex
      as WAVEOUTCAPS    Caps
      as HWAVEOUT       hDevice
      as MMRESULT       LastResult
    end type
    ' one global instance
    dim shared as ESPEAKSYNTH eSpeak

    ' init datapath, synth and voices
    constructor ESPEAKSYNTH(datapath as string,DeviceIndex as uinteger)
     
      ' ####################
      ' # init speak synth #
      ' ####################
      nRate=22050:nSamplesPerBuffer=2205
      if datapath="" then datapath=ExePath()
      if (espeak_Initialize(2,nSamplesPerBuffer,datapath)<>nRate) then
        open ERR for output as #99
        print #99,"error: Initialize(" & datapath & ") !"
        close #99
        beep:sleep:end 1
      end if
      Voices = espeak_ListVoices(0)
      while Voices[nVoices]<>0
        nVoices+=1
      wend
      if (nVoices<1) then
        open ERR for output as #99
        print #99,"error: no voices !"
        close #99
        beep:sleep:end 1
      end if
      espeak_SetSynthCallback(@SynthCallback)
     
      ' ######################
      ' # setup audio device #
      ' ######################
      LastResult=waveOutGetDevCaps(DeviceIndex, _
                                   @Caps, _
                                   sizeof(WAVEOUTCAPS))
      if (LastResult<>MMSYSERR_NOERROR) then
        open ERR for output as #99
        print #99,"error: get audio caps !"
        close #99
        beep:sleep:end 1
      end if
      with wfex
        .wFormatTag      = WAVE_FORMAT_PCM
        .nSamplesPerSec  = nRate
        .nChannels       = 1
        .wBitsPerSample  = 16
        .nBlockAlign     = (.wBitsPerSample shr 3) * .nChannels
        .nAvgBytesPerSec = .nBlockAlign * .nSamplesPerSec
        .cbSize          = 0 ' no extra bytes
      end with
      LastResult = waveOutOpen(@hDevice, _
                               DeviceIndex, _
                               cptr(LPCWAVEFORMATEX,@wfex), _
                               cast(uinteger,@AudioCallback), _
                               cast(uinteger,@this), _
                               CALLBACK_FUNCTION)
      if (LastResult<>MMSYSERR_NOERROR) or (IsAudioOpen<>1) then
        open ERR for output as #99
        print #99,"error: open audio device !"
        close #99
        beep:sleep:end 1
      end if
      pWAVEHeader=calloc(11,sizeof(uinteger))
    end constructor

    ' stop audiodevice, voicesynth and  free all resources
    destructor ESPEAKSYNTH
      ' ##############
      ' # stop synth #
      ' ##############
      if espeak_IsPlaying() then
        espeak_Cancel()
        sleep 100,1
      end if 
      ' ########################
      ' # free synth resources #
      ' ########################
      espeak_Terminate()
     
      ' ##############
      ' # stop audio #
      ' ##############
      if IsAudioOpen then
        waveOutReset(hDevice)
        sleep 500,1
        dim as integer count = 100
        ' ########################
        ' # free audio resources #
        ' ########################
        LastResult=waveOutClose(hDevice)
        while (LastResult=WAVERR_STILLPLAYING) andalso (count>0)
          sleep 10,1:count-=1
          LastResult=waveOutClose(hDevice)
        wend 
      end if 
      if pWAVEHeader then
        free(pWAVEHeader)
      end if 
    end destructor

    sub ESPEAKSYNTH.AudioCallBack(hDevice   as HWAVEOUT, _
                                  DriverMsg as uinteger, _
                                  pSynth    as ESPEAKSYNTH ptr, _
                                  pBuffer   as PWAVEHDR, _
                                  Param2    as DWORD)
      select case as const DriverMsg
      case WOM_DONE
        if (pBuffer<>NULL) then
          ' unprepare and free buffer
          waveOutUnprepareHeader(pSynth->hDevice,pBuffer,sizeof(WAVEHDR))
          free(pBuffer->lpData)
          free(pBuffer)
          pSynth->nActiveBuffers-=1
        end if 
      case WOM_OPEN
        pSynth->IsAudioOpen = 1
      case WOM_CLOSE
        pSynth->IsAudioOpen = 0
      end select
    end sub

    function ESPEAKSYNTH.SynthCallback cdecl (pWave       as short ptr, _
                                              nNewSamples as integer, _
                                              pEvent      as ESPEAK_EVENT ptr) as CallbackResult
                                                             

     
      if (nNewSamples>0) then
        nNewSamples shl=1 ' n samples to n bytes
        dim as ESPEAKSYNTH ptr pSynth = pEvent->User_Data                                         
        if (pSynth<>NULL) then
          if (pSynth->IsAudioOpen) then
            dim as PWAVEHDR pBuffer = calloc(1,sizeof(WAVEHDR))
            pBuffer->lpData=calloc(1,nNewSamples)
            pBuffer->dwBufferLength=nNewSamples
            memcpy(pBuffer->lpData,pWave,nNewSamples)
            waveOutPrepareHeader(pSynth->hDevice,pBuffer,sizeof(WAVEHDR))
            waveOutWrite(pSynth->hDevice,pBuffer,sizeof(WAVEHDR))
            pSynth->nActiveBuffers+=1
          end if
          ' in recording mode ?
          if (pSynth->hFile<>0) then
            dim as ubyte ptr p=cptr(ubyte ptr,pWave)
            put #pSynth->hFile,,*p,nNewSamples
            pSynth->nByesRecorded+=nNewSamples
          end if
        end if   
      end if
      return OK
    end function

    sub ESPEAKSYNTH.InRange(byref value as integer,min as integer,max as integer)
      if value<min then
        value=min
      elseif value>max then
        value=max
      end if   
    end sub

    function ESPEAKSYNTH.VoiceCount as integer
      return nVoices
    end function 

    function ESPEAKSYNTH.GetVoiceName(index as integer) as string
      InRange(index,0,nVoices-1)
      return *Voices[index]->Name
    end function

    sub ESPEAKSYNTH.SetVoiceName(voicename as string)
      espeak_SetVoiceByName(voicename)
    end sub

    property ESPEAKSYNTH.WordsPerMinute(value as integer)
      InRange(value,80,450):espeak_SetParameter(PARAM_RATE,value)
    end property
    property ESPEAKSYNTH.WordsPerMinute as integer
      return espeak_GetParameter(PARAM_RATE,1)
    end property
    property ESPEAKSYNTH.WordsPerMinuteDefault as integer
      return espeak_GetParameter(PARAM_RATE,0)
    end property

    property ESPEAKSYNTH.WordGap(value as integer)
      value\=10
      InRange(value,0,100):espeak_SetParameter(PARAM_WORDGAP,value)
    end property
    property ESPEAKSYNTH.WordGap as integer
      return espeak_GetParameter(PARAM_WORDGAP,1)*10
    end property
    property ESPEAKSYNTH.WordGapDefault as integer
      return espeak_GetParameter(PARAM_WORDGAP,0)*10
    end property

    property ESPEAKSYNTH.Volume(value as integer)
      InRange(value,0,200):espeak_SetParameter(PARAM_VOLUME,value)
    end property
    property ESPEAKSYNTH.Volume as integer
      return espeak_GetParameter(PARAM_VOLUME,1)
    end property
    property ESPEAKSYNTH.VolumeDefault as integer
      return espeak_GetParameter(PARAM_VOLUME,0)
    end property

    property ESPEAKSYNTH.Pitch(value as integer)
      InRange(value,0,100):espeak_SetParameter(PARAM_PITCH,value)
    end property
    property ESPEAKSYNTH.Pitch as integer
      return espeak_GetParameter(PARAM_PITCH,1)
    end property
    property ESPEAKSYNTH.PitchDefault as integer
      return espeak_GetParameter(PARAM_PITCH,0)
    end property

    property ESPEAKSYNTH.Range(value as integer)
      InRange(value,0,100):espeak_SetParameter(PARAM_RANGE,value)
    end property
    property ESPEAKSYNTH.Range as integer
      return espeak_GetParameter(PARAM_RANGE,1)
    end property
    property ESPEAKSYNTH.RangeDefault as integer
      return espeak_GetParameter(PARAM_RANGE,0)
    end property

    property ESPEAKSYNTH.Synchron(onoff as integer)
      IsSynchron=(onoff<>0)
    end property
    property ESPEAKSYNTH.Synchron as integer
      return IsSynchron
    end property

    sub ESPEAKSYNTH.BeginRecording(file as string)
      ' reset counter
      nByesRecorded=0
      hFile=FreeFile()
      if open(file,for binary,access write,as #hFile) then
        ? "error: can't create '" & file & " !"
        beep:hFile=0
      else
        ' write placeholder RIFF WAVE header
        put #hFile,,*pWAVEHeader,11
      end if
    end sub
    sub ESPEAKSYNTH.EndRecording
      ' create and write the real WAVE header
      pWAVEHeader[ 0]=FCC("RIFF")                   ' RIFF chunk
      pWAVEHeader[ 1]=36 + nByesRecorded           ' size of WAVE chunk + data size
      pWAVEHeader[ 2]=FCC("WAVE")                   ' WAVE chunk
      pWAVEHeader[ 3]=FCC("fmt ")                   ' fmt chunk
      pWAVEHeader[ 4]=16                            ' size of fmt chunk
      pWAVEHeader[ 5]=(wfex.nChannels shl 16) or 1  ' nchannels + PCM_FORMAT flag
      pWAVEHeader[ 6]=wfex.nSamplesPerSec           ' playback rate
      pWAVEHeader[ 7]=wfex.nAvgBytesPerSec          ' bytes per sec.
      pWAVEHeader[ 8]=(wfex.wBitsPerSample shl 16) or wfex.nBlockAlign    ' bits per sample + blockalign
      pWAVEHeader[ 9]=FCC("data")                   ' data chunk
      pWAVEHeader[10]=nByesRecorded
      seek #hFile,1
      put #hFile,,*pWaveHeader,11
      close #hFile
      hFile=0
      nByesRecorded=0
    end sub
    function ESPEAKSYNTH.Speak(txt as string,file as string) as integer
      dim as integer n=len(txt)
      if (n>0) then
        dim as uinteger unicid
        if len(file) then BeginRecording(file)
        function = espeak_Synth(strptr(txt),n,0,POS_CHARACTER,0,espeakCHARS_8bit,@unicid,@this)
        ' in sync or recording mode wait on end
        if (IsSynchron<>0) or (hFile<>0) then
          espeak_Synchronize()
          while (nActiveBuffers>0):sleep(10):wend
        end if 
        if (hFile) then EndRecording()
      end if
    end function 

    function ESPEAKSYNTH.Speak(txt as wstring,file as string) as integer
      dim as integer n=len(txt)
      if (n>0) then
        dim as uinteger unicid
        if len(file) then BeginRecording(file)
        function = espeak_Synth(strptr(txt),n,0,POS_CHARACTER,0,espeakCHARS_WCHAR,@unicid,@this)
        ' in sync or recording mode wait on end
        if (IsSynchron<>0) or (hFile<>0) then
          espeak_Synchronize()
          while (nActiveBuffers>0):sleep(10):wend
        end if 
        if (hFile) then EndRecording()
      end if
    end function


    #endif  ' __ESPEAK_SYNTH_BI__



am i being thick , or are there spelling errors or bugs or something


typical errors line 47 , 350 & 355
Expected pointer, found ',' in 'declare function Speak(txt as wstring,file as string="") as integer'
Expected pointer, found ',' in 'function ESPEAKSYNTH.Speak(txt as wstring,file as string) as integer'
Invalid data types, found ')' in 'function = espeak_Synth(strptr(txt),n,0,POS_CHARACTER,0,espeakCHARS_WCHAR,@unicid,@this)'

'
CrashDrive
Posts: 6
Joined: Aug 07, 2011 5:25

Re: Speak and recording of text in 59 languages styles (win3

Post by CrashDrive »

TESLACOIL wrote: typical errors line 47 , 350 & 355
Expected pointer, found ',' in 'declare function Speak(txt as wstring,file as string="") as integer'
----------------------------------------------------------------------------------------------------------------------------------------
@TESLACOIL
I got those same errors using an older version of FreeBasic.
Using newer version and all is well.
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

Re: Speak and recording of text in 59 languages styles (win3

Post by TESLACOIL »

thx
kiyotewolf
Posts: 1009
Joined: Oct 11, 2008 7:42
Location: ABQ, NM
Contact:

Re: Speak and recording of text in 59 languages styles (win3

Post by kiyotewolf »

Used 7-zip to unzip the file..

got this error

7-Zip: Diagnostic Messages

Data error in "eSpeakSynth\espeak-data\da_dict.' File is broken
kiyotewolf
Posts: 1009
Joined: Oct 11, 2008 7:42
Location: ABQ, NM
Contact:

Re: Speak and recording of text in 59 languages styles (win3

Post by kiyotewolf »

Is there a way to get a female sounding voice?



~Paul
erion
Posts: 1
Joined: Nov 02, 2008 8:55

Re: Speak and recording of text in 59 languages styles (win3

Post by erion »

Hello,

I'm trying to add a stop function to this library, however the application hangs the moment I call waveOutReset().
The function is very simple, it calls waveOutPause and waveOutReset. I've tried to debug this, but it seems it is happening at the API level, i.e. not in the FB code. Does anyone know what could be the problem? Or is WinMM that buggy?

Much thanks,
Erion
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Speak and recording of text in 59 languages styles (win32).

Post by VANYA »

@D.J.Peters
Please update the link. By the way, all links to your projects that lead to the alice-dsl.net / .... server do not work.
Thanks!
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Speak and recording of text in 59 languages styles (win32).

Post by D.J.Peters »

VANYA wrote:@D.J.Peters
Please update the link. By the way, all links to your projects that lead to the alice-dsl.net / .... server do not work.
Thanks!
link is ok now but is old stuff :-)
Post Reply