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

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
D.J.Peters
Posts: 7852
Joined: May 28, 2005 3:28

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

Postby D.J.Peters » Jan 07, 2012 3:47

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 Jan 15, 2012 19:48, edited 7 times in total.
VANYA
Posts: 1324
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

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

Postby VANYA » Jan 07, 2012 6:11

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

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

Postby D.J.Peters » Jan 07, 2012 13:33

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

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

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

Postby D.J.Peters » Jan 07, 2012 18:01

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).

Postby pestery » Jan 08, 2012 1:57

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

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

Postby Coolman » Jan 15, 2012 17:00

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

Postby TESLACOIL » Mar 01, 2012 5:58

.
.
.
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

Postby CrashDrive » Mar 01, 2012 22:33

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

Postby TESLACOIL » Mar 02, 2012 5:28

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

Postby kiyotewolf » Mar 04, 2012 1:13

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

Postby kiyotewolf » Mar 04, 2012 7:30

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

Postby erion » Jul 27, 2012 16:58

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

Return to “Libraries”

Who is online

Users browsing this forum: No registered users and 1 guest